summaryrefslogtreecommitdiff
path: root/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'ssl')
-rw-r--r--ssl/quic/quic_impl.c47
-rw-r--r--ssl/quic/quic_lcidm.c14
-rw-r--r--ssl/quic/quic_reactor.c6
-rw-r--r--ssl/quic/quic_rx_depack.c3
-rw-r--r--ssl/quic/quic_srtm.c7
-rw-r--r--ssl/quic/quic_stream_map.c3
-rw-r--r--ssl/quic/uint_set.c4
-rw-r--r--ssl/record/methods/tls_common.c17
-rw-r--r--ssl/s3_lib.c6
-rw-r--r--ssl/ssl_asn1.c4
-rw-r--r--ssl/ssl_lib.c22
-rw-r--r--ssl/ssl_sess.c4
-rw-r--r--ssl/statem/statem_dtls.c8
-rw-r--r--ssl/t1_lib.c96
14 files changed, 150 insertions, 91 deletions
diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c
index 1b4bbd4a9215..a8f9ac92c2a4 100644
--- a/ssl/quic/quic_impl.c
+++ b/ssl/quic/quic_impl.c
@@ -4504,6 +4504,10 @@ SSL *ossl_quic_new_from_listener(SSL *ssl, uint64_t flags)
* to grab reference for qc.
*/
qc->ch = ossl_quic_port_create_outgoing(qc->port, qc->tls);
+ if (qc->ch == NULL) {
+ QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
+ goto err;
+ }
ossl_quic_channel_set_msg_callback(qc->ch, ql->obj.ssl.ctx->msg_callback, &qc->obj.ssl);
ossl_quic_channel_set_msg_callback_arg(qc->ch, ql->obj.ssl.ctx->msg_callback_arg);
@@ -4600,9 +4604,10 @@ SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags)
int ret;
QCTX ctx;
SSL *conn_ssl = NULL;
+ SSL *conn_ssl_tmp = NULL;
SSL_CONNECTION *conn = NULL;
QUIC_CHANNEL *new_ch = NULL;
- QUIC_CONNECTION *qc;
+ QUIC_CONNECTION *qc = NULL;
int no_block = ((flags & SSL_ACCEPT_CONNECTION_NO_BLOCK) != 0);
if (!expect_quic_listener(ssl, &ctx))
@@ -4651,28 +4656,38 @@ SSL *ossl_quic_accept_connection(SSL *ssl, uint64_t flags)
* bound to new_ch. If channel constructor fails to create any item here
* it just fails to create channel.
*/
- if (!ossl_assert((conn_ssl = ossl_quic_channel_get0_tls(new_ch)) != NULL)
- || !ossl_assert((conn = SSL_CONNECTION_FROM_SSL(conn_ssl)) != NULL)
- || !ossl_assert((conn_ssl = SSL_CONNECTION_GET_USER_SSL(conn)) != NULL))
+ if (!ossl_assert((conn_ssl_tmp = ossl_quic_channel_get0_tls(new_ch)) != NULL)
+ || !ossl_assert((conn = SSL_CONNECTION_FROM_SSL(conn_ssl_tmp)) != NULL)
+ || !ossl_assert((conn_ssl_tmp = SSL_CONNECTION_GET_USER_SSL(conn)) != NULL))
goto out;
- qc = (QUIC_CONNECTION *)conn_ssl;
- qc->pending = 0;
- if (!SSL_up_ref(&ctx.ql->obj.ssl)) {
- /*
- * You might expect ossl_quic_channel_free() to be called here. Be
- * assured it happens, The process goes as follows:
- * - The SSL_free() here is being handled by ossl_quic_free().
- * - The very last step of ossl_quic_free() is call to qc_cleanup()
- * where channel gets freed.
- */
- SSL_free(conn_ssl);
+ qc = (QUIC_CONNECTION *)conn_ssl_tmp;
+ if (SSL_up_ref(&ctx.ql->obj.ssl)) {
+ qc->listener = ctx.ql;
+ conn_ssl = conn_ssl_tmp;
+ conn_ssl_tmp = NULL;
+ qc->pending = 0;
}
- qc->listener = ctx.ql;
out:
qctx_unlock(&ctx);
+ /*
+ * You might expect ossl_quic_channel_free() to be called here. Be
+ * assured it happens, The process goes as follows:
+ * - The SSL_free() here is being handled by ossl_quic_free().
+ * - The very last step of ossl_quic_free() is call to qc_cleanup()
+ * where channel gets freed.
+ * NOTE: We defer this SSL_free until after the call to qctx_unlock above
+ * to avoid the deadlock that would occur when ossl_quic_free attempts to
+ * re-acquire this mutex. We also do the gymnastics with conn_ssl and
+ * conn_ssl_tmp above so that we only actually do the free on the SSL
+ * object if the up-ref above fails, in such a way that we don't unbalance
+ * the listener refcount (i.e. if the up-ref fails above, we don't set the
+ * listener pointer so that we don't then drop the ref-count erroneously
+ * during the free operation.
+ */
+ SSL_free(conn_ssl_tmp);
return conn_ssl;
}
diff --git a/ssl/quic/quic_lcidm.c b/ssl/quic/quic_lcidm.c
index 660eb802ba32..89ee95055dc1 100644
--- a/ssl/quic/quic_lcidm.c
+++ b/ssl/quic/quic_lcidm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -74,15 +74,21 @@ static unsigned long lcid_hash(const QUIC_LCID *lcid_obj)
0,
};
unsigned long hashval = 0;
+ unsigned char digest[SIPHASH_MIN_DIGEST_SIZE];
- if (!SipHash_set_hash_size(&siphash, sizeof(unsigned long)))
+ /* Use a supported SipHash digest size (8 or 16); 8 is sufficient here. */
+ if (!SipHash_set_hash_size(&siphash, SIPHASH_MIN_DIGEST_SIZE))
goto out;
if (!SipHash_Init(&siphash, (uint8_t *)lcid_obj->hash_key, 0, 0))
goto out;
SipHash_Update(&siphash, lcid_obj->cid.id, lcid_obj->cid.id_len);
- if (!SipHash_Final(&siphash, (unsigned char *)&hashval,
- sizeof(unsigned long)))
+ if (!SipHash_Final(&siphash, digest, SIPHASH_MIN_DIGEST_SIZE))
goto out;
+
+ /*
+ * Truncate the 64-bit SipHash digest into an unsigned long.
+ */
+ memcpy(&hashval, digest, sizeof(hashval) < sizeof(digest) ? sizeof(hashval) : sizeof(digest));
out:
return hashval;
}
diff --git a/ssl/quic/quic_reactor.c b/ssl/quic/quic_reactor.c
index 1a95f131e30c..c30bc3c595ab 100644
--- a/ssl/quic/quic_reactor.c
+++ b/ssl/quic/quic_reactor.c
@@ -76,6 +76,12 @@ void ossl_quic_reactor_cleanup(QUIC_REACTOR *rtor)
}
#if defined(OPENSSL_SYS_WINDOWS)
+
+/* Work around for MinGW builds. */
+#if defined(__MINGW32__) && !defined(SIO_UDP_NETRESET)
+#define SIO_UDP_NETRESET _WSAIOW(IOC_VENDOR, 15)
+#endif
+
/*
* On Windows recvfrom() may return WSAECONNRESET when destination port
* used in preceding call to sendto() is no longer reachable. The reset
diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c
index 83f66ef59e5a..786af9b4c221 100644
--- a/ssl/quic/quic_rx_depack.c
+++ b/ssl/quic/quic_rx_depack.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -1316,6 +1316,7 @@ static int depack_process_frames(QUIC_CHANNEL *ch, PACKET *pkt,
OSSL_QUIC_ERR_PROTOCOL_VIOLATION,
frame_type,
"NEW_CONN_ID valid only in 0/1-RTT");
+ return 0;
}
if (!depack_do_frame_new_conn_id(pkt, ch, ackm_data))
return 0;
diff --git a/ssl/quic/quic_srtm.c b/ssl/quic/quic_srtm.c
index 405376fc465d..46f675cef239 100644
--- a/ssl/quic/quic_srtm.c
+++ b/ssl/quic/quic_srtm.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -168,6 +168,11 @@ void ossl_quic_srtm_free(QUIC_SRTM *srtm)
lh_SRTM_ITEM_free(srtm->items_rev);
if (srtm->items_fwd != NULL) {
+ /*
+ * We don't need to call lh_SRTM_ITEM_set_down_load(..., 0)
+ * here because srtm_free_each() callback for _doall() does
+ * not call to lh_SRTIM_ITEM_delete().
+ */
lh_SRTM_ITEM_doall(srtm->items_fwd, srtm_free_each);
lh_SRTM_ITEM_free(srtm->items_fwd);
}
diff --git a/ssl/quic/quic_stream_map.c b/ssl/quic/quic_stream_map.c
index ae6a0a01e983..b8175849a019 100644
--- a/ssl/quic/quic_stream_map.c
+++ b/ssl/quic/quic_stream_map.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -122,6 +122,7 @@ static void release_each(QUIC_STREAM *stream, void *arg)
void ossl_quic_stream_map_cleanup(QUIC_STREAM_MAP *qsm)
{
+ lh_QUIC_STREAM_set_down_load(qsm->map, 0);
ossl_quic_stream_map_visit(qsm, release_each, qsm);
lh_QUIC_STREAM_free(qsm->map);
diff --git a/ssl/quic/uint_set.c b/ssl/quic/uint_set.c
index f81148c79af7..e217816a395b 100644
--- a/ssl/quic/uint_set.c
+++ b/ssl/quic/uint_set.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -303,6 +303,8 @@ int ossl_uint_set_remove(UINT_SET *s, const UINT_RANGE *range)
* handled by the above cases.
*/
y = create_set_item(end + 1, z->range.end);
+ if (y == NULL)
+ return 0;
ossl_list_uint_set_insert_after(s, z, y);
z->range.end = start - 1;
break;
diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c
index bbfb3620f195..bf035b13d54f 100644
--- a/ssl/record/methods/tls_common.c
+++ b/ssl/record/methods/tls_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -620,6 +620,11 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
thisrr->length = sslv2len & 0x7fff;
+ if (!rl->funcs->validate_record_header(rl, thisrr)) {
+ /* RLAYERfatal already called */
+ return OSSL_RECORD_RETURN_FATAL;
+ }
+
if (thisrr->length > TLS_BUFFER_get_len(rbuf)
- SSL2_RT_HEADER_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
@@ -656,6 +661,11 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
if (rl->msg_callback != NULL)
rl->msg_callback(0, version, SSL3_RT_HEADER, p, 5, rl->cbarg);
+ if (!rl->funcs->validate_record_header(rl, thisrr)) {
+ /* RLAYERfatal already called */
+ return OSSL_RECORD_RETURN_FATAL;
+ }
+
if (thisrr->length > TLS_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_PACKET_LENGTH_TOO_LONG);
@@ -663,11 +673,6 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
}
}
- if (!rl->funcs->validate_record_header(rl, thisrr)) {
- /* RLAYERfatal already called */
- return OSSL_RECORD_RETURN_FATAL;
- }
-
/* now rl->rstate == SSL_ST_READ_BODY */
}
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 0e1445b38fb7..213ec84b171d 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -4322,7 +4322,7 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp)(void))
switch (cmd) {
#if !defined(OPENSSL_NO_DEPRECATED_3_0)
case SSL_CTRL_SET_TMP_DH_CB:
- sc->cert->dh_tmp_cb = (DH * (*)(SSL *, int, int)) fp;
+ sc->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
ret = 1;
break;
#endif
@@ -4593,7 +4593,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
switch (cmd) {
#if !defined(OPENSSL_NO_DEPRECATED_3_0)
case SSL_CTRL_SET_TMP_DH_CB: {
- ctx->cert->dh_tmp_cb = (DH * (*)(SSL *, int, int)) fp;
+ ctx->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
} break;
#endif
case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 5d4ec7e6ed87..13ab6490b9a7 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@@ -81,7 +81,7 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = {
ASN1_EXP_OPT(SSL_SESSION_ASN1, peer_rpk, ASN1_OCTET_STRING, 20)
} static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1)
- IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1)
+IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1)
/* Utility functions for i2d_SSL_SESSION */
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index ac77faa677ce..05b0209a76b3 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
@@ -3412,22 +3412,21 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
int i;
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
- if (sc == NULL)
+ if (size < 2 || buf == NULL)
return NULL;
- if (!sc->server
- || sc->peer_ciphers == NULL
- || size < 2)
+ buf[0] = '\0';
+
+ if (sc == NULL || !sc->server)
return NULL;
p = buf;
clntsk = sc->peer_ciphers;
srvrsk = SSL_get_ciphers(s);
- if (clntsk == NULL || srvrsk == NULL)
- return NULL;
- if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0)
- return NULL;
+ if (clntsk == NULL || sk_SSL_CIPHER_num(clntsk) == 0
+ || srvrsk == NULL || sk_SSL_CIPHER_num(srvrsk) == 0)
+ return buf;
for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) {
int n;
@@ -3447,10 +3446,9 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
}
/* No overlap */
- if (p == buf)
- return NULL;
+ if (p != buf)
+ p[-1] = '\0';
- p[-1] = '\0';
return buf;
}
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index e54fb53e5294..04cbfa5cfa94 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -790,9 +790,9 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
ssl_tsan_counter(ctx, &ctx->stats.sess_cache_full);
}
}
- }
- SSL_SESSION_list_add(ctx, c);
+ SSL_SESSION_list_add(ctx, c);
+ }
if (s != NULL) {
/*
diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c
index 4052ef6219b8..f62b757721fc 100644
--- a/ssl/statem/statem_dtls.c
+++ b/ssl/statem/statem_dtls.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -1177,7 +1177,11 @@ int dtls1_buffer_message(SSL_CONNECTION *s, int is_ccs)
return 0;
}
- pqueue_insert(s->d1->sent_messages, item);
+ if (pqueue_insert(s->d1->sent_messages, item) == NULL) {
+ dtls1_hm_fragment_free(frag);
+ pitem_free(item);
+ return 0;
+ }
return 1;
}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index cd471a636db1..ded6a1eadfb8 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -211,7 +211,7 @@ static const uint16_t suiteb_curves[] = {
/* Group list string of the built-in pseudo group DEFAULT_SUITE_B */
#define SUITE_B_GROUP_NAME "DEFAULT_SUITE_B"
-#define SUITE_B_GROUP_LIST "secp256r1:secp384r1",
+#define SUITE_B_GROUP_LIST "?secp256r1:?secp384r1",
struct provider_ctx_data_st {
SSL_CTX *ctx;
@@ -1244,8 +1244,8 @@ typedef struct {
size_t ksidcnt; /* Number of key shares */
uint16_t *ksid_arr; /* The IDs of the key share groups (flat list) */
/* Variable to keep state between execution of callback or helper functions */
- size_t tuple_mode; /* Keeps track whether tuple_cb called from 'the top' or from gid_cb */
- int ignore_unknown_default; /* Flag such that unknown groups for DEFAULT[_XYZ] are ignored */
+ int inner; /* Are we expanding a DEFAULT list */
+ int first; /* First tuple of possibly nested expansion? */
} gid_cb_st;
/* Forward declaration of tuple callback function */
@@ -1264,7 +1264,7 @@ static int gid_cb(const char *elem, int len, void *arg)
int found_group = 0;
char etmp[GROUP_NAME_BUFFER_LENGTH];
int retval = 1; /* We assume success */
- char *current_prefix;
+ const char *current_prefix;
int ignore_unknown = 0;
int add_keyshare = 0;
int remove_group = 0;
@@ -1320,16 +1320,16 @@ static int gid_cb(const char *elem, int len, void *arg)
for (i = 0; i < OSSL_NELEM(default_group_strings); i++) {
if ((size_t)len == (strlen(default_group_strings[i].list_name))
&& OPENSSL_strncasecmp(default_group_strings[i].list_name, elem, len) == 0) {
+ int saved_first;
+
/*
* We're asked to insert an entire list of groups from a
* DEFAULT[_XYZ] 'pseudo group' which we do by
* recursively calling this function (indirectly via
* CONF_parse_list and tuple_cb); essentially, we treat a DEFAULT
* group string like a tuple which is appended to the current tuple
- * rather then starting a new tuple. Variable tuple_mode is the flag which
- * controls append tuple vs start new tuple.
+ * rather then starting a new tuple.
*/
-
if (ignore_unknown || remove_group)
return -1; /* removal or ignore not allowed here -> syntax error */
@@ -1350,15 +1350,17 @@ static int gid_cb(const char *elem, int len, void *arg)
default_group_strings[i].group_string,
strlen(default_group_strings[i].group_string));
restored_default_group_string[strlen(default_group_strings[i].group_string) + restored_prefix_index] = '\0';
- /* We execute the recursive call */
- garg->ignore_unknown_default = 1; /* We ignore unknown groups for DEFAULT_XYZ */
- /* we enforce group mode (= append tuple) for DEFAULT_XYZ group lists */
- garg->tuple_mode = 0;
- /* We use the tuple_cb callback to process the pseudo group tuple */
+ /*
+ * Append first tuple of result to current tuple, and don't
+ * terminate the last tuple until we return to a top-level
+ * tuple_cb.
+ */
+ saved_first = garg->first;
+ garg->inner = garg->first = 1;
retval = CONF_parse_list(restored_default_group_string,
TUPLE_DELIMITER_CHARACTER, 1, tuple_cb, garg);
- garg->tuple_mode = 1; /* next call to tuple_cb will again start new tuple */
- garg->ignore_unknown_default = 0; /* reset to original value */
+ garg->inner = 0;
+ garg->first = saved_first;
/* We don't need the \0-terminated string anymore */
OPENSSL_free(restored_default_group_string);
@@ -1378,9 +1380,6 @@ static int gid_cb(const char *elem, int len, void *arg)
if (len == 0)
return -1; /* Seems we have prefxes without a group name -> syntax error */
- if (garg->ignore_unknown_default == 1) /* Always ignore unknown groups for DEFAULT[_XYZ] */
- ignore_unknown = 1;
-
/* Memory management in case more groups are present compared to initial allocation */
if (garg->gidcnt == garg->gidmax) {
uint16_t *tmp = OPENSSL_realloc(garg->gid_arr,
@@ -1514,7 +1513,7 @@ static int gid_cb(const char *elem, int len, void *arg)
/* and update the book keeping for the number of groups in current tuple */
garg->tuplcnt_arr[garg->tplcnt]++;
- /* We memorize if needed that we want to add a key share for the current group */
+ /* We want to add a key share for the current group */
if (add_keyshare)
garg->ksid_arr[garg->ksidcnt++] = gid;
}
@@ -1523,6 +1522,39 @@ done:
return retval;
}
+static int grow_tuples(gid_cb_st *garg)
+{
+ static size_t max_tplcnt = (~(size_t)0) / sizeof(size_t);
+
+ /* This uses OPENSSL_realloc_array() in newer releases */
+ if (garg->tplcnt == garg->tplmax) {
+ size_t newcnt = garg->tplmax + GROUPLIST_INCREMENT;
+ size_t newsz = newcnt * sizeof(size_t);
+ size_t *tmp;
+
+ if (newsz > max_tplcnt
+ || (tmp = OPENSSL_realloc(garg->tuplcnt_arr, newsz)) == NULL)
+ return 0;
+
+ garg->tplmax = newcnt;
+ garg->tuplcnt_arr = tmp;
+ }
+ return 1;
+}
+
+static int close_tuple(gid_cb_st *garg)
+{
+ size_t gidcnt = garg->tuplcnt_arr[garg->tplcnt];
+
+ if (gidcnt == 0)
+ return 1;
+ if (!grow_tuples(garg))
+ return 0;
+
+ garg->tuplcnt_arr[++garg->tplcnt] = 0;
+ return 1;
+}
+
/* Extract and process a tuple of groups */
static int tuple_cb(const char *tuple, int len, void *arg)
{
@@ -1536,16 +1568,9 @@ static int tuple_cb(const char *tuple, int len, void *arg)
return 0;
}
- /* Memory management for tuples */
- if (garg->tplcnt == garg->tplmax) {
- size_t *tmp = OPENSSL_realloc(garg->tuplcnt_arr,
- (garg->tplmax + GROUPLIST_INCREMENT) * sizeof(*garg->tuplcnt_arr));
-
- if (tmp == NULL)
- return 0;
- garg->tplmax += GROUPLIST_INCREMENT;
- garg->tuplcnt_arr = tmp;
- }
+ if (garg->inner && !garg->first && !close_tuple(garg))
+ return 0;
+ garg->first = 0;
/* Convert to \0-terminated string */
restored_tuple_string = OPENSSL_malloc((len + 1 /* \0 */) * sizeof(char));
@@ -1560,15 +1585,8 @@ static int tuple_cb(const char *tuple, int len, void *arg)
/* We don't need the \o-terminated string anymore */
OPENSSL_free(restored_tuple_string);
- if (garg->tuplcnt_arr[garg->tplcnt] > 0) { /* Some valid groups are present in current tuple... */
- if (garg->tuple_mode) {
- /* We 'close' the tuple */
- garg->tplcnt++;
- garg->tuplcnt_arr[garg->tplcnt] = 0; /* Next tuple is initialized to be empty */
- garg->tuple_mode = 1; /* next call will start a tuple (unless overridden in gid_cb) */
- }
- }
-
+ if (!garg->inner && !close_tuple(garg))
+ return 0;
return retval;
}
@@ -1599,8 +1617,6 @@ int tls1_set_groups_list(SSL_CTX *ctx,
}
memset(&gcb, 0, sizeof(gcb));
- gcb.tuple_mode = 1; /* We prepare to collect the first tuple */
- gcb.ignore_unknown_default = 0;
gcb.gidmax = GROUPLIST_INCREMENT;
gcb.tplmax = GROUPLIST_INCREMENT;
gcb.ksidmax = GROUPLIST_INCREMENT;