From 8e3a02f252f43a8ce68c5002d849ec78219cbcbc Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 15 Dec 2025 09:47:16 +0000 Subject: [PATCH 01/11] Add support for SSLParameters setNamedGroups and getNamedGroups. These methods were added in Java 20, but Conscrypt didn't support them yet. --- .../src/main/java/org/conscrypt/Platform.java | 7 + .../org/conscrypt/ConscryptEngineSocket.java | 2 +- .../ConscryptFileDescriptorSocket.java | 2 +- .../main/java/org/conscrypt/NativeSsl.java | 68 +++++++ .../java/org/conscrypt/OpenSSLSocketImpl.java | 3 + .../java/org/conscrypt/SSLParametersImpl.java | 17 ++ .../javax/net/ssl/SSLSocketTest.java | 185 +++++++++++++++++- .../java/org/conscrypt/Java9PlatformUtil.java | 36 +++- 8 files changed, 311 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/org/conscrypt/Platform.java b/android/src/main/java/org/conscrypt/Platform.java index c4e447a49..83c29dd1b 100644 --- a/android/src/main/java/org/conscrypt/Platform.java +++ b/android/src/main/java/org/conscrypt/Platform.java @@ -254,6 +254,10 @@ private static void setSSLParametersOnImpl(SSLParameters params, SSLParametersIm Method m_getUseCipherSuitesOrder = params.getClass().getMethod("getUseCipherSuitesOrder"); impl.setUseCipherSuitesOrder((boolean) m_getUseCipherSuitesOrder.invoke(params)); + + Method getNamedGroupsMethod = params.getClass().getMethod("getNamedGroups"); + impl.setNamedGroups( + (String[]) getNamedGroupsMethod.invoke(params)); } public static void setSSLParameters( @@ -323,6 +327,9 @@ private static void getSSLParametersFromImpl(SSLParameters params, SSLParameters Method m_setUseCipherSuitesOrder = params.getClass().getMethod("setUseCipherSuitesOrder", boolean.class); m_setUseCipherSuitesOrder.invoke(params, impl.getUseCipherSuitesOrder()); + + Method setNamedGroupsMethod = params.getClass().getMethod("setNamedGroups", String[].class); + setNamedGroupsMethod.invoke(params, (Object[]) impl.getNamedGroups()); } public static void getSSLParameters( diff --git a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java index fdd434d7c..42f602366 100644 --- a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java +++ b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java @@ -432,7 +432,7 @@ public final void setEnabledProtocols(String[] protocols) { } @Override - final String getCurveNameForTesting() { + public String getCurveNameForTesting() { return engine.getCurveNameForTesting(); } diff --git a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java index 62f30bea1..af0a34323 100644 --- a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java +++ b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java @@ -761,7 +761,7 @@ public final void setEnabledProtocols(String[] protocols) { } @Override - final String getCurveNameForTesting() { + public String getCurveNameForTesting() { return ssl.getCurveNameForTesting(); } diff --git a/common/src/main/java/org/conscrypt/NativeSsl.java b/common/src/main/java/org/conscrypt/NativeSsl.java index 762314d5a..8fef37061 100644 --- a/common/src/main/java/org/conscrypt/NativeSsl.java +++ b/common/src/main/java/org/conscrypt/NativeSsl.java @@ -277,6 +277,61 @@ String getRequestedServerName() { byte[] getTlsChannelId() throws SSLException { return NativeCrypto.SSL_get_tls_channel_id(ssl, this); } + + + // Converts a Java "named group" to the corresponding BoringSSL curve name. + private static int toBoringSslCurve(String javaNamedGroup) { + if (javaNamedGroup.equals("X25519") || javaNamedGroup.equals("x25519")) { + return NativeConstants.NID_X25519; + } + if (javaNamedGroup.equals("P-256") || javaNamedGroup.equals("secp256r1")) { + return NativeConstants.NID_X9_62_prime256v1; + } + if (javaNamedGroup.equals("P-384") || javaNamedGroup.equals("secp384r1")) { + return NativeConstants.NID_secp384r1; + } + if (javaNamedGroup.equals("P-521") || javaNamedGroup.equals("secp521r1")) { + return NativeConstants.NID_secp521r1; + } + if (javaNamedGroup.equals("X25519MLKEM768")) { + return NativeConstants.NID_X25519MLKEM768; + } + if (javaNamedGroup.equals("X25519Kyber768Draft00")) { + return NativeConstants.NID_X25519Kyber768Draft00; + } + if (javaNamedGroup.equals("MLKEM1024")) { + return NativeConstants.NID_ML_KEM_1024; + } + return -1; // Unknown curve. + } + + // Default curves to use if namedGroups is null. + // Same curves as StandardNames.ELLIPTIC_CURVES_DEFAULT + private static final int[] DEFAULT_GROUPS = + new int[] { + NativeConstants.NID_X25519, + NativeConstants.NID_X9_62_prime256v1, + NativeConstants.NID_secp384r1 + }; + + /** + * Converts a list of java named groups to an array of groups that can be passed to BoringSSL. + * + *

Unknown curves are ignored. + */ + public static int[] toBoringSslGroups(String[] javaNamedGroups) { + int[] outputGroups = new int[javaNamedGroups.length]; + int i = 0; + for (String javaNamedGroup : javaNamedGroups) { + int group = toBoringSslCurve(javaNamedGroup); + if (group > 0) { + outputGroups[i] = group; + } + i++; + } + return outputGroups; + } + void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOException { boolean enableSessionCreation = parameters.getEnableSessionCreation(); @@ -320,6 +375,19 @@ void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOExcept ssl, this, parameters.enabledCipherSuites, parameters.enabledProtocols); } + String[] paramsNamedGroups = parameters.getNamedGroups(); + // - If the named groups are null, we use the default groups. + // - If the named groups are not null, it overrides the default groups. + // - Unknown curves are ignored. + // See: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/javax/net/ssl/SSLParameters.html#getNamedGroups() + if (paramsNamedGroups == null) { + // Use the default curves. + NativeCrypto.SSL_set1_groups(ssl, this, DEFAULT_GROUPS); + } else { + NativeCrypto.SSL_set1_groups( + ssl, this, toBoringSslGroups(paramsNamedGroups)); + } + if (parameters.applicationProtocols.length > 0) { NativeCrypto.setApplicationProtocols(ssl, this, isClient(), parameters.applicationProtocols); } diff --git a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java index 5aabdc358..2fed76c19 100644 --- a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java +++ b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java @@ -151,4 +151,7 @@ public final byte[] getAlpnSelectedProtocol() { public final void setAlpnProtocols(byte[] protocols) { setApplicationProtocols(SSLUtils.decodeProtocols(protocols == null ? EmptyArray.BYTE : protocols)); } + + @Override + public abstract String getCurveNameForTesting(); } diff --git a/common/src/main/java/org/conscrypt/SSLParametersImpl.java b/common/src/main/java/org/conscrypt/SSLParametersImpl.java index f2056f2bd..f78b8691b 100644 --- a/common/src/main/java/org/conscrypt/SSLParametersImpl.java +++ b/common/src/main/java/org/conscrypt/SSLParametersImpl.java @@ -82,6 +82,8 @@ final class SSLParametersImpl implements Cloneable { // cannot be customized, so for simplicity this field never contains any TLS 1.3 suites. String[] enabledCipherSuites; + String[] namedGroups; + // if the peer with this parameters tuned to work in client mode private boolean client_mode = true; // if the peer with this parameters tuned to require client authentication @@ -363,6 +365,21 @@ void setEnabledProtocols(String[] protocols) { enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone(); } + void setNamedGroups(String[] namedGroups) { + if (namedGroups == null) { + this.namedGroups = null; + return; + } + this.namedGroups = namedGroups.clone(); + } + + String[] getNamedGroups() { + if (namedGroups == null) { + return null; + } + return this.namedGroups.clone(); + } + /* * Sets the list of ALPN protocols. */ 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 083a10a9e..d03b676e1 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 @@ -93,6 +93,10 @@ public class SSLSocketTest { private final ExecutorService executor = Executors.newCachedThreadPool(t -> new Thread(threadGroup, t)); + String getCurveName(SSLSocket socket) { + return ((OpenSSLSocketImpl) socket).getCurveNameForTesting(); + } + /** * Returns the named groups, or null if the method is not available (older versions of * Java/Android). @@ -812,19 +816,21 @@ public void setSSLParameters_invalidCipherSuite_throwsIllegalArgumentException() } @Test - public void setAndGetSSLParameters_withSetNamedGroups_isIgnored() throws Exception { + public void setAndGetSSLParameters_withSetNamedGroups_works() throws Exception { SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLParameters parameters = new SSLParameters( new String[] {"TLS_AES_128_GCM_SHA256"}, new String[] {"TLSv1.3"}); + + assertArrayEquals(null, getNamedGroupsOrNull(ssl.getSSLParameters())); + + // values passed to setNamedGroups are not validated, any strings work. setNamedGroups(parameters, new String[] {"foo", "bar"}); ssl.setSSLParameters(parameters); SSLParameters sslParameters = ssl.getSSLParameters(); - // getNamedGroups currently returns null because setNamedGroups is not supported. - // This is allowed, see: - // https://docs.oracle.com/en/java/javase/24/docs/api/java.base/javax/net/ssl/SSLParameters.html#getNamedGroups() - assertArrayEquals(null, getNamedGroupsOrNull(sslParameters)); + + assertArrayEquals(new String[] {"foo", "bar"}, getNamedGroupsOrNull(sslParameters)); } } @@ -911,6 +917,175 @@ public void test_SSLSocket_ClientHello_cipherSuites() throws Exception { getSSLSocketFactoriesToTest()); } + @Test + public void handshake_noNamedGroups_usesX25519() throws Exception { + TestSSLContext context = TestSSLContext.create(); + final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( + context.host, context.port); + final SSLSocket server = (SSLSocket) context.serverSocket.accept(); + Future s = runAsync(() -> { + server.startHandshake(); + return null; + }); + Future c = runAsync(() -> { + client.startHandshake(); + return null; + }); + s.get(); + c.get(); + // By default, BoringSSL uses X25519, P-256, and P-384, in this order. + // So X25519 gets priority. + assertEquals("X25519", getCurveName(client)); + assertEquals("X25519", getCurveName(server)); + client.close(); + server.close(); + context.close(); + } + + @Test + public void handshake_p256IsSupportedByDefault() throws Exception { + TestSSLContext context = TestSSLContext.create(); + final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( + context.host, context.port); + final SSLSocket server = (SSLSocket) context.serverSocket.accept(); + Future s = runAsync(() -> { + server.startHandshake(); + return null; + }); + Future c = runAsync(() -> { + SSLParameters parameters = client.getSSLParameters(); + setNamedGroups(parameters, new String[] {"P-256"}); + client.setSSLParameters(parameters); + client.startHandshake(); + return null; + }); + s.get(); + c.get(); + // By default, BoringSSL uses X25519, P-256, and P-384. If the client + // requests P-256, it will be chosen. + assertEquals("P-256", getCurveName(client)); + assertEquals("P-256", getCurveName(server)); + client.close(); + server.close(); + context.close(); + } + + @Test + public void handshake_p384IsSupportedByDefault() throws Exception { + TestSSLContext context = TestSSLContext.create(); + final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( + context.host, context.port); + final SSLSocket server = (SSLSocket) context.serverSocket.accept(); + Future s = runAsync(() -> { + SSLParameters parameters = server.getSSLParameters(); + // secp384r1 is an alias for P-384. + setNamedGroups(parameters, new String[] {"secp384r1"}); + server.setSSLParameters(parameters); + server.startHandshake(); + return null; + }); + Future c = runAsync(() -> { + client.startHandshake(); + return null; + }); + s.get(); + c.get(); + // By default, BoringSSL uses X25519, P-256, and P-384. If the server only supports P-384, + // it will be chosen. + assertEquals("P-384", getCurveName(client)); + assertEquals("P-384", getCurveName(server)); + client.close(); + server.close(); + context.close(); + } + + @Test + public void handshake_setsNamedGroups_usesFirstServerNamedGroupThatClientSupports() throws Exception { + TestSSLContext context = TestSSLContext.create(); + final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( + context.host, context.port); + final SSLSocket server = (SSLSocket) context.serverSocket.accept(); + Future s = runAsync(() -> { + SSLParameters parameters = server.getSSLParameters(); + setNamedGroups(parameters, new String[] {"P-384", "X25519"}); + server.setSSLParameters(parameters); + server.startHandshake(); + return null; + }); + Future c = runAsync(() -> { + SSLParameters parameters = client.getSSLParameters(); + setNamedGroups(parameters, new String[] {"P-521", "X25519", "P-384"}); + client.setSSLParameters(parameters); + client.startHandshake(); + return null; + }); + s.get(); + c.get(); + assertEquals("P-384", getCurveName(client)); + assertEquals("P-384", getCurveName(server)); + client.close(); + server.close(); + context.close(); + } + + @Test + public void handshake_withX25519MLKEM768_works() throws Exception { + TestSSLContext context = TestSSLContext.create(); + final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( + context.host, context.port); + final SSLSocket server = (SSLSocket) context.serverSocket.accept(); + Future s = runAsync(() -> { + SSLParameters parameters = server.getSSLParameters(); + setNamedGroups(parameters, new String[] {"X25519MLKEM768"}); + server.setSSLParameters(parameters); + server.startHandshake(); + return null; + }); + Future c = runAsync(() -> { + SSLParameters parameters = client.getSSLParameters(); + setNamedGroups(parameters, new String[] {"X25519MLKEM768"}); + client.setSSLParameters(parameters); + client.startHandshake(); + return null; + }); + s.get(); + c.get(); + assertEquals("X25519MLKEM768", getCurveName(client)); + assertEquals("X25519MLKEM768", getCurveName(server)); + client.close(); + server.close(); + context.close(); + } + + @Test + public void handshake_namedGroupsDontIntersect_throwsException() throws Exception { + TestSSLContext context = TestSSLContext.create(); + final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( + context.host, context.port); + final SSLSocket server = (SSLSocket) context.serverSocket.accept(); + Future s = runAsync(() -> { + SSLParameters parameters = server.getSSLParameters(); + setNamedGroups(parameters, new String[] {"X25519", "P-384"}); + server.setSSLParameters(parameters); + server.startHandshake(); + return null; + }); + Future c = runAsync(() -> { + SSLParameters parameters = client.getSSLParameters(); + setNamedGroups(parameters, new String[] {"P-256", "P-521"}); + client.setSSLParameters(parameters); + client.startHandshake(); + return null; + }); + ExecutionException serverException = assertThrows(ExecutionException.class, s::get); + assertTrue(serverException.getCause() instanceof SSLHandshakeException); + ExecutionException clientException = assertThrows(ExecutionException.class, c::get); + assertTrue(clientException.getCause() instanceof SSLHandshakeException); + client.close(); + server.close(); + context.close(); + } + @Test public void test_SSLSocket_ClientHello_supportedCurves() throws Exception { ForEachRunner.runNamed(sslSocketFactory -> { diff --git a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java index 6e3fae650..79ee4943e 100644 --- a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java +++ b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java @@ -47,14 +47,28 @@ final class Java9PlatformUtil { static void setSSLParameters( SSLParameters src, SSLParametersImpl dest, AbstractConscryptSocket socket) { Java8PlatformUtil.setSSLParameters(src, dest, socket); - + try{ + Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); + dest.setNamedGroups( + (String[]) getNamedGroupsMethod.invoke(src)); + } catch (ReflectiveOperationException | SecurityException e) { + // Ignored. getNamedGroups was added in Java 20. + } dest.setApplicationProtocols(getApplicationProtocols(src)); } static void getSSLParameters( SSLParameters dest, SSLParametersImpl src, AbstractConscryptSocket socket) { Java8PlatformUtil.getSSLParameters(dest, src, socket); - + try{ + String[] namedGroups = src.getNamedGroups(); + Method setNamedGroupsMethod = dest.getClass().getMethod( + "setNamedGroups", String[].class); + setNamedGroupsMethod.invoke( + dest, (Object) namedGroups); + } catch (ReflectiveOperationException | SecurityException e) { + // Ignored. setNamedGroups was added in Java 20. + } setApplicationProtocols(dest, src.getApplicationProtocols()); } @@ -62,6 +76,14 @@ static void setSSLParameters( SSLParameters src, SSLParametersImpl dest, ConscryptEngine engine) { Java8PlatformUtil.setSSLParameters(src, dest, engine); + try{ + Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); + dest.setNamedGroups( + (String[]) getNamedGroupsMethod.invoke(src)); + } catch (ReflectiveOperationException | SecurityException e) { + // Ignored. getNamedGroups was added in Java 20. + } + dest.setApplicationProtocols(getApplicationProtocols(src)); } @@ -69,6 +91,16 @@ static void getSSLParameters( SSLParameters dest, SSLParametersImpl src, ConscryptEngine engine) { Java8PlatformUtil.getSSLParameters(dest, src, engine); + try{ + String[] namedGroups = src.getNamedGroups(); + Method setNamedGroupsMethod = dest.getClass().getMethod( + "setNamedGroups", String[].class); + setNamedGroupsMethod.invoke( + dest, (Object) namedGroups); + } catch (ReflectiveOperationException | SecurityException e) { + // Ignored. setNamedGroups was added in Java 20. + } + setApplicationProtocols(dest, src.getApplicationProtocols()); } From 747acab7d3d44b998774012571afd120eadb615c Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 15 Dec 2025 10:43:53 +0000 Subject: [PATCH 02/11] Fix format. --- .../src/main/java/org/conscrypt/Platform.java | 5 +-- .../main/java/org/conscrypt/NativeSsl.java | 40 ++++++++----------- .../java/org/conscrypt/OpenSSLSocketImpl.java | 5 +-- .../javax/net/ssl/SSLSocketTest.java | 3 +- .../java/org/conscrypt/Java9PlatformUtil.java | 28 ++++++------- 5 files changed, 35 insertions(+), 46 deletions(-) diff --git a/android/src/main/java/org/conscrypt/Platform.java b/android/src/main/java/org/conscrypt/Platform.java index 83c29dd1b..1bdf9ccc5 100644 --- a/android/src/main/java/org/conscrypt/Platform.java +++ b/android/src/main/java/org/conscrypt/Platform.java @@ -254,10 +254,9 @@ private static void setSSLParametersOnImpl(SSLParameters params, SSLParametersIm Method m_getUseCipherSuitesOrder = params.getClass().getMethod("getUseCipherSuitesOrder"); impl.setUseCipherSuitesOrder((boolean) m_getUseCipherSuitesOrder.invoke(params)); - + Method getNamedGroupsMethod = params.getClass().getMethod("getNamedGroups"); - impl.setNamedGroups( - (String[]) getNamedGroupsMethod.invoke(params)); + impl.setNamedGroups((String[]) getNamedGroupsMethod.invoke(params)); } public static void setSSLParameters( diff --git a/common/src/main/java/org/conscrypt/NativeSsl.java b/common/src/main/java/org/conscrypt/NativeSsl.java index 8fef37061..748cade8c 100644 --- a/common/src/main/java/org/conscrypt/NativeSsl.java +++ b/common/src/main/java/org/conscrypt/NativeSsl.java @@ -277,10 +277,9 @@ String getRequestedServerName() { byte[] getTlsChannelId() throws SSLException { return NativeCrypto.SSL_get_tls_channel_id(ssl, this); } - - // Converts a Java "named group" to the corresponding BoringSSL curve name. - private static int toBoringSslCurve(String javaNamedGroup) { + // Converts a Java "named group" to the corresponding BoringSSL group NID, or -1. + private static int toBoringSslGroupNid(String javaNamedGroup) { if (javaNamedGroup.equals("X25519") || javaNamedGroup.equals("x25519")) { return NativeConstants.NID_X25519; } @@ -302,28 +301,24 @@ private static int toBoringSslCurve(String javaNamedGroup) { if (javaNamedGroup.equals("MLKEM1024")) { return NativeConstants.NID_ML_KEM_1024; } - return -1; // Unknown curve. + return -1; // Unknown curve. } - // Default curves to use if namedGroups is null. - // Same curves as StandardNames.ELLIPTIC_CURVES_DEFAULT - private static final int[] DEFAULT_GROUPS = - new int[] { - NativeConstants.NID_X25519, - NativeConstants.NID_X9_62_prime256v1, - NativeConstants.NID_secp384r1 - }; + // Default curves to use if namedGroups is null. + // Same curves as StandardNames.ELLIPTIC_CURVES_DEFAULT + private static final int[] DEFAULT_GROUPS = new int[] {NativeConstants.NID_X25519, + NativeConstants.NID_X9_62_prime256v1, NativeConstants.NID_secp384r1}; - /** - * Converts a list of java named groups to an array of groups that can be passed to BoringSSL. - * - *

Unknown curves are ignored. - */ - public static int[] toBoringSslGroups(String[] javaNamedGroups) { + /** + * Converts a list of java named groups to an array of groups that can be passed to BoringSSL. + * + *

Unknown curves are ignored. + */ + public static int[] toBoringSslGroups(String[] javaNamedGroups) { int[] outputGroups = new int[javaNamedGroups.length]; int i = 0; for (String javaNamedGroup : javaNamedGroups) { - int group = toBoringSslCurve(javaNamedGroup); + int group = toBoringSslGroupNid(javaNamedGroup); if (group > 0) { outputGroups[i] = group; } @@ -332,7 +327,6 @@ public static int[] toBoringSslGroups(String[] javaNamedGroups) { return outputGroups; } - void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOException { boolean enableSessionCreation = parameters.getEnableSessionCreation(); if (!enableSessionCreation) { @@ -379,13 +373,13 @@ void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOExcept // - If the named groups are null, we use the default groups. // - If the named groups are not null, it overrides the default groups. // - Unknown curves are ignored. - // See: https://docs.oracle.com/en/java/javase/25/docs/api/java.base/javax/net/ssl/SSLParameters.html#getNamedGroups() + // See: + // https://docs.oracle.com/en/java/javase/25/docs/api/java.base/javax/net/ssl/SSLParameters.html#getNamedGroups() if (paramsNamedGroups == null) { // Use the default curves. NativeCrypto.SSL_set1_groups(ssl, this, DEFAULT_GROUPS); } else { - NativeCrypto.SSL_set1_groups( - ssl, this, toBoringSslGroups(paramsNamedGroups)); + NativeCrypto.SSL_set1_groups(ssl, this, toBoringSslGroups(paramsNamedGroups)); } if (parameters.applicationProtocols.length > 0) { diff --git a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java index 2fed76c19..f0c2571e1 100644 --- a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java +++ b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java @@ -151,7 +151,6 @@ public final byte[] getAlpnSelectedProtocol() { public final void setAlpnProtocols(byte[] protocols) { setApplicationProtocols(SSLUtils.decodeProtocols(protocols == null ? EmptyArray.BYTE : protocols)); } - - @Override - public abstract String getCurveNameForTesting(); + + @Override public abstract String getCurveNameForTesting(); } 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 d03b676e1..ea41df2a0 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 @@ -1000,7 +1000,8 @@ public void handshake_p384IsSupportedByDefault() throws Exception { } @Test - public void handshake_setsNamedGroups_usesFirstServerNamedGroupThatClientSupports() throws Exception { + public void handshake_setsNamedGroups_usesFirstServerNamedGroupThatClientSupports() + throws Exception { TestSSLContext context = TestSSLContext.create(); final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( context.host, context.port); diff --git a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java index 79ee4943e..63756701e 100644 --- a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java +++ b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java @@ -47,10 +47,9 @@ final class Java9PlatformUtil { static void setSSLParameters( SSLParameters src, SSLParametersImpl dest, AbstractConscryptSocket socket) { Java8PlatformUtil.setSSLParameters(src, dest, socket); - try{ + try { Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); - dest.setNamedGroups( - (String[]) getNamedGroupsMethod.invoke(src)); + dest.setNamedGroups((String[]) getNamedGroupsMethod.invoke(src)); } catch (ReflectiveOperationException | SecurityException e) { // Ignored. getNamedGroups was added in Java 20. } @@ -60,12 +59,11 @@ static void setSSLParameters( static void getSSLParameters( SSLParameters dest, SSLParametersImpl src, AbstractConscryptSocket socket) { Java8PlatformUtil.getSSLParameters(dest, src, socket); - try{ + try { String[] namedGroups = src.getNamedGroups(); - Method setNamedGroupsMethod = dest.getClass().getMethod( - "setNamedGroups", String[].class); - setNamedGroupsMethod.invoke( - dest, (Object) namedGroups); + Method setNamedGroupsMethod = + dest.getClass().getMethod("setNamedGroups", String[].class); + setNamedGroupsMethod.invoke(dest, (Object) namedGroups); } catch (ReflectiveOperationException | SecurityException e) { // Ignored. setNamedGroups was added in Java 20. } @@ -76,10 +74,9 @@ static void setSSLParameters( SSLParameters src, SSLParametersImpl dest, ConscryptEngine engine) { Java8PlatformUtil.setSSLParameters(src, dest, engine); - try{ + try { Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); - dest.setNamedGroups( - (String[]) getNamedGroupsMethod.invoke(src)); + dest.setNamedGroups((String[]) getNamedGroupsMethod.invoke(src)); } catch (ReflectiveOperationException | SecurityException e) { // Ignored. getNamedGroups was added in Java 20. } @@ -91,12 +88,11 @@ static void getSSLParameters( SSLParameters dest, SSLParametersImpl src, ConscryptEngine engine) { Java8PlatformUtil.getSSLParameters(dest, src, engine); - try{ + try { String[] namedGroups = src.getNamedGroups(); - Method setNamedGroupsMethod = dest.getClass().getMethod( - "setNamedGroups", String[].class); - setNamedGroupsMethod.invoke( - dest, (Object) namedGroups); + Method setNamedGroupsMethod = + dest.getClass().getMethod("setNamedGroups", String[].class); + setNamedGroupsMethod.invoke(dest, (Object) namedGroups); } catch (ReflectiveOperationException | SecurityException e) { // Ignored. setNamedGroups was added in Java 20. } From eeeae6985430f20657d5c5f9d3cf5d185e9dc58d Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 15 Dec 2025 12:43:24 +0000 Subject: [PATCH 03/11] Add missing import. --- .../test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 ea41df2a0..baa1ffb79 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 @@ -27,6 +27,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import org.conscrypt.OpenSSLSocketImpl; import org.conscrypt.TestUtils; import org.conscrypt.java.security.StandardNames; import org.conscrypt.java.security.TestKeyStore; @@ -42,7 +43,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; - import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -61,6 +61,7 @@ import java.util.HashSet; import java.util.List; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; From 40753c98b18f62171fc1b3383c3b88de7c957131 Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 15 Dec 2025 12:47:16 +0000 Subject: [PATCH 04/11] Fix format. --- .../src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java | 1 + 1 file changed, 1 insertion(+) 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 baa1ffb79..4ca4fcc7b 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 @@ -43,6 +43,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; + import java.io.EOFException; import java.io.IOException; import java.io.InputStream; From 146c615d141ea4d5cc24652fd060d212463cf312 Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 15 Dec 2025 13:32:15 +0000 Subject: [PATCH 05/11] Add missing changes to platform platform. --- .../src/main/java/org/conscrypt/Platform.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/platform/src/main/java/org/conscrypt/Platform.java b/platform/src/main/java/org/conscrypt/Platform.java index e98ece7c3..a34be6da9 100644 --- a/platform/src/main/java/org/conscrypt/Platform.java +++ b/platform/src/main/java/org/conscrypt/Platform.java @@ -166,6 +166,10 @@ static void setSSLParameters( SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) { impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm()); impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder()); + + Method getNamedGroupsMethod = params.getClass().getMethod("getNamedGroups"); + impl.setNamedGroups((String[]) getNamedGroupsMethod.invoke(params)); + List serverNames = params.getServerNames(); if (serverNames != null) { for (SNIServerName serverName : serverNames) { @@ -182,6 +186,10 @@ static void getSSLParameters( SSLParameters params, SSLParametersImpl impl, AbstractConscryptSocket socket) { params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm()); params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder()); + + Method setNamedGroupsMethod = params.getClass().getMethod("setNamedGroups", String[].class); + setNamedGroupsMethod.invoke(params, (Object[]) impl.getNamedGroups()); + if (impl.getUseSni() && AddressUtils.isValidSniHostname(socket.getHostname())) { params.setServerNames(Collections.singletonList( new SNIHostName(socket.getHostname()))); @@ -193,6 +201,10 @@ static void setSSLParameters( SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) { impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm()); impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder()); + + Method getNamedGroupsMethod = params.getClass().getMethod("getNamedGroups"); + impl.setNamedGroups((String[]) getNamedGroupsMethod.invoke(params)); + List serverNames = params.getServerNames(); if (serverNames != null) { for (SNIServerName serverName : serverNames) { @@ -209,6 +221,10 @@ static void getSSLParameters( SSLParameters params, SSLParametersImpl impl, ConscryptEngine engine) { params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm()); params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder()); + + Method setNamedGroupsMethod = params.getClass().getMethod("setNamedGroups", String[].class); + setNamedGroupsMethod.invoke(params, (Object[]) impl.getNamedGroups()); + if (impl.getUseSni() && AddressUtils.isValidSniHostname(engine.getHostname())) { params.setServerNames(Collections.singletonList( new SNIHostName(engine.getHostname()))); From f37c271cc6ed522d05c7d404b92adadf0157c84a Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 15 Dec 2025 14:49:28 +0000 Subject: [PATCH 06/11] Do not ignore failed set/get named group. --- .../src/main/java/org/conscrypt/Java9PlatformUtil.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java index 63756701e..fca6c175b 100644 --- a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java +++ b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java @@ -51,7 +51,7 @@ static void setSSLParameters( Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); dest.setNamedGroups((String[]) getNamedGroupsMethod.invoke(src)); } catch (ReflectiveOperationException | SecurityException e) { - // Ignored. getNamedGroups was added in Java 20. + throw new RuntimeException("SSLParameters.getNamedGroups failed.", e); } dest.setApplicationProtocols(getApplicationProtocols(src)); } @@ -65,7 +65,7 @@ static void getSSLParameters( dest.getClass().getMethod("setNamedGroups", String[].class); setNamedGroupsMethod.invoke(dest, (Object) namedGroups); } catch (ReflectiveOperationException | SecurityException e) { - // Ignored. setNamedGroups was added in Java 20. + throw new RuntimeException("SSLParameters.setNamedGroups failed.", e); } setApplicationProtocols(dest, src.getApplicationProtocols()); } @@ -78,7 +78,7 @@ static void setSSLParameters( Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); dest.setNamedGroups((String[]) getNamedGroupsMethod.invoke(src)); } catch (ReflectiveOperationException | SecurityException e) { - // Ignored. getNamedGroups was added in Java 20. + throw new RuntimeException("SSLParameters.getNamedGroups failed.", e); } dest.setApplicationProtocols(getApplicationProtocols(src)); @@ -94,7 +94,7 @@ static void getSSLParameters( dest.getClass().getMethod("setNamedGroups", String[].class); setNamedGroupsMethod.invoke(dest, (Object) namedGroups); } catch (ReflectiveOperationException | SecurityException e) { - // Ignored. setNamedGroups was added in Java 20. + throw new RuntimeException("SSLParameters.setNamedGroups failed.", e); } setApplicationProtocols(dest, src.getApplicationProtocols()); From 873b15b5f0c190ea2852be26c370d5a26757b792 Mon Sep 17 00:00:00 2001 From: juergw Date: Thu, 18 Dec 2025 12:59:44 +0000 Subject: [PATCH 07/11] Remove forgotten tags. --- common/src/main/java/org/conscrypt/ConscryptEngineSocket.java | 4 ---- .../test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java | 1 - 2 files changed, 5 deletions(-) diff --git a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java index ed8885842..db1376d68 100644 --- a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java +++ b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java @@ -432,11 +432,7 @@ public final void setEnabledProtocols(String[] protocols) { } @Override -<<<<<<< HEAD - public String getCurveNameForTesting() { -======= public final String getCurveNameForTesting() { ->>>>>>> upstream/master return engine.getCurveNameForTesting(); } 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 52d001496..5ed1eb94e 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 @@ -962,7 +962,6 @@ public void handshake_noNamedGroupsProperty_usesDefaultGroups() throws Exception } @Test -<<<<<<< HEAD public void handshake_p256IsSupportedByDefault() throws Exception { TestSSLContext context = TestSSLContext.create(); final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( From b5aa9eaa5032d27a488af9ae7f421cac264d4d5e Mon Sep 17 00:00:00 2001 From: juergw Date: Thu, 18 Dec 2025 15:47:54 +0000 Subject: [PATCH 08/11] Fix SSLSocketTest for the case where SSLParameters doesn't support named groups. --- .../javax/net/ssl/SSLSocketTest.java | 101 ++++++++++++------ 1 file changed, 71 insertions(+), 30 deletions(-) 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 5ed1eb94e..19556559b 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 @@ -833,22 +833,32 @@ public void setSSLParameters_invalidCipherSuite_throwsIllegalArgumentException() } } + boolean sslParametersSupportsNamedGroups() throws SecurityException { + try{ + Method unused = SSLParameters.class.getMethod("getNamedGroups"); + return true; + } catch (NoSuchMethodException e) { + return false; + } + } + @Test - public void setAndGetSSLParameters_withSetNamedGroups_works() throws Exception { + public void setAndGetSSLParameters_withSetNamedGroups_worksIfSupported() throws Exception { SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault(); try (SSLSocket ssl = (SSLSocket) sf.createSocket()) { SSLParameters parameters = new SSLParameters( new String[] {"TLS_AES_128_GCM_SHA256"}, new String[] {"TLSv1.3"}); - assertArrayEquals(null, getNamedGroupsOrNull(ssl.getSSLParameters())); - // values passed to setNamedGroups are not validated, any strings work. setNamedGroups(parameters, new String[] {"foo", "bar"}); ssl.setSSLParameters(parameters); SSLParameters sslParameters = ssl.getSSLParameters(); - - assertArrayEquals(new String[] {"foo", "bar"}, getNamedGroupsOrNull(sslParameters)); + if (sslParametersSupportsNamedGroups()) { + assertArrayEquals(new String[] {"foo", "bar"}, getNamedGroupsOrNull(sslParameters)); + } else { + assertArrayEquals(null, getNamedGroupsOrNull(sslParameters)); + } } } @@ -962,7 +972,9 @@ public void handshake_noNamedGroupsProperty_usesDefaultGroups() throws Exception } @Test - public void handshake_p256IsSupportedByDefault() throws Exception { + public void handshake_namedGroupsProperty_usesFirstKnownEntry() throws Exception { + System.setProperty("jdk.tls.namedGroups", "X25519MLKEM768,X25519"); + TestSSLContext context = TestSSLContext.create(); final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( context.host, context.port); @@ -972,27 +984,20 @@ public void handshake_p256IsSupportedByDefault() throws Exception { return null; }); Future c = runAsync(() -> { - SSLParameters parameters = client.getSSLParameters(); - setNamedGroups(parameters, new String[] {"P-256"}); - client.setSSLParameters(parameters); client.startHandshake(); return null; }); s.get(); c.get(); - // By default, BoringSSL uses X25519, P-256, and P-384. If the client - // requests P-256, it will be chosen. - assertEquals("P-256", getCurveName(client)); - assertEquals("P-256", getCurveName(server)); + assertEquals("X25519MLKEM768", getCurveName(client)); + assertEquals("X25519MLKEM768", getCurveName(server)); client.close(); server.close(); context.close(); } @Test - public void handshake_namedGroupsProperty_usesFirstKnownEntry() throws Exception { - System.setProperty("jdk.tls.namedGroups", "X25519MLKEM768,X25519"); - + public void handshake_p256IsSupportedByDefault() throws Exception { TestSSLContext context = TestSSLContext.create(); final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket( context.host, context.port); @@ -1002,13 +1007,24 @@ public void handshake_namedGroupsProperty_usesFirstKnownEntry() throws Exception return null; }); Future c = runAsync(() -> { + SSLParameters parameters = client.getSSLParameters(); + setNamedGroups(parameters, new String[] {"P-256"}); + client.setSSLParameters(parameters); client.startHandshake(); return null; }); s.get(); c.get(); - assertEquals("X25519MLKEM768", getCurveName(client)); - assertEquals("X25519MLKEM768", getCurveName(server)); + // By default, BoringSSL uses X25519, P-256, and P-384. + if (sslParametersSupportsNamedGroups()) { + // If the client requests P-256, it will be chosen. + assertEquals("P-256", getCurveName(client)); + assertEquals("P-256", getCurveName(server)); + } else { + // Otherwise, X25519 gets priority. + assertEquals("X25519", getCurveName(client)); + assertEquals("X25519", getCurveName(server)); + } client.close(); server.close(); context.close(); @@ -1034,10 +1050,16 @@ public void handshake_p384IsSupportedByDefault() throws Exception { }); s.get(); c.get(); - // By default, BoringSSL uses X25519, P-256, and P-384. If the server only supports P-384, - // it will be chosen. - assertEquals("P-384", getCurveName(client)); - assertEquals("P-384", getCurveName(server)); + // By default, BoringSSL uses X25519, P-256, and P-384. + if (sslParametersSupportsNamedGroups()) { + // If the client requests P-384, it will be chosen. + assertEquals("P-384", getCurveName(client)); + assertEquals("P-384", getCurveName(server)); + } else { + // Otherwise, X25519 gets priority. + assertEquals("X25519", getCurveName(client)); + assertEquals("X25519", getCurveName(server)); + } client.close(); server.close(); context.close(); @@ -1066,8 +1088,15 @@ public void handshake_setsNamedGroups_usesFirstServerNamedGroupThatClientSupport }); s.get(); c.get(); - assertEquals("P-384", getCurveName(client)); - assertEquals("P-384", getCurveName(server)); + if (sslParametersSupportsNamedGroups()) { + // P-384 is the first named group in the server's list that both support. + assertEquals("P-384", getCurveName(client)); + assertEquals("P-384", getCurveName(server)); + } else { + // The defaults are used, and X25519 gets priority. + assertEquals("X25519", getCurveName(client)); + assertEquals("X25519", getCurveName(server)); + } client.close(); server.close(); context.close(); @@ -1095,8 +1124,14 @@ public void handshake_withX25519MLKEM768_works() throws Exception { }); s.get(); c.get(); - assertEquals("X25519MLKEM768", getCurveName(client)); - assertEquals("X25519MLKEM768", getCurveName(server)); + if (sslParametersSupportsNamedGroups()) { + assertEquals("X25519MLKEM768", getCurveName(client)); + assertEquals("X25519MLKEM768", getCurveName(server)); + } else { + // The defaults are used, and X25519 gets priority. + assertEquals("X25519", getCurveName(client)); + assertEquals("X25519", getCurveName(server)); + } client.close(); server.close(); context.close(); @@ -1122,10 +1157,16 @@ public void handshake_namedGroupsDontIntersect_throwsException() throws Exceptio client.startHandshake(); return null; }); - ExecutionException serverException = assertThrows(ExecutionException.class, s::get); - assertTrue(serverException.getCause() instanceof SSLHandshakeException); - ExecutionException clientException = assertThrows(ExecutionException.class, c::get); - assertTrue(clientException.getCause() instanceof SSLHandshakeException); + if (sslParametersSupportsNamedGroups()) { + ExecutionException serverException = assertThrows(ExecutionException.class, s::get); + assertTrue(serverException.getCause() instanceof SSLHandshakeException); + ExecutionException clientException = assertThrows(ExecutionException.class, c::get); + assertTrue(clientException.getCause() instanceof SSLHandshakeException); + } else { + // The defaults are used, and X25519 gets priority. + assertEquals("X25519", getCurveName(client)); + assertEquals("X25519", getCurveName(server)); + } client.close(); server.close(); context.close(); From 602a78f2a6ea7220399929194c1eb8f9844043c8 Mon Sep 17 00:00:00 2001 From: juergw Date: Thu, 18 Dec 2025 15:52:38 +0000 Subject: [PATCH 09/11] Fix whitespace. --- .../test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 19556559b..12047140f 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 @@ -834,7 +834,7 @@ public void setSSLParameters_invalidCipherSuite_throwsIllegalArgumentException() } boolean sslParametersSupportsNamedGroups() throws SecurityException { - try{ + try { Method unused = SSLParameters.class.getMethod("getNamedGroups"); return true; } catch (NoSuchMethodException e) { From b2bd7d6209219b4eaded3f68afc7fcfef1623ddd Mon Sep 17 00:00:00 2001 From: juergw Date: Thu, 18 Dec 2025 17:05:46 +0000 Subject: [PATCH 10/11] Don't throw exception when method is not available. --- .../src/main/java/org/conscrypt/Java9PlatformUtil.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java index fca6c175b..aef049c06 100644 --- a/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java +++ b/openjdk/src/main/java/org/conscrypt/Java9PlatformUtil.java @@ -51,7 +51,7 @@ static void setSSLParameters( Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); dest.setNamedGroups((String[]) getNamedGroupsMethod.invoke(src)); } catch (ReflectiveOperationException | SecurityException e) { - throw new RuntimeException("SSLParameters.getNamedGroups failed.", e); + // Method is not available. Ignore. } dest.setApplicationProtocols(getApplicationProtocols(src)); } @@ -65,7 +65,7 @@ static void getSSLParameters( dest.getClass().getMethod("setNamedGroups", String[].class); setNamedGroupsMethod.invoke(dest, (Object) namedGroups); } catch (ReflectiveOperationException | SecurityException e) { - throw new RuntimeException("SSLParameters.setNamedGroups failed.", e); + // Method is not available. Ignore. } setApplicationProtocols(dest, src.getApplicationProtocols()); } @@ -78,7 +78,7 @@ static void setSSLParameters( Method getNamedGroupsMethod = src.getClass().getMethod("getNamedGroups"); dest.setNamedGroups((String[]) getNamedGroupsMethod.invoke(src)); } catch (ReflectiveOperationException | SecurityException e) { - throw new RuntimeException("SSLParameters.getNamedGroups failed.", e); + // Method is not available. Ignore. } dest.setApplicationProtocols(getApplicationProtocols(src)); @@ -94,7 +94,7 @@ static void getSSLParameters( dest.getClass().getMethod("setNamedGroups", String[].class); setNamedGroupsMethod.invoke(dest, (Object) namedGroups); } catch (ReflectiveOperationException | SecurityException e) { - throw new RuntimeException("SSLParameters.setNamedGroups failed.", e); + // Method is not available. Ignore. } setApplicationProtocols(dest, src.getApplicationProtocols()); From b26175400d9b0ad50c379ee0ea9f06b6e37ef384 Mon Sep 17 00:00:00 2001 From: juergw Date: Mon, 22 Dec 2025 14:00:38 +0000 Subject: [PATCH 11/11] Fix test. They currently fail because I forgot to add a the get() calls. --- .../test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java | 2 ++ 1 file changed, 2 insertions(+) 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 12047140f..bd021b70f 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 @@ -1163,6 +1163,8 @@ public void handshake_namedGroupsDontIntersect_throwsException() throws Exceptio ExecutionException clientException = assertThrows(ExecutionException.class, c::get); assertTrue(clientException.getCause() instanceof SSLHandshakeException); } else { + s.get(); + c.get(); // The defaults are used, and X25519 gets priority. assertEquals("X25519", getCurveName(client)); assertEquals("X25519", getCurveName(server));