Hi Sean, That does make sense, thank you. The distinction between what a provider sends by default and what it can negotiate is the one that matters, and I had been conflating the two. The narrower point I was reaching for was about the specification
Hi Sean,
That does make sense, thank you. The distinction between what a provider sends
by default and what it can negotiate is the one that matters, and I had been
conflating the two.
The narrower point I was reaching for was about the specification rather than
provider-independence. The getSupportedSSLParameters javadoc says only that
"The parameters will always have the ciphersuites and protocols arrays set to
non-null values", so an application reading namedGroups from it is relying on
unspecified behaviour even against a provider that does populate it. A
first-class method carries its own contract, and that is the part of
JDK-8388519 I expect to be most useful in practice.
It also supplies the pre-flight check my original case needed. On 27-ea
MLKEM768 is recognised but inactive ("Ignore inactive or disabled named
group"), and JEP 527 lists non-hybrid ML-KEM key exchange for TLS as a
non-goal, so at present an application cannot tell in advance whether a
requested group will be used or quietly dropped. Being able to ask before
calling setNamedGroups is what closes that.
On the ClientHello with no supported_groups or key_share extension, thank you
for taking a look. That is case C4 in the matrix at
https://github.com/Arpan0995/jdk-tls-namedgroup-silent-drop, which records the
debug trace ("Ignore key_share extension, no supported groups") and both peer
outcomes: handshake_failure from a Bouncy Castle 1.84 server, and
missing_extension from a stock JSSE server. Happy to test any change against it.
Thanks again for the time on this.
Best regards,
Arpan Sharma
On Fri, Jul 24, 2026 at 2:33 PM Sean Mullan <[email protected]> wrote:
>
>
> On 7/23/26 6:51 PM, Arpan Sharma wrote:
>
>
> > You probably already know this, but you can set only PQC or hybrid
> > named groups if you don't want classical groups to be used.
>
> I tested that guard too, and it has a sharp edge worth noting: with
> setNamedGroups({"MLKEM768"}) alone on a JDK that does not support it,
> the call succeeds and nothing fails locally. The client still sends a
> ClientHello — with no supported_groups or key_share extension at all
> — and the failure surfaces only as the peer's fatal alert, whose type
> depends on the peer (a Bouncy Castle 1.84 server produced
> handshake_failure; in an earlier test a stock JSSE server produced
> missing_extension). So the connection does fail closed, but remotely
> and in a way that is hard to attribute to the dropped group. The
> supported-groups query API in JDK-8388519 gives applications the
> right tool here: check first, then set.
>
> That does seem a bit odd. We'll take a closer look at that case and see if it needs to be addressed better.
>
> On that API, one data point that may be useful for the RFE: on
> 26.0.1 and 27-ea, SSLContext.getSupportedSSLParameters()
> .getNamedGroups() already returns the provider's supported list (my
> reproducer uses it as its baseline). But as far as I can tell the
> getSupportedSSLParameters() spec only guarantees that the ciphersuite
> and protocol arrays are populated, so an application cannot rely on
> it across providers — a first-class API in the style of
> getSupportedCipherSuites would give that query an actual contract.
>
> getSupportedCipherSuites() is also provider specific. It returns all the suites that a provider implements and can be negotiated.
>
> SSLContext.getSupportedSSLParameters().getNamedGroups() only returns the groups that the provider would send to the server by default,
> for example in the supported_groups extension. There can be other groups that the provider may implement but not send by default,
> and this new method would return that. Hope that makes sense.
>
> --Sean