// (b) for all x in {1, ..., n}, the certificate was valid at the
// time in question.
//
// Because this is the X.509 algorithm, we also check if all
// cerificates are of type X509Certificate.
PolicyNodeImpl rootNode = new PolicyNodeImpl();
Set initPolicies = ((PKIXParameters) params).getInitialPolicies();
rootNode.setValidPolicy(ANY_POLICY);
rootNode.setCritical(false);
rootNode.setDepth(0);
if (initPolicies != null)
rootNode.addAllExpectedPolicies(initPolicies);
else
rootNode.addExpectedPolicy(ANY_POLICY);
List checks = ((PKIXParameters) params).getCertPathCheckers();
List l = path.getCertificates();
if (l == null || l.size() == 0)
throw new CertPathValidatorException();
X509Certificate[] p = null;
try
{
p = (X509Certificate[]) l.toArray(new X509Certificate[l.size()]);
}
catch (ClassCastException cce)
{
throw new CertPathValidatorException("invalid certificate path");
}
String sigProvider = ((PKIXParameters) params).getSigProvider();
PublicKey prevKey = null;
Date now = ((PKIXParameters) params).getDate();
if (now == null)
now = new Date();
LinkedList policyConstraints = new LinkedList();
for (int i = p.length - 1; i >= 0; i--)
{
try
{
p[i].checkValidity(now);
}
catch (CertificateException ce)
{
throw new CertPathValidatorException(ce.toString());
}
Set uce = getCritExts(p[i]);
for (Iterator check = checks.iterator(); check.hasNext();)
{
try
{
((PKIXCertPathChecker) check.next()).check(p[i], uce);
}
catch (Exception x)
{
}
}
PolicyConstraint constr = null;
if (p[i] instanceof GnuPKIExtension)
{
Extension pcx = ((GnuPKIExtension) p[i]).getExtension(PolicyConstraint.ID);
if (pcx != null)
constr = (PolicyConstraint) pcx.getValue();
}
else
{
byte[] pcx = p[i].getExtensionValue(PolicyConstraint.ID.toString());
if (pcx != null)
{
try
{
constr = new PolicyConstraint(pcx);
}
catch (Exception x)
{
}
}
}
if (constr != null && constr.getRequireExplicitPolicy() >= 0)
policyConstraints.add(new int[] { p.length - i,
constr.getRequireExplicitPolicy() });
updatePolicyTree(p[i], rootNode, p.length - i, (PKIXParameters) params,
checkExplicitPolicy(p.length - i, policyConstraints));
// The rest of the tests involve this cert's relationship with the
// next in the path. If this cert is the end entity, we can stop.
if (i == 0)
break;
basicSanity(p, i);
PublicKey pubKey = null;
try
{
pubKey = p[i].getPublicKey();
if (pubKey instanceof DSAPublicKey)
{
DSAParams dsa = ((DSAPublicKey) pubKey).getParams();
// If the DSA public key is missing its parameters, use those
// from the previous cert's key.
if (dsa == null || dsa.getP() == null || dsa.getG() == null
|| dsa.getQ() == null)
{
if (prevKey == null)
throw new InvalidKeyException("DSA keys not chainable");
if (! (prevKey instanceof DSAPublicKey))
throw new InvalidKeyException("DSA keys not chainable");
dsa = ((DSAPublicKey) prevKey).getParams();
pubKey = new DSSPublicKey(Registry.X509_ENCODING_ID,
dsa.getP(), dsa.getQ(),
dsa.getG(),
((DSAPublicKey) pubKey).getY());
}
}
if (sigProvider == null)
p[i - 1].verify(pubKey);
else
p[i - 1].verify(pubKey, sigProvider);
prevKey = pubKey;
}
catch (Exception e)
{
throw new CertPathValidatorException(e.toString());
}
if (! p[i].getSubjectDN().equals(p[i - 1].getIssuerDN()))
throw new CertPathValidatorException("issuer DN mismatch");
boolean[] issuerUid = p[i - 1].getIssuerUniqueID();
boolean[] subjectUid = p[i].getSubjectUniqueID();
if (issuerUid != null && subjectUid != null)
if (! Arrays.equals(issuerUid, subjectUid))
throw new CertPathValidatorException("UID mismatch");
// Check the certificate against the revocation lists.
if (((PKIXParameters) params).isRevocationEnabled())
{
X509CRLSelectorImpl selector = new X509CRLSelectorImpl();
try
{
selector.addIssuerName(p[i].getSubjectDN());
}
catch (IOException ioe)
{
throw new CertPathValidatorException("error selecting CRLs");
}
List certStores = ((PKIXParameters) params).getCertStores();
List crls = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext();)
{
CertStore cs = (CertStore) it.next();
try
{
Collection c = cs.getCRLs(selector);
crls.addAll(c);
}
catch (CertStoreException cse)
{
}
}
if (crls.isEmpty())
throw new CertPathValidatorException("no CRLs for issuer");
boolean certOk = false;
for (Iterator it = crls.iterator(); it.hasNext();)
{
CRL crl = (CRL) it.next();
if (! (crl instanceof X509CRL))
continue;
X509CRL xcrl = (X509CRL) crl;
if (! checkCRL(xcrl, p, now, p[i], pubKey, certStores))
continue;
if (xcrl.isRevoked(p[i - 1]))
throw new CertPathValidatorException("certificate is revoked");
else
certOk = true;
}
if (! certOk)
throw new CertPathValidatorException(
"certificate's validity could not be determined");
}
}
rootNode.setReadOnly();
// Now ensure that the first certificate in the chain was issued
// by a trust anchor.
Exception cause = null;
Set anchors = ((PKIXParameters) params).getTrustAnchors();
for (Iterator i = anchors.iterator(); i.hasNext();)