1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 package com.android.org.bouncycastle.jce.provider; 3 4 import java.io.IOException; 5 import java.security.AccessController; 6 import java.security.PrivateKey; 7 import java.security.PrivilegedAction; 8 import java.security.Provider; 9 import java.security.PublicKey; 10 import java.util.HashMap; 11 import java.util.Iterator; 12 import java.util.Map; 13 14 import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier; 15 import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 16 import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 17 import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider; 18 import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration; 19 import com.android.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil; 20 import com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider; 21 import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; 22 // Android-removed: Unsupported algorithms 23 // import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; 24 // import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceCCA2KeyFactorySpi; 25 // import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi; 26 // import org.bouncycastle.pqc.jcajce.provider.newhope.NHKeyFactorySpi; 27 // import org.bouncycastle.pqc.jcajce.provider.qtesla.QTESLAKeyFactorySpi; 28 // import org.bouncycastle.pqc.jcajce.provider.rainbow.RainbowKeyFactorySpi; 29 // import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi; 30 // import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi; 31 // import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi; 32 33 /** 34 * To add the provider at runtime use: 35 * <pre> 36 * import java.security.Security; 37 * import org.bouncycastle.jce.provider.BouncyCastleProvider; 38 * 39 * Security.addProvider(new BouncyCastleProvider()); 40 * </pre> 41 * The provider can also be configured as part of your environment via 42 * static registration by adding an entry to the java.security properties 43 * file (found in $JAVA_HOME/jre/lib/security/java.security, where 44 * $JAVA_HOME is the location of your JDK/JRE distribution). You'll find 45 * detailed instructions in the file but basically it comes down to adding 46 * a line: 47 * <pre> 48 * <code> 49 * security.provider.<n>=org.bouncycastle.jce.provider.BouncyCastleProvider 50 * </code> 51 * </pre> 52 * Where <n> is the preference you want the provider at (1 being the 53 * most preferred). 54 * <p>Note: JCE algorithm names should be upper-case only so the case insensitive 55 * test for getInstance works. 56 * @hide This class is not part of the Android public SDK API 57 */ 58 @libcore.api.CorePlatformApi 59 public final class BouncyCastleProvider extends Provider 60 implements ConfigurableProvider 61 { 62 private static String info = "BouncyCastle Security Provider v1.61"; 63 64 public static final String PROVIDER_NAME = "BC"; 65 66 public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration(); 67 68 private static final Map keyInfoConverters = new HashMap(); 69 70 /* 71 * Configurable symmetric ciphers 72 */ 73 private static final String SYMMETRIC_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.symmetric."; 74 75 private static final String[] SYMMETRIC_GENERIC = 76 { 77 // Android-changed: Remove unsupported algorithms, add our own version of PBEv2 AlgParams 78 // "PBEPBKDF1", "PBEPBKDF2", "PBEPKCS12", "TLSKDF", "SCRYPT" 79 "PBEPBKDF2", "PBEPKCS12", "PBES2AlgorithmParameters" 80 }; 81 82 private static final String[] SYMMETRIC_MACS = 83 { 84 // Android-removed: Unsupported algorithms 85 // "SipHash", "Poly1305" 86 }; 87 88 private static final String[] SYMMETRIC_CIPHERS = 89 { 90 // Android-changed: Unsupported algorithms 91 // "AES", "ARC4", "ARIA", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede", 92 // "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5", 93 // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish", 94 // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF", "DSTU7624", "GOST3412_2015" 95 "AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish", 96 }; 97 98 /* 99 * Configurable asymmetric ciphers 100 */ 101 private static final String ASYMMETRIC_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.asymmetric."; 102 103 // this one is required for GNU class path - it needs to be loaded first as the 104 // later ones configure it. 105 private static final String[] ASYMMETRIC_GENERIC = 106 { 107 // Android-changed: Unsupported algorithms 108 // "X509", "IES" 109 "X509" 110 }; 111 112 private static final String[] ASYMMETRIC_CIPHERS = 113 { 114 // Android-changed: Unsupported algorithms 115 // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC" 116 "DSA", "DH", "EC", "RSA", 117 }; 118 119 /* 120 * Configurable digests 121 */ 122 private static final String DIGEST_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.digest."; 123 private static final String[] DIGESTS = 124 { 125 // Android-changed: Unsupported algorithms 126 // "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", 127 // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564" 128 "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", 129 }; 130 131 /* 132 * Configurable keystores 133 */ 134 private static final String KEYSTORE_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.keystore."; 135 private static final String[] KEYSTORES = 136 { 137 "BC", "BCFKS", "PKCS12" 138 }; 139 140 // Android-removed: Unsupported algorithms 141 // /* 142 // * Configurable secure random 143 // */ 144 // private static final String SECURE_RANDOM_PACKAGE = "org.bouncycastle.jcajce.provider.drbg."; 145 // private static final String[] SECURE_RANDOMS = 146 // { 147 // "DRBG" 148 // }; 149 150 /** 151 * Construct a new provider. This should only be required when 152 * using runtime registration of the provider using the 153 * <code>Security.addProvider()</code> mechanism. 154 */ 155 @dalvik.annotation.compat.UnsupportedAppUsage 156 @libcore.api.CorePlatformApi 157 public BouncyCastleProvider() 158 { 159 super(PROVIDER_NAME, 1.61, info); 160 161 AccessController.doPrivileged(new PrivilegedAction() 162 { 163 public Object run() 164 { 165 setup(); 166 return null; 167 } 168 }); 169 } 170 171 private void setup() 172 { 173 loadAlgorithms(DIGEST_PACKAGE, DIGESTS); 174 175 loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_GENERIC); 176 177 loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_MACS); 178 179 loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_CIPHERS); 180 181 loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_GENERIC); 182 183 loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_CIPHERS); 184 185 loadAlgorithms(KEYSTORE_PACKAGE, KEYSTORES); 186 187 // Android-removed: Unsupported algorithms 188 /* 189 loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS); 190 191 loadPQCKeys(); // so we can handle certificates containing them. 192 // 193 // X509Store 194 // 195 put("X509Store.CERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertCollection"); 196 put("X509Store.ATTRIBUTECERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreAttrCertCollection"); 197 put("X509Store.CRL/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCRLCollection"); 198 put("X509Store.CERTIFICATEPAIR/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertPairCollection"); 199 200 put("X509Store.CERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCerts"); 201 put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs"); 202 put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts"); 203 put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs"); 204 205 // 206 // X509StreamParser 207 // 208 put("X509StreamParser.CERTIFICATE", "org.bouncycastle.jce.provider.X509CertParser"); 209 put("X509StreamParser.ATTRIBUTECERTIFICATE", "org.bouncycastle.jce.provider.X509AttrCertParser"); 210 put("X509StreamParser.CRL", "org.bouncycastle.jce.provider.X509CRLParser"); 211 put("X509StreamParser.CERTIFICATEPAIR", "org.bouncycastle.jce.provider.X509CertPairParser"); 212 213 // 214 // cipher engines 215 // 216 put("Cipher.BROKENPBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithMD5AndDES"); 217 218 put("Cipher.BROKENPBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithSHA1AndDES"); 219 220 221 put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish"); 222 223 // Certification Path API 224 put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi"); 225 put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi"); 226 put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); 227 put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); 228 */ 229 // END Android-removed: Unsupported algorithms 230 put("CertPathValidator.PKIX", "com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); 231 put("CertPathBuilder.PKIX", "com.android.org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); 232 put("CertStore.Collection", "com.android.org.bouncycastle.jce.provider.CertStoreCollectionSpi"); 233 // BEGIN Android-removed: Unsupported algorithms 234 // put("CertStore.LDAP", "org.bouncycastle.jce.provider.X509LDAPCertStoreSpi"); 235 // put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi"); 236 // put("Alg.Alias.CertStore.X509LDAP", "LDAP"); 237 // END Android-removed: Unsupported algorithms 238 } 239 240 private void loadAlgorithms(String packageName, String[] names) 241 { 242 for (int i = 0; i != names.length; i++) 243 { 244 Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + names[i] + "$Mappings"); 245 246 if (clazz != null) 247 { 248 try 249 { 250 ((AlgorithmProvider)clazz.newInstance()).configure(this); 251 } 252 catch (Exception e) 253 { // this should never ever happen!! 254 throw new InternalError("cannot create instance of " 255 + packageName + names[i] + "$Mappings : " + e); 256 } 257 } 258 } 259 } 260 261 // BEGIN Android-removed: Unsupported algorithms 262 /* 263 private void loadPQCKeys() 264 { 265 addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi()); 266 addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi()); 267 addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi()); 268 addKeyInfoConverter(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyFactorySpi()); 269 addKeyInfoConverter(PQCObjectIdentifiers.mcEliece, new McElieceKeyFactorySpi()); 270 addKeyInfoConverter(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2KeyFactorySpi()); 271 addKeyInfoConverter(PQCObjectIdentifiers.rainbow, new RainbowKeyFactorySpi()); 272 addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_I, new QTESLAKeyFactorySpi()); 273 addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_size, new QTESLAKeyFactorySpi()); 274 addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_speed, new QTESLAKeyFactorySpi()); 275 addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi()); 276 addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi()); 277 } 278 */ 279 // END Android-removed: Unsupported algorithms 280 281 public void setParameter(String parameterName, Object parameter) 282 { 283 synchronized (CONFIGURATION) 284 { 285 ((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter); 286 } 287 } 288 289 public boolean hasAlgorithm(String type, String name) 290 { 291 return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name); 292 } 293 294 public void addAlgorithm(String key, String value) 295 { 296 if (containsKey(key)) 297 { 298 throw new IllegalStateException("duplicate provider key (" + key + ") found"); 299 } 300 301 put(key, value); 302 } 303 304 public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className) 305 { 306 addAlgorithm(type + "." + oid, className); 307 addAlgorithm(type + ".OID." + oid, className); 308 } 309 310 public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter) 311 { 312 synchronized (keyInfoConverters) 313 { 314 keyInfoConverters.put(oid, keyInfoConverter); 315 } 316 } 317 318 public void addAttributes(String key, Map<String, String> attributeMap) 319 { 320 for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();) 321 { 322 String attributeName = (String)it.next(); 323 String attributeKey = key + " " + attributeName; 324 if (containsKey(attributeKey)) 325 { 326 throw new IllegalStateException("duplicate provider attribute key (" + attributeKey + ") found"); 327 } 328 329 put(attributeKey, attributeMap.get(attributeName)); 330 } 331 } 332 333 private static AsymmetricKeyInfoConverter getAsymmetricKeyInfoConverter(ASN1ObjectIdentifier algorithm) 334 { 335 synchronized (keyInfoConverters) 336 { 337 return (AsymmetricKeyInfoConverter)keyInfoConverters.get(algorithm); 338 } 339 } 340 341 public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) 342 throws IOException 343 { 344 AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm()); 345 346 if (converter == null) 347 { 348 return null; 349 } 350 351 return converter.generatePublic(publicKeyInfo); 352 } 353 354 public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo) 355 throws IOException 356 { 357 AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm()); 358 359 if (converter == null) 360 { 361 return null; 362 } 363 364 return converter.generatePrivate(privateKeyInfo); 365 } 366 } 367