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