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