All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.5.

There is a newer version: 1.46
Show newest version
package org.bouncycastle.jce.provider;

import org.bouncycastle.jce.exception.ExtCertPathBuilderException;

import javax.security.auth.x500.X500Principal;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertPathBuilderSpi;
import java.security.cert.CertPathParameters;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertSelector;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Implements the PKIX CertPathBuilding algorithem for BouncyCastle.
 * 
* MAYBE: implement more CertPath validation whil build path to omit invalid pathes * * @see CertPathBuilderSpi **/ public class PKIXCertPathBuilderSpi extends CertPathBuilderSpi { /** * Build and validate a CertPath using the given parameter. * * @param params PKIXBuilderParameters object containing all * information to build the CertPath **/ public CertPathBuilderResult engineBuild( CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { if (!(params instanceof PKIXBuilderParameters)) { throw new InvalidAlgorithmParameterException("params must be a PKIXBuilderParameters instance"); } PKIXBuilderParameters pkixParams = (PKIXBuilderParameters)params; Collection targets; Iterator targetIter; List certPathList = new ArrayList(); Set certPathSet = new HashSet(); X509Certificate cert; Collection certs; CertPath certPath = null; Exception certPathException = null; // search target certificates CertSelector certSelect = pkixParams.getTargetCertConstraints(); if (certSelect == null) { throw new CertPathBuilderException("targetCertConstraints must be non-null for CertPath building"); } try { targets = CertPathValidatorUtilities.findCertificates(certSelect, pkixParams.getCertStores()); } catch (AnnotatedException e) { throw new ExtCertPathBuilderException("Error finding target certificate.", e.getCause()); } if (targets.isEmpty()) { throw new CertPathBuilderException("no certificate found matching targetCertContraints"); } CertificateFactory cFact; CertPathValidator validator; try { cFact = CertificateFactory.getInstance("X.509", "BC"); validator = CertPathValidator.getInstance("PKIX", "BC"); } catch (Exception e) { throw new CertPathBuilderException("exception creating support classes: " + e); } // // check all potential target certificates targetIter = targets.iterator(); while (targetIter.hasNext()) { cert = (X509Certificate)targetIter.next(); certPathList.clear(); certPathSet.clear(); while (cert != null) { // add cert to the certpath certPathList.add(cert); certPathSet.add(cert); // check whether the issuer of is a TrustAnchor if (findTrustAnchor(cert, pkixParams.getTrustAnchors()) != null) { try { certPath = cFact.generateCertPath(certPathList); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(certPath, pkixParams); return new PKIXCertPathBuilderResult(certPath, result.getTrustAnchor(), result.getPolicyTree(), result.getPublicKey()); } catch (CertificateException ex) { certPathException = ex; } catch (CertPathValidatorException ex) { certPathException = ex; } // if validation failed go to next certificate cert = null; } else { // try to get the issuer certificate from one // of the CertStores try { X509Certificate issuer = findIssuer(cert, pkixParams.getCertStores()); if (issuer.equals(cert)) { cert = null; } else { cert = issuer; // validation failed - circular path detected, go to next certificate if (certPathSet.contains(cert)) { cert = null; } } } catch (CertPathValidatorException ex) { certPathException = ex; cert = null; } } } } if (certPath != null) { throw new CertPathBuilderException("found certificate chain, but could not be validated", certPathException); } throw new CertPathBuilderException("unable to find certificate chain"); } /** * Search the given Set of TrustAnchor's for one that is the * issuer of the fiven X509 certificate. * * @param cert the X509 certificate * @param trustAnchors a Set of TrustAnchor's * * @return the TrustAnchor object if found or * null if not. * */ final TrustAnchor findTrustAnchor( X509Certificate cert, Set trustAnchors) throws CertPathBuilderException { Iterator iter = trustAnchors.iterator(); TrustAnchor trust = null; PublicKey trustPublicKey = null; Exception invalidKeyEx = null; X509CertSelector certSelectX509 = new X509CertSelector(); try { certSelectX509.setSubject(cert.getIssuerX500Principal().getEncoded()); } catch (IOException ex) { throw new CertPathBuilderException("can't get trust anchor principal",null); } 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 certIssuer = cert.getIssuerX500Principal(); 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 { cert.verify(trustPublicKey); } catch (Exception ex) { invalidKeyEx = ex; trust = null; } } } if (trust == null && invalidKeyEx != null) { throw new CertPathBuilderException("TrustAnchor found put certificate validation failed",invalidKeyEx); } return trust; } /** * Find the issuer certificate of the given certificate. * * @param cert the certificate hows issuer certificate should * be found. * @param certStores a list of CertStore object * that will be searched * * @return then X509Certificate object containing * the issuer certificate or null if not found * * @exception CertPathValidatorException if a TrustAnchor was * found but the signature verificytion on the given certificate * has thrown an exception. This Exception can be obtainted with * getCause() method. **/ private X509Certificate findIssuer( X509Certificate cert, List certStores) throws CertPathValidatorException { Exception invalidKeyEx = null; X509CertSelector certSelect = new X509CertSelector(); try { certSelect.setSubject(cert.getIssuerX500Principal().getEncoded()); } catch (IOException ex) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } Iterator iter; try { iter = CertPathValidatorUtilities.findCertificates(certSelect, certStores).iterator(); } catch (AnnotatedException e) { throw new CertPathValidatorException(e.getCause()); } X509Certificate issuer = null; while (iter.hasNext() && issuer == null) { issuer = (X509Certificate)iter.next(); try { cert.verify(issuer.getPublicKey()); } catch (Exception ex) { invalidKeyEx = ex; issuer = null; } } if (issuer == null && invalidKeyEx == null) { throw new CertPathValidatorException("Issuer not found", null, null, -1); } if (issuer == null && invalidKeyEx != null) { throw new CertPathValidatorException("issuer found but certificate validation failed",invalidKeyEx,null,-1); } return issuer; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy