14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.asymmetric.x509;
2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.InputStream;
5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.PushbackInputStream;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CRL;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CRLException;
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertPath;
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateException;
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateFactorySpi;
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.cert.CertificateParsingException;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.X509Certificate;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.ArrayList;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Collection;
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Iterator;
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.List;
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1InputStream;
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Sequence;
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Set;
224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1TaggedObject;
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.pkcs.SignedData;
25e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstromimport org.bouncycastle.asn1.x509.Certificate;
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.CertificateList;
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * class for dealing with X509 certificates.
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p>
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----"
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * objects.
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic class CertificateFactory
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    extends CertificateFactorySpi
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE");
39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL");
40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ASN1Set sData = null;
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int                sDataObjectCount = 0;
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private InputStream currentStream = null;
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ASN1Set sCrlData = null;
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int                sCrlDataObjectCount = 0;
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private InputStream currentCrlStream = null;
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private java.security.cert.Certificate readDERCertificate(
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1InputStream dIn)
51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException, CertificateParsingException
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Sequence seq = (ASN1Sequence)dIn.readObject();
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (seq.size() > 1
564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier)
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData))
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                sData = SignedData.getInstance(ASN1Sequence.getInstance(
614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    (ASN1TaggedObject)seq.getObjectAt(1), true)).getCertificates();
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return getCertificate();
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new X509CertificateObject(
68e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom                            Certificate.getInstance(seq));
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private java.security.cert.Certificate getCertificate()
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CertificateParsingException
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (sData != null)
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            while (sDataObjectCount < sData.size())
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                Object obj = sData.getObjectAt(sDataObjectCount++);
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Sequence)
81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                   return new X509CertificateObject(
83e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom                                    Certificate.getInstance(obj));
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return null;
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private java.security.cert.Certificate readPEMCertificate(
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        InputStream in)
93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException, CertificateParsingException
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Sequence seq = PEM_CERT_PARSER.readPEMObject(in);
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (seq != null)
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return new X509CertificateObject(
100e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom                            Certificate.getInstance(seq));
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return null;
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    protected CRL createCRL(CertificateList c)
107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    throws CRLException
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return new X509CRLObject(c);
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private CRL readPEMCRL(
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        InputStream in)
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException, CRLException
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
116c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Sequence seq = PEM_CRL_PARSER.readPEMObject(in);
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (seq != null)
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
120c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return createCRL(
121c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                            CertificateList.getInstance(seq));
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return null;
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
127c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private CRL readDERCRL(
1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1InputStream aIn)
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException, CRLException
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Sequence seq = (ASN1Sequence)aIn.readObject();
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (seq.size() > 1
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                && seq.getObjectAt(0) instanceof ASN1ObjectIdentifier)
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (seq.getObjectAt(0).equals(PKCSObjectIdentifiers.signedData))
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                sCrlData = SignedData.getInstance(ASN1Sequence.getInstance(
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    (ASN1TaggedObject)seq.getObjectAt(1), true)).getCRLs();
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return getCRL();
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return createCRL(
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                     CertificateList.getInstance(seq));
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
149c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private CRL getCRL()
150c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CRLException
151c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
152c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (sCrlData == null || sCrlDataObjectCount >= sCrlData.size())
153c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return null;
155c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
156c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
157c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return createCRL(
158c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                            CertificateList.getInstance(
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                sCrlData.getObjectAt(sCrlDataObjectCount++)));
160c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
161c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Generates a certificate object and initializes it with the data
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * read from the input stream inStream.
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public java.security.cert.Certificate engineGenerateCertificate(
1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        InputStream in)
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateException
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (currentStream == null)
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            currentStream = in;
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sData = null;
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sDataObjectCount = 0;
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (currentStream != in) // reset if input stream has changed
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            currentStream = in;
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sData = null;
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sDataObjectCount = 0;
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (sData != null)
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (sDataObjectCount != sData.size())
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return getCertificate();
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    sData = null;
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    sDataObjectCount = 0;
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return null;
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            PushbackInputStream pis = new PushbackInputStream(in);
200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            int tag = pis.read();
201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (tag == -1)
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return null;
205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            pis.unread(tag);
208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (tag != 0x30)  // assume ascii PEM encoded.
210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return readPEMCertificate(pis);
212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
2154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return readDERCertificate(new ASN1InputStream(pis));
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (Exception e)
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new ExCertificateException(e);
221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Returns a (possibly empty) collection view of the certificates
226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * read from the given input stream inStream.
227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public Collection engineGenerateCertificates(
2294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        InputStream inStream)
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateException
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
2324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        java.security.cert.Certificate     cert;
2334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        List certs = new ArrayList();
234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while ((cert = engineGenerateCertificate(inStream)) != null)
236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            certs.add(cert);
238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return certs;
241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Generates a certificate revocation list (CRL) object and initializes
245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * it with the data read from the input stream inStream.
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CRL engineGenerateCRL(
2484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        InputStream inStream)
249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CRLException
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (currentCrlStream == null)
252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            currentCrlStream = inStream;
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sCrlData = null;
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sCrlDataObjectCount = 0;
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (currentCrlStream != inStream) // reset if input stream has changed
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            currentCrlStream = inStream;
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sCrlData = null;
261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sCrlDataObjectCount = 0;
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (sCrlData != null)
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
268c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (sCrlDataObjectCount != sCrlData.size())
269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
270c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return getCRL();
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    sCrlData = null;
275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    sCrlDataObjectCount = 0;
276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return null;
277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
279c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
280c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            PushbackInputStream pis = new PushbackInputStream(inStream);
281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            int tag = pis.read();
282c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
283c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (tag == -1)
284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
285c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return null;
286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
287c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
288c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            pis.unread(tag);
289c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
290c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (tag != 0x30)  // assume ascii PEM encoded.
291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
292c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return readPEMCRL(pis);
293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
295c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {       // lazy evaluate to help processing of large CRLs
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return readDERCRL(new ASN1InputStream(pis, true));
297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (CRLException e)
300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw e;
302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (Exception e)
304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new CRLException(e.toString());
306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Returns a (possibly empty) collection view of the CRLs read from
311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * the given input stream inStream.
312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * The inStream may contain a sequence of DER-encoded CRLs, or
314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * a PKCS#7 CRL set.  This is a PKCS#7 SignedData object, with the
315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * only signficant field being crls.  In particular the signature
316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * and the contents are ignored.
317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public Collection engineGenerateCRLs(
3194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        InputStream inStream)
320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CRLException
321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
3224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        CRL crl;
3234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        List crls = new ArrayList();
324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while ((crl = engineGenerateCRL(inStream)) != null)
326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            crls.add(crl);
328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return crls;
331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public Iterator engineGetCertPathEncodings()
334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
335200c44f2dde27abe81d5125f893e6b6ed9b69674Kenny Root        return PKIXCertPath.certPathEncodings.iterator();
336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CertPath engineGenerateCertPath(
339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        InputStream inStream)
340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateException
341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return engineGenerateCertPath(inStream, "PkiPath");
343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CertPath engineGenerateCertPath(
346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        InputStream inStream,
347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String encoding)
348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateException
349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new PKIXCertPath(inStream, encoding);
351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public CertPath engineGenerateCertPath(
354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        List certificates)
355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateException
356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Iterator iter = certificates.iterator();
358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object obj;
359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (iter.hasNext())
360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            obj = iter.next();
362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj != null)
363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (!(obj instanceof X509Certificate))
365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
366c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    throw new CertificateException("list contains non X509Certificate object while creating CertPath\n" + obj.toString());
367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new PKIXCertPath(certificates);
371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
3724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private class ExCertificateException
3744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        extends CertificateException
3754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        private Throwable cause;
3774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        public ExCertificateException(Throwable cause)
3794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.cause = cause;
3814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        public ExCertificateException(String msg, Throwable cause)
3844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            super(msg);
3864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.cause = cause;
3884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        public Throwable getCause()
3914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return cause;
3934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
396