summaryrefslogtreecommitdiff
path: root/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXAttrCertPathValidatorSpi.java
blob: ee7270389d9cb389f00350e91c508d37b661c304 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package org.bouncycastle.jce.provider;

import java.security.InvalidAlgorithmParameterException;
import java.security.Provider;
import java.security.Security;
import java.security.cert.CertPath;
import java.security.cert.CertPathParameters;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.CertPathValidatorSpi;
import java.security.cert.PKIXParameters;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.bouncycastle.jcajce.PKIXExtendedParameters;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
import org.bouncycastle.util.Selector;
import org.bouncycastle.x509.ExtendedPKIXParameters;
import org.bouncycastle.x509.X509AttributeCertStoreSelector;
import org.bouncycastle.x509.X509AttributeCertificate;

/**
 * CertPathValidatorSpi implementation for X.509 Attribute Certificates la RFC 3281.
 * 
 * @see org.bouncycastle.x509.ExtendedPKIXParameters
 */
public class PKIXAttrCertPathValidatorSpi
    extends CertPathValidatorSpi
{
    private final JcaJceHelper helper = new BCJcaJceHelper();

    public PKIXAttrCertPathValidatorSpi()
    {
    }

    /**
     * Validates an attribute certificate with the given certificate path.
     * 
     * <p>
     * <code>params</code> must be an instance of
     * <code>ExtendedPKIXParameters</code>.
     * <p>
     * The target constraints in the <code>params</code> must be an
     * <code>X509AttributeCertStoreSelector</code> with at least the attribute
     * certificate criterion set. Obey that also target informations may be
     * necessary to correctly validate this attribute certificate.
     * <p>
     * The attribute certificate issuer must be added to the trusted attribute
     * issuers with {@link org.bouncycastle.x509.ExtendedPKIXParameters#setTrustedACIssuers(java.util.Set)}.
     * 
     * @param certPath The certificate path which belongs to the attribute
     *            certificate issuer public key certificate.
     * @param params The PKIX parameters.
     * @return A <code>PKIXCertPathValidatorResult</code> of the result of
     *         validating the <code>certPath</code>.
     * @throws java.security.InvalidAlgorithmParameterException if <code>params</code> is
     *             inappropriate for this validator.
     * @throws java.security.cert.CertPathValidatorException if the verification fails.
     */
    public CertPathValidatorResult engineValidate(CertPath certPath,
        CertPathParameters params) throws CertPathValidatorException,
        InvalidAlgorithmParameterException
    {
        if (!(params instanceof ExtendedPKIXParameters || params instanceof PKIXExtendedParameters))
        {
            throw new InvalidAlgorithmParameterException(
                "Parameters must be a "
                    + ExtendedPKIXParameters.class.getName() + " instance.");
        }
        Set attrCertCheckers = new HashSet();
        Set prohibitedACAttrbiutes = new HashSet();
        Set necessaryACAttributes = new HashSet();
        Set trustedACIssuers = new HashSet();

        PKIXExtendedParameters paramsPKIX;
        if (params instanceof PKIXParameters)
        {
            PKIXExtendedParameters.Builder paramsPKIXBldr = new PKIXExtendedParameters.Builder((PKIXParameters)params);

            if (params instanceof ExtendedPKIXParameters)
            {
                ExtendedPKIXParameters extPKIX = (ExtendedPKIXParameters)params;

                paramsPKIXBldr.setUseDeltasEnabled(extPKIX.isUseDeltasEnabled());
                paramsPKIXBldr.setValidityModel(extPKIX.getValidityModel());
                attrCertCheckers = extPKIX.getAttrCertCheckers();
                prohibitedACAttrbiutes = extPKIX.getProhibitedACAttributes();
                necessaryACAttributes = extPKIX.getNecessaryACAttributes();
            }

            paramsPKIX = paramsPKIXBldr.build();
        }
        else
        {
            paramsPKIX = (PKIXExtendedParameters)params;
        }

        Selector certSelect = paramsPKIX.getTargetConstraints();
        if (!(certSelect instanceof X509AttributeCertStoreSelector))
        {
            throw new InvalidAlgorithmParameterException(
                "TargetConstraints must be an instance of "
                    + X509AttributeCertStoreSelector.class.getName() + " for "
                    + this.getClass().getName() + " class.");
        }

        X509AttributeCertificate attrCert = ((X509AttributeCertStoreSelector) certSelect)
            .getAttributeCert();

        CertPath holderCertPath = RFC3281CertPathUtilities.processAttrCert1(attrCert, paramsPKIX);
        CertPathValidatorResult result = RFC3281CertPathUtilities.processAttrCert2(certPath, paramsPKIX);
        X509Certificate issuerCert = (X509Certificate) certPath
            .getCertificates().get(0);
        RFC3281CertPathUtilities.processAttrCert3(issuerCert, paramsPKIX);
        RFC3281CertPathUtilities.processAttrCert4(issuerCert, trustedACIssuers);
        RFC3281CertPathUtilities.processAttrCert5(attrCert, paramsPKIX);
        // 6 already done in X509AttributeCertStoreSelector
        RFC3281CertPathUtilities.processAttrCert7(attrCert, certPath, holderCertPath, paramsPKIX, attrCertCheckers);
        RFC3281CertPathUtilities.additionalChecks(attrCert, prohibitedACAttrbiutes, necessaryACAttributes);
        Date date = null;
        try
        {
            date = CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX, null, -1);
        }
        catch (AnnotatedException e)
        {
            throw new ExtCertPathValidatorException(
                "Could not get validity date from attribute certificate.", e);
        }
        RFC3281CertPathUtilities.checkCRLs(attrCert, paramsPKIX, issuerCert, date, certPath.getCertificates(), helper);
        return result;
    }
}