{
// conflicting trust anchors
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,
"CertPathReviewer.conflictingTrustAnchors",
new Object[] {new Integer(trustColl.size()),
new UntrustedInput(cert.getIssuerX500Principal())});
addError(msg);
}
else if (trustColl.isEmpty())
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,
"CertPathReviewer.noTrustAnchorFound",
new Object[] {new UntrustedInput(cert.getIssuerX500Principal()),
new Integer(pkixParams.getTrustAnchors().size())});
addError(msg);
}
else
{
PublicKey trustPublicKey;
trust = (TrustAnchor) trustColl.iterator().next();
if (trust.getTrustedCert() != null)
{
trustPublicKey = trust.getTrustedCert().getPublicKey();
}
else
{
trustPublicKey = trust.getCAPublicKey();
}
try
{
cert.verify(trustPublicKey);
}
catch (Exception e)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustButInvalidCert");
addError(msg);
trust = null;
}
}
}
catch (CertPathReviewerException cpre)
{
addError(cpre.getErrorMessage());
}
if (trust != null)
{
// get the name of the trustAnchor
X509Certificate sign = trust.getTrustedCert();
try
{
if (sign != null)
{
trustPrincipal = getSubjectPrincipal(sign);
}
else
{
trustPrincipal = new X500Principal(trust.getCAName());
}
}
catch (IllegalArgumentException ex)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustDNInvalid",
new Object[] {new UntrustedInput(trust.getCAName())});
addError(msg);
}
}
// 1.6.2 - Initialization
PublicKey workingPublicKey = null;
X500Principal workingIssuerName = trustPrincipal;
X509Certificate sign = null;
AlgorithmIdentifier workingAlgId = null;
DERObjectIdentifier workingPublicKeyAlgorithm = null;
DEREncodable workingPublicKeyParameters = null;
if (trust != null)
{
sign = trust.getTrustedCert();
if (sign != null)
{
workingPublicKey = sign.getPublicKey();
}
else
{
workingPublicKey = trust.getCAPublicKey();
}
try
{
workingAlgId = getAlgorithmIdentifier(workingPublicKey);
workingPublicKeyAlgorithm = workingAlgId.getObjectId();
workingPublicKeyParameters = workingAlgId.getParameters();
}
catch (CertPathValidatorException ex)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.trustPubKeyError");
addError(msg);
workingAlgId = null;
}
}
// Basic cert checks
X509Certificate cert = null;
int i;
for (int index = certs.size() - 1; index >= 0; index--)
{
//
// i as defined in the algorithm description
//
i = n - index;
//
// set certificate to be checked in this round
// sign and workingPublicKey and workingIssuerName are set
// at the end of the for loop and initialied the
// first time from the TrustAnchor
//
cert = (X509Certificate) certs.get(index);
// verify signature
if (workingPublicKey != null)
{
try
{
cert.verify(workingPublicKey, "BC");
}
catch (GeneralSecurityException ex)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.signatureNotVerified",
new Object[] {ex.getMessage(),ex});
addError(msg,index);
}
}
else
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.NoIssuerPublicKey");
addError(msg,index);
}
// certificate valid?
try
{
cert.checkValidity(validDate);
}
catch (CertificateNotYetValidException cnve)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certificateNotYetValid",
new Object[] {cert.getNotBefore()});
addError(msg,index);
}
catch (CertificateExpiredException cee)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.certificateExpired",
new Object[] {cert.getNotAfter()});
addError(msg,index);
}
// certificate revoked?
if (pkixParams.isRevocationEnabled())
{
// read crl distribution points extension
CRLDistPoint crlDistPoints = null;
try
{
DERObject crl_dp = getExtensionValue(cert,CRL_DIST_POINTS);
if (crl_dp != null)
{
crlDistPoints = CRLDistPoint.getInstance(crl_dp);
}
}
catch (AnnotatedException ae)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlDistPtExtError");
addError(msg,index);
}
// read authority information access extension
AuthorityInformationAccess authInfoAcc = null;
try
{
DERObject auth_info_acc = getExtensionValue(cert,AUTH_INFO_ACCESS);
if (auth_info_acc != null)
{
authInfoAcc = AuthorityInformationAccess.getInstance(auth_info_acc);
}
}
catch (AnnotatedException ae)
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlAuthInfoAccError");
addError(msg,index);
}
Vector crlDistPointUrls = getCRLDistUrls(crlDistPoints,authInfoAcc);
Vector ocspUrls = getOCSPUrls(authInfoAcc);
// add notifications with the crl distribution points
// output crl distribution points
Iterator urlIt = crlDistPointUrls.iterator();
while (urlIt.hasNext())
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.crlDistPoint",
new Object[] {new UntrustedInput(urlIt.next())});
addNotification(msg,index);
}
// output ocsp urls
urlIt = ocspUrls.iterator();
while (urlIt.hasNext())
{
ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.ocspLocation",
new Object[] {new UntrustedInput(urlIt.next())});
addNotification(msg,index);
}
// TODO also support Netscapes revocation-url and/or OCSP instead of CRLs for revocation checking
// check CRLs