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.ASN1GeneralizedTime;
22 import org.bouncycastle.asn1.ASN1InputStream;
23 import org.bouncycastle.asn1.ASN1Integer;
24 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
25 import org.bouncycastle.asn1.ASN1Sequence;
26 import org.bouncycastle.asn1.DERBitString;
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.Extensions;
31 import org.bouncycastle.asn1.x509.TBSCertList;
32 import org.bouncycastle.asn1.x509.Time;
33 import org.bouncycastle.asn1.x509.V2TBSCertListGenerator;
34 import org.bouncycastle.asn1.x509.X509Extensions;
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 (GeneralSecurityException e)
296         {
297             throw new SecurityException("exception: " + e);
298         }
299     }
300 
301     /**
302      * generate an X509 CRL, based on the current issuer and subject
303      * using the default provider.
304      * <p>
305      * <b>Note:</b> this differs from the deprecated method in that the default provider is
306      * used - not "BC".
307      * </p>
308      */
generate( PrivateKey key)309     public X509CRL generate(
310         PrivateKey      key)
311         throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
312     {
313         return generate(key, (SecureRandom)null);
314     }
315 
316     /**
317      * generate an X509 CRL, based on the current issuer and subject
318      * using the default provider and an user defined SecureRandom object as
319      * source of randomness.
320      * <p>
321      * <b>Note:</b> this differs from the deprecated method in that the default provider is
322      * used - not "BC".
323      * </p>
324      */
generate( PrivateKey key, SecureRandom random)325     public X509CRL generate(
326         PrivateKey      key,
327         SecureRandom    random)
328         throws CRLException, IllegalStateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
329     {
330         TBSCertList tbsCrl = generateCertList();
331         byte[] signature;
332 
333         try
334         {
335             signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, key, random, tbsCrl);
336         }
337         catch (IOException e)
338         {
339             throw new ExtCRLException("cannot generate CRL encoding", e);
340         }
341 
342         return generateJcaObject(tbsCrl, signature);
343     }
344 
345     /**
346      * generate an X509 certificate, based on the current issuer and subject
347      * using the passed in provider for the signing.
348      */
generate( PrivateKey key, String provider)349     public X509CRL generate(
350         PrivateKey      key,
351         String          provider)
352         throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
353     {
354         return generate(key, provider, null);
355     }
356 
357     /**
358      * generate an X509 CRL, based on the current issuer and subject,
359      * using the passed in provider for the signing.
360      */
generate( PrivateKey key, String provider, SecureRandom random)361     public X509CRL generate(
362         PrivateKey      key,
363         String          provider,
364         SecureRandom    random)
365         throws CRLException, IllegalStateException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException, InvalidKeyException
366     {
367         TBSCertList tbsCrl = generateCertList();
368         byte[] signature;
369 
370         try
371         {
372             signature = X509Util.calculateSignature(sigOID, signatureAlgorithm, provider, key, random, tbsCrl);
373         }
374         catch (IOException e)
375         {
376             throw new ExtCRLException("cannot generate CRL encoding", e);
377         }
378 
379         return generateJcaObject(tbsCrl, signature);
380     }
381 
generateCertList()382     private TBSCertList generateCertList()
383     {
384         if (!extGenerator.isEmpty())
385         {
386             tbsGen.setExtensions(extGenerator.generate());
387         }
388 
389         return tbsGen.generateTBSCertList();
390     }
391 
generateJcaObject(TBSCertList tbsCrl, byte[] signature)392     private X509CRL generateJcaObject(TBSCertList tbsCrl, byte[] signature)
393         throws CRLException
394     {
395         ASN1EncodableVector v = new ASN1EncodableVector();
396 
397         v.add(tbsCrl);
398         v.add(sigAlgId);
399         v.add(new DERBitString(signature));
400 
401         return new X509CRLObject(new CertificateList(new DERSequence(v)));
402     }
403 
404     /**
405      * Return an iterator of the signature names supported by the generator.
406      *
407      * @return an iterator containing recognised names.
408      */
getSignatureAlgNames()409     public Iterator getSignatureAlgNames()
410     {
411         return X509Util.getAlgNames();
412     }
413 
414     private static class ExtCRLException
415         extends CRLException
416     {
417         Throwable cause;
418 
ExtCRLException(String message, Throwable cause)419         ExtCRLException(String message, Throwable cause)
420         {
421             super(message);
422             this.cause = cause;
423         }
424 
getCause()425         public Throwable getCause()
426         {
427             return cause;
428         }
429     }
430 }
431