diff options
32 files changed, 1046 insertions, 17 deletions
diff --git a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java index 10bb621498d..ac6148a7a04 100644 --- a/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java +++ b/luni/src/test/java/libcore/java/security/KeyPairGeneratorTest.java @@ -54,12 +54,21 @@ import javax.crypto.spec.DHParameterSpec; import junit.framework.TestCase; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class KeyPairGeneratorTest extends TestCase { private List<Provider> providers = new ArrayList<Provider>(); @Override - public void setUp() { + public void setUp() throws Exception { + super.setUp(); + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + Provider[] providers = Security.getProviders(); for (Provider p : providers) { // Do not test AndroidKeyStore Provider. It does not accept vanilla public keys for @@ -72,8 +81,11 @@ public class KeyPairGeneratorTest extends TestCase { } @Override - public void tearDown() { + public void tearDown() throws Exception { providers.clear(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); } public void test_providerCount() { diff --git a/luni/src/test/java/libcore/java/security/MessageDigestTest.java b/luni/src/test/java/libcore/java/security/MessageDigestTest.java index 1a00af43717..d08920bae39 100644 --- a/luni/src/test/java/libcore/java/security/MessageDigestTest.java +++ b/luni/src/test/java/libcore/java/security/MessageDigestTest.java @@ -36,8 +36,27 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import junit.framework.TestCase; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public final class MessageDigestTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private final byte[] sha_456 = { -24, 9, -59, -47, -50, -92, 123, 69, -29, 71, 1, -46, 63, 96, -118, -102, 88, 3, 77, -55 diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java index dab862a9c9d..64ea0e6fd23 100644 --- a/luni/src/test/java/libcore/java/security/ProviderTest.java +++ b/luni/src/test/java/libcore/java/security/ProviderTest.java @@ -58,7 +58,27 @@ import javax.crypto.NoSuchPaddingException; import junit.framework.TestCase; import libcore.javax.crypto.MockKey; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class ProviderTest extends TestCase { + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private static final boolean LOG_DEBUG = false; /** diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java index fe431ed005b..28e735c836f 100644 --- a/luni/src/test/java/libcore/java/security/SignatureTest.java +++ b/luni/src/test/java/libcore/java/security/SignatureTest.java @@ -70,7 +70,27 @@ import junit.framework.TestCase; import libcore.util.HexEncoding; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class SignatureTest extends TestCase { + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private static abstract class MockProvider extends Provider { public MockProvider(String name) { super(name, 1.0, "Mock provider used for testing"); diff --git a/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java b/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java index 0c0ad0c7553..e621b5c18e6 100644 --- a/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java +++ b/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java @@ -49,7 +49,27 @@ import com.android.org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import junit.framework.TestCase; import libcore.java.security.TestKeyStore; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class CertPathValidatorTest extends TestCase { + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private OCSPResp generateOCSPResponse(X509Certificate serverCertJca, X509Certificate caCertJca, PrivateKey caKey, CertificateStatus status) throws Exception { X509CertificateHolder caCert = new JcaX509CertificateHolder(caCertJca); diff --git a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java index 7b82cc6f0d7..1c85b838440 100644 --- a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java +++ b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java @@ -61,8 +61,27 @@ import javax.security.auth.x500.X500Principal; import junit.framework.TestCase; import libcore.java.security.StandardNames; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class CertificateFactoryTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private static final String VALID_CERTIFICATE_PEM = "-----BEGIN CERTIFICATE-----\n" + "MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM\n" diff --git a/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java b/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java index d0cdf730e53..a26c631e769 100644 --- a/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java +++ b/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java @@ -22,8 +22,27 @@ import java.security.KeyStore; import java.security.cert.PKIXParameters; import libcore.java.security.TestKeyStore; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class PKIXParametersTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + public void testKeyStoreConstructor() throws Exception { TestKeyStore server = TestKeyStore.getServer(); KeyStore.PrivateKeyEntry pke = server.getPrivateKey("RSA", "RSA"); diff --git a/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java b/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java index 4b10030981f..e2066ae72c1 100644 --- a/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java +++ b/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java @@ -17,6 +17,9 @@ import java.util.Map; import junit.framework.TestCase; import libcore.java.security.TestKeyStore; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class PKIXRevocationCheckerTest extends TestCase { PKIXRevocationChecker checker; @@ -28,6 +31,11 @@ public class PKIXRevocationCheckerTest extends TestCase { protected void setUp() throws Exception { super.setUp(); + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX"); CertPathChecker rc = cpb.getRevocationChecker(); assertNotNull(rc); @@ -41,6 +49,13 @@ public class PKIXRevocationCheckerTest extends TestCase { issuer = intermediate.getPrivateKey("RSA", "RSA"); } + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + public void test_Initializes() throws Exception { assertEquals(0, checker.getOcspResponses().size()); assertEquals(0, checker.getOcspExtensions().size()); diff --git a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java index 7178a59d9b1..b11b40e44e9 100644 --- a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java +++ b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java @@ -18,6 +18,8 @@ package libcore.java.security.cert; import static java.nio.charset.StandardCharsets.UTF_8; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; import sun.security.provider.X509Factory; import sun.security.x509.X509CRLImpl; import tests.support.resource.Support_Resources; @@ -51,6 +53,25 @@ import junit.framework.TestCase; import libcore.java.security.StandardNames; public class X509CRLTest extends TestCase { + + @Override + public void setUp() throws Exception { + super.setUp(); + mX509Providers = Security.getProviders("CertificateFactory.X509"); + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private Provider[] mX509Providers; private static final String CERT_RSA = "x509/cert-rsa.der"; @@ -499,11 +520,4 @@ public class X509CRLTest extends TestCase { assertEquals(entry1, entry2); } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mX509Providers = Security.getProviders("CertificateFactory.X509"); - } } diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java index abc938e7b7c..95a95c0f4bb 100644 --- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java +++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java @@ -59,9 +59,32 @@ import java.util.Set; import javax.security.auth.x500.X500Principal; import junit.framework.TestCase; import libcore.java.security.StandardNames; + +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; import tests.support.resource.Support_Resources; public class X509CertificateTest extends TestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mX509Providers = Security.getProviders("CertificateFactory.X509"); + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private Provider[] mX509Providers; private static final String CERT_RSA = "x509/cert-rsa.der"; @@ -1327,11 +1350,4 @@ public class X509CertificateTest extends TestCase { } return certBytes; } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mX509Providers = Security.getProviders("CertificateFactory.X509"); - } } diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java index f995a7cba09..6592eb52edd 100644 --- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java +++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java @@ -68,8 +68,27 @@ import junit.framework.TestCase; import libcore.java.security.StandardNames; import libcore.java.security.TestKeyStore; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public final class CipherTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + /** GCM tag size used for tests. */ private static final int GCM_TAG_SIZE_BITS = 96; diff --git a/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java index 69d93541e71..3a23e8cc72e 100644 --- a/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java +++ b/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java @@ -45,10 +45,30 @@ import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import libcore.util.HexEncoding; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + /** * Tests for all registered Elliptic Curve Diffie-Hellman {@link KeyAgreement} providers. */ public class ECDHKeyAgreementTest extends TestCase { + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + // Two key pairs and the resulting shared secret for the Known Answer Test private static final byte[] KAT_PUBLIC_KEY1_X509 = HexEncoding.decode( "3059301306072a8648ce3d020106082a8648ce3d030107034200049fc2f71f85446b1371244491d83" diff --git a/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java b/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java index 57635625c23..fd0d43d405d 100644 --- a/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java +++ b/luni/src/test/java/libcore/javax/crypto/KeyGeneratorTest.java @@ -28,8 +28,27 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import junit.framework.TestCase; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class KeyGeneratorTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private static boolean isUnsupported(KeyGenerator kg) { // Don't bother testing "Sun..." KeyGenerators return (kg.getAlgorithm().startsWith("Sun")); diff --git a/luni/src/test/java/libcore/javax/crypto/MacTest.java b/luni/src/test/java/libcore/javax/crypto/MacTest.java index 61da2bbe227..3e49cd694e9 100644 --- a/luni/src/test/java/libcore/javax/crypto/MacTest.java +++ b/luni/src/test/java/libcore/javax/crypto/MacTest.java @@ -28,7 +28,27 @@ import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import junit.framework.TestCase; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class MacTest extends TestCase { + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private static abstract class MockProvider extends Provider { public MockProvider(String name) { super(name, 1.0, "Mock provider used for testing"); diff --git a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java index 5471b1f5df7..2f4effa4706 100644 --- a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java +++ b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java @@ -24,9 +24,28 @@ import javax.security.auth.x500.X500Principal; import junit.framework.TestCase; import libcore.util.SerializationTester; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class X500PrincipalTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + public void testSerialization() { String expected = "aced0005737200266a617661782e73656375726974792e617574682e7" + "83530302e583530305072696e636970616cf90dff3c88b877c703000078707572" diff --git a/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java b/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java new file mode 100644 index 00000000000..88766715169 --- /dev/null +++ b/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package libcore.sun.security.jca; + +import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import dalvik.system.VMRuntime; + +import java.lang.reflect.Method; +import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.security.Signature; +import java.util.ArrayList; +import java.util.List; +import javax.crypto.KeyGenerator; +import javax.crypto.Mac; + +import sun.security.jca.Providers; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +/** + * Tests that the deprecation of algorithms from the BC provider works as expected. Requests + * from an application targeting an API level before the deprecation should receive them, + * but those targeting an API level after the deprecation should cause an exception. Tests + * a representative sample of services and algorithms and various ways of naming them. + */ +@RunWith(JUnit4.class) +public class ProvidersTest { + + /** + * An object that can be called to call an appropriate getInstance method. Since + * each type of object has its own class that the method should be called on, + * it's either this or reflection, and this seems more straightforward. + */ + private interface Algorithm { + Object getInstance() throws GeneralSecurityException; + } + + // getInstance calls that result in requests to BC + private static final List<Algorithm> BC_ALGORITHMS = new ArrayList<>(); + // getInstance calls that result in requests to Conscrypt + private static final List<Algorithm> CONSCRYPT_ALGORITHMS = new ArrayList<>(); + static { + // A concrete algorithm, provider by name + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Signature.getInstance("sha224withrsa", "BC"); + } + }); + // A concrete algorithm, provider by instance + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return KeyFactory.getInstance("EC", Security.getProvider("BC")); + } + }); + // An alias for another algorithm, provider by name + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Signature.getInstance("MD5withRSAEncryption", "BC"); + } + }); + // An alias for another algorithm, provider by instance + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return KeyGenerator.getInstance("HMAC-MD5", Security.getProvider("BC")); + } + }); + // An alias with unusual characters, provider by name + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Mac.getInstance("Hmac/sha256", "BC"); + } + }); + // An alias with unusual characters, provider by instance + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Signature.getInstance("SHA384/rsA", Security.getProvider("BC")); + } + }); + // An alias by OID, provider by name + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + // OID for SHA-256 + return MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC"); + } + }); + // An alias by OID, provider by instance + BC_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + // OID for AES-128 + return AlgorithmParameters.getInstance("2.16.840.1.101.3.4.1.2", + Security.getProvider("BC")); + } + }); + // All the same algorithms as for BC, but with no provider, which should produce + // the Conscrypt implementation + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Signature.getInstance("sha224withrsa"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return KeyFactory.getInstance("EC"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Signature.getInstance("MD5withRSAEncryption"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return KeyGenerator.getInstance("HMAC-MD5"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Mac.getInstance("Hmac/sha256"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + return Signature.getInstance("SHA384/rsA"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + // OID for SHA-256 + return MessageDigest.getInstance("2.16.840.1.101.3.4.2.1"); + } + }); + CONSCRYPT_ALGORITHMS.add(new Algorithm() { + @Override + public Object getInstance() throws GeneralSecurityException { + // OID for AES-128 + return AlgorithmParameters.getInstance("2.16.840.1.101.3.4.1.2"); + } + }); + } + + private static Provider getProvider(Object object) throws Exception { + // Every JCA object has a getProvider() method + Method m = object.getClass().getMethod("getProvider"); + return (Provider) m.invoke(object); + } + + @Test + public void testBeforeLimit() throws Exception { + // When we're before the limit of the target API, all calls should succeed + try { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion() + 1); + for (Algorithm a : BC_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("BC", getProvider(result).getName()); + } + for (Algorithm a : CONSCRYPT_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("AndroidOpenSSL", getProvider(result).getName()); + } + } finally { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + } + } + + @Test + public void testAtLimit() throws Exception { + // When we're at the limit of the target API, all calls should still succeed + try { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + for (Algorithm a : BC_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("BC", getProvider(result).getName()); + } + for (Algorithm a : CONSCRYPT_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("AndroidOpenSSL", getProvider(result).getName()); + } + } finally { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + } + } + + @Test + public void testPastLimit() throws Exception { + // When we're beyond the limit of the target API, the Conscrypt calls should succeed + // but the BC calls should throw NoSuchAlgorithmException + try { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion() - 1); + for (Algorithm a : BC_ALGORITHMS) { + try { + a.getInstance(); + fail("getInstance should have thrown"); + } catch (NoSuchAlgorithmException expected) { + } + } + for (Algorithm a : CONSCRYPT_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("AndroidOpenSSL", getProvider(result).getName()); + } + } finally { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + } + } + + @Test + public void testCustomProvider() throws Exception { + // When we install our own separate instance of Bouncy Castle, the system should + // respect that and allow us to use its implementation. + Provider originalBouncyCastle = null; + int originalBouncyCastleIndex = -1; + for (int i = 0; i < Security.getProviders().length; i++) { + if (Security.getProviders()[i].getName().equals("BC")) { + originalBouncyCastle = Security.getProviders()[i]; + originalBouncyCastleIndex = i; + break; + } + } + assertNotNull(originalBouncyCastle); + Provider newBouncyCastle = new BouncyCastleProvider(); + assertEquals("BC", newBouncyCastle.getName()); + try { + // Remove the existing BC provider and replace it with a different one + Security.removeProvider("BC"); + Security.insertProviderAt(newBouncyCastle, originalBouncyCastleIndex); + // Set the target API limit such that the BC algorithms are disallowed + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion() - 1); + for (Algorithm a : BC_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("BC", getProvider(result).getName()); + } + for (Algorithm a : CONSCRYPT_ALGORITHMS) { + Object result = a.getInstance(); + assertEquals("AndroidOpenSSL", getProvider(result).getName()); + } + } finally { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + Security.removeProvider("BC"); + Security.insertProviderAt(originalBouncyCastle, originalBouncyCastleIndex); + } + } +}
\ No newline at end of file diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java index 48d945b384f..7d8aff0e114 100644 --- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java +++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java @@ -48,12 +48,31 @@ import libcore.java.security.StandardNames; import libcore.javax.crypto.MockKey; import libcore.javax.crypto.MockKey2; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + /** * Tests for Mac class constructors and methods * */ public class MacTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + public static final String srvMac = "Mac"; private static String defaultAlgorithm = null; diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java index d5947803d45..689efa51c4b 100644 --- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java +++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java @@ -32,6 +32,9 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class MessageDigest2Test extends junit.framework.TestCase { private static final String MESSAGEDIGEST_ID = "MessageDigest."; @@ -425,11 +428,24 @@ public class MessageDigest2Test extends junit.framework.TestCase { assertNotNull("toString is null", str); } - protected void setUp() { + protected void setUp() throws Exception { + super.setUp(); Provider[] providers = Security.getProviders("MessageDigest.SHA"); for (Provider provider : providers) { digestAlgs.put(provider, getDigestAlgorithms(provider)); } + + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); } /* diff --git a/luni/src/test/java/tests/security/cert/CertificateFactory4Test.java b/luni/src/test/java/tests/security/cert/CertificateFactory4Test.java index 060a4a2ffa2..18fe0c4e6fd 100644 --- a/luni/src/test/java/tests/security/cert/CertificateFactory4Test.java +++ b/luni/src/test/java/tests/security/cert/CertificateFactory4Test.java @@ -19,6 +19,8 @@ package tests.security.cert; import junit.framework.TestCase; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; import tests.support.resource.Support_Resources; import tests.support.Support_GetResource; @@ -40,6 +42,22 @@ import java.util.List; public class CertificateFactory4Test extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + private static final String BASE_URL = Support_GetResource .getResourceURL("/../internalres/"); diff --git a/luni/src/test/java/tests/targets/security/cert/CertificateTest.java b/luni/src/test/java/tests/targets/security/cert/CertificateTest.java index adfe275f2db..80b34c017de 100644 --- a/luni/src/test/java/tests/targets/security/cert/CertificateTest.java +++ b/luni/src/test/java/tests/targets/security/cert/CertificateTest.java @@ -35,8 +35,27 @@ import java.util.List; import junit.framework.TestCase; import libcore.java.security.StandardNames; +import dalvik.system.VMRuntime; +import sun.security.jca.Providers; + public class CertificateTest extends TestCase { + // Allow access to deprecated BC algorithms in this test, so we can ensure they + // continue to work + @Override + public void setUp() throws Exception { + super.setUp(); + Providers.setMaximumAllowableApiLevelForBcDeprecation( + VMRuntime.getRuntime().getTargetSdkVersion()); + } + + @Override + public void tearDown() throws Exception { + Providers.setMaximumAllowableApiLevelForBcDeprecation( + Providers.DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION); + super.tearDown(); + } + /* * Following certificate chain was taken from https://www.verisign.com and * uses MD2withRSA for the root certificate. This chain stops validating diff --git a/ojluni/src/main/java/java/security/AlgorithmParameters.java b/ojluni/src/main/java/java/security/AlgorithmParameters.java index 36bb3ee02b6..864866ef7df 100644 --- a/ojluni/src/main/java/java/security/AlgorithmParameters.java +++ b/ojluni/src/main/java/java/security/AlgorithmParameters.java @@ -29,6 +29,8 @@ import java.io.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; +import sun.security.jca.Providers; + /** * This class is used as an opaque representation of cryptographic parameters. * @@ -285,6 +287,8 @@ public class AlgorithmParameters { { if (provider == null || provider.length() == 0) throw new IllegalArgumentException("missing provider"); + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "AlgorithmParameters", algorithm); Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", provider); return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], @@ -330,6 +334,8 @@ public class AlgorithmParameters { { if (provider == null) throw new IllegalArgumentException("missing provider"); + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "AlgorithmParameters", algorithm); Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", provider); return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], diff --git a/ojluni/src/main/java/java/security/KeyFactory.java b/ojluni/src/main/java/java/security/KeyFactory.java index a6b912c5500..d01ce161273 100644 --- a/ojluni/src/main/java/java/security/KeyFactory.java +++ b/ojluni/src/main/java/java/security/KeyFactory.java @@ -231,6 +231,8 @@ public class KeyFactory { */ public static KeyFactory getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyFactory", algorithm); Instance instance = GetInstance.getInstance("KeyFactory", KeyFactorySpi.class, algorithm, provider); return new KeyFactory((KeyFactorySpi)instance.impl, @@ -268,6 +270,8 @@ public class KeyFactory { */ public static KeyFactory getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyFactory", algorithm); Instance instance = GetInstance.getInstance("KeyFactory", KeyFactorySpi.class, algorithm, provider); return new KeyFactory((KeyFactorySpi)instance.impl, diff --git a/ojluni/src/main/java/java/security/KeyPairGenerator.java b/ojluni/src/main/java/java/security/KeyPairGenerator.java index 68ab5e94c1c..51a0ec93917 100644 --- a/ojluni/src/main/java/java/security/KeyPairGenerator.java +++ b/ojluni/src/main/java/java/security/KeyPairGenerator.java @@ -299,6 +299,8 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi { public static KeyPairGenerator getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyPairGenerator", algorithm); Instance instance = GetInstance.getInstance("KeyPairGenerator", KeyPairGeneratorSpi.class, algorithm, provider); return getInstance(instance, algorithm); @@ -335,6 +337,8 @@ public abstract class KeyPairGenerator extends KeyPairGeneratorSpi { */ public static KeyPairGenerator getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyPairGenerator", algorithm); Instance instance = GetInstance.getInstance("KeyPairGenerator", KeyPairGeneratorSpi.class, algorithm, provider); return getInstance(instance, algorithm); diff --git a/ojluni/src/main/java/java/security/MessageDigest.java b/ojluni/src/main/java/java/security/MessageDigest.java index 8e5dab14138..ab2614a5625 100644 --- a/ojluni/src/main/java/java/security/MessageDigest.java +++ b/ojluni/src/main/java/java/security/MessageDigest.java @@ -35,6 +35,8 @@ import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; +import sun.security.jca.Providers; + /** * This MessageDigest class provides applications the functionality of a * message digest algorithm, such as SHA-1 or SHA-256. @@ -255,6 +257,8 @@ public abstract class MessageDigest extends MessageDigestSpi { { if (provider == null || provider.length() == 0) throw new IllegalArgumentException("missing provider"); + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "MessageDigest", algorithm); Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); if (objs[0] instanceof MessageDigest) { MessageDigest md = (MessageDigest)objs[0]; @@ -303,6 +307,8 @@ public abstract class MessageDigest extends MessageDigestSpi { { if (provider == null) throw new IllegalArgumentException("missing provider"); + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "MessageDigest", algorithm); Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); if (objs[0] instanceof MessageDigest) { MessageDigest md = (MessageDigest)objs[0]; diff --git a/ojluni/src/main/java/java/security/Signature.java b/ojluni/src/main/java/java/security/Signature.java index 5a0e6a87a48..9deaf564647 100644 --- a/ojluni/src/main/java/java/security/Signature.java +++ b/ojluni/src/main/java/java/security/Signature.java @@ -498,6 +498,8 @@ public abstract class Signature extends SignatureSpi { } return getInstanceRSA(p); } + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "Signature", algorithm); Instance instance = GetInstance.getInstance ("Signature", SignatureSpi.class, algorithm, provider); return getInstance(instance, algorithm); @@ -541,6 +543,8 @@ public abstract class Signature extends SignatureSpi { } return getInstanceRSA(provider); } + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "Signature", algorithm); Instance instance = GetInstance.getInstance ("Signature", SignatureSpi.class, algorithm, provider); return getInstance(instance, algorithm); diff --git a/ojluni/src/main/java/java/security/cert/CertificateFactory.java b/ojluni/src/main/java/java/security/cert/CertificateFactory.java index e74ff0a2e85..5ccbb33386e 100644 --- a/ojluni/src/main/java/java/security/cert/CertificateFactory.java +++ b/ojluni/src/main/java/java/security/cert/CertificateFactory.java @@ -250,6 +250,8 @@ public class CertificateFactory { String provider) throws CertificateException, NoSuchProviderException { try { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "CertificateFactory", type); Instance instance = GetInstance.getInstance("CertificateFactory", CertificateFactorySpi.class, type, provider); return new CertificateFactory((CertificateFactorySpi)instance.impl, @@ -291,6 +293,8 @@ public class CertificateFactory { public static final CertificateFactory getInstance(String type, Provider provider) throws CertificateException { try { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "CertificateFactory", type); Instance instance = GetInstance.getInstance("CertificateFactory", CertificateFactorySpi.class, type, provider); return new CertificateFactory((CertificateFactorySpi)instance.impl, diff --git a/ojluni/src/main/java/javax/crypto/KeyAgreement.java b/ojluni/src/main/java/javax/crypto/KeyAgreement.java index ffa18b1cc1d..ce42de8ae4b 100644 --- a/ojluni/src/main/java/javax/crypto/KeyAgreement.java +++ b/ojluni/src/main/java/javax/crypto/KeyAgreement.java @@ -252,6 +252,8 @@ public class KeyAgreement { public static final KeyAgreement getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyAgreement", algorithm); Instance instance = JceSecurity.getInstance ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider); return new KeyAgreement((KeyAgreementSpi)instance.impl, @@ -292,6 +294,8 @@ public class KeyAgreement { */ public static final KeyAgreement getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyAgreement", algorithm); Instance instance = JceSecurity.getInstance ("KeyAgreement", KeyAgreementSpi.class, algorithm, provider); return new KeyAgreement((KeyAgreementSpi)instance.impl, diff --git a/ojluni/src/main/java/javax/crypto/KeyGenerator.java b/ojluni/src/main/java/javax/crypto/KeyGenerator.java index 5dfde971f2e..b0977f0a5fa 100644 --- a/ojluni/src/main/java/javax/crypto/KeyGenerator.java +++ b/ojluni/src/main/java/javax/crypto/KeyGenerator.java @@ -326,6 +326,8 @@ public class KeyGenerator { public static final KeyGenerator getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyGenerator", algorithm); Instance instance = JceSecurity.getInstance("KeyGenerator", KeyGeneratorSpi.class, algorithm, provider); return new KeyGenerator((KeyGeneratorSpi)instance.impl, @@ -364,6 +366,8 @@ public class KeyGenerator { */ public static final KeyGenerator getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "KeyGenerator", algorithm); Instance instance = JceSecurity.getInstance("KeyGenerator", KeyGeneratorSpi.class, algorithm, provider); return new KeyGenerator((KeyGeneratorSpi)instance.impl, diff --git a/ojluni/src/main/java/javax/crypto/Mac.java b/ojluni/src/main/java/javax/crypto/Mac.java index c3d99fb354d..dab6971ca45 100644 --- a/ojluni/src/main/java/javax/crypto/Mac.java +++ b/ojluni/src/main/java/javax/crypto/Mac.java @@ -309,6 +309,8 @@ public class Mac implements Cloneable { */ public static final Mac getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "Mac", algorithm); Instance instance = JceSecurity.getInstance ("Mac", MacSpi.class, algorithm, provider); return new Mac((MacSpi)instance.impl, instance.provider, algorithm); @@ -344,6 +346,8 @@ public class Mac implements Cloneable { */ public static final Mac getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "Mac", algorithm); Instance instance = JceSecurity.getInstance ("Mac", MacSpi.class, algorithm, provider); return new Mac((MacSpi)instance.impl, instance.provider, algorithm); diff --git a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java index c1358c2064d..be1cef476a7 100644 --- a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java +++ b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java @@ -385,6 +385,8 @@ public class SecretKeyFactory { public static final SecretKeyFactory getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "SecretKeyFactory", algorithm); Instance instance = JceSecurity.getInstance("SecretKeyFactory", SecretKeyFactorySpi.class, algorithm, provider); return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl, @@ -425,6 +427,8 @@ public class SecretKeyFactory { */ public static final SecretKeyFactory getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { + // Android-added: Check for Bouncy Castle deprecation + Providers.checkBouncyCastleDeprecation(provider, "SecretKeyFactory", algorithm); Instance instance = JceSecurity.getInstance("SecretKeyFactory", SecretKeyFactorySpi.class, algorithm, provider); return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl, diff --git a/ojluni/src/main/java/sun/security/jca/Providers.java b/ojluni/src/main/java/sun/security/jca/Providers.java index e39543af23c..e50ce231255 100644 --- a/ojluni/src/main/java/sun/security/jca/Providers.java +++ b/ojluni/src/main/java/sun/security/jca/Providers.java @@ -26,7 +26,13 @@ package sun.security.jca; +import dalvik.system.VMRuntime; +import java.security.NoSuchAlgorithmException; import java.security.Provider; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; /** * Collection of methods to get and set provider list. Also includes @@ -48,6 +54,10 @@ public class Providers { // Note volatile immutable object, so no synchronization needed. private static volatile ProviderList providerList; + // Android-added: Keep reference to system-created Bouncy Castle provider + // See comments near deprecation methods at the bottom of this file. + private static volatile Provider SYSTEM_BOUNCY_CASTLE_PROVIDER; + static { // set providerList to empty list first in case initialization somehow // triggers a getInstance() call (although that should not happen) @@ -64,6 +74,8 @@ public class Providers { throw new AssertionError("Unable to configure default providers"); } // END Android-added: Initialize all providers and assert that this succeeds. + // Android-added: Set BC provider instance + SYSTEM_BOUNCY_CASTLE_PROVIDER = providerList.getProvider("BC"); } private Providers() { @@ -263,4 +275,283 @@ public class Providers { threadListsUsed--; } + // BEGIN Android-added: Check for requests of deprecated Bouncy Castle algorithms. + // Beginning in Android P, Bouncy Castle versions of algorithms available through + // Conscrypt are deprecated. We will no longer supply them to applications + // with a target API level of P or later, and will print a warning for applications + // with a target API level before P. + // + // We only care about the system-provided Bouncy Castle provider; applications are allowed to + // install their own copy of Bouncy Castle if they want to continue using those implementations. + + /** + * Maximum target API level for which we will provide the deprecated Bouncy Castle algorithms. + * + * Only exists for testing and shouldn't be changed. + * + * @hide + */ + public static final int DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION = 26; + + private static int maximumAllowableApiLevelForBcDeprecation = + DEFAULT_MAXIMUM_ALLOWABLE_TARGET_API_LEVEL_FOR_BC_DEPRECATION; + + /** + * Sets the target API level for BC deprecation, only for use in tests. + * + * @hide + */ + public static void setMaximumAllowableApiLevelForBcDeprecation(int targetApiLevel) { + maximumAllowableApiLevelForBcDeprecation = targetApiLevel; + } + + /** + * Returns the target API level for BC deprecation, only for use in tests. + * + * @hide + */ + public static int getMaximumAllowableApiLevelForBcDeprecation() { + return maximumAllowableApiLevelForBcDeprecation; + } + + /** + * Checks if the installed provider with the given name is the system-installed Bouncy + * Castle provider. If so, throws {@code NoSuchAlgorithmException} if the algorithm + * being requested is deprecated and the application targets a late-enough API level. + * + * @hide + */ + public static synchronized void checkBouncyCastleDeprecation(String provider, + String service, String algorithm) throws NoSuchAlgorithmException { + // Applications may install their own BC provider, only the algorithms from the system + // provider are deprecated. + if ("BC".equals(provider) + && providerList.getProvider(provider) == SYSTEM_BOUNCY_CASTLE_PROVIDER) { + checkBouncyCastleDeprecation(service, algorithm); + } + } + + /** + * Checks if the given provider is the system-installed Bouncy Castle provider. If so, + * throws {@code NoSuchAlgorithmException} if the algorithm being requested is deprecated + * and the application targets a late-enough API level. + * + * @hide + */ + public static synchronized void checkBouncyCastleDeprecation(Provider provider, + String service, String algorithm) throws NoSuchAlgorithmException { + // Applications may install their own BC provider, only the algorithms from the system + // provider are deprecated. + if (provider == SYSTEM_BOUNCY_CASTLE_PROVIDER) { + checkBouncyCastleDeprecation(service, algorithm); + } + } + + // The set of algorithms that are deprecated. This list is created using + // libcore/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java + private static final Set<String> DEPRECATED_ALGORITHMS = new HashSet<String>(); + static { + DEPRECATED_ALGORITHMS.addAll(Arrays.asList( + "ALGORITHMPARAMETERS.1.2.840.113549.3.7", + "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.2", + "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.22", + "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.26", + "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.42", + "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.46", + "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.6", + "ALGORITHMPARAMETERS.AES", + "ALGORITHMPARAMETERS.DESEDE", + "ALGORITHMPARAMETERS.EC", + "ALGORITHMPARAMETERS.GCM", + "ALGORITHMPARAMETERS.OAEP", + "ALGORITHMPARAMETERS.TDEA", + "CERTIFICATEFACTORY.X.509", + "CERTIFICATEFACTORY.X509", + // TODO(flooey, b/67626877): Implement Cipher support + // "CIPHER.1.2.840.113549.3.4", + // "CIPHER.2.16.840.1.101.3.4.1.26", + // "CIPHER.2.16.840.1.101.3.4.1.46", + // "CIPHER.2.16.840.1.101.3.4.1.6", + // "CIPHER.AES/GCM/NOPADDING", + // "CIPHER.ARC4", + // "CIPHER.ARCFOUR", + // "CIPHER.OID.1.2.840.113549.3.4", + // "CIPHER.RC4", + "KEYAGREEMENT.ECDH", + "KEYFACTORY.1.2.840.10045.2.1", + "KEYFACTORY.1.2.840.113549.1.1.1", + "KEYFACTORY.1.2.840.113549.1.1.7", + "KEYFACTORY.1.3.133.16.840.63.0.2", + "KEYFACTORY.2.5.8.1.1", + "KEYFACTORY.EC", + "KEYFACTORY.RSA", + "KEYGENERATOR.1.2.840.113549.2.10", + "KEYGENERATOR.1.2.840.113549.2.11", + "KEYGENERATOR.1.2.840.113549.2.7", + "KEYGENERATOR.1.2.840.113549.2.8", + "KEYGENERATOR.1.2.840.113549.2.9", + "KEYGENERATOR.1.3.6.1.5.5.8.1.1", + "KEYGENERATOR.1.3.6.1.5.5.8.1.2", + "KEYGENERATOR.2.16.840.1.101.3.4.2.1", + "KEYGENERATOR.AES", + "KEYGENERATOR.DESEDE", + "KEYGENERATOR.HMAC-MD5", + "KEYGENERATOR.HMAC-SHA1", + "KEYGENERATOR.HMAC-SHA224", + "KEYGENERATOR.HMAC-SHA256", + "KEYGENERATOR.HMAC-SHA384", + "KEYGENERATOR.HMAC-SHA512", + "KEYGENERATOR.HMAC/MD5", + "KEYGENERATOR.HMAC/SHA1", + "KEYGENERATOR.HMAC/SHA224", + "KEYGENERATOR.HMAC/SHA256", + "KEYGENERATOR.HMAC/SHA384", + "KEYGENERATOR.HMAC/SHA512", + "KEYGENERATOR.HMACMD5", + "KEYGENERATOR.HMACSHA1", + "KEYGENERATOR.HMACSHA224", + "KEYGENERATOR.HMACSHA256", + "KEYGENERATOR.HMACSHA384", + "KEYGENERATOR.HMACSHA512", + "KEYGENERATOR.TDEA", + "KEYPAIRGENERATOR.1.2.840.10045.2.1", + "KEYPAIRGENERATOR.1.2.840.113549.1.1.1", + "KEYPAIRGENERATOR.1.2.840.113549.1.1.7", + "KEYPAIRGENERATOR.1.3.133.16.840.63.0.2", + "KEYPAIRGENERATOR.2.5.8.1.1", + "KEYPAIRGENERATOR.EC", + "KEYPAIRGENERATOR.RSA", + "MAC.1.2.840.113549.2.10", + "MAC.1.2.840.113549.2.11", + "MAC.1.2.840.113549.2.7", + "MAC.1.2.840.113549.2.8", + "MAC.1.2.840.113549.2.9", + "MAC.1.3.6.1.5.5.8.1.1", + "MAC.1.3.6.1.5.5.8.1.2", + "MAC.2.16.840.1.101.3.4.2.1", + "MAC.HMAC-MD5", + "MAC.HMAC-SHA1", + "MAC.HMAC-SHA224", + "MAC.HMAC-SHA256", + "MAC.HMAC-SHA384", + "MAC.HMAC-SHA512", + "MAC.HMAC/MD5", + "MAC.HMAC/SHA1", + "MAC.HMAC/SHA224", + "MAC.HMAC/SHA256", + "MAC.HMAC/SHA384", + "MAC.HMAC/SHA512", + "MAC.HMACMD5", + "MAC.HMACSHA1", + "MAC.HMACSHA224", + "MAC.HMACSHA256", + "MAC.HMACSHA384", + "MAC.HMACSHA512", + "MAC.PBEWITHHMACSHA224", + "MAC.PBEWITHHMACSHA256", + "MAC.PBEWITHHMACSHA384", + "MAC.PBEWITHHMACSHA512", + "MESSAGEDIGEST.1.2.840.113549.2.5", + "MESSAGEDIGEST.1.3.14.3.2.26", + "MESSAGEDIGEST.2.16.840.1.101.3.4.2.1", + "MESSAGEDIGEST.2.16.840.1.101.3.4.2.2", + "MESSAGEDIGEST.2.16.840.1.101.3.4.2.3", + "MESSAGEDIGEST.2.16.840.1.101.3.4.2.4", + "MESSAGEDIGEST.MD5", + "MESSAGEDIGEST.SHA", + "MESSAGEDIGEST.SHA-1", + "MESSAGEDIGEST.SHA-224", + "MESSAGEDIGEST.SHA-256", + "MESSAGEDIGEST.SHA-384", + "MESSAGEDIGEST.SHA-512", + "MESSAGEDIGEST.SHA1", + "MESSAGEDIGEST.SHA224", + "MESSAGEDIGEST.SHA256", + "MESSAGEDIGEST.SHA384", + "MESSAGEDIGEST.SHA512", + "SECRETKEYFACTORY.DESEDE", + "SECRETKEYFACTORY.TDEA", + "SIGNATURE.1.2.840.10045.4.1", + "SIGNATURE.1.2.840.10045.4.3.1", + "SIGNATURE.1.2.840.10045.4.3.2", + "SIGNATURE.1.2.840.10045.4.3.3", + "SIGNATURE.1.2.840.10045.4.3.4", + "SIGNATURE.1.2.840.113549.1.1.11", + "SIGNATURE.1.2.840.113549.1.1.12", + "SIGNATURE.1.2.840.113549.1.1.13", + "SIGNATURE.1.2.840.113549.1.1.14", + "SIGNATURE.1.2.840.113549.1.1.4", + "SIGNATURE.1.2.840.113549.1.1.5", + "SIGNATURE.1.3.14.3.2.29", + "SIGNATURE.ECDSA", + "SIGNATURE.ECDSAWITHSHA1", + "SIGNATURE.MD5/RSA", + "SIGNATURE.MD5WITHRSA", + "SIGNATURE.MD5WITHRSAENCRYPTION", + "SIGNATURE.NONEWITHECDSA", + "SIGNATURE.OID.1.2.840.10045.4.3.1", + "SIGNATURE.OID.1.2.840.10045.4.3.2", + "SIGNATURE.OID.1.2.840.10045.4.3.3", + "SIGNATURE.OID.1.2.840.10045.4.3.4", + "SIGNATURE.OID.1.2.840.113549.1.1.11", + "SIGNATURE.OID.1.2.840.113549.1.1.12", + "SIGNATURE.OID.1.2.840.113549.1.1.13", + "SIGNATURE.OID.1.2.840.113549.1.1.14", + "SIGNATURE.OID.1.2.840.113549.1.1.4", + "SIGNATURE.OID.1.2.840.113549.1.1.5", + "SIGNATURE.OID.1.3.14.3.2.29", + "SIGNATURE.SHA1/RSA", + "SIGNATURE.SHA1WITHECDSA", + "SIGNATURE.SHA1WITHRSA", + "SIGNATURE.SHA1WITHRSAENCRYPTION", + "SIGNATURE.SHA224/ECDSA", + "SIGNATURE.SHA224/RSA", + "SIGNATURE.SHA224WITHECDSA", + "SIGNATURE.SHA224WITHRSA", + "SIGNATURE.SHA224WITHRSAENCRYPTION", + "SIGNATURE.SHA256/ECDSA", + "SIGNATURE.SHA256/RSA", + "SIGNATURE.SHA256WITHECDSA", + "SIGNATURE.SHA256WITHRSA", + "SIGNATURE.SHA256WITHRSAENCRYPTION", + "SIGNATURE.SHA384/ECDSA", + "SIGNATURE.SHA384/RSA", + "SIGNATURE.SHA384WITHECDSA", + "SIGNATURE.SHA384WITHRSA", + "SIGNATURE.SHA384WITHRSAENCRYPTION", + "SIGNATURE.SHA512/ECDSA", + "SIGNATURE.SHA512/RSA", + "SIGNATURE.SHA512WITHECDSA", + "SIGNATURE.SHA512WITHRSA", + "SIGNATURE.SHA512WITHRSAENCRYPTION" + )); + } + + /** + * Throws an exception or logs a warning if the supplied service and algorithm identify + * a deprecated algorithm from Bouncy Castle, depending on the application's target API level. + * Only called if we have already determined that the request is for the system Bouncy Castle + * provider. + */ + private static void checkBouncyCastleDeprecation(String service, String algorithm) + throws NoSuchAlgorithmException { + String key = service + "." + algorithm; + if (DEPRECATED_ALGORITHMS.contains(key.toUpperCase(Locale.US))) { + if (VMRuntime.getRuntime().getTargetSdkVersion() + <= maximumAllowableApiLevelForBcDeprecation) { + // This application is allowed to access these functions, only print a warning + System.logE(" ******** DEPRECATED FUNCTIONALITY ********"); + System.logE(" * The implementation of the " + key + " algorithm from"); + System.logE(" * the BC provider is deprecated in this version of Android."); + System.logE(" * It will be removed in a future version of Android and your"); + System.logE(" * application will no longer be able to request it. Please see"); + System.logE(" * ((TODO(flooey, b/67626877): Blog Post Link)) for more details."); + } else { + throw new NoSuchAlgorithmException("The BC provider no longer provides an" + + " implementation for " + key + ". Please see" + + " ((TODO(flooey, b/67626877): Blog Post Link)) for more details."); + } + } + } + } diff --git a/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java b/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java new file mode 100644 index 00000000000..f27918769a3 --- /dev/null +++ b/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package libcore.java.security; + +import java.security.Provider; +import java.security.Security; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Prints a list of all algorithms (including aliases) that overlap between Conscrypt and + * Bouncy Castle. Intended to be run via vogar. + * <p> + * {@code vogar libcore/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java} + */ +public class ProviderOverlap { + + public static void main(String[] argv) throws Exception { + Set<String> conscrypt = getAlgorithms(Security.getProvider("AndroidOpenSSL")); + Set<String> bc = getAlgorithms(Security.getProvider("BC")); + SortedSet<String> overlap = new TreeSet<>(conscrypt); + overlap.retainAll(bc); + for (String s : overlap) { + System.out.println(s); + } + } + + private static Set<String> getAlgorithms(Provider p) { + Set<String> result = new HashSet<>(); + for (Object keyObj : p.keySet()) { + String key = (String) keyObj; + if (key.contains(" ")) { + // These are implementation properties like "Provider.id name" + continue; + } + if (key.startsWith("Alg.Alias.")) { + // This is an alias, strip its prefix + key = key.substring("Alg.Alias.".length()); + } + result.add(key.toUpperCase(Locale.US)); + } + return result; + } +}
\ No newline at end of file |