1 package org.bouncycastle.x509;
2 
3 import java.io.IOException;
4 import java.math.BigInteger;
5 import java.security.GeneralSecurityException;
6 import java.security.InvalidKeyException;
7 import java.security.NoSuchAlgorithmException;
8 import java.security.NoSuchProviderException;
9 import java.security.PrivateKey;
10 import java.security.SecureRandom;
11 import java.security.SignatureException;
12 import java.security.cert.CRLException;
13 import java.security.cert.X509CRL;
14 import java.security.cert.X509CRLEntry;
15 import java.util.Date;
16 import java.util.Iterator;
17 import java.util.Set;
18 
19 import org.bouncycastle.asn1.ASN1Encodable;
20 import org.bouncycastle.asn1.ASN1EncodableVector;
21 import org.bouncycastle.asn1.ASN1InputStream;
22 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
23 import org.bouncycastle.asn1.ASN1Sequence;
24 import org.bouncycastle.asn1.DERBitString;
25 import org.bouncycastle.asn1.ASN1GeneralizedTime;
26 import org.bouncycastle.asn1.ASN1Integer;
27 import org.bouncycastle.asn1.DERSequence;
28 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
29 import org.bouncycastle.asn1.x509.CertificateList;
30 import org.bouncycastle.asn1.x509.TBSCertList;
31 import org.bouncycastle.asn1.x509.Time;
32 import org.bouncycastle.asn1.x509.V2TBSCertListGenerator;
33 import org.bouncycastle.asn1.x509.X509Extensions;
34 import org.bouncycastle.asn1.x509.Extensions;
35 import org.bouncycastle.asn1.x509.X509ExtensionsGenerator;
36 import org.bouncycastle.asn1.x509.X509Name;
37 import org.bouncycastle.jce.provider.X509CRLObject;
38 
39 /**
40  * class to produce an X.509 Version 2 CRL.
41  *  @deprecated use org.bouncycastle.cert.X509v2CRLBuilder.
42  */
43 public class X509V2CRLGenerator
44 {
45     private V2TBSCertListGenerator      tbsGen;
46     private ASN1ObjectIdentifier         sigOID;
47     private AlgorithmIdentifier         sigAlgId;
48     private String                      signatureAlgorithm;
49     private X509ExtensionsGenerator     extGenerator;
50 
X509V2CRLGenerator()51     public X509V2CRLGenerator()
52     {
53         tbsGen = new V2TBSCertListGenerator();
54         extGenerator = new X509ExtensionsGenerator();
55     }
56 
57     /**
58      * reset the generator
59      */
reset()60     public void reset()
61     {
62         tbsGen = new V2TBSCertListGenerator();
63         extGenerator.reset();
64     }
65 
66     /**
67      * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the
68      * certificate.
69      */
setIssuerDN( X509Name issuer)70     public void setIssuerDN(
71         X509Name   issuer)
72     {
73         tbsGen.setIssuer(issuer);
74     }
75 
setThisUpdate( Date date)76     public void setThisUpdate(
77         Date    date)
78     {
79         tbsGen.setThisUpdate(new Time(date));
80     }
81 
setNextUpdate( Date date)82     public void setNextUpdate(
83         Date    date)
84     {
85         tbsGen.setNextUpdate(new Time(date));
86     }
87 
88     /**
89      * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise
90      * or 0 if CRLReason is not to be used
91      **/
addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason)92     public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason)
93     {
94         tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason);
95     }
96 
97     /**
98      * Add a CRL entry with an Invalidity Date extension as well as a CRLReason extension.
99      * Reason being as indicated by CRLReason, i.e. CRLReason.keyCompromise
100      * or 0 if CRLReason is not to be used
101      **/
addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason, Date invalidityDate)102     public void addCRLEntry(BigInteger userCertificate, Date revocationDate, int reason, Date invalidityDate)
103     {
104         tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate));
105     }
106 
107     /**
108      * Add a CRL entry with extensions.
109      **/
addCRLEntry(BigInteger userCertificate, Date revocationDate, X509Extensions extensions)110     public void addCRLEntry(BigInteger userCertificate, Date revocationDate, X509Extensions extensions)
111     {
112         tbsGen.addCRLEntry(new ASN1Integer(userCertificate), new Time(revocationDate), Extensions.getInstance(extensions));
113     }
114 
115     /**
116      * Add the CRLEntry objects contained in a previous CRL.
117      *
118      * @param other the X509CRL to source the other entries from.
119      */
addCRL(X509CRL other)120     public void addCRL(X509CRL other)
121         throws CRLException
122     {
123         Set revocations = other.getRevokedCertificates();
124 
125         if (revocations != null)
126         {
127             Iterator it = revocations.iterator();
128             while (it.hasNext())
129             {
130                 X509CRLEntry entry = (X509CRLEntry)it.next();
131 
132                 ASN1InputStream aIn = new ASN1InputStream(entry.getEncoded());
133 
134                 try
135                 {
136                     tbsGen.addCRLEntry(ASN1Sequence.getInstance(aIn.readObject()));
137                 }
138                 catch (IOException e)
139                 {
140                     throw new CRLException("exception processing encoding of CRL: " + e.toString());
141                 }
142             }
143         }
144     }
145 
146     /**
147      * Set the signature algorithm. This can be either a name or an OID, names
148      * are treated as case insensitive.
149      *
150      * @param signatureAlgorithm string representation of the algorithm name.
151      */
setSignatureAlgorithm( String signatureAlgorithm)152     public void setSignatureAlgorithm(
153         String  signatureAlgorithm)
154     {
155         this.signatureAlgorithm = signatureAlgorithm;
156 
157         try
158         {
159             sigOID = X509Util.getAlgorithmOID(signatureAlgorithm);
160         }
161         catch (Exception e)
162         {
163             throw new IllegalArgumentException("Unknown signature type requested");
164         }
165 
166         sigAlgId = X509Util.getSigAlgID(sigOID, signatureAlgorithm);
167 
168         tbsGen.setSignature(sigAlgId);
169     }
170 
171     /**
172      * add a given extension field for the standard extensions tag (tag 0)
173      */
addExtension( String oid, boolean critical, ASN1Encodable value)174     public void addExtension(
175         String          oid,
176         boolean         critical,
177         ASN1Encodable    value)
178     {
179         this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
180     }
181 
182     /**
183      * add a given extension field for the standard extensions tag (tag 0)
184      */
addExtension( ASN1ObjectIdentifier oid, boolean critical, ASN1Encodable value)185     public void addExtension(
186         ASN1ObjectIdentifier oid,
187         boolean             critical,
188         ASN1Encodable value)
189     {
190         extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
191     }
192 
193     /**
194      * add a given extension field for the standard extensions tag (tag 0)
195      */
addExtension( String oid, boolean critical, byte[] value)196     public void addExtension(
197         String          oid,
198         boolean         critical,
199         byte[]          value)
200     {
201         this.addExtension(new ASN1ObjectIdentifier(oid), critical, value);
202     }
203 
204     /**
205      * add a given extension field for the standard extensions tag (tag 0)
206      */
addExtension( ASN1ObjectIdentifier oid, boolean critical, byte[] value)207     public void addExtension(
208         ASN1ObjectIdentifier oid,
209         boolean             critical,
210         byte[]              value)
211     {
212         extGenerator.addExtension(new ASN1ObjectIdentifier(oid.getId()), critical, value);
213     }
214 
215     /**
216      * generate an X509 CRL, based on the current issuer and subject
217      * using the default provider "BC".
218      * @deprecated use generate(key, "BC")
219      */
generateX509CRL( PrivateKey key)220     public X509CRL generateX509CRL(
221         PrivateKey      key)
222         throws SecurityException, SignatureException, InvalidKeyException
223     {
224         try
225         {
226             return generateX509CRL(key, "BC", null);
227         }
228         catch (NoSuchProviderException e)
229         {
230             throw new SecurityException("BC provider not installed!");
231         }
232     }
233 
234     /**
235      * generate an X509 CRL, based on the current issuer and subject
236      * using the default provider "BC" and an user defined SecureRandom object as
237      * source of randomness.
238      * @deprecated use generate(key, random, "BC")
239      */
generateX509CRL( PrivateKey key, SecureRandom random)240     public X509CRL generateX509CRL(
241         PrivateKey      key,
242         SecureRandom    random)
243         throws SecurityException, SignatureException, InvalidKeyException
244     {
245         try
246         {
247             return generateX509CRL(key, "BC", random);
248         }
249         catch (NoSuchProviderException e)
250         {
251             throw new SecurityException("BC provider not installed!");
252         }
253     }
254 
255     /**
256      * generate an X509 certificate, based on the current issuer and subject
257      * using the passed in provider for the signing.
258      * @deprecated use generate()
259      */
generateX509CRL( PrivateKey key, String provider)260     public X509CRL generateX509CRL(
261         PrivateKey      key,
262         String          provider)
263         throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
264     {
265         return generateX509CRL(key, provider, null);
266     }
267 
268     /**
269      * generate an X509 CRL, based on the current issuer and subject,
270      * using the passed in provider for the signing.
271      * @deprecated use generate()
272      */
generateX509CRL( PrivateKey key, String provider, SecureRandom random)273     public X509CRL generateX509CRL(
274         PrivateKey      key,
275         String          provider,
276         SecureRandom    random)
277         throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException
278     {
279         try
280         {
281             return generate(key, provider, random);
282         }
283         catch (NoSuchProviderException e)
284         {
285             throw e;
286         }
287         catch (SignatureException e)
288         {
289             throw e;
290         }
291         catch (InvalidKeyException e)
292         {
293             throw e;
294         }
295         catch (NoSuchAlgorithmException e)
296         {
297             throw new SecurityException("exception: " + e);
298         }
299         catch (GeneralSecurityException e)
300         {
301             throw new SecurityException("exception: " + e);
302         }
303     }
304 
305     /**
306      * generate an X509 CRL, based on the current issuer and subject
307      * using the default provider.
308      * <p>
309      * <b>Note:</b> this differs from the deprecated method in that the default provider is
310      * used - not "BC".
311      * </p>
312      */
generate( PrivateKey key)313     public X509CRL generate(
314         PrivateKey      key)
315         throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
316     {
317         return generate(key, (SecureRandom)null);
318     }
319 
320     /**
321      * generate an X509 CRL, based on the current issuer and subject
322      * using the default provider and an user defined SecureRandom object as
323      * source of randomness.
324      * <p>
325      * <b>Note:</b> this differs from the deprecated method in that the default provider is
326      * used - not "BC".
327      * </p>
328      */
generate( PrivateKey key, SecureRandom random)329     public X509CRL generate(
330         PrivateKey      key,
331         SecureRandom    random)
332         throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
333     {
334         TBSCertList tbsCrl = generateCertList();
335         byte[] signature;
336 
337         try
338         {
339             signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCrl);
340         }
341         catch (IOException e)
342         {
343             throw new ExtCRLException("cannot generate CRL encoding", e);
344         }
345 
346         return generateJcaObject(tbsCrl, signature);
347     }
348 
349     /**
350      * generate an X509 certificate, based on the current issuer and subject
351      * using the passed in provider for the signing.
352      */
generate( PrivateKey key, String provider)353     public X509CRL generate(
354         PrivateKey      key,
355         String          provider)
356         throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
357     {
358         return generate(key, provider, null);
359     }
360 
361     /**
362      * generate an X509 CRL, based on the current issuer and subject,
363      * using the passed in provider for the signing.
364      */
generate( PrivateKey key, String provider, SecureRandom random)365     public X509CRL generate(
366         PrivateKey      key,
367         String          provider,
368         SecureRandom    random)
369         throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
370     {
371         TBSCertList tbsCrl = generateCertList();
372         byte[] signature;
373 
374         try
375         {
376             signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCrl);
377         }
378         catch (IOException e)
379         {
380             throw new ExtCRLException("cannot generate CRL encoding", e);
381         }
382 
383         return generateJcaObject(tbsCrl, signature);
384     }
385 
generateCertList()386     private TBSCertList generateCertList()
387     {
388         if (!extGenerator.isEmpty())
389         {
390             tbsGen.setExtensions(extGenerator.generate());
391         }
392 
393         return tbsGen.generateTBSCertList();
394     }
395 
generateJcaObject(TBSCertList tbsCrl, byte[] signature)396     private X509CRL generateJcaObject(TBSCertList tbsCrl, byte[] signature)
397         throws CRLException
398     {
399         ASN1EncodableVector v = new ASN1EncodableVector();
400 
401         v.add(tbsCrl);
402         v.add(sigAlgId);
403         v.add(new DERBitString(signature));
404 
405         return new X509CRLObject(new CertificateList(new DERSequence(v)));
406     }
407 
408     /**
409      * Return an iterator of the signature names supported by the generator.
410      *
411      * @return an iterator containing recognised names.
412      */
getSignatureAlgNames()413     public Iterator getSignatureAlgNames()
414     {
415         return X509Util.getAlgNames();
416     }
417 
418     private static class ExtCRLException
419         extends CRLException
420     {
421         Throwable cause;
422 
ExtCRLException(String message, Throwable cause)423         ExtCRLException(String message, Throwable cause)
424         {
425             super(message);
426             this.cause = cause;
427         }
428 
getCause()429         public Throwable getCause()
430         {
431             return cause;
432         }
433     }
434 }
435