X509V3CertificateGenerator.java revision c37f4a04ef89e73a39a59f3c5a179af8c8ab5974
1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.x509;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable;
4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1EncodableVector;
5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1InputStream;
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBitString;
7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DEREncodable;
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERInteger;
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERObjectIdentifier;
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERSequence;
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.TBSCertificateStructure;
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.Time;
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.X509CertificateStructure;
17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.X509ExtensionsGenerator;
18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.x509.X509Name;
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.jce.X509Principal;
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.jce.provider.X509CertificateObject;
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.x509.extension.X509ExtensionUtil;
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport javax.security.auth.x500.X500Principal;
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.math.BigInteger;
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.GeneralSecurityException;
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.InvalidKeyException;
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.NoSuchAlgorithmException;
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.NoSuchProviderException;
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.PrivateKey;
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.PublicKey;
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SecureRandom;
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SignatureException;
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.cert.CertificateEncodingException;
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.CertificateParsingException;
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.cert.X509Certificate;
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Date;
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Iterator;
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * class to produce an X.509 Version 3 certificate.
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class X509V3CertificateGenerator
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private V3TBSCertificateGenerator   tbsGen;
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private DERObjectIdentifier         sigOID;
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private AlgorithmIdentifier         sigAlgId;
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private String                      signatureAlgorithm;
49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private X509ExtensionsGenerator     extGenerator;
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public X509V3CertificateGenerator()
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen = new V3TBSCertificateGenerator();
54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        extGenerator = new X509ExtensionsGenerator();
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * reset the generator
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void reset()
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen = new V3TBSCertificateGenerator();
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        extGenerator.reset();
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * set the serial number for the certificate.
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setSerialNumber(
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        BigInteger      serialNumber)
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (serialNumber.compareTo(BigInteger.ZERO) <= 0)
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("serial number must be a positive integer");
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen.setSerialNumber(new DERInteger(serialNumber));
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * certificate.
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setIssuerDN(
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X500Principal   issuer)
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            tbsGen.setIssuer(new X509Principal(issuer.getEncoded()));
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("can't process principal: " + e);
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * certificate.
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setIssuerDN(
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X509Name   issuer)
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen.setIssuer(issuer);
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setNotBefore(
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Date    date)
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen.setStartDate(new Time(date));
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setNotAfter(
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Date    date)
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen.setEndDate(new Time(date));
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Set the subject distinguished name. The subject describes the entity associated with the public key.
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setSubjectDN(
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X500Principal   subject)
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            tbsGen.setSubject(new X509Principal(subject.getEncoded()));
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("can't process principal: " + e);
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Set the subject distinguished name. The subject describes the entity associated with the public key.
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setSubjectDN(
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X509Name   subject)
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen.setSubject(subject);
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setPublicKey(
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        PublicKey       key)
146c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IllegalArgumentException
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
150c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            tbsGen.setSubjectPublicKeyInfo(
151c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                       SubjectPublicKeyInfo.getInstance(new ASN1InputStream(key.getEncoded()).readObject()));
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (Exception e)
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("unable to process key - " + e.toString());
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Set the signature algorithm. This can be either a name or an OID, names
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * are treated as case insensitive.
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param signatureAlgorithm string representation of the algorithm name.
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void setSignatureAlgorithm(
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String  signatureAlgorithm)
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.signatureAlgorithm = signatureAlgorithm;
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (Exception e)
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("Unknown signature type requested: " + signatureAlgorithm);
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
179c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        tbsGen.setSignature(sigAlgId);
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * Set the subject unique ID - note: it is very rare that it is correct to do this.
186c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public void setSubjectUniqueID(boolean[] uniqueID)
188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        tbsGen.setSubjectUniqueID(booleanToBitString(uniqueID));
190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
192c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * Set the issuer unique ID - note: it is very rare that it is correct to do this.
194c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public void setIssuerUniqueID(boolean[] uniqueID)
196c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        tbsGen.setIssuerUniqueID(booleanToBitString(uniqueID));
198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private DERBitString booleanToBitString(boolean[] id)
201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
202c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        byte[] bytes = new byte[(id.length + 7) / 8];
203c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
204c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (int i = 0; i != id.length; i++)
205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            bytes[i / 8] |= (id[i]) ? (1 << ((7 - (i % 8)))) : 0;
207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
209c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int pad = id.length % 8;
210c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (pad == 0)
212c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return new DERBitString(bytes);
214c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else
216c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
217c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return new DERBitString(bytes, 8 - pad);
218c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
219c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
220c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
221c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a given extension field for the standard extensions tag (tag 3)
223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
224b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void addExtension(
225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          oid,
226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean         critical,
227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DEREncodable    value)
228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.addExtension(new DERObjectIdentifier(oid), critical, value);
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a given extension field for the standard extensions tag (tag 3)
234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void addExtension(
236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DERObjectIdentifier oid,
237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             critical,
238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DEREncodable        value)
239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        extGenerator.addExtension(oid, critical,  value);
241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a given extension field for the standard extensions tag (tag 3)
245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * The value parameter becomes the contents of the octet string associated
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * with the extension.
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void addExtension(
249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          oid,
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean         critical,
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]          value)
252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.addExtension(new DERObjectIdentifier(oid), critical, value);
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a given extension field for the standard extensions tag (tag 3)
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void addExtension(
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DERObjectIdentifier oid,
261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             critical,
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]              value)
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
264c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        extGenerator.addExtension(oid, critical, value);
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a given extension field for the standard extensions tag (tag 3)
269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * copying the extension value from another certificate.
270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @throws CertificateParsingException if the extension cannot be extracted.
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void copyAndAddExtension(
273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          oid,
274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean         critical,
275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X509Certificate cert)
276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateParsingException
277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[] extValue = cert.getExtensionValue(oid);
279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (extValue == null)
281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new CertificateParsingException("extension " + oid + " not present");
283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            ASN1Encodable value = X509ExtensionUtil.fromExtensionValue(extValue);
288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.addExtension(oid, critical, value);
290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new CertificateParsingException(e.toString());
294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add a given extension field for the standard extensions tag (tag 3)
299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * copying the extension value from another certificate.
300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @throws CertificateParsingException if the extension cannot be extracted.
301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void copyAndAddExtension(
303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DERObjectIdentifier oid,
304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             critical,
305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        X509Certificate     cert)
306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws CertificateParsingException
307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.copyAndAddExtension(oid.getId(), critical, cert);
309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate an X509 certificate, based on the current issuer and subject
313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * using the default provider "BC".
314c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @deprecated use generate(key, "BC")
315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public X509Certificate generateX509Certificate(
317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        PrivateKey      key)
318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws SecurityException, SignatureException, InvalidKeyException
319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return generateX509Certificate(key, "BC", null);
323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (NoSuchProviderException e)
325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new SecurityException("BC provider not installed!");
327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate an X509 certificate, based on the current issuer and subject
332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * using the default provider "BC", and the passed in source of randomness
333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * (if required).
334c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @deprecated use generate(key, random, "BC")
335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public X509Certificate generateX509Certificate(
337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        PrivateKey      key,
338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        SecureRandom    random)
339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws SecurityException, SignatureException, InvalidKeyException
340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return generateX509Certificate(key, "BC", random);
344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (NoSuchProviderException e)
346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new SecurityException("BC provider not installed!");
348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate an X509 certificate, based on the current issuer and subject,
353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * using the passed in provider for the signing.
354c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @deprecated use generate()
355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public X509Certificate generateX509Certificate(
357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        PrivateKey      key,
358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          provider)
359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return generateX509Certificate(key, provider, null);
362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate an X509 certificate, based on the current issuer and subject,
366b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * using the passed in provider for the signing and the supplied source
367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * of randomness, if required.
368c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @deprecated use generate()
369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public X509Certificate generateX509Certificate(
371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        PrivateKey      key,
372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          provider,
373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        SecureRandom    random)
374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
375b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
376c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        try
377b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
378c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return generate(key, provider, random);
379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
380c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (NoSuchProviderException e)
381c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
382c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw e;
383c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
384c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (SignatureException e)
385c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
386c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw e;
387c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
388c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (InvalidKeyException e)
389b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
390c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw e;
391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
392c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (GeneralSecurityException e)
393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
394c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new SecurityException("exception: " + e);
395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
396c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
398c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
399c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * generate an X509 certificate, based on the current issuer and subject
400c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * using the default provider.
401c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * <p>
402c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * <b>Note:</b> this differs from the deprecated method in that the default provider is
403c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * used - not "BC".
404c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * </p>
405c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
406c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public X509Certificate generate(
407c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        PrivateKey      key)
408c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
409c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
410c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return generate(key, (SecureRandom)null);
411c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
412c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
413c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
414c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * generate an X509 certificate, based on the current issuer and subject
415c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * using the default provider, and the passed in source of randomness
416c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * (if required).
417c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * <p>
418c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * <b>Note:</b> this differs from the deprecated method in that the default provider is
419c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * used - not "BC".
420c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * </p>
421c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
422c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public X509Certificate generate(
423c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        PrivateKey      key,
424c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        SecureRandom    random)
425c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
426c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
427c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        TBSCertificateStructure tbsCert = generateTbsCert();
428c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        byte[] signature;
429c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
430c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        try
431b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
432c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert);
433b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
434c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (IOException e)
435b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
436c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
437b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
438b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
439c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        try
440b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
441c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return generateJcaObject(tbsCert, signature);
442b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
443c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (CertificateParsingException e)
444c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
445c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new ExtCertificateEncodingException("exception producing certificate object", e);
446c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
447c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
448b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
449c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
450c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * generate an X509 certificate, based on the current issuer and subject,
451c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * using the passed in provider for the signing.
452c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
453c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public X509Certificate generate(
454c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        PrivateKey      key,
455c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String          provider)
456c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
457c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
458c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return generate(key, provider, null);
459c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
460c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
461c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
462c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * generate an X509 certificate, based on the current issuer and subject,
463c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * using the passed in provider for the signing and the supplied source
464c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * of randomness, if required.
465c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
466c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public X509Certificate generate(
467c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        PrivateKey      key,
468c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String          provider,
469c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        SecureRandom    random)
470c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
471c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
472c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        TBSCertificateStructure tbsCert = generateTbsCert();
473c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        byte[] signature;
474b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
475b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
476b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
477c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert);
478c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
479c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (IOException e)
480c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
481c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
482c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
483b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
484c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        try
485c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
486c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return generateJcaObject(tbsCert, signature);
487b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
488c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (CertificateParsingException e)
489c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
490c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new ExtCertificateEncodingException("exception producing certificate object", e);
491c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
492c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
493c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
494c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private TBSCertificateStructure generateTbsCert()
495c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
496c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!extGenerator.isEmpty())
497b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
498c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            tbsGen.setExtensions(extGenerator.generate());
499b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
500b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
501c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return tbsGen.generateTBSCertificate();
502c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
503c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
504c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private X509Certificate generateJcaObject(TBSCertificateStructure tbsCert, byte[] signature)
505c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws CertificateParsingException
506c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
507c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1EncodableVector v = new ASN1EncodableVector();
508b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
509b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        v.add(tbsCert);
510b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        v.add(sigAlgId);
511c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        v.add(new DERBitString(signature));
512b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
513b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new X509CertificateObject(new X509CertificateStructure(new DERSequence(v)));
514b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
515c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
516b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
517b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return an iterator of the signature names supported by the generator.
518b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
519b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return an iterator containing recognised names.
520b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
521b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public Iterator getSignatureAlgNames()
522b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
523b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return X509Util.getAlgNames();
524b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
525b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
526