aboutsummaryrefslogtreecommitdiff
path: root/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector
diff options
context:
space:
mode:
Diffstat (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector')
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATSLVerifier.java265
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATslKeySelector.java123
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java12
3 files changed, 394 insertions, 6 deletions
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATSLVerifier.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATSLVerifier.java
new file mode 100644
index 0000000..39b2f8c
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATSLVerifier.java
@@ -0,0 +1,265 @@
+package at.gv.egovernment.moa.spss.tsl.connector;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.security.cert.X509Certificate;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBIntrospector;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.NodeSetData;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import iaik.server.modules.xml.MOAXSecProvider;
+import iaik.xml.crypto.tsl.TSLConstants;
+import iaik.xml.crypto.tsl.TSLContext;
+import iaik.xml.crypto.tsl.TSLEngine;
+import iaik.xml.crypto.tsl.ex.SeverityAspect.Severity;
+import iaik.xml.crypto.tsl.ex.TSLSecurityException;
+import iaik.xml.crypto.tsl.ex.TSLVerificationException;
+import iaik.xml.crypto.tsl.gen.TrustStatusListType;
+import iaik.xml.crypto.tsl.verify.ITSLVerifier;
+import iaik.xml.crypto.utils.URIDereferencerImpl;
+
+public class MOATSLVerifier implements ITSLVerifier {
+
+ private static final Logger logger = LoggerFactory.getLogger(MOATSLVerifier.class);
+
+ private static iaik.xml.crypto.xmldsig.gen.ObjectFactory dsOf = new iaik.xml.crypto.xmldsig.gen.ObjectFactory();
+
+ private static JAXBIntrospector JI = TSLEngine.jc.createJAXBIntrospector();
+
+ public Boolean verifyTSL(Document tslDoc, TSLContext tslContext,
+ ListIterator<X509Certificate> euTslCertsHash) {
+
+ boolean coreValidity = false;
+
+ try {
+ // Signature s = new Signature();
+ // TrustServiceStatusList tssl = new TrustServiceStatusList();
+ JAXBElement<iaik.xml.crypto.xmldsig.gen.SignatureType> s = dsOf.createSignature(new iaik.xml.crypto.xmldsig.gen.SignatureType());
+// _l.debug(""+JI.getElementName(s));
+ JAXBElement<TrustStatusListType> tssl = TSLConstants.TSL_OF.createTrustServiceStatusList(new TrustStatusListType());
+// _l.debug(""+JI.getElementName(tssl));
+
+ Element tsslE = tslDoc.getDocumentElement();
+
+ if (tsslE == null) {
+ tslContext.throwException(new TSLVerificationException("Empty XML File", Severity.xml_failed));
+ // } else if (!tsslE.getNamespaceURI().equals(tssl.getName().getNamespaceURI())) {
+ } else if (!tsslE.getNamespaceURI().equals(JI.getElementName(tssl).getNamespaceURI())) {
+ tslContext.throwException(new TSLVerificationException("Incorrect Namespace", Severity.xml_failed));
+ // } else if (!tsslE.getLocalName().equals(tssl.getName().getLocalPart())) {
+ } else if (!tsslE.getLocalName().equals(JI.getElementName(tssl).getLocalPart())) {
+ tslContext.throwException(new TSLVerificationException("Wrong Document Element in document "+tslDoc.getDocumentURI(), Severity.xml_failed));
+ }
+
+ //now we can be sure the right document element is in place, Schema validation does not assure this for us
+ //Schema validation however assures that the internal Structure of TrustServicesStatus List is correct
+
+ // B.6 1) It MUST be an enveloped signature.
+
+ Node n = tsslE.getLastChild();
+
+ while ( n != null && ! (n instanceof Element) ) {
+ n = n.getPreviousSibling();
+ }
+
+ Element sig = (Element) n;
+
+ if (sig == null ||
+ // ! sig.getNamespaceURI().equals(s.getName().getNamespaceURI()) ||
+ // ! sig.getLocalName().equals(s.getName().getLocalPart())) {
+ ! sig.getNamespaceURI().equals(JI.getElementName(s).getNamespaceURI()) ||
+ ! sig.getLocalName().equals(JI.getElementName(s).getLocalPart())) {
+
+ tslContext.throwException(
+ new TSLVerificationException(
+ TSLSecurityException.Type.NO_TSL_SIGNATURE)
+ );
+
+ } else {
+
+ NodeList cn = tsslE.getChildNodes();
+
+ for (int j = 0; j < cn.getLength(); j++) {
+ cn.item(j);
+ }
+
+ //TODO assure connection with the PKI Module
+ DOMValidateContext valContext = new DOMValidateContext(
+ new MOATslKeySelector(euTslCertsHash, tslContext),
+ sig);
+
+ if (valContext.getURIDereferencer() == null) {
+ valContext.setURIDereferencer(new URIDereferencerImpl());
+ }
+
+ // valContext.setProperty("iaik.xml.crypto.debug.OutputStream", System.out);
+ valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
+
+ XMLSignatureFactory fac = MOAXSecProvider.getXMLSignatureFactory();
+
+ // unmarshal the XMLSignature
+ XMLSignature signature = fac.unmarshalXMLSignature(valContext);
+
+ // Validate the XMLSignature (generated above)
+ coreValidity = signature.validate(valContext);
+ // Check core validation status
+ if (coreValidity == false) {
+ debug(valContext, "Signature failed core validation");
+ boolean sv = signature.getSignatureValue().validate(valContext);
+ debug(valContext, "signature validation status: " + sv);
+ // check the validation status of each Reference
+ Iterator it = signature.getSignedInfo().getReferences().iterator();
+ for (int j = 0; it.hasNext(); j++) {
+ boolean refValid = ((Reference) it.next()).validate(valContext);
+ debug(valContext, "ref[" + j + "] validity status: " + refValid);
+ }
+
+ tslContext.throwException(new TSLVerificationException("Signature failed core validation", Severity.signature_failed));
+ }
+
+ SignedInfo si = signature.getSignedInfo();
+ Iterator it = si.getReferences().iterator();
+
+
+ // 2) Its ds:SignedInfo element MUST contain a ds:Reference element with the
+ // URI attribute set to a value referencing the TrustServiceStatusList
+ // element enveloping the signature itself. This ds:Reference element MUST
+ // satisfy the following requirements:
+ // a) It MUST contain only one ds:Transforms element.
+ // b) This ds:Transforms element MUST contain two ds:Transform elements. The
+ // first one will be one whose Algorithm attribute indicates the enveloped
+ // transformation with the value:
+ // "http://www.w3.org/2000/09/xmldsig#enveloped-signature". The second one
+ // will be one whose Algorithm attribute instructs to perform the exclusive
+ // canonicalization "http://www.w3.org/2001/10/xml-exc-c14n#"
+
+ boolean found_proper_tsslE_reference = false;
+
+ for (int j = 0; it.hasNext(); j++) {
+ Reference ref = ((Reference) it.next());
+ Data d = valContext.getURIDereferencer().dereference(ref, valContext);
+
+ if(!(d instanceof NodeSetData)) {
+ continue;
+ } else {
+ NodeSetData nsd = (NodeSetData) d;
+
+
+ if (nsd.iterator().next() == tsslE) {
+
+ //Assured by XMLSchema
+ //throw new TSLException("B.6 2 a) It MUST contain only one ds:Transforms element.");
+
+ if(ref.getTransforms().size() != 2) {
+ tslContext.throwException(
+ new TSLVerificationException(TSLSecurityException.Type.NON_CONFORMANT_TRANSFORMS_IN_TSL_SIGNATURE)
+ );
+ } else {
+
+ Transform[] transforms = (Transform[]) ref.getTransforms().toArray(new Transform[2]);
+
+ //TODO assign severity, code some heuristic showing the problems
+ if (! transforms[0].getAlgorithm().equals("http://www.w3.org/2000/09/xmldsig#enveloped-signature")) {
+ tslContext.throwException(
+ new TSLVerificationException(TSLSecurityException.Type.NON_CONFORMANT_TRANSFORM_IN_TSL_SIGNATURE)
+ );
+
+ }
+
+ //TODO assign severity, code some heuristic showing the problems
+ if (! transforms[1].getAlgorithm().equals("http://www.w3.org/2001/10/xml-exc-c14n#")) {
+ tslContext.throwException(
+ new TSLVerificationException(TSLSecurityException.Type.NON_CONFORMANT_C14N_IN_TSL_SIGNATURE)
+ );
+ }
+ }
+
+ found_proper_tsslE_reference = true;
+ }//if (nsd.iterator().next() == tsslE)
+
+ }
+ }
+
+ if(!found_proper_tsslE_reference) {
+ tslContext.throwException(
+ new TSLVerificationException(TSLSecurityException.Type.NON_CONFORMANT_REFERENCE_IN_TSL_SIGNATURE)
+ );
+ }
+
+ // 3) ds:CanonicalizationMethod MUST be
+ // "http://www.w3.org/2001/10/xml-exc-c14n#".
+ if (! si.getCanonicalizationMethod().getAlgorithm().equals("http://www.w3.org/2001/10/xml-exc-c14n#")){
+ tslContext.throwException(
+ new TSLVerificationException(TSLSecurityException.Type.NON_CONFORMANT_C14N_IN_CANONICALIZATION_METHOD)
+ );
+ }
+
+ // 4) It MAY have other ds:Reference elements.
+
+ }
+ } catch (URIReferenceException e) {
+ tslContext.throwException(new TSLVerificationException(e));
+ } catch (MarshalException e) {
+ tslContext.throwException(new TSLVerificationException(e));
+ } catch (XMLSignatureException e) {
+ logger.error("Failed to verify XML Signature for TSL!", e);
+ return (Boolean) tslContext.throwException(
+ new TSLSecurityException(TSLSecurityException.Type.ERRORS_IN_TSL_SIGNATURE),
+ //we need an anonymous class to find the enclosing Method
+ (new Object(){}).getClass().getEnclosingMethod(),
+ null,
+ new Object[] {tslDoc, tslContext, euTslCertsHash}
+ );
+ }
+ return coreValidity;
+ }
+
+ public static void debug(DOMCryptoContext context, String message) {
+
+ Object propDebug = context.getProperty("iaik.xml.crypto.debug.OutputStream");
+
+ if ( propDebug == null) {
+ return;
+ }
+
+ if (! (propDebug instanceof OutputStream)) {
+ System.err.println("Failed to write to debug output stream. " +
+ "DOMCryptoContext's Property (\"iaik.xml.crypto.debug.OutputStream\") " +
+ "has to be of type OutputStream."
+ );
+ } else {
+
+ OutputStream os = (OutputStream) propDebug;
+ try {
+ (new OutputStreamWriter(os)).write(message);
+ } catch (IOException e) {
+ System.err.println("Failed to write to debug output stream. " + e.getMessage());
+ //TODO we cannot close the output stream here ...
+ }
+ }
+
+ }
+
+}
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATslKeySelector.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATslKeySelector.java
new file mode 100644
index 0000000..efdd877
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/MOATslKeySelector.java
@@ -0,0 +1,123 @@
+package at.gv.egovernment.moa.spss.tsl.connector;
+
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.KeySelectorException;
+import javax.xml.crypto.KeySelectorResult;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.X509Data;
+
+import iaik.server.modules.xmlverify.MOAKeySelector;
+import iaik.xml.crypto.tsl.TSLContext;
+import iaik.xml.crypto.tsl.ex.TSLSecurityException;
+import iaik.xml.crypto.tsl.ex.TSLVerificationException;
+import iaik.xml.crypto.tsl.verify.TslKeyInfoHints;
+import iaik.xml.crypto.utils.X509KeySelectorResult;
+
+public class MOATslKeySelector extends MOAKeySelector {
+
+ private final ListIterator<X509Certificate> tslSignerCerts_;
+ private TSLContext tslContextI_;
+
+ public MOATslKeySelector(ListIterator<X509Certificate> euTslCertsHash, TSLContext tslContext) {
+ if(euTslCertsHash == null){
+ tslContext.throwException(
+ new TSLVerificationException(
+ TSLSecurityException.Type.MISSING_INFO_ON_TSL_SIGNER)
+ );
+ }
+ tslSignerCerts_ = euTslCertsHash;
+ tslContextI_ = tslContext;
+ tslContext.toString();
+ }
+
+ @Override
+ protected KeyInfoHints newKeyInfoHints(KeyInfo keyInfo,
+ XMLCryptoContext context)
+ throws KeySelectorException {
+
+ return new TslKeyInfoHints(keyInfo, context, tslContextI_, tslSignerCerts_);
+
+ }
+
+ @Override
+ protected KeySelectorResult select(KeyInfoHints hints,
+ KeySelectorResult[] results) {
+
+ if (results.length > 1){
+
+ return (KeySelectorResult) tslContextI_.throwException(
+ new TSLSecurityException(TSLSecurityException.Type.UNTRUSTED_TSL_SIGNER),
+ //we need an anonymous class to find the enclosing Method
+ (new Object(){}).getClass().getEnclosingMethod(),
+ this,
+ new Object[] {hints, results}
+ );
+
+ } else {
+ KeySelectorResult result = results[0];
+ if (result instanceof X509KeySelectorResult) {
+ result = new MOAX509KeySelectorResult((X509KeySelectorResult)result);
+ } else {
+ result = new MOAKeySelectorResult(result.getKey());
+ }
+ return result;
+ }
+ }
+
+ @Override
+ public KeySelectorResult select(X509Data x509Data,
+ Purpose purpose,
+ AlgorithmMethod method,
+ XMLCryptoContext context) throws KeySelectorException {
+
+ X509KeySelectorResult ksr;
+ try {
+ ksr = (X509KeySelectorResult) super.select(x509Data, purpose, method, context);
+ } catch (ClassCastException e) {
+ ksr = (X509KeySelectorResult) tslContextI_.throwException(
+ e,
+ //we need an anonymous class to find the enclosing Method
+ (new Object(){}).getClass().getEnclosingMethod(),
+ this,
+ new Object[]{x509Data, purpose, method, context});
+ }
+
+ if (ksr == null){
+ //there has been a Problem with the X509Data
+ ksr = (X509KeySelectorResult) tslContextI_.throwException(
+ new KeySelectorException(failReason_.replace(". ", ".\n")),
+ //we need an anonymous class to find the enclosing Method
+ (new Object(){}).getClass().getEnclosingMethod(),
+ this,
+ new Object[]{x509Data, purpose, method, context});
+ }
+
+ List l = ksr.getCertificates();
+ tslContextI_.securityCheck(
+ TSLSecurityException.Type.UNTRUSTED_TSL_SIGNER,
+ (X509Certificate[]) l.toArray(new X509Certificate[l.size()]),
+ tslSignerCerts_
+ );
+
+ return ksr;
+ }
+
+ @Override
+ protected KeySelectorResult select(X509Certificate cert, Purpose purpose,
+ AlgorithmMethod method, XMLCryptoContext context)
+ throws KeySelectorException {
+
+ tslContextI_.securityCheck(
+ TSLSecurityException.Type.UNTRUSTED_TSL_SIGNER,
+ cert,
+ tslSignerCerts_
+ );
+
+ return super.select(cert, purpose, method, context);
+ }
+} \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java
index 82df37b..fee6ebe 100644
--- a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java
@@ -29,8 +29,8 @@ import at.gv.egovernment.moa.spss.tsl.utils.TSLEUImportFromFileContext;
import at.gv.egovernment.moa.spss.tsl.utils.TSLEvaluationContext;
import at.gv.egovernment.moa.spss.tsl.utils.TSLImportFromFileContext;
import iaik.asn1.ObjectID;
-import iaik.util._15;
-import iaik.util.logging._l;
+import iaik.util.GeneralUtils15;
+import iaik.util.logging.GeneralLog;
import iaik.utils.RFC2253NameParser;
import iaik.xml.crypto.EccProviderAdapter;
import iaik.xml.crypto.XSecProvider;
@@ -314,7 +314,7 @@ public class TSLConnector implements TSLConnectorInterface {
log.debug(Thread.currentThread() + " waiting for other threads ...");
topLevelTslContext.waitForAllOtherThreads();
- log.debug(_15.dumpAllThreads());
+ log.debug(GeneralUtils15.dumpAllThreads());
log.debug(Thread.currentThread() + " reactivated after other threads finished ...");
connection = null;
@@ -395,7 +395,7 @@ public class TSLConnector implements TSLConnectorInterface {
log.debug("### SURNAME registered as " + ObjectID.surName + " ###");
RFC2253NameParser.register("SURNAME", ObjectID.surName);
- XSecProvider.addAsProvider(false);
+ //XSecProvider.addAsProvider(false);
TSLEngine tslEngine;
TslSqlConnectionWrapper connection = null;
@@ -557,7 +557,7 @@ public class TSLConnector implements TSLConnectorInterface {
log.debug(Thread.currentThread() + " waiting for other threads ...");
topLevelTslContext.waitForAllOtherThreads();
- log.debug(_15.dumpAllThreads());
+ log.debug(GeneralUtils15.dumpAllThreads());
log.debug(Thread.currentThread() + " reactivated after other threads finished ...");
connection = null;
@@ -635,7 +635,7 @@ public class TSLConnector implements TSLConnectorInterface {
} catch (TSLEngineFatalException e) {
e.printStackTrace();
- _l.err("could not export Certs", e);
+ GeneralLog.err("could not export Certs", e);
throw new TSLEngineDiedException(e);
}