aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java308
1 files changed, 308 insertions, 0 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java
new file mode 100644
index 000000000..b9c15e75e
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.id.auth.validator;
+
+import java.security.InvalidKeyException;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import at.gv.egiz.eaaf.core.api.idp.auth.data.IIdentityLink;
+import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse;
+import at.gv.egovernment.moa.id.auth.exception.ValidateException;
+import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.commons.api.AuthConfiguration;
+import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters;
+import at.gv.egovernment.moa.id.commons.api.data.IVerifiyXMLSignatureResponse;
+import at.gv.egovernment.moa.id.commons.api.exceptions.ConfigurationException;
+import at.gv.egovernment.moa.id.commons.utils.MOAIDMessageProvider;
+import at.gv.egovernment.moa.logging.Logger;
+import iaik.asn1.structures.Name;
+import iaik.security.ec.common.ECPublicKey;
+import iaik.utils.RFC2253NameParserException;
+import iaik.x509.X509Certificate;
+import iaik.x509.X509ExtensionInitException;
+
+/**
+ * This class is used to validate an {@link VerifyXMLSignatureResponse}
+ * returned by MOA-SPSS
+ *
+ * @author Stefan Knirsch
+ * @version $Id$
+ */
+public class VerifyXMLSignatureResponseValidator {
+
+ /** Identification string for checking identity link */
+ public static final String CHECK_IDENTITY_LINK = "IdentityLink";
+ /** Identification string for checking authentication block */
+ public static final String CHECK_AUTH_BLOCK = "AuthBlock";
+
+ /** Singleton instance. <code>null</code>, if none has been created. */
+ private static VerifyXMLSignatureResponseValidator instance;
+
+ /**
+ * Constructor for a singleton VerifyXMLSignatureResponseValidator.
+ */
+ public static synchronized VerifyXMLSignatureResponseValidator getInstance()
+ throws ValidateException {
+ if (instance == null) {
+ instance = new VerifyXMLSignatureResponseValidator();
+ }
+ return instance;
+ }
+
+ /**
+ * Validates a {@link VerifyXMLSignatureResponse} returned by MOA-SPSS.
+ *
+ * @param verifyXMLSignatureResponse the <code>&lt;VerifyXMLSignatureResponse&gt;</code>
+ * @param identityLinkSignersSubjectDNNames subject names configured
+ * @param whatToCheck is used to identify whether the identityLink or the Auth-Block is validated
+ * @param oaParam specifies whether the validation result of the
+ * manifest has to be ignored (identityLink validation if
+ * the OA is a business service) or not
+ * @throws ValidateException on any validation error
+ * @throws ConfigurationException
+ */
+ public void validate(IVerifiyXMLSignatureResponse verifyXMLSignatureResponse,
+ List<String> identityLinkSignersSubjectDNNames,
+ String whatToCheck,
+ IOAAuthParameters oaParam,
+ AuthConfiguration authConfig)
+ throws ValidateException, ConfigurationException {
+
+ if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0)
+ throw new ValidateException("validator.06", new Object[] {whatToCheck});
+
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() != 0) {
+ String checkFailedReason ="";
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() == 1)
+ checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.21", null);
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() == 2)
+ checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.22", null);
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() == 3)
+ checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.23", null);
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() == 4)
+ checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.24", null);
+ if (verifyXMLSignatureResponse.getCertificateCheckCode() == 5)
+ checkFailedReason = MOAIDMessageProvider.getInstance().getMessage("validator.25", null);
+
+// TEST CARDS
+ if (whatToCheck.equals(CHECK_IDENTITY_LINK))
+ throw new ValidateException("validator.07", new Object[] { checkFailedReason } );
+ else
+ throw new ValidateException("validator.19", new Object[] { checkFailedReason } );
+ }
+
+ //check QC
+ if (authConfig.isCertifiacteQCActive() &&
+ !whatToCheck.equals(CHECK_IDENTITY_LINK) &&
+ !verifyXMLSignatureResponse.isQualifiedCertificate()) {
+
+ //check if testcards are active and certificate has an extension for test credentials
+ if (oaParam.isTestCredentialEnabled()) {
+ boolean foundTestCredentialOID = false;
+ try {
+ X509Certificate signerCert = verifyXMLSignatureResponse.getX509certificate();
+
+ List<String> validOIDs = new ArrayList<String>();
+ if (oaParam.getTestCredentialOIDs() != null)
+ validOIDs.addAll(oaParam.getTestCredentialOIDs());
+ else
+ validOIDs.add(MOAIDAuthConstants.TESTCREDENTIALROOTOID);
+
+ Set<String> extentsions = signerCert.getCriticalExtensionOIDs();
+ extentsions.addAll(signerCert.getNonCriticalExtensionOIDs());
+ Iterator<String> extit = extentsions.iterator();
+ while(extit.hasNext()) {
+ String certOID = extit.next();
+ for (String el : validOIDs) {
+ if (certOID.startsWith(el))
+ foundTestCredentialOID = true;
+ }
+ }
+
+ } catch (Exception e) {
+ Logger.warn("Test credential OID extraction FAILED.", e);
+
+ }
+ //throw Exception if not TestCredentialOID is found
+ if (!foundTestCredentialOID)
+ throw new ValidateException("validator.72", null);
+
+ } else
+ throw new ValidateException("validator.71", null);
+ }
+
+ // if OA is type is business service the manifest validation result has
+ // to be ignored
+ boolean ignoreManifestValidationResult = false;
+ if (whatToCheck.equals(CHECK_IDENTITY_LINK))
+ ignoreManifestValidationResult = (oaParam.hasBaseIdInternalProcessingRestriction()) ? true
+ : false;
+
+ if (ignoreManifestValidationResult) {
+ Logger.debug("OA type is business service, thus ignoring DSIG manifest validation result");
+ } else {
+ if (verifyXMLSignatureResponse.isXmlDSIGManigest())
+ if (verifyXMLSignatureResponse.getXmlDSIGManifestCheckCode() != 0)
+ throw new ValidateException("validator.08", null);
+ }
+
+
+ // Check the signature manifest only when verifying the signed AUTHBlock
+ if (whatToCheck.equals(CHECK_AUTH_BLOCK)) {
+ if (verifyXMLSignatureResponse.getSignatureManifestCheckCode() > 0) {
+ throw new ValidateException("validator.50", null);
+ }
+ }
+
+ //Check whether the returned X509 SubjectName is in the MOA-ID configuration or not
+ if (identityLinkSignersSubjectDNNames != null) {
+ String subjectDN = "";
+ X509Certificate x509Cert = verifyXMLSignatureResponse.getX509certificate();
+ try {
+ subjectDN = ((Name) x509Cert.getSubjectDN()).getRFC2253String();
+ }
+ catch (RFC2253NameParserException e) {
+ throw new ValidateException("validator.17", null);
+ }
+ //System.out.println("subjectDN: " + subjectDN);
+ // check the authorisation to sign the identity link
+ if (!identityLinkSignersSubjectDNNames.contains(subjectDN)) {
+ // subject DN check failed, try OID check:
+ try {
+ if (x509Cert.getExtension(MOAIDAuthConstants.IDENTITY_LINK_SIGNER_OID) == null) {
+ throw new ValidateException("validator.18", new Object[] { subjectDN });
+ } else {
+ Logger.debug("Identity link signer cert accepted for signing identity link: " +
+ "subjectDN check failed, but OID check successfully passed.");
+ }
+ } catch (X509ExtensionInitException e) {
+ throw new ValidateException("validator.49", null);
+ }
+ } else {
+ Logger.debug("Identity link signer cert accepted for signing identity link: " +
+ "subjectDN check successfully passed.");
+ }
+
+ }
+ }
+
+ /**
+ * Method validateCertificate.
+ * @param verifyXMLSignatureResponse The VerifyXMLSignatureResponse
+ * @param idl The Identitylink
+ * @throws ValidateException
+ */
+ public void validateCertificate(
+ IVerifiyXMLSignatureResponse verifyXMLSignatureResponse,
+ IIdentityLink idl)
+ throws ValidateException {
+
+ X509Certificate x509Response = verifyXMLSignatureResponse.getX509certificate();
+ PublicKey[] pubKeysIdentityLink = (PublicKey[]) idl.getPublicKey();
+
+ PublicKey pubKeySignature = x509Response.getPublicKey();
+ checkIDLAgainstSignatureCertificate(pubKeysIdentityLink, pubKeySignature);
+
+ }
+
+
+ public void checkIDLAgainstSignatureCertificate( PublicKey[] pubKeysIdentityLink, PublicKey pubKeySignature) throws ValidateException {
+ boolean found = false;
+ for (int i = 0; i < pubKeysIdentityLink.length; i++) {
+ PublicKey idlPubKey = pubKeysIdentityLink[i];
+ //compare RSAPublicKeys
+ if ((idlPubKey instanceof java.security.interfaces.RSAPublicKey) &&
+ (pubKeySignature instanceof java.security.interfaces.RSAPublicKey)) {
+
+ RSAPublicKey rsaPubKeySignature = (RSAPublicKey) pubKeySignature;
+ RSAPublicKey rsakey = (RSAPublicKey) pubKeysIdentityLink[i];
+
+ if (rsakey.getModulus().equals(rsaPubKeySignature.getModulus())
+ && rsakey.getPublicExponent().equals(rsaPubKeySignature.getPublicExponent()))
+ found = true;
+ }
+
+ //compare ECDSAPublicKeys
+ if( ( (idlPubKey instanceof java.security.interfaces.ECPublicKey) ||
+ (idlPubKey instanceof ECPublicKey)) &&
+ ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) ||
+ (pubKeySignature instanceof ECPublicKey) ) ) {
+
+ try {
+ ECPublicKey ecdsaPubKeySignature = new ECPublicKey(pubKeySignature.getEncoded());
+ ECPublicKey ecdsakey = new ECPublicKey(pubKeysIdentityLink[i].getEncoded());
+
+ if(ecdsakey.equals(ecdsaPubKeySignature))
+ found = true;
+
+ } catch (InvalidKeyException e) {
+ Logger.warn("ECPublicKey can not parsed into a iaik.ECPublicKey", e);
+ throw new ValidateException("validator.09", null);
+ }
+
+
+
+ }
+
+// Logger.debug("IDL-Pubkey=" + idl.getPublicKey()[i].getClass().getName()
+// + " Resp-Pubkey=" + pubKeySignature.getClass().getName());
+
+ }
+
+ if (!found) {
+
+ throw new ValidateException("validator.09", null);
+
+ }
+ }
+
+}