[automerger skipped] Merge: Make tests agnostic about TLS v1.x. am: 5dc9cdaf41 -s ours am: e6b1e3af07 -s ours

am skip reason: Merged-In If8c48afcd1a6a417d1410ce4335f16cac3abd191 with SHA-1 d075ab478a is already in history

Original change: https://android-review.googlesource.com/c/platform/external/conscrypt/+/2923169

Change-Id: I84352260568c91b4eaa2868b6a7e991c1bfed967
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/common/src/main/java/org/conscrypt/OpenSSLKey.java b/common/src/main/java/org/conscrypt/OpenSSLKey.java
index 06fdd4e..6eb94f4 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLKey.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLKey.java
@@ -313,7 +313,7 @@
     PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
         switch (NativeCrypto.EVP_PKEY_type(ctx)) {
             case NativeConstants.EVP_PKEY_RSA:
-                return new OpenSSLRSAPrivateKey(this);
+                return OpenSSLRSAPrivateKey.getInstance(this);
             case NativeConstants.EVP_PKEY_EC:
                 return new OpenSSLECPrivateKey(this);
             default:
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
index 6724535..ff9be81 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -15,16 +15,25 @@
  */
 package org.conscrypt.java.security;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.security.KeyFactory;
 import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
 import java.security.Security;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
 import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
@@ -33,6 +42,7 @@
 import java.util.Arrays;
 import java.util.List;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
@@ -59,12 +69,16 @@
     }
 
     @Test
-    public void testExtraBufferSpace_Private() throws Exception {
-        PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
-        byte[] encoded = privateKey.getEncoded();
-        byte[] longBuffer = new byte[encoded.length + 147];
-        System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
-        KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
+    public void getEncodedFailsWhenCrtValuesMissing() throws Exception {
+        PrivateKey privateKey = getPrivateKey();
+        try {
+            // Key has only modulus and private exponent so can't be encoded as PKCS#8
+            privateKey.getEncoded();
+            fail();
+        } catch (RuntimeException e) {
+            // Expected
+        }
     }
 
     @Test
@@ -105,4 +119,42 @@
             // expected
         }
     }
+
+    @Test
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
+    public void javaSerialization() throws Exception{
+        PrivateKey privatekey = getPrivateKey();
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bos);
+        out.writeObject(privatekey);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bis);
+        PrivateKey copy = (PrivateKey) in.readObject();
+
+        assertEquals(privatekey, copy);
+    }
+
+    // b/209335673 Base image has fix for b/191150645 but release version of module does not,
+    // @Override
+    // protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
+    //     return Arrays.asList(
+    //             new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
+    //     );
+    // }
+
+    // The private RSA key returned by DefaultKeys.getPrivateKey() is built from a PKCS#8
+    // KeySpec and so will be an instance of RSAPrivateCrtKey, but we want to test RSAPrivateKey
+    // in this unit test and so we extract the modulus and private exponent to build the
+    // correct private key subtype.
+    private PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
+        RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) DefaultKeys.getPrivateKey(algorithmName);
+        RSAPrivateKeySpec spec =
+                new RSAPrivateKeySpec(crtKey.getModulus(), crtKey.getPrivateExponent());
+        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(spec);
+        assertTrue(privateKey instanceof RSAPrivateKey);
+        assertFalse(privateKey instanceof RSAPrivateCrtKey);
+        return privateKey;
+    }
 }
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index 957be7a..3afa73f 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -15,9 +15,23 @@
  */
 package org.conscrypt.java.security;
 
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.KeyFactory;
 import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPublicKeySpec;
+import org.junit.Ignore;
+import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 import tests.util.ServiceTester;
@@ -42,4 +56,37 @@
     // implmenetations.
     return tester.skipProvider("BC");
   }
+
+  @Test
+  public void testExtraBufferSpace_Private() throws Exception {
+    PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+    // b/209335673 Base image has fix for b/191150645 but release version of module does not
+    // assertTrue(privateKey instanceof RSAPrivateCrtKey);
+
+    byte[] encoded = privateKey.getEncoded();
+    byte[] longBuffer = new byte[encoded.length + 147];
+    System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
+    PrivateKey copy =
+            KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
+    assertEquals(privateKey, copy);
+  }
+
+  @Test
+  @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
+  public void javaSerialization() throws Exception{
+    PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+    assertTrue(privateKey instanceof RSAPrivateCrtKey);
+
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    ObjectOutputStream out = new ObjectOutputStream(bos);
+    out.writeObject(privateKey);
+
+    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+    ObjectInputStream in = new ObjectInputStream(bis);
+    PrivateKey copy = (PrivateKey) in.readObject();
+    assertTrue(copy instanceof RSAPrivateCrtKey);
+
+    assertEquals(privateKey.getFormat(), copy.getFormat());
+    assertArrayEquals(privateKey.getEncoded(), copy.getEncoded());
+  }
 }
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
index f34b935..61216ab 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLKey.java
@@ -319,7 +319,7 @@
     PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
         switch (NativeCrypto.EVP_PKEY_type(ctx)) {
             case NativeConstants.EVP_PKEY_RSA:
-                return new OpenSSLRSAPrivateKey(this);
+                return OpenSSLRSAPrivateKey.getInstance(this);
             case NativeConstants.EVP_PKEY_EC:
                 return new OpenSSLECPrivateKey(this);
             default:
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
index 6b0567e..1c51b59 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSA.java
@@ -16,16 +16,25 @@
  */
 package com.android.org.conscrypt.java.security;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.security.KeyFactory;
 import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
 import java.security.Security;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
 import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
@@ -34,6 +43,7 @@
 import java.util.List;
 import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
@@ -62,12 +72,16 @@
     }
 
     @Test
-    public void testExtraBufferSpace_Private() throws Exception {
-        PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
-        byte[] encoded = privateKey.getEncoded();
-        byte[] longBuffer = new byte[encoded.length + 147];
-        System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
-        KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
+    public void getEncodedFailsWhenCrtValuesMissing() throws Exception {
+        PrivateKey privateKey = getPrivateKey();
+        try {
+            // Key has only modulus and private exponent so can't be encoded as PKCS#8
+            privateKey.getEncoded();
+            fail();
+        } catch (RuntimeException e) {
+            // Expected
+        }
     }
 
     @Test
@@ -108,4 +122,42 @@
             // expected
         }
     }
+
+    @Test
+    @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
+    public void javaSerialization() throws Exception {
+        PrivateKey privatekey = getPrivateKey();
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(bos);
+        out.writeObject(privatekey);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bis);
+        PrivateKey copy = (PrivateKey) in.readObject();
+
+        assertEquals(privatekey, copy);
+    }
+
+    // b/209335673 Base image has fix for b/191150645 but release version of module does not,
+    // @Override
+    // protected List<KeyPair> getKeys() throws NoSuchAlgorithmException, InvalidKeySpecException {
+    //     return Arrays.asList(
+    //             new KeyPair(DefaultKeys.getPublicKey(algorithmName), getPrivateKey())
+    //     );
+    // }
+
+    // The private RSA key returned by DefaultKeys.getPrivateKey() is built from a PKCS#8
+    // KeySpec and so will be an instance of RSAPrivateCrtKey, but we want to test RSAPrivateKey
+    // in this unit test and so we extract the modulus and private exponent to build the
+    // correct private key subtype.
+    private PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
+        RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) DefaultKeys.getPrivateKey(algorithmName);
+        RSAPrivateKeySpec spec =
+                new RSAPrivateKeySpec(crtKey.getModulus(), crtKey.getPrivateExponent());
+        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(spec);
+        assertTrue(privateKey instanceof RSAPrivateKey);
+        assertFalse(privateKey instanceof RSAPrivateCrtKey);
+        return privateKey;
+    }
 }
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
index 15b1628..d8d8ebe 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyFactoryTestRSACrt.java
@@ -16,9 +16,23 @@
  */
 package com.android.org.conscrypt.java.security;
 
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.KeyFactory;
 import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPublicKeySpec;
+import org.junit.Ignore;
+import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 import tests.util.ServiceTester;
@@ -46,4 +60,37 @@
     // implmenetations.
     return tester.skipProvider("BC");
   }
+
+  @Test
+  public void testExtraBufferSpace_Private() throws Exception {
+      PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+      // b/209335673 Base image has fix for b/191150645 but release version of module does not
+      // assertTrue(privateKey instanceof RSAPrivateCrtKey);
+
+      byte[] encoded = privateKey.getEncoded();
+      byte[] longBuffer = new byte[encoded.length + 147];
+      System.arraycopy(encoded, 0, longBuffer, 0, encoded.length);
+      PrivateKey copy =
+              KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(longBuffer));
+      assertEquals(privateKey, copy);
+  }
+
+  @Test
+  @Ignore("b/209335673 Base image has fix for b/191150645 but release version of module does not")
+  public void javaSerialization() throws Exception {
+      PrivateKey privateKey = DefaultKeys.getPrivateKey("RSA");
+      assertTrue(privateKey instanceof RSAPrivateCrtKey);
+
+      ByteArrayOutputStream bos = new ByteArrayOutputStream();
+      ObjectOutputStream out = new ObjectOutputStream(bos);
+      out.writeObject(privateKey);
+
+      ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+      ObjectInputStream in = new ObjectInputStream(bis);
+      PrivateKey copy = (PrivateKey) in.readObject();
+      assertTrue(copy instanceof RSAPrivateCrtKey);
+
+      assertEquals(privateKey.getFormat(), copy.getFormat());
+      assertArrayEquals(privateKey.getEncoded(), copy.getEncoded());
+  }
 }
diff --git a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java
index 8a751aa..319b198 100644
--- a/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java
+++ b/repackaged/testing/src/main/java/com/android/org/conscrypt/java/security/AbstractKeyFactoryTest.java
@@ -33,8 +33,7 @@
  * @hide This class is not part of the Android public SDK API
  */
 public abstract class AbstractKeyFactoryTest<PublicKeySpec extends KeySpec, PrivateKeySpec extends KeySpec> {
-
-    private final String algorithmName;
+    protected final String algorithmName;
     private final Class<PublicKeySpec> publicKeySpecClass;
     private final Class<PrivateKeySpec> privateKeySpecClass;
 
diff --git a/testing/src/main/java/org/conscrypt/java/security/AbstractKeyFactoryTest.java b/testing/src/main/java/org/conscrypt/java/security/AbstractKeyFactoryTest.java
index 3523e45..ae5c963 100644
--- a/testing/src/main/java/org/conscrypt/java/security/AbstractKeyFactoryTest.java
+++ b/testing/src/main/java/org/conscrypt/java/security/AbstractKeyFactoryTest.java
@@ -30,7 +30,7 @@
 
 public abstract class AbstractKeyFactoryTest<PublicKeySpec extends KeySpec, PrivateKeySpec extends KeySpec> {
 
-    private final String algorithmName;
+    protected final String algorithmName;
     private final Class<PublicKeySpec> publicKeySpecClass;
     private final Class<PrivateKeySpec> privateKeySpecClass;