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