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