package at.gv.egovernment.moa.id.auth.validator; 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.PublicKey; import java.security.interfaces.RSAPublicKey; import java.util.List; 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.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. null, 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 <VerifyXMLSignatureResponse> * @param identityLinkSignersSubjectDNNames subject names configured * @param whatToCheck is used to identify whether the identityLink or the Auth-Block is validated * @param ignoreManifestValidationResult 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 */ public void validate(VerifyXMLSignatureResponse verifyXMLSignatureResponse, List identityLinkSignersSubjectDNNames, String whatToCheck, boolean ignoreManifestValidationResult) throws ValidateException { 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); if (whatToCheck.equals(CHECK_IDENTITY_LINK)) throw new ValidateException("validator.07", new Object[] { checkFailedReason } ); else throw new ValidateException("validator.19", new Object[] { checkFailedReason } ); } 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); } // 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 iaik.security.ecc.ecdsa.ECPublicKey) && (pubKeySignature instanceof iaik.security.ecc.ecdsa.ECPublicKey)) { ECPublicKey ecdsaPubKeySignature = (ECPublicKey) pubKeySignature; ECPublicKey ecdsakey = (ECPublicKey) pubKeysIdentityLink[i]; if(ecdsakey.equals(ecdsaPubKeySignature)) found = true; } } if (!found) throw new ValidateException("validator.09", null); } }