| /* GENERATED SOURCE. DO NOT MODIFY. */ |
| package com.android.org.bouncycastle.jce.provider; |
| |
| import java.io.IOException; |
| import java.security.AccessController; |
| import java.security.PrivateKey; |
| import java.security.PrivilegedAction; |
| import java.security.Provider; |
| import java.security.PublicKey; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier; |
| import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo; |
| import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; |
| import com.android.org.bouncycastle.jcajce.provider.config.ConfigurableProvider; |
| import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration; |
| import com.android.org.bouncycastle.jcajce.provider.symmetric.util.ClassUtil; |
| import com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider; |
| import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; |
| // Android-removed: Unsupported algorithms |
| // import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; |
| // import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceCCA2KeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.mceliece.McElieceKeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.newhope.NHKeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.qtesla.QTESLAKeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.rainbow.RainbowKeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.sphincs.Sphincs256KeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSKeyFactorySpi; |
| // import org.bouncycastle.pqc.jcajce.provider.xmss.XMSSMTKeyFactorySpi; |
| |
| /** |
| * To add the provider at runtime use: |
| * <pre> |
| * import java.security.Security; |
| * import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| * |
| * Security.addProvider(new BouncyCastleProvider()); |
| * </pre> |
| * The provider can also be configured as part of your environment via |
| * static registration by adding an entry to the java.security properties |
| * file (found in $JAVA_HOME/jre/lib/security/java.security, where |
| * $JAVA_HOME is the location of your JDK/JRE distribution). You'll find |
| * detailed instructions in the file but basically it comes down to adding |
| * a line: |
| * <pre> |
| * <code> |
| * security.provider.<n>=org.bouncycastle.jce.provider.BouncyCastleProvider |
| * </code> |
| * </pre> |
| * Where <n> is the preference you want the provider at (1 being the |
| * most preferred). |
| * <p>Note: JCE algorithm names should be upper-case only so the case insensitive |
| * test for getInstance works. |
| * @hide This class is not part of the Android public SDK API |
| */ |
| @libcore.api.CorePlatformApi |
| public final class BouncyCastleProvider extends Provider |
| implements ConfigurableProvider |
| { |
| private static String info = "BouncyCastle Security Provider v1.61"; |
| |
| public static final String PROVIDER_NAME = "BC"; |
| |
| public static final ProviderConfiguration CONFIGURATION = new BouncyCastleProviderConfiguration(); |
| |
| private static final Map keyInfoConverters = new HashMap(); |
| |
| /* |
| * Configurable symmetric ciphers |
| */ |
| private static final String SYMMETRIC_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.symmetric."; |
| |
| private static final String[] SYMMETRIC_GENERIC = |
| { |
| // Android-changed: Remove unsupported algorithms, add our own version of PBEv2 AlgParams |
| // "PBEPBKDF1", "PBEPBKDF2", "PBEPKCS12", "TLSKDF", "SCRYPT" |
| "PBEPBKDF2", "PBEPKCS12", "PBES2AlgorithmParameters" |
| }; |
| |
| private static final String[] SYMMETRIC_MACS = |
| { |
| // Android-removed: Unsupported algorithms |
| // "SipHash", "Poly1305" |
| }; |
| |
| private static final String[] SYMMETRIC_CIPHERS = |
| { |
| // Android-changed: Unsupported algorithms |
| // "AES", "ARC4", "ARIA", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede", |
| // "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5", |
| // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish", |
| // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF", "DSTU7624", "GOST3412_2015" |
| "AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish", |
| }; |
| |
| /* |
| * Configurable asymmetric ciphers |
| */ |
| private static final String ASYMMETRIC_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.asymmetric."; |
| |
| // this one is required for GNU class path - it needs to be loaded first as the |
| // later ones configure it. |
| private static final String[] ASYMMETRIC_GENERIC = |
| { |
| // Android-changed: Unsupported algorithms |
| // "X509", "IES" |
| "X509" |
| }; |
| |
| private static final String[] ASYMMETRIC_CIPHERS = |
| { |
| // Android-changed: Unsupported algorithms |
| // "DSA", "DH", "EC", "RSA", "GOST", "ECGOST", "ElGamal", "DSTU4145", "GM", "EdEC" |
| "DSA", "DH", "EC", "RSA", |
| }; |
| |
| /* |
| * Configurable digests |
| */ |
| private static final String DIGEST_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.digest."; |
| private static final String[] DIGESTS = |
| { |
| // Android-changed: Unsupported algorithms |
| // "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", |
| // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b", "Blake2s", "DSTU7564" |
| "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", |
| }; |
| |
| /* |
| * Configurable keystores |
| */ |
| private static final String KEYSTORE_PACKAGE = "com.android.org.bouncycastle.jcajce.provider.keystore."; |
| private static final String[] KEYSTORES = |
| { |
| "BC", "BCFKS", "PKCS12" |
| }; |
| |
| // Android-removed: Unsupported algorithms |
| // /* |
| // * Configurable secure random |
| // */ |
| // private static final String SECURE_RANDOM_PACKAGE = "org.bouncycastle.jcajce.provider.drbg."; |
| // private static final String[] SECURE_RANDOMS = |
| // { |
| // "DRBG" |
| // }; |
| |
| /** |
| * Construct a new provider. This should only be required when |
| * using runtime registration of the provider using the |
| * <code>Security.addProvider()</code> mechanism. |
| */ |
| @dalvik.annotation.compat.UnsupportedAppUsage |
| @libcore.api.CorePlatformApi |
| public BouncyCastleProvider() |
| { |
| super(PROVIDER_NAME, 1.61, info); |
| |
| AccessController.doPrivileged(new PrivilegedAction() |
| { |
| public Object run() |
| { |
| setup(); |
| return null; |
| } |
| }); |
| } |
| |
| private void setup() |
| { |
| loadAlgorithms(DIGEST_PACKAGE, DIGESTS); |
| |
| loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_GENERIC); |
| |
| loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_MACS); |
| |
| loadAlgorithms(SYMMETRIC_PACKAGE, SYMMETRIC_CIPHERS); |
| |
| loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_GENERIC); |
| |
| loadAlgorithms(ASYMMETRIC_PACKAGE, ASYMMETRIC_CIPHERS); |
| |
| loadAlgorithms(KEYSTORE_PACKAGE, KEYSTORES); |
| |
| // Android-removed: Unsupported algorithms |
| /* |
| loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS); |
| |
| loadPQCKeys(); // so we can handle certificates containing them. |
| // |
| // X509Store |
| // |
| put("X509Store.CERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertCollection"); |
| put("X509Store.ATTRIBUTECERTIFICATE/COLLECTION", "org.bouncycastle.jce.provider.X509StoreAttrCertCollection"); |
| put("X509Store.CRL/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCRLCollection"); |
| put("X509Store.CERTIFICATEPAIR/COLLECTION", "org.bouncycastle.jce.provider.X509StoreCertPairCollection"); |
| |
| put("X509Store.CERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCerts"); |
| put("X509Store.CRL/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCRLs"); |
| put("X509Store.ATTRIBUTECERTIFICATE/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPAttrCerts"); |
| put("X509Store.CERTIFICATEPAIR/LDAP", "org.bouncycastle.jce.provider.X509StoreLDAPCertPairs"); |
| |
| // |
| // X509StreamParser |
| // |
| put("X509StreamParser.CERTIFICATE", "org.bouncycastle.jce.provider.X509CertParser"); |
| put("X509StreamParser.ATTRIBUTECERTIFICATE", "org.bouncycastle.jce.provider.X509AttrCertParser"); |
| put("X509StreamParser.CRL", "org.bouncycastle.jce.provider.X509CRLParser"); |
| put("X509StreamParser.CERTIFICATEPAIR", "org.bouncycastle.jce.provider.X509CertPairParser"); |
| |
| // |
| // cipher engines |
| // |
| put("Cipher.BROKENPBEWITHMD5ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithMD5AndDES"); |
| |
| put("Cipher.BROKENPBEWITHSHA1ANDDES", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$BrokePBEWithSHA1AndDES"); |
| |
| |
| put("Cipher.OLDPBEWITHSHAANDTWOFISH-CBC", "org.bouncycastle.jce.provider.BrokenJCEBlockCipher$OldPBEWithSHAAndTwofish"); |
| |
| // Certification Path API |
| put("CertPathValidator.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathValidatorSpi"); |
| put("CertPathBuilder.RFC3281", "org.bouncycastle.jce.provider.PKIXAttrCertPathBuilderSpi"); |
| put("CertPathValidator.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); |
| put("CertPathBuilder.RFC3280", "org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); |
| */ |
| // END Android-removed: Unsupported algorithms |
| put("CertPathValidator.PKIX", "com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi"); |
| put("CertPathBuilder.PKIX", "com.android.org.bouncycastle.jce.provider.PKIXCertPathBuilderSpi"); |
| put("CertStore.Collection", "com.android.org.bouncycastle.jce.provider.CertStoreCollectionSpi"); |
| // BEGIN Android-removed: Unsupported algorithms |
| // put("CertStore.LDAP", "org.bouncycastle.jce.provider.X509LDAPCertStoreSpi"); |
| // put("CertStore.Multi", "org.bouncycastle.jce.provider.MultiCertStoreSpi"); |
| // put("Alg.Alias.CertStore.X509LDAP", "LDAP"); |
| // END Android-removed: Unsupported algorithms |
| } |
| |
| private void loadAlgorithms(String packageName, String[] names) |
| { |
| for (int i = 0; i != names.length; i++) |
| { |
| Class clazz = ClassUtil.loadClass(BouncyCastleProvider.class, packageName + names[i] + "$Mappings"); |
| |
| if (clazz != null) |
| { |
| try |
| { |
| ((AlgorithmProvider)clazz.newInstance()).configure(this); |
| } |
| catch (Exception e) |
| { // this should never ever happen!! |
| throw new InternalError("cannot create instance of " |
| + packageName + names[i] + "$Mappings : " + e); |
| } |
| } |
| } |
| } |
| |
| // BEGIN Android-removed: Unsupported algorithms |
| /* |
| private void loadPQCKeys() |
| { |
| addKeyInfoConverter(PQCObjectIdentifiers.sphincs256, new Sphincs256KeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.newHope, new NHKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.xmss, new XMSSKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.mcEliece, new McElieceKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.mcElieceCca2, new McElieceCCA2KeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.rainbow, new RainbowKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_I, new QTESLAKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_size, new QTESLAKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_III_speed, new QTESLAKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_I, new QTESLAKeyFactorySpi()); |
| addKeyInfoConverter(PQCObjectIdentifiers.qTESLA_p_III, new QTESLAKeyFactorySpi()); |
| } |
| */ |
| // END Android-removed: Unsupported algorithms |
| |
| public void setParameter(String parameterName, Object parameter) |
| { |
| synchronized (CONFIGURATION) |
| { |
| ((BouncyCastleProviderConfiguration)CONFIGURATION).setParameter(parameterName, parameter); |
| } |
| } |
| |
| public boolean hasAlgorithm(String type, String name) |
| { |
| return containsKey(type + "." + name) || containsKey("Alg.Alias." + type + "." + name); |
| } |
| |
| public void addAlgorithm(String key, String value) |
| { |
| if (containsKey(key)) |
| { |
| throw new IllegalStateException("duplicate provider key (" + key + ") found"); |
| } |
| |
| put(key, value); |
| } |
| |
| public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className) |
| { |
| addAlgorithm(type + "." + oid, className); |
| addAlgorithm(type + ".OID." + oid, className); |
| } |
| |
| public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter) |
| { |
| synchronized (keyInfoConverters) |
| { |
| keyInfoConverters.put(oid, keyInfoConverter); |
| } |
| } |
| |
| public void addAttributes(String key, Map<String, String> attributeMap) |
| { |
| for (Iterator it = attributeMap.keySet().iterator(); it.hasNext();) |
| { |
| String attributeName = (String)it.next(); |
| String attributeKey = key + " " + attributeName; |
| if (containsKey(attributeKey)) |
| { |
| throw new IllegalStateException("duplicate provider attribute key (" + attributeKey + ") found"); |
| } |
| |
| put(attributeKey, attributeMap.get(attributeName)); |
| } |
| } |
| |
| private static AsymmetricKeyInfoConverter getAsymmetricKeyInfoConverter(ASN1ObjectIdentifier algorithm) |
| { |
| synchronized (keyInfoConverters) |
| { |
| return (AsymmetricKeyInfoConverter)keyInfoConverters.get(algorithm); |
| } |
| } |
| |
| public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo) |
| throws IOException |
| { |
| AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm()); |
| |
| if (converter == null) |
| { |
| return null; |
| } |
| |
| return converter.generatePublic(publicKeyInfo); |
| } |
| |
| public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo) |
| throws IOException |
| { |
| AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm()); |
| |
| if (converter == null) |
| { |
| return null; |
| } |
| |
| return converter.generatePrivate(privateKeyInfo); |
| } |
| } |