From 32f92ab3a7b4604fc43b18b748d2d5c277cad75e Mon Sep 17 00:00:00 2001 From: Miguel Aranda Date: Mon, 22 Jun 2026 12:24:16 +0000 Subject: [PATCH] Project import generated by Copybara. PiperOrigin-RevId: 936001388 --- .../jni/main/cpp/conscrypt/native_crypto.cc | 95 +------------ .../conscrypt/OpenSslSlhDsaKeyFactory.java | 116 ++++++++++++++-- .../conscrypt/OpenSslSlhDsaPrivateKey.java | 18 +-- .../org/conscrypt/OpenSslSlhDsaPublicKey.java | 18 +-- .../test/java/org/conscrypt/SlhDsaTest.java | 128 +++++++++++++++++- .../java/security/KeyPairGeneratorTest.java | 3 +- .../security/cert/CertificateFactoryTest.java | 4 +- .../javax/crypto/CipherBasicsTest.java | 6 +- .../conscrypt/javax/crypto/CipherTest.java | 13 +- .../javax/crypto/ECDHKeyAgreementTest.java | 6 +- .../javax/crypto/XDHKeyAgreementTest.java | 4 +- .../javax/net/ssl/SSLContextTest.java | 6 +- .../javax/net/ssl/SSLSocketTest.java | 40 +++--- .../javax/net/ssl/TestSSLSessions.java | 4 +- .../main/java/tests/util/ServiceTester.java | 58 ++++++++ 15 files changed, 336 insertions(+), 183 deletions(-) diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc index 713a39d54..ef9256df7 100644 --- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc +++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc @@ -428,10 +428,7 @@ static jobjectArray CryptoBuffersToObjectArray(JNIEnv* env, * Converts ASN.1 BIT STRING to a jbooleanArray. */ jbooleanArray ASN1BitStringToBooleanArray(JNIEnv* env, const ASN1_BIT_STRING* bitStr) { - int size = ASN1_STRING_length(bitStr) * 8; - if (bitStr->flags & ASN1_STRING_FLAG_BITS_LEFT) { - size -= bitStr->flags & 0x07; - } + int size = ASN1_STRING_length(bitStr) * 8 - ASN1_BIT_STRING_unused_bits(bitStr); ScopedLocalRef bitsRef(env, env->NewBooleanArray(size)); if (bitsRef.get() == nullptr) { @@ -846,7 +843,6 @@ static jlong NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass, jbyteArray n, jb return 0; } -#if BORINGSSL_API_VERSION >= 20 bssl::UniquePtr nBN, eBN, dBN, pBN, qBN, dmp1BN, dmq1BN, iqmpBN; nBN = arrayToBignum(env, n); if (!nBN) { @@ -917,70 +913,6 @@ static jlong NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass, jbyteArray n, jb conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_PKEY_new_RSA"); return 0; } -#else - bssl::UniquePtr rsa(RSA_new()); - if (rsa.get() == nullptr) { - conscrypt::jniutil::throwRuntimeException(env, "RSA_new failed"); - return 0; - } - - if (!arrayToBignum(env, n, &rsa->n)) { - return 0; - } - - if (e != nullptr && !arrayToBignum(env, e, &rsa->e)) { - return 0; - } - - if (d != nullptr && !arrayToBignum(env, d, &rsa->d)) { - return 0; - } - - if (p != nullptr && !arrayToBignum(env, p, &rsa->p)) { - return 0; - } - - if (q != nullptr && !arrayToBignum(env, q, &rsa->q)) { - return 0; - } - - if (dmp1 != nullptr && !arrayToBignum(env, dmp1, &rsa->dmp1)) { - return 0; - } - - if (dmq1 != nullptr && !arrayToBignum(env, dmq1, &rsa->dmq1)) { - return 0; - } - - if (iqmp != nullptr && !arrayToBignum(env, iqmp, &rsa->iqmp)) { - return 0; - } - - if (conscrypt::trace::kWithJniTrace) { - if (p != nullptr && q != nullptr) { - int check = RSA_check_key(rsa.get()); - JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check); - } - } - - if (rsa->n == nullptr || (rsa->e == nullptr && rsa->d == nullptr)) { - conscrypt::jniutil::throwRuntimeException(env, "Unable to convert BigInteger to BIGNUM"); - return 0; - } - - /* - * If the private exponent is available, there is the potential to do signing - * operations. However, we can only do blinding if the public exponent is also - * available. Disable blinding if the public exponent isn't available. - * - * TODO[kroot]: We should try to recover the public exponent by trying - * some common ones such 3, 17, or 65537. - */ - if (rsa->d != nullptr && rsa->e == nullptr) { - JNI_TRACE("EVP_PKEY_new_RSA(...) disabling RSA blinding => %p", rsa.get()); - rsa->flags |= RSA_FLAG_NO_BLINDING; - } -#endif bssl::UniquePtr pkey(EVP_PKEY_new()); if (pkey.get() == nullptr) { @@ -1690,7 +1622,6 @@ static jlong NativeCrypto_getRSAPrivateKeyWrapper(JNIEnv* env, jclass, jobject j ensure_engine_globals(); -#if BORINGSSL_API_VERSION >= 20 // The PSS padding code needs access to the actual n, so set it even though we // don't set any other parts of the key bssl::UniquePtr n = arrayToBignum(env, modulusBytes); @@ -1705,19 +1636,6 @@ static jlong NativeCrypto_getRSAPrivateKeyWrapper(JNIEnv* env, jclass, jobject j conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate RSA key"); return 0; } -#else - bssl::UniquePtr rsa(RSA_new_method(g_engine)); - if (rsa == nullptr) { - conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate RSA key"); - return 0; - } - - // The PSS padding code needs access to the actual n, so set it even though we - // don't set any other parts of the key - if (!arrayToBignum(env, modulusBytes, &rsa->n)) { - return 0; - } -#endif auto ex_data = new KeyExData; ex_data->private_key = env->NewGlobalRef(javaKey); @@ -5788,12 +5706,9 @@ static jobject GENERAL_NAME_to_jobject(JNIEnv* env, GENERAL_NAME* gen) { /* Write in RFC 2253 format */ return X509_NAME_to_jstring(env, gen->d.directoryName, XN_FLAG_RFC2253); case GEN_IPADD: { -#ifdef _WIN32 - void* ip = reinterpret_cast(gen->d.ip->data); -#else - const void* ip = reinterpret_cast(gen->d.ip->data); -#endif - if (gen->d.ip->length == 4) { + const uint8_t* ip = ASN1_STRING_get0_data(gen->d.ip); + int ip_len = ASN1_STRING_length(gen->d.ip); + if (ip_len == 4) { // IPv4 std::unique_ptr buffer(new char[INET_ADDRSTRLEN]); if (inet_ntop(AF_INET, ip, buffer.get(), INET_ADDRSTRLEN) != nullptr) { @@ -5803,7 +5718,7 @@ static jobject GENERAL_NAME_to_jobject(JNIEnv* env, GENERAL_NAME* gen) { JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 failed %s", gen, strerror(errno)); } - } else if (gen->d.ip->length == 16) { + } else if (ip_len == 16) { // IPv6 std::unique_ptr buffer(new char[INET6_ADDRSTRLEN]); if (inet_ntop(AF_INET6, ip, buffer.get(), INET6_ADDRSTRLEN) != nullptr) { diff --git a/common/src/main/java/org/conscrypt/OpenSslSlhDsaKeyFactory.java b/common/src/main/java/org/conscrypt/OpenSslSlhDsaKeyFactory.java index 6cd9a6723..af498c8f1 100644 --- a/common/src/main/java/org/conscrypt/OpenSslSlhDsaKeyFactory.java +++ b/common/src/main/java/org/conscrypt/OpenSslSlhDsaKeyFactory.java @@ -26,22 +26,78 @@ import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; /** An implementation of a {@link KeyFactorySpi} for SLH-DSL keys based on BoringSSL. */ @Internal public final class OpenSslSlhDsaKeyFactory extends KeyFactorySpi { + // X.509 format preamble for SLH-DSA-SHA2-128S. + static final byte[] x509Preamble = new byte[] { + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x09, + (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x65, (byte) 0x03, + (byte) 0x04, (byte) 0x03, (byte) 0x14, (byte) 0x03, (byte) 0x21, (byte) 0x00}; + + // PKCS#8 format preamble for SLH-DSA-SHA2-128S. + static final byte[] pkcs8Preamble = + new byte[] {(byte) 0x30, (byte) 0x52, (byte) 0x02, (byte) 0x01, (byte) 0x00, + (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x09, (byte) 0x60, + (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x65, (byte) 0x03, + (byte) 0x04, (byte) 0x03, (byte) 0x14, (byte) 0x04, (byte) 0x40}; + public OpenSslSlhDsaKeyFactory() {} + private OpenSslSlhDsaPublicKey makePublicKeyFromRaw(byte[] raw) throws InvalidKeySpecException { + if (raw.length != OpenSslSlhDsaPublicKey.PUBLIC_KEY_SIZE_BYTES) { + throw new InvalidKeySpecException("Invalid raw public key length: " + raw.length + + " != " + + OpenSslSlhDsaPublicKey.PUBLIC_KEY_SIZE_BYTES); + } + try { + return new OpenSslSlhDsaPublicKey(raw); + } catch (IllegalArgumentException e) { + throw new InvalidKeySpecException("Invalid raw public key", e); + } + } + @Override protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { if (keySpec == null) { throw new InvalidKeySpecException("keySpec == null"); } - if (keySpec instanceof EncodedKeySpec) { - return new OpenSslSlhDsaPublicKey((EncodedKeySpec) keySpec); + if (!(keySpec instanceof EncodedKeySpec)) { + throw new InvalidKeySpecException("Currently only EncodedKeySpec is supported; was " + + keySpec.getClass().getName()); + } + EncodedKeySpec encodedKeySpec = (EncodedKeySpec) keySpec; + if ("raw".equalsIgnoreCase(encodedKeySpec.getFormat())) { + byte[] raw = encodedKeySpec.getEncoded(); + return makePublicKeyFromRaw(raw); + } + if (!encodedKeySpec.getFormat().equals("X.509")) { + throw new InvalidKeySpecException("Encoding must be in X.509 format"); + } + byte[] encoded = encodedKeySpec.getEncoded(); + if (ArrayUtils.startsWith(encoded, x509Preamble)) { + byte[] raw = Arrays.copyOfRange(encoded, x509Preamble.length, encoded.length); + return makePublicKeyFromRaw(raw); + } else { + throw new InvalidKeySpecException( + "Only X.509 format for SLH-DSA-SHA2-128S is supported"); + } + } + + private OpenSslSlhDsaPrivateKey makePrivateKeyFromRaw(byte[] raw) + throws InvalidKeySpecException { + if (raw.length != OpenSslSlhDsaPrivateKey.PRIVATE_KEY_SIZE_BYTES) { + throw new InvalidKeySpecException("Invalid raw private key length: " + raw.length + + " != " + + OpenSslSlhDsaPrivateKey.PRIVATE_KEY_SIZE_BYTES); + } + try { + return new OpenSslSlhDsaPrivateKey(raw); + } catch (IllegalArgumentException e) { + throw new InvalidKeySpecException("Invalid raw private key", e); } - throw new InvalidKeySpecException("Currently only EncodedKeySpec is supported; was " - + keySpec.getClass().getName()); } @Override @@ -49,11 +105,26 @@ protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpe if (keySpec == null) { throw new InvalidKeySpecException("keySpec == null"); } - if (keySpec instanceof EncodedKeySpec) { - return new OpenSslSlhDsaPrivateKey((EncodedKeySpec) keySpec); + if (!(keySpec instanceof EncodedKeySpec)) { + throw new InvalidKeySpecException("Currently only EncodedKeySpec is supported; was " + + keySpec.getClass().getName()); + } + EncodedKeySpec encodedKeySpec = (EncodedKeySpec) keySpec; + if ("raw".equalsIgnoreCase(encodedKeySpec.getFormat())) { + byte[] raw = encodedKeySpec.getEncoded(); + return makePrivateKeyFromRaw(raw); + } + if (!encodedKeySpec.getFormat().equals("PKCS#8")) { + throw new InvalidKeySpecException("Encoding must be in PKCS#8 format"); + } + byte[] encoded = encodedKeySpec.getEncoded(); + if (ArrayUtils.startsWith(encoded, pkcs8Preamble)) { + byte[] raw = Arrays.copyOfRange(encoded, pkcs8Preamble.length, encoded.length); + return makePrivateKeyFromRaw(raw); + } else { + throw new InvalidKeySpecException( + "Only PKCS#8 format for SLH-DSA-SHA2-128S is supported"); } - throw new InvalidKeySpecException("Currently only EncodedKeySpec is supported; was " - + keySpec.getClass().getName()); } @Override @@ -68,16 +139,18 @@ protected T engineGetKeySpec(Key key, Class keySpec) if (key instanceof OpenSslSlhDsaPublicKey) { OpenSslSlhDsaPublicKey conscryptKey = (OpenSslSlhDsaPublicKey) key; if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { - throw new UnsupportedOperationException( - "X509EncodedKeySpec is currently not supported"); + @SuppressWarnings("unchecked") + T result = (T) new X509EncodedKeySpec(key.getEncoded()); + return result; } else if (EncodedKeySpec.class.isAssignableFrom(keySpec)) { return KeySpecUtil.makeRawKeySpec(conscryptKey.getRaw(), keySpec); } } else if (key instanceof OpenSslSlhDsaPrivateKey) { OpenSslSlhDsaPrivateKey conscryptKey = (OpenSslSlhDsaPrivateKey) key; if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { - throw new UnsupportedOperationException( - "PKCS8EncodedKeySpec is currently not supported"); + @SuppressWarnings("unchecked") + T result = (T) new PKCS8EncodedKeySpec(key.getEncoded()); + return result; } else if (EncodedKeySpec.class.isAssignableFrom(keySpec)) { return KeySpecUtil.makeRawKeySpec(conscryptKey.getRaw(), keySpec); } @@ -95,7 +168,22 @@ protected Key engineTranslateKey(Key key) throws InvalidKeyException { if ((key instanceof OpenSslSlhDsaPublicKey) || (key instanceof OpenSslSlhDsaPrivateKey)) { return key; } - throw new InvalidKeyException( - "Key must be OpenSslSlhDsaPublicKey or OpenSslSlhDsaPrivateKey"); + if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")) { + byte[] encoded = key.getEncoded(); + try { + return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded)); + } catch (InvalidKeySpecException e) { + throw new InvalidKeyException(e); + } + } else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")) { + byte[] encoded = key.getEncoded(); + try { + return engineGeneratePublic(new X509EncodedKeySpec(encoded)); + } catch (InvalidKeySpecException e) { + throw new InvalidKeyException(e); + } + } else { + throw new InvalidKeyException("Unable to translate key into SLH-DSA key"); + } } } diff --git a/common/src/main/java/org/conscrypt/OpenSslSlhDsaPrivateKey.java b/common/src/main/java/org/conscrypt/OpenSslSlhDsaPrivateKey.java index 5a8d759a8..a465ae5e0 100644 --- a/common/src/main/java/org/conscrypt/OpenSslSlhDsaPrivateKey.java +++ b/common/src/main/java/org/conscrypt/OpenSslSlhDsaPrivateKey.java @@ -20,8 +20,6 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.PrivateKey; -import java.security.spec.EncodedKeySpec; -import java.security.spec.InvalidKeySpecException; import java.util.Arrays; /** A SLH-DSA private key. */ @@ -32,18 +30,6 @@ public class OpenSslSlhDsaPrivateKey implements PrivateKey { private byte[] raw; - public OpenSslSlhDsaPrivateKey(EncodedKeySpec keySpec) throws InvalidKeySpecException { - byte[] encoded = keySpec.getEncoded(); - if ("raw".equalsIgnoreCase(keySpec.getFormat())) { - if (encoded.length != PRIVATE_KEY_SIZE_BYTES) { - throw new InvalidKeySpecException("Invalid key size"); - } - raw = encoded; - } else { - throw new InvalidKeySpecException("Encoding must be in raw format"); - } - } - public OpenSslSlhDsaPrivateKey(byte[] raw) { if (raw.length != PRIVATE_KEY_SIZE_BYTES) { throw new IllegalArgumentException("Invalid key size"); @@ -58,12 +44,12 @@ public String getAlgorithm() { @Override public String getFormat() { - throw new UnsupportedOperationException("getFormat() not yet supported"); + return "PKCS#8"; } @Override public byte[] getEncoded() { - throw new UnsupportedOperationException("getEncoded() not yet supported"); + return ArrayUtils.concat(OpenSslSlhDsaKeyFactory.pkcs8Preamble, raw); } byte[] getRaw() { diff --git a/common/src/main/java/org/conscrypt/OpenSslSlhDsaPublicKey.java b/common/src/main/java/org/conscrypt/OpenSslSlhDsaPublicKey.java index fb9f75d6c..b7bb74d4d 100644 --- a/common/src/main/java/org/conscrypt/OpenSslSlhDsaPublicKey.java +++ b/common/src/main/java/org/conscrypt/OpenSslSlhDsaPublicKey.java @@ -20,8 +20,6 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.PublicKey; -import java.security.spec.EncodedKeySpec; -import java.security.spec.InvalidKeySpecException; import java.util.Arrays; /** An SLH-DSA public key. */ @@ -32,18 +30,6 @@ public class OpenSslSlhDsaPublicKey implements PublicKey { private final byte[] raw; - public OpenSslSlhDsaPublicKey(EncodedKeySpec keySpec) throws InvalidKeySpecException { - byte[] encoded = keySpec.getEncoded(); - if ("raw".equalsIgnoreCase(keySpec.getFormat())) { - if (encoded.length != PUBLIC_KEY_SIZE_BYTES) { - throw new InvalidKeySpecException("Invalid key size"); - } - raw = encoded; - } else { - throw new InvalidKeySpecException("Encoding must be in raw format"); - } - } - public OpenSslSlhDsaPublicKey(byte[] raw) { if (raw.length != PUBLIC_KEY_SIZE_BYTES) { throw new IllegalArgumentException("Invalid key size"); @@ -58,12 +44,12 @@ public String getAlgorithm() { @Override public String getFormat() { - throw new UnsupportedOperationException("getFormat() not yet supported"); + return "X.509"; } @Override public byte[] getEncoded() { - throw new UnsupportedOperationException("getEncoded() not yet supported"); + return ArrayUtils.concat(OpenSslSlhDsaKeyFactory.x509Preamble, raw); } byte[] getRaw() { diff --git a/common/src/test/java/org/conscrypt/SlhDsaTest.java b/common/src/test/java/org/conscrypt/SlhDsaTest.java index ecc6982c5..664a13c0b 100644 --- a/common/src/test/java/org/conscrypt/SlhDsaTest.java +++ b/common/src/test/java/org/conscrypt/SlhDsaTest.java @@ -16,6 +16,9 @@ package org.conscrypt; +import static org.conscrypt.TestUtils.decodeBase64; +import static org.conscrypt.TestUtils.decodeHex; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -175,18 +178,133 @@ public void fromRawPublicKey_checksSize() throws Exception { () -> keyFactory.generatePublic(new RawKeySpec(new byte[33]))); } + /** Helper class to test KeyFactory.translateKey. */ + private static class TestPublicKey implements PublicKey { + TestPublicKey(byte[] x509Encoded) { + this.x509Encoded = x509Encoded; + } + + private final byte[] x509Encoded; + + @Override + public String getAlgorithm() { + return "SLH-DSA-SHA2-128S"; + } + + @Override + public String getFormat() { + return "X.509"; + } + + @Override + public byte[] getEncoded() { + return x509Encoded; + } + } + + /** Helper class to test KeyFactory.translateKey. */ + private static class TestPrivateKey implements PrivateKey { + TestPrivateKey(byte[] pkcs8Encoded) { + this.pkcs8Encoded = pkcs8Encoded; + } + + private final byte[] pkcs8Encoded; + + @Override + public String getAlgorithm() { + return "SLH-DSA-SHA2-128S"; + } + + @Override + public String getFormat() { + return "PKCS#8"; + } + + @Override + public byte[] getEncoded() { + return pkcs8Encoded; + } + } + @Test - public void x509AndPkcs8_areNotSupported() throws Exception { + public void x509AndPkcs8_works() throws Exception { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("SLH-DSA-SHA2-128S", conscryptProvider); KeyPair keyPair = keyGen.generateKeyPair(); + assertEquals("PKCS#8", keyPair.getPrivate().getFormat()); + // 64 bytes for the raw key + 20 bytes for the preamble. + assertEquals(84, keyPair.getPrivate().getEncoded().length); + + assertEquals("X.509", keyPair.getPublic().getFormat()); + // 32 bytes for the raw key + 18 bytes for the preamble. + assertEquals(50, keyPair.getPublic().getEncoded().length); + KeyFactory keyFactory = KeyFactory.getInstance("SLH-DSA-SHA2-128S", conscryptProvider); - assertThrows(UnsupportedOperationException.class, - () -> keyFactory.getKeySpec(keyPair.getPrivate(), PKCS8EncodedKeySpec.class)); - assertThrows(UnsupportedOperationException.class, - () -> keyFactory.getKeySpec(keyPair.getPublic(), X509EncodedKeySpec.class)); + PKCS8EncodedKeySpec privateKeySpec = + keyFactory.getKeySpec(keyPair.getPrivate(), PKCS8EncodedKeySpec.class); + assertEquals("PKCS#8", privateKeySpec.getFormat()); + assertArrayEquals(keyPair.getPrivate().getEncoded(), privateKeySpec.getEncoded()); + + X509EncodedKeySpec publicKeySpec = + keyFactory.getKeySpec(keyPair.getPublic(), X509EncodedKeySpec.class); + assertEquals("X.509", publicKeySpec.getFormat()); + assertArrayEquals(keyPair.getPublic().getEncoded(), publicKeySpec.getEncoded()); + + PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); + PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); + + assertEquals(keyPair.getPrivate(), privateKey); + assertEquals(keyPair.getPublic(), publicKey); + + assertEquals(keyPair.getPrivate(), keyFactory.translateKey(keyPair.getPrivate())); + assertEquals( + keyPair.getPrivate(), + keyFactory.translateKey(new TestPrivateKey(keyPair.getPrivate().getEncoded()))); + assertEquals(keyPair.getPublic(), keyFactory.translateKey(keyPair.getPublic())); + assertEquals(keyPair.getPublic(), + keyFactory.translateKey(new TestPublicKey(keyPair.getPublic().getEncoded()))); + } + + @Test + public void testVectorsFromRfc9909_works() throws Exception { + // Taken from RFC 9909, Section C.1 and C.2. + String pkcs8EncodedPrivateKeyBase64 = + "MFICAQAwCwYJYIZIAWUDBAMUBECiJjvKRYYINlIxYASVI9YhZ3+tkNUetgZ6Mn4N" + + "HmSlASuBCex3fKpOHwJMz8+Ul9mRgFCSgPQlavKwevgCibSU"; + byte[] pkcs8EncodedPrivateKey = decodeBase64(pkcs8EncodedPrivateKeyBase64); + + String x509EncodedPublicKeyBase64 = + "MDAwCwYJYIZIAWUDBAMUAyEAK4EJ7Hd8qk4fAkzPz5SX2ZGAUJKA9CVq8rB6+AKJ" + + "tJQ="; + byte[] x509EncodedPublicKey = decodeBase64(x509EncodedPublicKeyBase64); + + byte[] rawPublicKey = decodeHex("2B8109EC777CAA4E1F024CCFCF9497D9" + + "9180509280F4256AF2B07AF80289B494"); + + byte[] rawPrivateKey = decodeHex("A2263BCA45860836523160049523D621" + + "677FAD90D51EB6067A327E0D1E64A501" + + "2B8109EC777CAA4E1F024CCFCF9497D9" + + "9180509280F4256AF2B07AF80289B494"); + + KeyFactory keyFactory = KeyFactory.getInstance("SLH-DSA-SHA2-128S", conscryptProvider); + + PrivateKey privateKey = + keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedPrivateKey)); + PublicKey publicKey = + keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedPublicKey)); + + assertEquals("PKCS#8", privateKey.getFormat()); + assertArrayEquals(pkcs8EncodedPrivateKey, privateKey.getEncoded()); + assertEquals("X.509", publicKey.getFormat()); + assertArrayEquals(x509EncodedPublicKey, publicKey.getEncoded()); + + EncodedKeySpec rawPrivateKeySpec = keyFactory.getKeySpec(privateKey, RawKeySpec.class); + assertArrayEquals(rawPrivateKey, rawPrivateKeySpec.getEncoded()); + + EncodedKeySpec rawPublicKeySpec = keyFactory.getKeySpec(publicKey, RawKeySpec.class); + assertArrayEquals(rawPublicKey, rawPublicKeySpec.getEncoded()); } @Test diff --git a/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java b/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java index e6eb3d4cd..7bf176643 100644 --- a/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java +++ b/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java @@ -38,7 +38,6 @@ import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; -import java.security.Security; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; @@ -327,7 +326,7 @@ private void test_KeyWithAllKeyFactories(Key k) throws Exception { byte[] encoded = k.getEncoded(); String keyAlgo = k.getAlgorithm(); - for (Provider p : Security.getProviders()) { + for (Provider p : ServiceTester.getProviders()) { Set services = p.getServices(); for (Provider.Service service : services) { if (!"KeyFactory".equals(service.getType())) { diff --git a/common/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java b/common/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java index 881912e7b..910d597bf 100644 --- a/common/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java +++ b/common/src/test/java/org/conscrypt/java/security/cert/CertificateFactoryTest.java @@ -17,7 +17,6 @@ package org.conscrypt.java.security.cert; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -52,7 +51,6 @@ import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; -import java.security.Security; import java.security.cert.CRL; import java.security.cert.CRLException; import java.security.cert.CertPath; @@ -654,7 +652,7 @@ public void testGenerateCertPath() throws Exception { List duplicatedCerts = new ArrayList<>(certs); duplicatedCerts.add(cert2.certificate); - Provider[] providers = Security.getProviders("CertificateFactory.X509"); + Provider[] providers = ServiceTester.getProviders("CertificateFactory.X509"); for (Provider p : providers) { final CertificateFactory cf = CertificateFactory.getInstance("X.509", p); diff --git a/common/src/test/java/org/conscrypt/javax/crypto/CipherBasicsTest.java b/common/src/test/java/org/conscrypt/javax/crypto/CipherBasicsTest.java index 1aa8d375f..b8e72fcb6 100644 --- a/common/src/test/java/org/conscrypt/javax/crypto/CipherBasicsTest.java +++ b/common/src/test/java/org/conscrypt/javax/crypto/CipherBasicsTest.java @@ -34,7 +34,6 @@ import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.Provider; -import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import java.util.HashMap; @@ -45,6 +44,7 @@ import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import tests.util.ServiceTester; /** * Test for basic compliance for ciphers. This test uses reference vectors produced by @@ -201,7 +201,7 @@ private byte[] callCipher(Cipher cipher, byte[] input, int expectedOutputLength, @Test public void testBasicEncryption() throws Exception { - for (Provider p : Security.getProviders()) { + for (Provider p : ServiceTester.getProviders()) { for (Map.Entry entry : BASIC_CIPHER_TO_TEST_DATA.entrySet()) { String transformation = entry.getKey(); @@ -362,7 +362,7 @@ public void arrayBasedAssessment(Cipher cipher, byte[] aad, byte[] tag, byte[] p @Test public void testAeadEncryption() throws Exception { TestUtils.assumeAEADAvailable(); - for (Provider p : Security.getProviders()) { + for (Provider p : ServiceTester.getProviders()) { for (Map.Entry entry : AEAD_CIPHER_TO_TEST_DATA.entrySet()) { String transformation = entry.getKey(); diff --git a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java index cb2cc3bc9..78b5e8779 100644 --- a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java +++ b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java @@ -55,7 +55,6 @@ import java.security.Security; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; @@ -84,6 +83,7 @@ import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.PSource; import javax.crypto.spec.SecretKeySpec; +import tests.util.ServiceTester; @RunWith(JUnit4.class) public final class CipherTest { @@ -1032,7 +1032,7 @@ public void test_getInstance() throws Exception { Set seenBaseCipherNames = new HashSet<>(); Set seenCiphersWithModeAndPadding = new HashSet<>(); - Provider[] providers = Security.getProviders(); + Provider[] providers = ServiceTester.getProviders(); for (Provider provider : providers) { Set services = provider.getServices(); for (Provider.Service service : services) { @@ -3822,14 +3822,14 @@ private void testCipher_Success_ForAllSupportingProviders_AtLeastOneProviderRequ for (CipherTestParam testVector : testVectors) { ArrayList providers = new ArrayList<>(); - Provider[] providerArray = Security.getProviders("Cipher." + testVector.transformation); + Provider[] providerArray = ServiceTester.getProviders("Cipher." + testVector.transformation); if (providerArray != null) { Collections.addAll(providers, providerArray); } if (testVector.transformation.indexOf('/') > 0) { Provider[] baseTransformProviderArray = - Security.getProviders("Cipher." + ServiceTester.getProviders("Cipher." + testVector.transformation.substring( 0, testVector.transformation.indexOf('/'))); if (baseTransformProviderArray != null) { @@ -4588,7 +4588,8 @@ public void testRC4_MultipleKeySizes() throws Exception { /* Find all providers that provide ARC4. We must have at least one! */ Map filter = new HashMap<>(); filter.put("Cipher.ARC4", ""); - Provider[] providers = Security.getProviders(filter); + //? + Provider[] providers = ServiceTester.getProviders(filter); assertTrue("There must be security providers of Cipher.ARC4", providers.length > 0); /* Keep track of this for later error messages */ @@ -4632,7 +4633,7 @@ public void testRC4_MultipleKeySizes() throws Exception { @Test public void testAES_keyConstrained() throws Exception { - Provider[] providers = Security.getProviders(); + Provider[] providers = ServiceTester.getProviders(); for (Provider p : providers) { if (isBuggyProvider(p.getName())) { continue; diff --git a/common/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java b/common/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java index c41162cf7..dacec62aa 100644 --- a/common/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java +++ b/common/src/test/java/org/conscrypt/javax/crypto/ECDHKeyAgreementTest.java @@ -44,7 +44,6 @@ import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; -import java.security.Security; import java.security.interfaces.ECKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; @@ -59,6 +58,7 @@ import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; +import tests.util.ServiceTester; /** * Tests for all registered Elliptic Curve Diffie-Hellman {@link KeyAgreement} providers. @@ -459,7 +459,7 @@ private void invokeCallingMethodForEachKeyAgreementProvider() throws Exception { } private static Provider[] getKeyAgreementProviders() { - Provider[] providers = Security.getProviders("KeyAgreement.ECDH"); + Provider[] providers = ServiceTester.getProviders("KeyAgreement.ECDH"); if (providers == null) { return new Provider[0]; } @@ -469,7 +469,7 @@ private static Provider[] getKeyAgreementProviders() { } private static Provider[] getKeyFactoryProviders() { - Provider[] providers = Security.getProviders("KeyFactory.EC"); + Provider[] providers = ServiceTester.getProviders("KeyFactory.EC"); if (providers == null) { return new Provider[0]; } diff --git a/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java b/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java index 96e536f7e..c9d8c604b 100644 --- a/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java +++ b/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java @@ -10,11 +10,11 @@ import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; -import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; +import tests.util.ServiceTester; /** * Tests for all registered X25519 and X448 {@link KeyAgreement} providers. @@ -95,7 +95,7 @@ private void setupKeys(Provider p) throws Exception { @Test public void test_XDHKeyAgreement() throws Exception { final String keyAgreementAlgorithm = String.format("KeyAgreement.%s", getAlgorithm()); - for (Provider p : Security.getProviders(keyAgreementAlgorithm)) { + for (Provider p : ServiceTester.getProviders(keyAgreementAlgorithm)) { // Skip testing Android Keystore as it's covered by CTS tests. if ("AndroidKeyStore".equals(p.getName())) { continue; diff --git a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java index 05f1f0afb..48e3d7e90 100644 --- a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java +++ b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLContextTest.java @@ -16,7 +16,6 @@ package org.conscrypt.javax.net.ssl; -import static org.conscrypt.TestUtils.isTlsV1Supported; import static org.conscrypt.TestUtils.isWindows; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -71,6 +70,7 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactorySpi; import javax.net.ssl.X509KeyManager; +import tests.util.ServiceTester; @RunWith(JUnit4.class) public class SSLContextTest { @@ -319,7 +319,7 @@ public void test_SSLContext_getProtocol() throws Exception { public void test_SSLContext_getProvider() throws Exception { Provider provider = SSLContext.getDefault().getProvider(); assertNotNull(provider); - assertEquals(StandardNames.JSSE_PROVIDER_NAME, provider.getName()); + assertEquals("OpenSSLProvider", provider.getClass().getSimpleName()); } @Test @@ -672,7 +672,7 @@ public void test_SSLContext_SSLv3Unsupported() throws Exception { // Find the default provider for TLS and verify that it does NOT support SSLv3. Provider defaultTlsProvider = null; for (String protocol : new String[] {"SSLContext.TLSv1.2", "SSLContext.TLSv1"}) { - for (Provider p : Security.getProviders()) { + for (Provider p : ServiceTester.getProviders()) { if (p.get(protocol) != null) { defaultTlsProvider = p; break; diff --git a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java index 3787545d6..5c20475e2 100644 --- a/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java +++ b/common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java @@ -94,6 +94,8 @@ public class SSLSocketTest { private final ExecutorService executor = Executors.newCachedThreadPool(t -> new Thread(threadGroup, t)); + private static final TestSSLContext testSslContext = TestSSLContext.create(); + String getCurveName(SSLSocket socket) { return ((OpenSSLSocketImpl) socket).getCurveNameForTesting(); } @@ -146,12 +148,12 @@ public void teardown() throws InterruptedException { @Test public void test_SSLSocket_defaultConfiguration() throws Exception { SSLConfigurationAsserts.assertSSLSocketDefaultConfiguration( - (SSLSocket) SSLSocketFactory.getDefault().createSocket()); + (SSLSocket) testSslContext.clientContext.getSocketFactory().createSocket()); } @Test public void test_SSLSocket_getSupportedCipherSuites_returnsCopies() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { assertNotSame(ssl.getSupportedCipherSuites(), ssl.getSupportedCipherSuites()); } @@ -303,7 +305,7 @@ public void test_SSLSocket_InputStream_read() throws Exception { @Test public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { assertNotSame(ssl.getEnabledCipherSuites(), ssl.getEnabledCipherSuites()); } @@ -311,7 +313,7 @@ public void test_SSLSocket_getEnabledCipherSuites_returnsCopies() throws Excepti @Test public void test_SSLSocket_setEnabledCipherSuites_storesCopy() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { String[] array = new String[] {ssl.getEnabledCipherSuites()[0]}; String originalFirstElement = array[0]; @@ -370,7 +372,7 @@ public void test_SSLSocket_setEnabledCipherSuites_TLS13() throws Exception { @Test public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { assertNotSame(ssl.getSupportedProtocols(), ssl.getSupportedProtocols()); } @@ -378,7 +380,7 @@ public void test_SSLSocket_getSupportedProtocols_returnsCopies() throws Exceptio @Test public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { assertNotSame(ssl.getEnabledProtocols(), ssl.getEnabledProtocols()); } @@ -386,7 +388,7 @@ public void test_SSLSocket_getEnabledProtocols_returnsCopies() throws Exception @Test public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { String[] array = new String[] {ssl.getEnabledProtocols()[0]}; String originalFirstElement = array[0]; @@ -398,7 +400,7 @@ public void test_SSLSocket_setEnabledProtocols_storesCopy() throws Exception { @Test public void test_SSLSocket_setEnabledProtocols() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { assertThrows(IllegalArgumentException.class, () -> ssl.setEnabledProtocols(null)); assertThrows(IllegalArgumentException.class, @@ -488,7 +490,7 @@ public void test_SSLSocket_noncontiguousProtocols_canNegotiate() throws Exceptio @Test public void test_SSLSocket_getSession() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLSession session = ssl.getSession(); assertNotNull(session); @@ -498,7 +500,7 @@ public void test_SSLSocket_getSession() throws Exception { @Test public void test_SSLSocket_getHandshakeSession_unconnected() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket socket = (SSLSocket) sf.createSocket()) { SSLSession session = socket.getHandshakeSession(); assertNull(session); @@ -747,7 +749,7 @@ public void test_SSLSocket_untrustedServer() throws Exception { @Test public void test_SSLSocket_getSSLParameters() throws Exception { TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable(); - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLParameters p = ssl.getSSLParameters(); assertNotNull(p); @@ -771,7 +773,7 @@ public void test_SSLSocket_getSSLParameters() throws Exception { @Test public void test_SSLSocket_setSSLParameters() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { String[] defaultCipherSuites = ssl.getEnabledCipherSuites(); String[] defaultProtocols = ssl.getEnabledProtocols(); @@ -819,7 +821,7 @@ public void test_SSLSocket_setSSLParameters() throws Exception { @Test public void setAndGetSSLParameters_alwaysSupportsDefaultCipherSuites() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLParameters inputParameters = new SSLParameters( new String[] {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"}, @@ -839,7 +841,7 @@ public void setAndGetSSLParameters_alwaysSupportsDefaultCipherSuites() throws Ex @Test public void setSSLParameters_invalidCipherSuite_throwsIllegalArgumentException() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLParameters parameters = new SSLParameters(new String[] {"invalid"}, new String[] {"TLSv1.3"}); @@ -858,7 +860,7 @@ boolean sslParametersSupportsNamedGroups() throws SecurityException { @Test public void setAndGetSSLParameters_withSetNamedGroups_worksIfSupported() throws Exception { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLParameters parameters = new SSLParameters(new String[] {"TLS_AES_128_GCM_SHA256"}, new String[] {"TLSv1.3"}); @@ -881,7 +883,7 @@ public void test_SSLSocket_setSoTimeout_basic() throws Exception { try (ServerSocket listening = new ServerSocket(0)) { Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort()); assertEquals(0, underlying.getSoTimeout()); - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); Socket wrapping = sf.createSocket(underlying, null, -1, false); assertEquals(0, wrapping.getSoTimeout()); // setting wrapper sets underlying and ... @@ -905,7 +907,7 @@ public void test_SSLSocket_setSoTimeout_wrapper() throws Exception { // setSoTimeout applies to read, not connect, so connect first Socket underlying = new Socket(listening.getInetAddress(), listening.getLocalPort()); Socket server = listening.accept(); - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = testSslContext.clientContext.getSocketFactory(); Socket clientWrapping = sf.createSocket(underlying, null, -1, false); underlying.setSoTimeout(1); assertThrows(SocketTimeoutException.class, () -> clientWrapping.getInputStream().read()); @@ -1348,7 +1350,7 @@ public void test_SSLSocket_ClientHello_compressionMethods() throws Exception { private List> getSSLSocketFactoriesToTest() throws NoSuchAlgorithmException, KeyManagementException { List> result = new ArrayList<>(); - result.add(Pair.of("default", (SSLSocketFactory) SSLSocketFactory.getDefault())); + result.add(Pair.of("default", testSslContext.clientContext.getSocketFactory())); for (String sslContextProtocol : StandardNames.SSL_CONTEXT_PROTOCOLS_WITH_DEFAULT_CONFIG) { SSLContext sslContext = SSLContext.getInstance(sslContextProtocol); if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(sslContextProtocol)) { @@ -1472,7 +1474,7 @@ public void test_SSLSocket_tlsFallback_byVersion() throws Exception { SSLContext.getDefault().getDefaultSSLParameters().getProtocols(); for (final String protocol : supportedProtocols) { SSLSocketFactory factory = new DelegatingSSLSocketFactory( - (SSLSocketFactory) SSLSocketFactory.getDefault()) { + testSslContext.clientContext.getSocketFactory()) { @Override protected SSLSocket configureSocket(SSLSocket socket) { socket.setEnabledProtocols(new String[] {protocol}); diff --git a/testing/src/main/java/org/conscrypt/javax/net/ssl/TestSSLSessions.java b/testing/src/main/java/org/conscrypt/javax/net/ssl/TestSSLSessions.java index 74986666b..502795fea 100644 --- a/testing/src/main/java/org/conscrypt/javax/net/ssl/TestSSLSessions.java +++ b/testing/src/main/java/org/conscrypt/javax/net/ssl/TestSSLSessions.java @@ -15,9 +15,11 @@ */ package org.conscrypt.javax.net.ssl; +import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; + /** * TestSSLSessions is a convenience class for other tests that want * precreated SSLSessions for testing. It contains a connected @@ -63,7 +65,7 @@ public static TestSSLSessions create() { public static TestSSLSessions create(TestSSLContext context) { try { - SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocketFactory sf = SSLContext.getDefault().getSocketFactory(); SSLSocket ssl = (SSLSocket) sf.createSocket(); SSLSession invalid = ssl.getSession(); TestSSLSocketPair s = TestSSLSocketPair.create(context).connect(); diff --git a/testing/src/main/java/tests/util/ServiceTester.java b/testing/src/main/java/tests/util/ServiceTester.java index 69cae0f67..d5b0fb570 100644 --- a/testing/src/main/java/tests/util/ServiceTester.java +++ b/testing/src/main/java/tests/util/ServiceTester.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; /** @@ -43,6 +44,58 @@ public interface Test { void test(Provider p, String algorithm) throws Exception; } + private static Provider[] providersToTest = null; + + /** + * Sets the list of providers to be returned by {@link #getProviders()}, {@link + * #getProviders(String)}, and {@link #getProviders(Map)}. + */ + public static void setProviders(Provider[] providers) { + if (providers.length == 0) { + throw new IllegalArgumentException("providers must not be empty"); + } + providersToTest = providers.clone(); + } + + /** + * If {@link #setProviders(Provider[])} has not been called, returns the list of providers from + * {@link Security.getProviders()}. Otherwise, returns the list of providers set by {@link + * #setProviders(Provider[])}. + */ + public static Provider[] getProviders() { + if (providersToTest != null) { + return providersToTest.clone(); + } else { + return Security.getProviders(); + } + } + + /** + * If {@link #setProviders(Provider[])} has not been called, returns the list of providers from + * {@link Security.getProviders(filter)}. Otherwise, returns the list of providers set by {@link + * #setProviders(Provider[])}. + */ + public static Provider[] getProviders(String filter) { + if (providersToTest != null) { + return providersToTest.clone(); + } else { + return Security.getProviders(filter); + } + } + + /** + * If {@link #setProviders(Provider[])} has not been called, returns the list of providers from + * {@link Security.getProviders(filter)} that support the given service and algorithm. Otherwise, + * returns the list of providers set by {@link #setProviders(Provider[])}. + */ + public static Provider[] getProviders(Map filter) { + if (providersToTest != null) { + return providersToTest.clone(); + } else { + return Security.getProviders(filter); + } + } + private static final String SEPARATOR = "||"; private final String service; private final Set providers = new LinkedHashSet<>(); @@ -146,6 +199,11 @@ public ServiceTester skipCombination(String provider, String algorithm) { * an exception with the details of the failure(s). */ public void run(Test test) { + if (providersToTest != null) { + for (Provider p : providersToTest) { + providers.add(p); + } + } if (providers.isEmpty()) { providers.addAll(Arrays.asList(Security.getProviders())); }