diff options
Diffstat (limited to 'id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java')
-rw-r--r-- | id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java new file mode 100644 index 000000000..ac528c89d --- /dev/null +++ b/id/server/modules/moa-id-modul-citizencard_authentication/src/main/java/at/gv/egovernment/moa/id/auth/validator/VerifyXMLSignatureResponseValidator.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * 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 iaik.asn1.ObjectID; +import iaik.asn1.structures.Name; +import iaik.security.ecc.ecdsa.ECPublicKey; +import iaik.utils.RFC2253NameParserException; +import iaik.x509.X509Certificate; +import iaik.x509.X509ExtensionInitException; + +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.egovernment.moa.id.auth.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.auth.data.IdentityLink; +import at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse; +import at.gv.egovernment.moa.id.auth.exception.ValidateException; +import at.gv.egovernment.moa.id.config.ConfigurationException; +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.util.MOAIDMessageProvider; +import at.gv.egovernment.moa.logging.Logger; + +/** + * 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><VerifyXMLSignatureResponse></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(VerifyXMLSignatureResponse verifyXMLSignatureResponse, + List<String> identityLinkSignersSubjectDNNames, + String whatToCheck, + IOAAuthParameters oaParam) + throws ValidateException, ConfigurationException { + + if (verifyXMLSignatureResponse.getSignatureCheckCode() != 0) + throw new ValidateException("validator.06", null); + + 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 (AuthConfigurationProviderFactory.getInstance().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.getBusinessService()) ? 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( + VerifyXMLSignatureResponse verifyXMLSignatureResponse, + IdentityLink idl) + throws ValidateException { + + X509Certificate x509Response = verifyXMLSignatureResponse.getX509certificate(); + PublicKey[] pubKeysIdentityLink = (PublicKey[]) idl.getPublicKey(); + + PublicKey pubKeySignature = x509Response.getPublicKey(); + + boolean found = false; + for (int i = 0; i < pubKeysIdentityLink.length; i++) { + + //compare RSAPublicKeys + if ((idl.getPublicKey()[i] 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( ( (idl.getPublicKey()[i] instanceof java.security.interfaces.ECPublicKey) || + (idl.getPublicKey()[i] instanceof iaik.security.ecc.ecdsa.ECPublicKey)) && + ( (pubKeySignature instanceof java.security.interfaces.ECPublicKey) || + (pubKeySignature instanceof iaik.security.ecc.ecdsa.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); + + } + } + +} |