1 package org.bouncycastle.jce; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.IOException; 6 import java.security.InvalidKeyException; 7 import java.security.KeyFactory; 8 import java.security.NoSuchAlgorithmException; 9 import java.security.NoSuchProviderException; 10 import java.security.PrivateKey; 11 import java.security.PublicKey; 12 import java.security.Signature; 13 import java.security.SignatureException; 14 import java.security.spec.InvalidKeySpecException; 15 import java.security.spec.X509EncodedKeySpec; 16 import java.util.Set; 17 import java.util.HashSet; 18 import java.util.Hashtable; 19 20 import javax.security.auth.x500.X500Principal; 21 22 import org.bouncycastle.asn1.ASN1InputStream; 23 import org.bouncycastle.asn1.ASN1Sequence; 24 import org.bouncycastle.asn1.ASN1Set; 25 import org.bouncycastle.asn1.DERBitString; 26 import org.bouncycastle.asn1.DERObjectIdentifier; 27 import org.bouncycastle.asn1.DEROutputStream; 28 import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 29 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 30 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 31 import org.bouncycastle.asn1.pkcs.CertificationRequest; 32 import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; 33 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 34 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 35 import org.bouncycastle.asn1.x509.X509Name; 36 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 37 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; 38 import org.bouncycastle.util.Strings; 39 40 /** 41 * A class for verifying and creating PKCS10 Certification requests. 42 * <pre> 43 * CertificationRequest ::= SEQUENCE { 44 * certificationRequestInfo CertificationRequestInfo, 45 * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, 46 * signature BIT STRING 47 * } 48 * 49 * CertificationRequestInfo ::= SEQUENCE { 50 * version INTEGER { v1(0) } (v1,...), 51 * subject Name, 52 * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, 53 * attributes [0] Attributes{{ CRIAttributes }} 54 * } 55 * 56 * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }} 57 * 58 * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { 59 * type ATTRIBUTE.&id({IOSet}), 60 * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) 61 * } 62 * </pre> 63 */ 64 public class PKCS10CertificationRequest 65 extends CertificationRequest 66 { 67 private static Hashtable algorithms = new Hashtable(); 68 private static Hashtable keyAlgorithms = new Hashtable(); 69 private static Hashtable oids = new Hashtable(); 70 private static Set noParams = new HashSet(); 71 72 static 73 { 74 // BEGIN android-removed 75 // Dropping MD2 76 // algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2")); 77 // algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2")); 78 // END android-removed 79 algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4")); 80 algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4")); 81 algorithms.put("RSAWITHMD5", new DERObjectIdentifier("1.2.840.113549.1.1.4")); 82 algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5")); 83 algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5")); 84 algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); 85 algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); 86 algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); 87 algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); 88 algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); 89 algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); 90 algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); 91 algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); 92 algorithms.put("RSAWITHSHA1", new DERObjectIdentifier("1.2.840.113549.1.1.5")); 93 algorithms.put("RIPEMD160WITHRSAENCRYPTION", new DERObjectIdentifier("1.3.36.3.3.1.2")); 94 algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier("1.3.36.3.3.1.2")); 95 algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3")); 96 algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3")); 97 algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); 98 algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); 99 algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); 100 algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); 101 algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); 102 algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); 103 algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); 104 algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); 105 algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); 106 algorithms.put("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); 107 algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); 108 //algorithms.put("ECGOST3410WITHGOST3411", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); 109 110 // 111 // reverse mappings 112 // 113 oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.5"), "SHA1WITHRSA"); 114 oids.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA"); 115 oids.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA"); 116 oids.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA"); 117 oids.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA"); 118 oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3411WITHGOST3410"); 119 //oids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "GOST3411WITHECGOST3410"); 120 121 oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.4"), "MD5WITHRSA"); 122 // BEGIN android-removed 123 // Dropping MD2 124 // oids.put(new DERObjectIdentifier("1.2.840.113549.1.1.2"), "MD2WITHRSA"); 125 // END android-removed 126 oids.put(new DERObjectIdentifier("1.2.840.10040.4.3"), "SHA1WITHDSA"); 127 oids.put(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA"); 128 oids.put(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA"); 129 oids.put(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA"); 130 oids.put(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA"); 131 oids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA"); 132 oids.put(OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA"); 133 oids.put(OIWObjectIdentifiers.dsaWithSHA1, "SHA1WITHDSA"); 134 oids.put(NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA"); 135 oids.put(NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA"); 136 137 // 138 // key types 139 // 140 keyAlgorithms.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); 141 keyAlgorithms.put(X9ObjectIdentifiers.id_dsa, "DSA"); 142 143 // 144 // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. 145 // The parameters field SHALL be NULL for RSA based signature algorithms. 146 // 147 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); 148 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); 149 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); 150 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); 151 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); 152 noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); 153 noParams.add(NISTObjectIdentifiers.dsa_with_sha224); 154 noParams.add(NISTObjectIdentifiers.dsa_with_sha256); 155 } 156 157 private static ASN1Sequence toDERSequence( 158 byte[] bytes) 159 { 160 try 161 { 162 ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); 163 ASN1InputStream dIn = new ASN1InputStream(bIn); 164 165 return (ASN1Sequence)dIn.readObject(); 166 } 167 catch (Exception e) 168 { 169 throw new IllegalArgumentException("badly encoded request"); 170 } 171 } 172 173 /** 174 * construct a PKCS10 certification request from a DER encoded 175 * byte stream. 176 */ 177 public PKCS10CertificationRequest( 178 byte[] bytes) 179 { 180 super(toDERSequence(bytes)); 181 } 182 183 public PKCS10CertificationRequest( 184 ASN1Sequence sequence) 185 { 186 super(sequence); 187 } 188 189 /** 190 * create a PKCS10 certfication request using the BC provider. 191 */ 192 public PKCS10CertificationRequest( 193 String signatureAlgorithm, 194 X509Name subject, 195 PublicKey key, 196 ASN1Set attributes, 197 PrivateKey signingKey) 198 throws NoSuchAlgorithmException, NoSuchProviderException, 199 InvalidKeyException, SignatureException 200 { 201 this(signatureAlgorithm, subject, key, attributes, signingKey, "BC"); 202 } 203 204 private static X509Name convertName( 205 X500Principal name) 206 { 207 try 208 { 209 return new X509Principal(name.getEncoded()); 210 } 211 catch (IOException e) 212 { 213 throw new IllegalArgumentException("can't convert name"); 214 } 215 } 216 217 /** 218 * create a PKCS10 certfication request using the BC provider. 219 */ 220 public PKCS10CertificationRequest( 221 String signatureAlgorithm, 222 X500Principal subject, 223 PublicKey key, 224 ASN1Set attributes, 225 PrivateKey signingKey) 226 throws NoSuchAlgorithmException, NoSuchProviderException, 227 InvalidKeyException, SignatureException 228 { 229 this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, "BC"); 230 } 231 232 /** 233 * create a PKCS10 certfication request using the named provider. 234 */ 235 public PKCS10CertificationRequest( 236 String signatureAlgorithm, 237 X500Principal subject, 238 PublicKey key, 239 ASN1Set attributes, 240 PrivateKey signingKey, 241 String provider) 242 throws NoSuchAlgorithmException, NoSuchProviderException, 243 InvalidKeyException, SignatureException 244 { 245 this(signatureAlgorithm, convertName(subject), key, attributes, signingKey, provider); 246 } 247 248 /** 249 * create a PKCS10 certfication request using the named provider. 250 */ 251 public PKCS10CertificationRequest( 252 String signatureAlgorithm, 253 X509Name subject, 254 PublicKey key, 255 ASN1Set attributes, 256 PrivateKey signingKey, 257 String provider) 258 throws NoSuchAlgorithmException, NoSuchProviderException, 259 InvalidKeyException, SignatureException 260 { 261 DERObjectIdentifier sigOID = (DERObjectIdentifier)algorithms.get(Strings.toUpperCase(signatureAlgorithm)); 262 263 if (sigOID == null) 264 { 265 throw new IllegalArgumentException("Unknown signature type requested"); 266 } 267 268 if (subject == null) 269 { 270 throw new IllegalArgumentException("subject must not be null"); 271 } 272 273 if (key == null) 274 { 275 throw new IllegalArgumentException("public key must not be null"); 276 } 277 278 if (noParams.contains(sigOID)) 279 { 280 this.sigAlgId = new AlgorithmIdentifier(sigOID); 281 } 282 else 283 { 284 this.sigAlgId = new AlgorithmIdentifier(sigOID, null); 285 } 286 287 byte[] bytes = key.getEncoded(); 288 ByteArrayInputStream bIn = new ByteArrayInputStream(bytes); 289 ASN1InputStream dIn = new ASN1InputStream(bIn); 290 291 try 292 { 293 this.reqInfo = new CertificationRequestInfo(subject, new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject()), attributes); 294 } 295 catch (IOException e) 296 { 297 throw new IllegalArgumentException("can't encode public key"); 298 } 299 300 Signature sig = null; 301 302 try 303 { 304 sig = Signature.getInstance(sigAlgId.getObjectId().getId(), provider); 305 } 306 catch (NoSuchAlgorithmException e) 307 { 308 sig = Signature.getInstance(signatureAlgorithm, provider); 309 } 310 311 sig.initSign(signingKey); 312 313 try 314 { 315 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 316 DEROutputStream dOut = new DEROutputStream(bOut); 317 318 dOut.writeObject(reqInfo); 319 320 sig.update(bOut.toByteArray()); 321 } 322 catch (Exception e) 323 { 324 throw new SecurityException("exception encoding TBS cert request - " + e); 325 } 326 327 this.sigBits = new DERBitString(sig.sign()); 328 } 329 330 /** 331 * return the public key associated with the certification request - 332 * the public key is created using the BC provider. 333 */ 334 public PublicKey getPublicKey() 335 throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException 336 { 337 return getPublicKey("BC"); 338 } 339 340 public PublicKey getPublicKey( 341 String provider) 342 throws NoSuchAlgorithmException, NoSuchProviderException, 343 InvalidKeyException 344 { 345 SubjectPublicKeyInfo subjectPKInfo = reqInfo.getSubjectPublicKeyInfo(); 346 X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes()); 347 AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithmId(); 348 349 try 350 { 351 try 352 { 353 return KeyFactory.getInstance(keyAlg.getObjectId().getId(), provider).generatePublic(xspec); 354 } 355 catch (NoSuchAlgorithmException e) 356 { 357 // 358 // try an alternate 359 // 360 if (keyAlgorithms.get(keyAlg.getObjectId()) != null) 361 { 362 String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getObjectId()); 363 364 return KeyFactory.getInstance(keyAlgorithm, provider).generatePublic(xspec); 365 } 366 367 throw e; 368 } 369 } 370 catch (InvalidKeySpecException e) 371 { 372 throw new InvalidKeyException("error decoding public key"); 373 } 374 } 375 376 /** 377 * verify the request using the BC provider. 378 */ 379 public boolean verify() 380 throws NoSuchAlgorithmException, NoSuchProviderException, 381 InvalidKeyException, SignatureException 382 { 383 return verify("BC"); 384 } 385 386 public boolean verify( 387 String provider) 388 throws NoSuchAlgorithmException, NoSuchProviderException, 389 InvalidKeyException, SignatureException 390 { 391 Signature sig = null; 392 393 try 394 { 395 sig = Signature.getInstance(sigAlgId.getObjectId().getId(), provider); 396 } 397 catch (NoSuchAlgorithmException e) 398 { 399 // 400 // try an alternate 401 // 402 if (oids.get(sigAlgId.getObjectId()) != null) 403 { 404 String signatureAlgorithm = (String)oids.get(sigAlgId.getObjectId()); 405 406 sig = Signature.getInstance(signatureAlgorithm, provider); 407 } 408 else 409 { 410 throw e; 411 } 412 } 413 414 sig.initVerify(this.getPublicKey(provider)); 415 416 try 417 { 418 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 419 DEROutputStream dOut = new DEROutputStream(bOut); 420 421 dOut.writeObject(reqInfo); 422 423 sig.update(bOut.toByteArray()); 424 } 425 catch (Exception e) 426 { 427 throw new SecurityException("exception encoding TBS cert request - " + e); 428 } 429 430 return sig.verify(sigBits.getBytes()); 431 } 432 433 /** 434 * return a DER encoded byte array representing this object 435 */ 436 public byte[] getEncoded() 437 { 438 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 439 DEROutputStream dOut = new DEROutputStream(bOut); 440 441 try 442 { 443 dOut.writeObject(this); 444 } 445 catch (IOException e) 446 { 447 throw new RuntimeException(e.toString()); 448 } 449 450 return bOut.toByteArray(); 451 } 452 } 453