pkixcertpathbuilderspi.java

来自「bouncycastle 是一个JAVA安全提供者」· Java 代码 · 共 354 行

JAVA
354
字号
package org.bouncycastle.jce.provider;import java.io.IOException;import java.security.InvalidAlgorithmParameterException;import java.security.PublicKey;import java.security.cert.*;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;import javax.security.auth.x500.X500Principal;/** * Implements the PKIX CertPathBuilding algorithem for BouncyCastle. * <br /> * <b>MAYBE: implement more CertPath validation whil build path to omit invalid pathes</b> * * @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();        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 = findCertificates(certSelect, pkixParams.getCertStores());        }        catch (CertStoreException e)        {            throw new CertPathBuilderException(e);        }        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();            while (cert != null)            {                // add cert to the certpath                certPathList.add(cert);                // check wether the issuer of <cert> 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;                        }                    }                    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 <code>TrustAnchor</code> object if found or     * <code>null</code> if not.     *     * @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     * <code>getCause()</code> method.     **/    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;    }    /**     * Return a Collection of all certificates found in the     * CertStore's that are matching the certSelect criteriums.     *     * @param certSelector a {@link CertSelector CertSelector}     * object that will be used to select the certificates     * @param certStores a List containing only {@link CertStore     * CertStore} objects. These are used to search for     * certificates     *     * @return a Collection of all found {@link Certificate Certificate}     * objects. May be empty but never <code>null</code>.     **/    private final Collection findCertificates(        CertSelector    certSelect,        List            certStores)         throws CertStoreException    {        Set certs = new HashSet();        Iterator iter = certStores.iterator();        while (iter.hasNext())        {            CertStore   certStore = (CertStore)iter.next();            certs.addAll(certStore.getCertificates(certSelect));        }        return certs;    }        /**     * Find the issuer certificate of the given certificate.     *     * @param cert the certificate hows issuer certificate should     * be found.     * @param certStores a list of <code>CertStore</code> object     * that will be searched     *     * @return then <code>X509Certificate</code> object containing     * the issuer certificate or <code>null</code> 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     * <code>getCause()</code> method.     **/    private final 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 = findCertificates(certSelect, certStores).iterator();        }        catch (CertStoreException e)        {            throw new CertPathValidatorException(e);        }                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;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?