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