diff options
Diffstat (limited to 'ssl')
| -rw-r--r-- | ssl/quic/quic_impl.c | 47 | ||||
| -rw-r--r-- | ssl/quic/quic_lcidm.c | 14 | ||||
| -rw-r--r-- | ssl/quic/quic_reactor.c | 6 | ||||
| -rw-r--r-- | ssl/quic/quic_rx_depack.c | 3 | ||||
| -rw-r--r-- | ssl/quic/quic_srtm.c | 7 | ||||
| -rw-r--r-- | ssl/quic/quic_stream_map.c | 3 | ||||
| -rw-r--r-- | ssl/quic/uint_set.c | 4 | ||||
| -rw-r--r-- | ssl/record/methods/tls_common.c | 17 | ||||
| -rw-r--r-- | ssl/s3_lib.c | 6 | ||||
| -rw-r--r-- | ssl/ssl_asn1.c | 4 | ||||
| -rw-r--r-- | ssl/ssl_lib.c | 22 | ||||
| -rw-r--r-- | ssl/ssl_sess.c | 4 | ||||
| -rw-r--r-- | ssl/statem/statem_dtls.c | 8 | ||||
| -rw-r--r-- | ssl/t1_lib.c | 96 |
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; |
