X509Certificate[] engineValidate(X509Certificate[] chain,
Collection otherCerts,
Object parameter) throws CertificateException {
if ((chain == null) || (chain.length == 0)) {
throw new CertificateException
("null or zero-length certificate chain");
}
if (TRY_VALIDATOR) {
// check if chain contains trust anchor
for (int i = 0; i < chain.length; i++) {
if (trustedCerts.contains(chain[i])) {
if (i == 0) {
return new X509Certificate[] {chain[0]};
}
// Remove and call validator
X509Certificate[] newChain = new X509Certificate[i];
System.arraycopy(chain, 0, newChain, 0, i);
return doValidate(newChain);
}
}
// not self issued and apparently issued by trust anchor?
X509Certificate last = chain[chain.length - 1];
X500Principal issuer = last.getIssuerX500Principal();
X500Principal subject = last.getSubjectX500Principal();
if (trustedSubjects.containsKey(issuer) && !issuer.equals(subject)
&& isSignatureValid(trustedSubjects.get(issuer), last)) {
return doValidate(chain);
}
// don't fallback to builder if called from plugin/webstart
if (plugin) {
// Validate chain even if no trust anchor is found. This
// allows plugin/webstart to make sure the chain is
// otherwise valid
if (chain.length > 1) {
X509Certificate[] newChain =
new X509Certificate[chain.length-1];
System.arraycopy(chain, 0, newChain, 0, newChain.length);
// temporarily set last cert as sole trust anchor
PKIXBuilderParameters params =
(PKIXBuilderParameters) parameterTemplate.clone();
try {
params.setTrustAnchors
(Collections.singleton(new TrustAnchor
(chain[chain.length-1], null)));
} catch (InvalidAlgorithmParameterException iape) {
// should never occur, but ...
throw new CertificateException(iape);
}
doValidate(newChain, params);
}
// if the rest of the chain is valid, throw exception
// indicating no trust anchor was found
throw new ValidatorException
(ValidatorException.T_NO_TRUST_ANCHOR);
}
// otherwise, fall back to builder
}
return doBuild(chain, otherCerts);
}
|