X509Util.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.x509; 2 3import java.io.IOException; 4import java.security.InvalidKeyException; 5import java.security.NoSuchAlgorithmException; 6import java.security.NoSuchProviderException; 7import java.security.PrivateKey; 8import java.security.Provider; 9import java.security.SecureRandom; 10import java.security.Security; 11import java.security.Signature; 12import java.security.SignatureException; 13import java.util.ArrayList; 14import java.util.Enumeration; 15import java.util.HashSet; 16import java.util.Hashtable; 17import java.util.Iterator; 18import java.util.List; 19import java.util.Set; 20 21import javax.security.auth.x500.X500Principal; 22 23import org.bouncycastle.asn1.ASN1Encodable; 24import org.bouncycastle.asn1.ASN1Encoding; 25import org.bouncycastle.asn1.ASN1Integer; 26import org.bouncycastle.asn1.DERNull; 27import org.bouncycastle.asn1.DERObjectIdentifier; 28// BEGIN android-removed 29// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 30// END android-removed 31import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; 32import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 33import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 34import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; 35// BEGIN android-removed 36// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; 37// END android-removed 38import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 39import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 40import org.bouncycastle.jce.X509Principal; 41import org.bouncycastle.util.Strings; 42 43class X509Util 44{ 45 private static Hashtable algorithms = new Hashtable(); 46 private static Hashtable params = new Hashtable(); 47 private static Set noParams = new HashSet(); 48 49 static 50 { 51 // BEGIN android-removed 52 // algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); 53 // algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); 54 // END android-removed 55 algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); 56 algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); 57 algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); 58 algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); 59 // BEGIN android-removed 60 // algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); 61 // algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); 62 // END android-removed 63 algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); 64 algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); 65 algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); 66 algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); 67 algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); 68 algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); 69 algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); 70 // BEGIN android-removed 71 // algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); 72 // END android-removed 73 algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); 74 algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); 75 algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); 76 // BEGIN android-removed 77 // algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); 78 // algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); 79 // algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); 80 // algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); 81 // algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); 82 // algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); 83 // END android-removed 84 algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); 85 algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); 86 // BEGIN android-removed 87 // algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); 88 // END android-removed 89 algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); 90 algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); 91 algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); 92 algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); 93 algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); 94 // BEGIN android-removed 95 // algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); 96 // END android-removed 97 algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); 98 algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); 99 algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); 100 // BEGIN android-removed 101 // algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); 102 // algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); 103 // algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); 104 // algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); 105 // algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); 106 // END android-removed 107 108 // 109 // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. 110 // The parameters field SHALL be NULL for RSA based signature algorithms. 111 // 112 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); 113 // BEGIN android-removed 114 // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); 115 // END android-removed 116 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); 117 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); 118 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); 119 noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); 120 // BEGIN android-removed 121 // noParams.add(NISTObjectIdentifiers.dsa_with_sha224); 122 // END android-removed 123 noParams.add(NISTObjectIdentifiers.dsa_with_sha256); 124 noParams.add(NISTObjectIdentifiers.dsa_with_sha384); 125 noParams.add(NISTObjectIdentifiers.dsa_with_sha512); 126 127 // 128 // RFC 4491 129 // 130 // BEGIN android-removed 131 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); 132 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); 133 // END android-removed 134 135 // 136 // explicit params 137 // 138 // BEGIN android-changed 139 AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); 140 // END android-changed 141 params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); 142 143 // BEGIN android-removed 144 // // BEGIN android-changed 145 // AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE); 146 // // END android-changed 147 // params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); 148 // END android-removed 149 150 // BEGIN android-changed 151 AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE); 152 // END android-changed 153 params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); 154 155 // BEGIN android-changed 156 AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE); 157 // END android-changed 158 params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); 159 160 // BEGIN android-changed 161 AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, DERNull.INSTANCE); 162 // END android-changed 163 params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); 164 } 165 166 private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) 167 { 168 return new RSASSAPSSparams( 169 hashAlgId, 170 new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), 171 new ASN1Integer(saltSize), 172 new ASN1Integer(1)); 173 } 174 175 static DERObjectIdentifier getAlgorithmOID( 176 String algorithmName) 177 { 178 algorithmName = Strings.toUpperCase(algorithmName); 179 180 if (algorithms.containsKey(algorithmName)) 181 { 182 return (DERObjectIdentifier)algorithms.get(algorithmName); 183 } 184 185 return new DERObjectIdentifier(algorithmName); 186 } 187 188 static AlgorithmIdentifier getSigAlgID( 189 DERObjectIdentifier sigOid, 190 String algorithmName) 191 { 192 if (noParams.contains(sigOid)) 193 { 194 return new AlgorithmIdentifier(sigOid); 195 } 196 197 algorithmName = Strings.toUpperCase(algorithmName); 198 199 if (params.containsKey(algorithmName)) 200 { 201 return new AlgorithmIdentifier(sigOid, (ASN1Encodable)params.get(algorithmName)); 202 } 203 else 204 { 205 // BEGIN android-changed 206 return new AlgorithmIdentifier(sigOid, DERNull.INSTANCE); 207 // END android-changed 208 } 209 } 210 211 static Iterator getAlgNames() 212 { 213 Enumeration e = algorithms.keys(); 214 List l = new ArrayList(); 215 216 while (e.hasMoreElements()) 217 { 218 l.add(e.nextElement()); 219 } 220 221 return l.iterator(); 222 } 223 224 static Signature getSignatureInstance( 225 String algorithm) 226 throws NoSuchAlgorithmException 227 { 228 return Signature.getInstance(algorithm); 229 } 230 231 static Signature getSignatureInstance( 232 String algorithm, 233 String provider) 234 throws NoSuchProviderException, NoSuchAlgorithmException 235 { 236 if (provider != null) 237 { 238 return Signature.getInstance(algorithm, provider); 239 } 240 else 241 { 242 return Signature.getInstance(algorithm); 243 } 244 } 245 246 static byte[] calculateSignature( 247 DERObjectIdentifier sigOid, 248 String sigName, 249 PrivateKey key, 250 SecureRandom random, 251 ASN1Encodable object) 252 throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException 253 { 254 Signature sig; 255 256 if (sigOid == null) 257 { 258 throw new IllegalStateException("no signature algorithm specified"); 259 } 260 261 sig = X509Util.getSignatureInstance(sigName); 262 263 if (random != null) 264 { 265 sig.initSign(key, random); 266 } 267 else 268 { 269 sig.initSign(key); 270 } 271 272 sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); 273 274 return sig.sign(); 275 } 276 277 static byte[] calculateSignature( 278 DERObjectIdentifier sigOid, 279 String sigName, 280 String provider, 281 PrivateKey key, 282 SecureRandom random, 283 ASN1Encodable object) 284 throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException 285 { 286 Signature sig; 287 288 if (sigOid == null) 289 { 290 throw new IllegalStateException("no signature algorithm specified"); 291 } 292 293 sig = X509Util.getSignatureInstance(sigName, provider); 294 295 if (random != null) 296 { 297 sig.initSign(key, random); 298 } 299 else 300 { 301 sig.initSign(key); 302 } 303 304 sig.update(object.toASN1Primitive().getEncoded(ASN1Encoding.DER)); 305 306 return sig.sign(); 307 } 308 309 static X509Principal convertPrincipal( 310 X500Principal principal) 311 { 312 try 313 { 314 return new X509Principal(principal.getEncoded()); 315 } 316 catch (IOException e) 317 { 318 throw new IllegalArgumentException("cannot convert principal"); 319 } 320 } 321 322 static class Implementation 323 { 324 Object engine; 325 Provider provider; 326 327 Implementation( 328 Object engine, 329 Provider provider) 330 { 331 this.engine = engine; 332 this.provider = provider; 333 } 334 335 Object getEngine() 336 { 337 return engine; 338 } 339 340 Provider getProvider() 341 { 342 return provider; 343 } 344 } 345 346 /** 347 * see if we can find an algorithm (or its alias and what it represents) in 348 * the property table for the given provider. 349 */ 350 static Implementation getImplementation( 351 String baseName, 352 String algorithm, 353 Provider prov) 354 throws NoSuchAlgorithmException 355 { 356 algorithm = Strings.toUpperCase(algorithm); 357 358 String alias; 359 360 while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) 361 { 362 algorithm = alias; 363 } 364 365 String className = prov.getProperty(baseName + "." + algorithm); 366 367 if (className != null) 368 { 369 try 370 { 371 Class cls; 372 ClassLoader clsLoader = prov.getClass().getClassLoader(); 373 374 if (clsLoader != null) 375 { 376 cls = clsLoader.loadClass(className); 377 } 378 else 379 { 380 cls = Class.forName(className); 381 } 382 383 return new Implementation(cls.newInstance(), prov); 384 } 385 catch (ClassNotFoundException e) 386 { 387 throw new IllegalStateException( 388 "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!"); 389 } 390 catch (Exception e) 391 { 392 throw new IllegalStateException( 393 "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!"); 394 } 395 } 396 397 throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName()); 398 } 399 400 /** 401 * return an implementation for a given algorithm/provider. 402 * If the provider is null, we grab the first avalaible who has the required algorithm. 403 */ 404 static Implementation getImplementation( 405 String baseName, 406 String algorithm) 407 throws NoSuchAlgorithmException 408 { 409 Provider[] prov = Security.getProviders(); 410 411 // 412 // search every provider looking for the algorithm we want. 413 // 414 for (int i = 0; i != prov.length; i++) 415 { 416 // 417 // try case insensitive 418 // 419 Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]); 420 if (imp != null) 421 { 422 return imp; 423 } 424 425 try 426 { 427 imp = getImplementation(baseName, algorithm, prov[i]); 428 } 429 catch (NoSuchAlgorithmException e) 430 { 431 // continue 432 } 433 } 434 435 throw new NoSuchAlgorithmException("cannot find implementation " + algorithm); 436 } 437 438 static Provider getProvider(String provider) 439 throws NoSuchProviderException 440 { 441 Provider prov = Security.getProvider(provider); 442 443 if (prov == null) 444 { 445 throw new NoSuchProviderException("Provider " + provider + " not found"); 446 } 447 448 return prov; 449 } 450} 451