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