]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
tls_construct_ctos_key_share(): Fix handling of HRR without key share request
authorTomas Mraz <tomas@openssl.org>
Fri, 21 Feb 2025 18:28:26 +0000 (19:28 +0100)
committerTomas Mraz <tomas@openssl.org>
Tue, 25 Feb 2025 14:34:24 +0000 (15:34 +0100)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26801)

ssl/statem/extensions_clnt.c

index 970160089b73b2fbf3342c04bc79562e5a917860..b977f8c3c03c57f9aef180abb13c66ca98596026 100644 (file)
@@ -633,15 +633,16 @@ static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int group_id,
     EVP_PKEY *key_share_key = NULL;
     size_t encodedlen;
 
-    if (s->s3.tmp.pkey != NULL && loop_num == 0) {
-        if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING)) {
+    if (loop_num < s->s3.tmp.num_ks_pkey) {
+        if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING)
+            || !ossl_assert(s->s3.tmp.ks_pkey[loop_num] != NULL)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
             return 0;
         }
         /*
          * Could happen if we got an HRR that wasn't requesting a new key_share
          */
-        key_share_key = s->s3.tmp.pkey;
+        key_share_key = s->s3.tmp.ks_pkey[loop_num];
     } else {
         key_share_key = ssl_generate_pkey_group(s, group_id);
         if (key_share_key == NULL) {
@@ -673,13 +674,14 @@ static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int group_id,
     /* We ensure in t1_lib.c that the loop number does not exceed OPENSSL_CLIENT_MAX_KEY_SHARES */
     s->s3.tmp.ks_pkey[loop_num] = key_share_key;
     s->s3.tmp.ks_group_id[loop_num] = group_id;
-    s->s3.tmp.num_ks_pkey++;
+    if (loop_num >= s->s3.tmp.num_ks_pkey)
+        s->s3.tmp.num_ks_pkey++;
 
     OPENSSL_free(encoded_pubkey);
 
     return 1;
  err:
-    if (s->s3.tmp.pkey == NULL)
+    if (key_share_key != s->s3.tmp.ks_pkey[loop_num])
         EVP_PKEY_free(key_share_key);
     OPENSSL_free(encoded_pubkey);
     return 0;
@@ -721,10 +723,10 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt,
 
     /* Add key shares */
 
-    s->s3.tmp.num_ks_pkey = 0;
-
-    if (s->s3.group_id != 0) {
+    if (s->s3.group_id != 0 && s->s3.tmp.pkey == NULL) {
+        /* new, single key share */
         group_id = s->s3.group_id;
+        s->s3.tmp.num_ks_pkey = 0;
         if (!add_key_share(s, pkt, group_id, 0)) {
             /* SSLfatal() already called */
             return EXT_RETURN_FAIL;