diff options
5 files changed, 178 insertions, 46 deletions
diff --git a/spss.server/res/resources/properties/spss_messages_de.properties b/spss.server/res/resources/properties/spss_messages_de.properties index a09b6c05e..ead8d3295 100644 --- a/spss.server/res/resources/properties/spss_messages_de.properties +++ b/spss.server/res/resources/properties/spss_messages_de.properties @@ -114,7 +114,7 @@ config.10=Fehler beim Einlesen der Konfiguration (siehe Log-Datei für Details) config.11=Fehler biem Erstellen der Konfiguration (siehe Log-Datei für Details) config.12=Fehler beim Einlesen des Profils config.13=Fehler beim Erstellen des CRLDistributionPoint: CAIssuerDN={0} ungültig -config.14=Die URI für das TrustProfile mit id={0} ist ungültig (URI={1}) +config.14=Das Attribut {0} für das TrustProfile mit id={1} ist ungültig (Wert={2}) config.15=Fehler beim Erstellen des TrustProfile id={0}: Name des Konfigurations-Verzeichnisses konnte nicht in eine URL umgewandet werden config.16=Fehler beim Erstellen von X509IssuerSerial (IssuerName={0}, SerialNumber={1}) config.17=DigestAlgorithmName unbekannt (AlgorithmName={0}) @@ -127,7 +127,7 @@ config.23=Fehler in der Konfiguration: {0} nicht konfiguriert oder ungültig, ver config.24=Fehler in der Konfiguration: Die GenericConfiguration mit name={0} ist bereits gesetzt config.25=Fehler in der Konfiguration: Das SoftwareKeyModule mit id={0} konnte nicht geladen werden, da die Datei {1} nicht existiert oder ein Verzeichnis bezeichnet config.26=Fehler beim Erstellen der KeyGroup mit id={0}: KeyModule mit id={1} unbekannt -config.27=Fehler in der Konfiguration: Das TrustProfile mit id={0} zeigt nicht auf ein existierendes Verzeichnis +config.27=Fehler in der Konfiguration: Das Attribut {0} des TrustProfiles mit id={1} zeigt nicht auf ein existierendes Verzeichnis config.28=Einen detaillierten Fehlerbericht entnehmen Sie bitte der Log-Datei. config.29=Es sind folgende leichte Fehler aufgetreten: config.30=Fehler in der Konfiguration: Die GenericConfiguration {0} zeigt nicht auf ein existierendes Verzeichnis oder das Verzeichnis konnte nicht erstellt werden diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java index 1e966911b..33e9daca1 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java @@ -827,32 +827,66 @@ public class ConfigurationPartsBuilder { while ((profileElem = (Element) profileIter.nextNode()) != null) { String id = profileElem.getAttribute("id"); String uriStr = profileElem.getAttribute("uri"); - - try { - URI uri = new URI(uriStr); - TrustProfile profile; - File profileDir; - + String signerCertsUriStr = profileElem.getAttribute("signerCertsUri"); + + boolean createTrustProfile = true; + + URI uri = null; + try + { + uri = new URI(uriStr); if (!uri.isAbsolute()) { // make it absolute to the config file uri = new URI(configRoot.toURL() + uriStr); } + } + catch (URIException e) { + warn("config.14", new Object[] { "uri", id, uriStr }, e); + createTrustProfile = false; + } + catch (MalformedURLException e) + { + warn("config.15", new Object[] {id}, e); + createTrustProfile = false; + } - profileDir = new File(uri.getPath()); - if (!profileDir.exists() || !profileDir.isDirectory()) { - warn("config.27", new Object[] { id }); - } + File profileDir = new File(uri.getPath()); + if (!profileDir.exists() || !profileDir.isDirectory()) { + warn("config.27", new Object[] { "uri", id }); + createTrustProfile = false; + } - if (trustProfiles.containsKey(id)) { - warn("config.04", new Object[] { "TrustProfile", id }); - } else { - profile = new TrustProfile(id, uri.toString()); - trustProfiles.put(id, profile); + if (trustProfiles.containsKey(id)) { + warn("config.04", new Object[] { "TrustProfile", id }); + createTrustProfile = false; + } + + URI signerCertsUri = null; + if (signerCertsUriStr != null && !"".equals(signerCertsUriStr)) + { + try + { + signerCertsUri = new URI(signerCertsUriStr); + if (!signerCertsUri.isAbsolute()) uri = new URI(configRoot.toURL() + signerCertsUriStr); + + File signerCertsDir = new File(signerCertsUri.getPath()); + if (!signerCertsDir.exists() || !signerCertsDir.isDirectory()) { + warn("config.27", new Object[] { "signerCertsUri", id }); + createTrustProfile = false; + } } - - } catch (URIException e) { - warn("config.14", new Object[] { id, uriStr }, e); - } catch (MalformedURLException e) { - warn("config.15", null, e); + catch (URIException e) { + warn("config.14", new Object[] { "signerCertsUri", id, uriStr }, e); + createTrustProfile = false; + } + catch (MalformedURLException e) { + warn("config.15", new Object[] {id}, e); + createTrustProfile = false; + } + } + + if (createTrustProfile) { + TrustProfile profile = new TrustProfile(id, uri.toString(), signerCertsUri.toString()); + trustProfiles.put(id, profile); } } diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java index 6ba33be63..929d5ce2b 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java @@ -11,16 +11,21 @@ public class TrustProfile { private String id; /** The URI giving the location of the trust profile. */ private String uri; + /** The URI giving the location of the allowed signer certificates. */ + private String signerCertsUri; /** * Create a <code>TrustProfile</code>. * * @param id The ID of the <code>TrustProfile</code> to create. * @param uri The URI of the <code>TrustProfile</code> to create. + * @param signerCertsUri The URI of the location of the allowed signer + * certificates of the <code>TrustProfile</code> to create. */ - public TrustProfile(String id, String uri) { + public TrustProfile(String id, String uri, String signerCertsUri) { this.id = id; this.uri = uri; + this.signerCertsUri = signerCertsUri; } /** @@ -40,4 +45,14 @@ public class TrustProfile { public String getUri() { return uri; } + + /** + * Return the URI giving the location of the allowed signer certificates + * of this <code>TrustProfile</code>. + * + * @return The URI of <code>TrustProfile</code>. + */ + public String getSignerCertsUri() { + return signerCertsUri; + } } diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java index 543fa3b01..af5787795 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java @@ -94,12 +94,16 @@ public class VerifyXMLSignatureResponseBuilder { * * @param result The result to set for the response. * @param profile The profile used for verifying the signature. + * @param transformsSignatureManifestCheck The overall result for the signature + * manifest check. + * @param certificateCheck The overall result for the certificate check. * @throws MOAApplicationException An error occurred adding the result. */ public void setResult( XMLSignatureVerificationResult result, XMLSignatureVerificationProfile profile, - ReferencesCheckResult transformsSignatureManifestCheck) + ReferencesCheckResult transformsSignatureManifestCheck, + CheckResult certificateCheck) throws MOAApplicationException { CertificateValidationResult certResult = @@ -230,11 +234,8 @@ public class VerifyXMLSignatureResponseBuilder { } } - // create the certificate check - certificateCheck = - factory.createCheckResult( - certResult.getValidationResultCode().intValue(), - null); + // create the certificate check + this.certificateCheck = certificateCheck; } /** diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java index e192b66a2..e8b2a5e10 100644 --- a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java +++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java @@ -1,20 +1,9 @@ package at.gv.egovernment.moa.spss.server.invoke; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; - import iaik.IAIKException; import iaik.IAIKRuntimeException; +import iaik.ixsil.exceptions.URIException; +import iaik.ixsil.util.URI; import iaik.server.modules.xml.DataObject; import iaik.server.modules.xml.XMLDataObject; import iaik.server.modules.xml.XMLSignature; @@ -26,18 +15,33 @@ import iaik.server.modules.xmlverify.XMLSignatureVerificationModule; import iaik.server.modules.xmlverify.XMLSignatureVerificationModuleFactory; import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile; import iaik.server.modules.xmlverify.XMLSignatureVerificationResult; +import iaik.x509.X509Certificate; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; import at.gv.egovernment.moa.logging.LogMsg; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.logging.LoggingContext; import at.gv.egovernment.moa.logging.LoggingContextManager; -import at.gv.egovernment.moa.util.CollectionUtils; -import at.gv.egovernment.moa.util.Constants; - import at.gv.egovernment.moa.spss.MOAApplicationException; import at.gv.egovernment.moa.spss.MOAException; import at.gv.egovernment.moa.spss.MOASystemException; import at.gv.egovernment.moa.spss.api.SPSSFactory; +import at.gv.egovernment.moa.spss.api.common.CheckResult; import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult; @@ -50,12 +54,15 @@ import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExpli import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; +import at.gv.egovernment.moa.spss.server.config.TrustProfile; import at.gv.egovernment.moa.spss.server.iaik.xml.XMLSignatureImpl; import at.gv.egovernment.moa.spss.server.logging.IaikLog; import at.gv.egovernment.moa.spss.server.logging.TransactionId; import at.gv.egovernment.moa.spss.server.transaction.TransactionContext; import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager; import at.gv.egovernment.moa.spss.util.MessageProvider; +import at.gv.egovernment.moa.util.CollectionUtils; +import at.gv.egovernment.moa.util.Constants; /** * A class providing a DOM based interface to the @@ -208,13 +215,88 @@ public class XMLSignatureVerificationInvoker { signatureManifestCheck = validateSignatureManifest(request, result, profile); + // Check if signer certificate is in trust profile's allowed signer certificates pool + TrustProfile trustProfile = context.getConfiguration().getTrustProfile(request.getTrustProfileId()); + CheckResult certificateCheck = validateSignerCertificate(result, trustProfile); + // build the response - responseBuilder.setResult(result, profile, signatureManifestCheck); + responseBuilder.setResult(result, profile, signatureManifestCheck, certificateCheck); return responseBuilder.getResponse(); } /** + * Checks if the signer certificate matches one of the allowed signer certificates specified + * in the provided <code>trustProfile</code>. + * + * @param result The result produced by the <code>XMLSignatureVerificationModule</code>. + * + * @param trustProfile The trust profile the signer certificate is validated against. + * + * @return The overal result of the certificate validation for the signer certificate. + * + * @throws MOAException if one of the signer certificates specified in the <code>trustProfile</code> + * cannot be read from the file system. + */ + private CheckResult validateSignerCertificate(XMLSignatureVerificationResult result, TrustProfile trustProfile) + throws MOAException + { + int resultCode = result.getCertificateValidationResult().getValidationResultCode().intValue(); + if (resultCode == 0 && trustProfile.getSignerCertsUri() != null) + { + X509Certificate signerCertificate = (X509Certificate) result.getCertificateValidationResult().getCertificateChain().get(0); + + File signerCertsDir = null; + try + { + signerCertsDir = new File(new URI(trustProfile.getSignerCertsUri()).getPath()); + } + catch (URIException e) + { + throw new MOASystemException("2900", null, e); // Should not happen, already checked at loading the MOA configuration + } + + File[] files = signerCertsDir.listFiles(); + if (files == null) resultCode = 1; + int i; + for (i = 0; i < files.length; i++) + { + if (!files[i].isDirectory()) + { + FileInputStream currentFIS = null; + try + { + currentFIS = new FileInputStream(files[i]); + } + catch (FileNotFoundException e) { + throw new MOASystemException("2900", null, e); + } + + try + { + X509Certificate currentCert = new X509Certificate(currentFIS); + if (currentCert.equals(signerCertificate)) break; + } + catch (Exception e) + { + // Simply ignore file if it cannot be interpreted as certificate + Logger.warn("Signatorzertifiat aus Trustprofile mit id=" + + trustProfile.getId() + " kann nicht geparst werden: " + + e.getMessage()); + } + } + } + if (i >= files.length) + { + resultCode = 1; // No signer certificate from the trustprofile pool matches the actual signer certificate + } + } + + SPSSFactory factory = SPSSFactory.getInstance(); + return factory.createCheckResult(resultCode, null); + } + + /** * Select the <code>dsig:Signature</code> DOM element within the signature * environment. * |