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);
}
// TODO See Bug #322
// Check result of SignatureManifestCheck
//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);
}
}