1 package org.bouncycastle.x509;
2 
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.math.BigInteger;
6 import java.security.GeneralSecurityException;
7 import java.security.InvalidKeyException;
8 import java.security.NoSuchAlgorithmException;
9 import java.security.NoSuchProviderException;
10 import java.security.PrivateKey;
11 import java.security.PublicKey;
12 import java.security.SecureRandom;
13 import java.security.SignatureException;
14 import java.security.cert.CertificateEncodingException;
15 import java.security.cert.CertificateParsingException;
16 import java.security.cert.X509Certificate;
17 import java.util.Date;
18 import java.util.Iterator;
19 
20 import org.bouncycastle.asn1.ASN1EncodableVector;
21 import org.bouncycastle.asn1.ASN1InputStream;
22 import org.bouncycastle.asn1.ASN1Integer;
23 import org.bouncycastle.asn1.ASN1Sequence;
24 import org.bouncycastle.asn1.DERBitString;
25 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
26 import org.bouncycastle.asn1.DERSequence;
27 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
28 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
29 import org.bouncycastle.asn1.x509.TBSCertificate;
30 import org.bouncycastle.asn1.x509.Time;
31 import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator;
32 import org.bouncycastle.asn1.x509.Certificate;
33 import org.bouncycastle.asn1.x509.X509Name;
34 import org.bouncycastle.jce.provider.X509CertificateObject;
35 
36 /**
37  * class to produce an X.509 Version 1 certificate.
38  * @deprecated use org.bouncycastle.cert.X509v1CertificateBuilder.
39  */
40 public class X509V1CertificateGenerator
41 {
42     private V1TBSCertificateGenerator   tbsGen;
43     private ASN1ObjectIdentifier         sigOID;
44     private AlgorithmIdentifier         sigAlgId;
45     private String                      signatureAlgorithm;
46 
X509V1CertificateGenerator()47     public X509V1CertificateGenerator()
48     {
49         tbsGen = new V1TBSCertificateGenerator();
50     }
51 
52     /**
53      * reset the generator
54      */
reset()55     public void reset()
56     {
57         tbsGen = new V1TBSCertificateGenerator();
58     }
59 
60     /**
61      * set the serial number for the certificate.
62      */
setSerialNumber( BigInteger serialNumber)63     public void setSerialNumber(
64         BigInteger      serialNumber)
65     {
66         if (serialNumber.compareTo(BigInteger.ZERO) <= 0)
67         {
68             throw new IllegalArgumentException("serial number must be a positive integer");
69         }
70 
71         tbsGen.setSerialNumber(new ASN1Integer(serialNumber));
72     }
73 
74     /**
75      * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
76      * certificate.
77      */
setIssuerDN( X509Name issuer)78     public void setIssuerDN(
79         X509Name   issuer)
80     {
81         tbsGen.setIssuer(issuer);
82     }
83 
setNotBefore( Date date)84     public void setNotBefore(
85         Date    date)
86     {
87         tbsGen.setStartDate(new Time(date));
88     }
89 
setNotAfter( Date date)90     public void setNotAfter(
91         Date    date)
92     {
93         tbsGen.setEndDate(new Time(date));
94     }
95 
96     /**
97      * Set the subject distinguished name. The subject describes the entity associated with the public key.
98      */
setSubjectDN( X509Name subject)99     public void setSubjectDN(
100         X509Name   subject)
101     {
102         tbsGen.setSubject(subject);
103     }
104 
setPublicKey( PublicKey key)105     public void setPublicKey(
106         PublicKey       key)
107     {
108         try
109         {
110             tbsGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
111         }
112         catch (Exception e)
113         {
114             throw new IllegalArgumentException("unable to process key - " + e.toString());
115         }
116     }
117 
118     /**
119      * Set the signature algorithm. This can be either a name or an OID, names
120      * are treated as case insensitive.
121      *
122      * @param signatureAlgorithm string representation of the algorithm name.
123      */
setSignatureAlgorithm( String signatureAlgorithm)124     public void setSignatureAlgorithm(
125         String  signatureAlgorithm)
126     {
127         this.signatureAlgorithm = signatureAlgorithm;
128 
129         try
130         {
131             sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
132         }
133         catch (Exception e)
134         {
135             throw new IllegalArgumentException("Unknown signature type requested");
136         }
137 
138         sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
139 
140         tbsGen.setSignature(sigAlgId);
141     }
142 
143     /**
144      * generate an X509 certificate, based on the current issuer and subject
145      * using the default provider "BC".
146      * @deprecated use generate(key, "BC")
147      */
generateX509Certificate( PrivateKey key)148     public X509Certificate generateX509Certificate(
149         PrivateKey      key)
150         throws SecurityException, SignatureException, InvalidKeyException
151     {
152         try
153         {
154             return generateX509Certificate(key, "BC", null);
155         }
156         catch (NoSuchProviderException e)
157         {
158             throw new SecurityException("BC provider not installed!");
159         }
160     }
161 
162     /**
163      * generate an X509 certificate, based on the current issuer and subject
164      * using the default provider "BC" and the passed in source of randomness
165      * @deprecated use generate(key, random, "BC")
166      */
generateX509Certificate( PrivateKey key, SecureRandom random)167     public X509Certificate generateX509Certificate(
168         PrivateKey      key,
169         SecureRandom    random)
170         throws SecurityException, SignatureException, InvalidKeyException
171     {
172         try
173         {
174             return generateX509Certificate(key, "BC", random);
175         }
176         catch (NoSuchProviderException e)
177         {
178             throw new SecurityException("BC provider not installed!");
179         }
180     }
181 
182     /**
183      * generate an X509 certificate, based on the current issuer and subject,
184      * using the passed in provider for the signing, and the passed in source
185      * of randomness (if required).
186      * @deprecated use generate()
187      */
generateX509Certificate( PrivateKey key, String provider)188     public X509Certificate generateX509Certificate(
189         PrivateKey      key,
190         String          provider)
191         throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
192     {
193         return generateX509Certificate(key, provider, null);
194     }
195 
196     /**
197      * generate an X509 certificate, based on the current issuer and subject,
198      * using the passed in provider for the signing, and the passed in source
199      * of randomness (if required).
200      * @deprecated use generate()
201      */
generateX509Certificate( PrivateKey key, String provider, SecureRandom random)202     public X509Certificate generateX509Certificate(
203         PrivateKey      key,
204         String          provider,
205         SecureRandom    random)
206         throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
207     {
208         try
209         {
210             return generate(key, provider, random);
211         }
212         catch (NoSuchProviderException e)
213         {
214             throw e;
215         }
216         catch (SignatureException e)
217         {
218             throw e;
219         }
220         catch (InvalidKeyException e)
221         {
222             throw e;
223         }
224         catch (GeneralSecurityException e)
225         {
226             throw new SecurityException("exception: " + e);
227         }
228     }
229 
230     /**
231      * generate an X509 certificate, based on the current issuer and subject
232      * using the default provider.
233      * <p>
234      * <b>Note:</b> this differs from the deprecated method in that the default provider is
235      * used - not "BC".
236      * </p>
237      */
generate( PrivateKey key)238     public X509Certificate generate(
239         PrivateKey      key)
240         throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
241     {
242         return generate(key, (SecureRandom)null);
243     }
244 
245     /**
246      * generate an X509 certificate, based on the current issuer and subject
247      * using the default provider and the passed in source of randomness
248      * <p>
249      * <b>Note:</b> this differs from the deprecated method in that the default provider is
250      * used - not "BC".
251      * </p>
252      */
generate( PrivateKey key, SecureRandom random)253     public X509Certificate generate(
254         PrivateKey      key,
255         SecureRandom    random)
256         throws CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
257     {
258         TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
259         byte[] signature;
260 
261         try
262         {
263             signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCert);
264         }
265         catch (IOException e)
266         {
267             throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
268         }
269 
270         return generateJcaObject(tbsCert, signature);
271     }
272 
273     /**
274      * generate an X509 certificate, based on the current issuer and subject,
275      * using the passed in provider for the signing, and the passed in source
276      * of randomness (if required).
277      */
generate( PrivateKey key, String provider)278     public X509Certificate generate(
279         PrivateKey      key,
280         String          provider)
281         throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
282     {
283         return generate(key, provider, null);
284     }
285 
286     /**
287      * generate an X509 certificate, based on the current issuer and subject,
288      * using the passed in provider for the signing, and the passed in source
289      * of randomness (if required).
290      */
generate( PrivateKey key, String provider, SecureRandom random)291     public X509Certificate generate(
292         PrivateKey      key,
293         String          provider,
294         SecureRandom    random)
295         throws CertificateEncodingException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
296     {
297         TBSCertificate tbsCert = tbsGen.generateTBSCertificate();
298         byte[] signature;
299 
300         try
301         {
302             signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCert);
303         }
304         catch (IOException e)
305         {
306             throw new ExtCertificateEncodingException("exception encoding TBS cert", e);
307         }
308 
309         return generateJcaObject(tbsCert, signature);
310     }
311 
generateJcaObject(TBSCertificate tbsCert, byte[] signature)312     private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature)
313         throws CertificateEncodingException
314     {
315         ASN1EncodableVector v = new ASN1EncodableVector();
316 
317         v.add(tbsCert);
318         v.add(sigAlgId);
319         v.add(new DERBitString(signature));
320 
321         try
322         {
323             return new X509CertificateObject(Certificate.getInstance(new DERSequence(v)));
324         }
325         catch (CertificateParsingException e)
326         {
327             throw new ExtCertificateEncodingException("exception producing certificate object", e);
328         }
329     }
330 
331     /**
332      * Return an iterator of the signature names supported by the generator.
333      *
334      * @return an iterator containing recognised names.
335      */
getSignatureAlgNames()336     public Iterator getSignatureAlgNames()
337     {
338         return X509Util.getAlgNames();
339     }
340 }
341