-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need support for multiple key share entries in ClientHello #21633
Comments
Does this mean that client, and server can use only 1 key, even if I make 3: RSA, DSA, ECDSA? Will your change allow to use multiple keys of same type, different strengths? For example, RSA: SHA1, and SHA256. Client, and server would choose key to match maximum strength that they have. My tutorial on configuration: #21643 (comment) There I mention that manual states that can configure only 1 key of each type. Does not specify what type means. What retry do you mean? - By protocol TLS, or new connection? |
This issue is a feature request that is only relevant to TLSv1.3. OpenSSL currently only supports one key_share in the ClientHello. The key_share uses a key exchange algorithm (e.g. X25519, X448, ECDHE with P-256 etc). Currently OpenSSL will use the first algorithm in the configured supported_groups list. See: https://www.openssl.org/docs/man3.1/man3/SSL_CTX_set1_groups_list.html By default, if no other configuration is applied, this will be X25519. Your question is confusing the algorithm selected for key exchange in the initial key_share with the algorithm used in the server certificate. The former is selected by the client and is completely separate to the certificate types configured on the server side.
The term retry here is specifical referring to a TLSv1.3 HelloRetryRequest message (HRR), i.e. part of the TLSv1.3 protocol. |
There seems to be discussion around this topic in #22203 and on behalf of @martinschmatz I would like to start work on this. Before starting I just wanted to confirm interest from the maintainers to not waste development time on a feature that has no path forward |
I think there is interest in having this feature. |
Better count how many clients send multiple key_share, and how many times server retries for different key_share. What happens on retry? Perhaps server lists its supported_groups to client. So, client can present 1 key_share again, and only 1 supported_groups chosen from list of server. |
@mattcaswell In analogy to the '?' prefix to ignore unknown groups in SSL_CTX_set1_groups_list, would it be acceptable to use a "!" as additional, optional prefix to indicate the desire to add a key share for this group? Remarks:
|
Yeah, that would work IMO. |
@t8m FYI - a first version to support multiple key shares is 'wiggling' (= basic operation with more testing required). One question came up: Do we want to limit the number of key shares? The standard does explicitly state: "Clients can offer as many KeyShareEntry values as the number of supported groups it is offering" OTOH, if a user is 'blindly' sending key shares for all its (quantum-safe) groups, this will generate a lot of traffic on the server side. Therefore, I'd prefer a max of 4 key shares to be allowed. This also has an impact on implementation (and performance): With limitation to max 4 key shares, an array can be used to keep track of key share variables, syscalls for dynamic memory allocations are required otherwise. |
I have no problem limiting the number of key shares. Perhaps use this construction so the number can be overridden at build time.
|
Code is running, survived first tests. Here a first write-up of what the code change will do, to be added here:
|
Limit on quantity of key_share violates RFC, and purpose of this issue to remove limit. Limit on client is appropriate, as it is supposed to choose. However, choice should be by user, rather than hard code in software (fixed). Better allow choice in configuration. You can reduce traffic by different means. I suggested to log clients, and servers in order to limit supported_groups, and key_share to what they usually have.
Makes no sense. Change words.
#22203 sates that it is a bug to treat key_share as preference. - Both for client, and server. Instead, must choose 1st supported_groups of client. HRR, if its key_share is absent.
Rephrase: If you do not add supported_groups, then OpenSSL uses built-in groups. This implies absent prefix "!". |
Limitation to 4 key_shares is intended and it's well understood that this choice deviates from the standard - unless one takes "In the absence of an application profile standard specifying otherwise [...]" into consideration. The standard is clear that the server is free to use whatever algorithm it wants to make a choice for a group: "The server processes the ClientHello and determines the appropriate cryptographic parameters for the connection." and "If the client has not provided a sufficient 'key_share' extension (e.g., it includes only DHE or ECDHE groups unacceptable to or unsupported by the server), the server corrects the mismatch with a HelloRetryRequest [...]". Can't work with statistics in my environment. Thanks for your considerations about wording, will be taken into account once documentation is finalized. |
You merely confirm that you violate standard.
You take away freedom. Yet call it freedom.
You mean there is no limit 4?
Can you examine logs? My word statistics was inappropriate. It means non-specific. I meant specific, memory about each client. I edited my post to change the word to log. You would see that most clients submit only 1 key_share, for 1st supported_groups. |
@BugOfBugs It was understood already in your post further up that you argue against limiting the number of Confirmed: Server is [technically] free to use a '!' prefix for none/any/all supported groups. And yes, I had the opportunity to look at some logs in the past - but still can't use what you suggest in my environment. |
My purpose was not to repeat myself.
There are no multiple arguments. Only 1: avoid syscalls for dynamic allocation of memory. You did not argue against using quantity of prefix "!" as maximum key_share.
You ignore my point that it is a bug to treat key_share as preference. Correct 2 steps should be:
Your personal situation is not what OpenSSL should stick to. Additional feature could be to keep log in memory. Dynamically decide whether to use multiple key_share, and how many. Decide per connection, server, client, time of day, etc. |
You seem to have missed the argument that default (build time configurable) limitation to a maximum of 4 When using a '!' prefix on client-side, quantity of '!' prefixes is equal to number of key shares. Always was, always will be - by way of how the '!' prefix is defined. I didn't ignore your assessment that "treating The fact that I can't use logs in my context does not imply that it would not be possible to create such logs using OpenSSL (hint: This post only in case it helps somebody to understand what we try to achieve. Based on your various posts I concluded for myself that you have no clue what you're talking about and that you are either unable or unwilling to read posts thoroughly, which implies that I added you to my personal troll filter. Bye. |
I did not. We presume a benefit minimal communication.
Do you agree to drop this excuse?
You yourself suggested the opposite: "!" is your invention, new.
Your algorithm suggests that you do ignore. Steps 1, and 3 choose by key_share.
This is no justification to break documentation. That says preference is supported_groups.
Not consequence.
I proved it is.
supported_groups is preference.
You never mentioned this. New argument.
I failed to find the mention. Please link.
Is not log, such.
- Wrong. Application still needs to decide which data to inspect. Still needs to log on its own. I assume that your answer means that you retract your argument that you can not use logs.
Please delete this paragraph as nonsense.
My pleasure. One such destructive person already left. I refuse to believe as if voluntarily he became ghost. I believe that supervisors of OpenSSL are vigilant, and good. |
@BugOfBugs @martinschmatz Please stop the unproductive and unprofessional ad hominem attacks immediately. |
The proposed server-side behaviour looks rather over-engineered to me. Forcing a client that presented a supported key share to HRR makes little sense to me, and requires some non-trivial justification. Otherwise, with "2" removed, the need for '!' on the server side goes away, just list the preferred (formerly required) groups first, and then "!" is only needed on the client side. In terms of UX, placing "!"s in the list introduces complexity that is easily avoided, by just allowing the client to separately specify a count of keyshares to send, with that many groups implicitly "banged" as it were. If there is a compelling reason for the server to force an avoidable HRR to force the client to send a different supported group, a similar count could be available server side, but I'm sceptical that this would be a good idea. |
CNSA 2.0 mandates to support and prefer Q-safe algorithms if available. Therefore, when a client supports a Q-safe algorithm for the key agreement, the server must be able select it - even at the cost of a HRR (which btw probably hurts the server more than the client due to network load at an aggregation point). Currently, server selects key-shares as per client preference. Hence, even if the client sends a legacy and a Q-safe key share (in that order), the server has no means to prefer the Q-safe key share group but will select the legacy key share group. One way to deal with that (without code change in apps) would be to extend the means available for server-side cipher preference ( "allowing the client to separately specify" --> If I understand your proposal correctly, this implies code changes in apps using OpenSSL - which we try to avoid for many reasons. A prefix character for a group in the string specifying the supported groups OTOH is only implying a change in config file(s), hence crypto-agile and seamlessly & immediately available for any application leveraging OpenSSL (e.g cURL, HAproxy, Nginx, Python, PostgreSQL etc). PS: The character used as prefix is certainly up for debate. '!' might not be the best choice, was used to show the principle. |
Well prefer is a flexible term, it doesn't specify how hard one should try to prefer, and certainly does not imply that one can't also prefer to avoid HRR. As for a separate knob for the share count, it need not require any change in client software, if said client software already supports loading of configuration files (needed anyway to load providers for pq algorithms, and specify various other knobs). Applications could of course implement direct support for the share count control, but delegating parsing of opaque config options to OpenSSL (from a file) or via the conf command API addresses this and future extensibility needs. That said, yes, there needs to be a way for the server's group order to be primary when the client presents multiple key shares. |
@vdukhovni Point well taken related to 'how stringent is the prefer mandate'. I'll have somebody reach out to the CNSA2.0 owners (NSA) for clarification. Fundamentally, I can identify the following scenarios (not implying that all are required, intended to structure the discussion). Client: Need a way to specify multiple client key shares to be included in Server (all below assume that there is some overlap in client & server
With the exception of the second server scenario (which value is anyway questionable at best), all scenarios can be addressed by the introduction of a prefix option in the respective lists of
|
How will that work for applications that act as both TLS server and client? Typically a client will want to send key_share for 1 PQC and 1 traditional group. |
@ghen2 Client and server sides each use a colon separated string of optionally prefixed groups. I guess you are well aware, but mentioning it nevertheless: TLS applications that are using OpenSSL are configured in two steps: First the config of a context is done, which can then be refined by configuring the SSL object. You didn't mention an example for such an application (do you have a specific one?), hence I'm speculating: Such applications are typically either proxies or u-services. In both scenarios, at least the upstream server is (hopefully) not hard coded but defined in a config file or ENV variable. Which implies that the groups used for upstream also can be defined this way. |
@vdukhovni The clarification question sent to NSA was as follows: [...]The client and server The response was (emphasis added by me): ==> We better prepare for a stringent interpretation of the mandate 'prefer' Q-safe key agreements. |
I see, so the ask is for servers to be able to implement:
based on plausible upcoming CNSA 2.0 requirements. And for clients I guess to be able to send more than one key share, because avoiding HRR by sending both a PQ keyshare and a "traditional" keyshare makes sense when many servers will support only traditional, while some will insist on (strongly prefer) PQ. At which point we it remains to bikeshed the configuration syntax.
In either case:
Finally, if a client supports multiple unsent keyshare types "preferred" by the server, which should the server select for HRR? This would be either based on server, or client preference, and presumably should follow the extant TLS-1.2 server vs. client cipher preference control. Is this a fair summary? |
@vdukhovni Yes, I'd say that's a fair summary. I have to admit that I never thought about your last paragraph: Server or client preference when selecting the group in the HRR. Seems I work to often with servers... Anyway, I think that could be addressed by using a '-' prefix on the client side for selection of key shares to be sent, and on server side to indicate client preference when selecting the group for the HRR, and a '_' prefix on server side to indicate server preference when selecting the group for the HRR. This again motivated by avoiding code changes. Having said that, adding a new option |
SSL_OP_CIPHER_SERVER_PREFERENCE already applies to group selection if there is no matching keyshare. Doesn't it? |
@t8m Don't see any evidence for that, neither in the overview, nor in the relevant code section. |
Hmm... but that applies to TLS <= 1.2 versions only apparently. |
Postfix would be an example of a client+server that talks to arbitrary endpoints in both directions. But for either example I'm aware of only a single setting to control supported groups for both directions at once, not separately. Example group list: (1) |
The Postfix
This is not a problem for Postfix, settings can be per-service in master.cf
In Postfix, you'd configure one setting for |
@vdukhovni yes I know that (and I do use such smtp/smtpd specific overrides), but in general It's just an example of one application (I didn't say one process) which acts as both TLS client and server. |
OK, yes, in some plausibly realistic, though also plausibly uncommon, situations the syntax desirable for clients might clash with the syntax that is desirable for servers. And therefore, we'd need to have a ( |
This comment was marked as off-topic.
This comment was marked as off-topic.
A cleaned up version of a POC patch created by @martinschmatz It still includes various printf lines and a few TODOs Fixes openssl#21633 Based-on-patch-by: Martin Schmatz <mrt@zurich.ibm.com> Signed-off-by: Alex Bozarth <ajbozart@us.ibm.com>
#21633 (comment) |
@BugOfBugs You keep spamming issues with off topic comments. Please refrain from that! There is nothing wrong with having a draft PR against some issue even if the discussion in the issue is not finished/resolved. |
As per RFC 8446 "Clients can offer as many KeyShareEntry values as the number of supported groups it is offering" in ClientHello during TLS1.3 handshake
But currently OpenSSL does not support multiple key share entries corresponding to all the groups from supported_group list.
It sends only first preferred group in key share. And if server does not support it then it requires retry.
eg. if I have below given 2 groups in supported_group
secp521r1 (0x0019)
x448 (0x001e)
then Key_Share extension should contain "KeyShareEntry" value for both the groups. But currently key_share is sent only for 1st group i.e. secp521r1 (0x0019)
We need this feature (multiple key share entries ) support in OpenSSL.
The text was updated successfully, but these errors were encountered: