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