/** * Search the given Set of TrustAnchor's for one that is the issuer of the given X509 certificate. * Uses the specified provider for signature verification, or the default provider if null. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * @param sigProvider the provider to use for signature verification * @return the <code>TrustAnchor</code> object if found or <code>null</code> if not. * @throws AnnotatedException if a TrustAnchor was found but the signature verification on the * given certificate has thrown an exception. */ protected static TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider) throws AnnotatedException { TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); X500Principal certIssuer = getEncodedIssuerPrincipal(cert); try { certSelectX509.setSubject(certIssuer.getEncoded()); } catch (IOException ex) { throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex); } Iterator iter = trustAnchors.iterator(); while (iter.hasNext() && trust == null) { trust = (TrustAnchor) iter.next(); if (trust.getTrustedCert() != null) { if (certSelectX509.match(trust.getTrustedCert())) { trustPublicKey = trust.getTrustedCert().getPublicKey(); } else { trust = null; } } else if (trust.getCAName() != null && trust.getCAPublicKey() != null) { try { X500Principal caName = new X500Principal(trust.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = trust.getCAPublicKey(); } else { trust = null; } } catch (IllegalArgumentException ex) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { verifyX509Certificate(cert, trustPublicKey, sigProvider); } catch (Exception ex) { invalidKeyEx = ex; trust = null; trustPublicKey = null; } } } if (trust == null && invalidKeyEx != null) { throw new AnnotatedException( "TrustAnchor found but certificate validation failed.", invalidKeyEx); } return trust; }
private void testExceptions() throws Exception { byte[] enc = {(byte) 0, (byte) 2, (byte) 3, (byte) 4, (byte) 5}; MyCertPath mc = new MyCertPath(enc); ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayInputStream is; byte[] arr; ObjectOutputStream oOut = new ObjectOutputStream(os); oOut.writeObject(mc); oOut.flush(); oOut.close(); try { CertificateFactory cFac = CertificateFactory.getInstance("X.509", "BC"); arr = os.toByteArray(); is = new ByteArrayInputStream(arr); cFac.generateCertPath(is); } catch (CertificateException e) { // ignore okay } CertificateFactory cf = CertificateFactory.getInstance("X.509"); List certCol = new ArrayList(); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certA))); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certB))); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certC))); certCol.add(cf.generateCertificate(new ByteArrayInputStream(certD))); CertPathBuilder pathBuilder = CertPathBuilder.getInstance("PKIX", "BC"); X509CertSelector select = new X509CertSelector(); select.setSubject(((X509Certificate) certCol.get(0)).getSubjectX500Principal().getEncoded()); Set trustanchors = new HashSet(); trustanchors.add( new TrustAnchor( (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(rootCertBin)), null)); CertStore certStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certCol)); PKIXBuilderParameters params = new PKIXBuilderParameters(trustanchors, select); params.addCertStore(certStore); try { CertPathBuilderResult result = pathBuilder.build(params); CertPath path = result.getCertPath(); fail("found cert path in circular set"); } catch (CertPathBuilderException e) { // expected } }
/** * Search the given Set of TrustAnchor's for one that is the issuer of the given X509 certificate. * * @param cert the X509 certificate * @param params with trust anchors * @return the <code>TrustAnchor</code> object if found or <code>null</code> if not. * @exception CertPathValidatorException if a TrustAnchor was found but the signature verification * on the given certificate has thrown an exception. This Exception can be obtainted with * <code>getCause()</code> method. */ static final TrustAnchor findTrustAnchor( X509Certificate cert, CertPath certPath, int index, PKIXParameters params) throws CertPathValidatorException { // If we have a trust anchor index, use it. if (params instanceof IndexedPKIXParameters) { IndexedPKIXParameters indexed = (IndexedPKIXParameters) params; return indexed.findTrustAnchor(cert, certPath, index); } Iterator iter = params.getTrustAnchors().iterator(); TrustAnchor found = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); try { certSelectX509.setSubject(getEncodedIssuerPrincipal(cert).getEncoded()); } catch (IOException ex) { throw new CertPathValidatorException(ex); } byte[] certBytes = null; try { certBytes = cert.getEncoded(); } catch (Exception e) { // ignore, just continue } while (iter.hasNext() && found == null) { found = (TrustAnchor) iter.next(); X509Certificate foundCert = found.getTrustedCert(); if (foundCert != null) { // If the trust anchor is identical to the certificate we're // done. Just return the anchor. // There is similar code in PKIXCertPathValidatorSpi. try { byte[] foundBytes = foundCert.getEncoded(); if (certBytes != null && Arrays.equals(foundBytes, certBytes)) { return found; } } catch (Exception e) { // ignore, continue and verify the certificate } if (certSelectX509.match(foundCert)) { trustPublicKey = foundCert.getPublicKey(); } else { found = null; } } else if (found.getCAName() != null && found.getCAPublicKey() != null) { try { X500Principal certIssuer = getEncodedIssuerPrincipal(cert); X500Principal caName = new X500Principal(found.getCAName()); if (certIssuer.equals(caName)) { trustPublicKey = found.getCAPublicKey(); } else { found = null; } } catch (IllegalArgumentException ex) { found = null; } } else { found = null; } if (trustPublicKey != null) { try { cert.verify(trustPublicKey); } catch (Exception ex) { invalidKeyEx = ex; found = null; } } } if (found == null && invalidKeyEx != null) { throw new CertPathValidatorException( "TrustAnchor found but certificate validation failed.", invalidKeyEx, certPath, index); } return found; }