From 8bfdb8b15d8a5ce1e43f4cc27fc0b5e1b602e04e Mon Sep 17 00:00:00 2001 From: K1 Date: Tue, 18 Jun 2024 20:11:50 +0800 Subject: [PATCH 1/4] Fix coverity issues, use of an uninitialized variable CID: 471247, 370239, 364178, 351779, 351777, 278417, 25398, 25379 --- crypto/evp/e_des.c | 3 ++- crypto/evp/e_des3.c | 3 ++- providers/implementations/ciphers/cipher_des_hw.c | 3 ++- providers/implementations/ciphers/cipher_tdes_default_hw.c | 3 ++- test/evp_fetch_prov_test.c | 4 ++-- test/siphash_internal_test.c | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/crypto/evp/e_des.c b/crypto/evp/e_des.c index 653a9bf94..84c1d51c7 100644 --- a/crypto/evp/e_des.c +++ b/crypto/evp/e_des.c @@ -135,7 +135,8 @@ static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t n, chunk = EVP_MAXCHUNK / 8; - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; if (inl < chunk) chunk = inl; diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index 1a109d11a..cf64174d7 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -151,7 +151,8 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t n; - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) inl *= 8; diff --git a/providers/implementations/ciphers/cipher_des_hw.c b/providers/implementations/ciphers/cipher_des_hw.c index a77fcc681..a2d54b46b 100644 --- a/providers/implementations/ciphers/cipher_des_hw.c +++ b/providers/implementations/ciphers/cipher_des_hw.c @@ -136,7 +136,8 @@ static int cipher_hw_des_cfb1_cipher(PROV_CIPHER_CTX *ctx, unsigned char *out, { size_t n, chunk = MAXCHUNK / 8; DES_key_schedule *key = &(((PROV_DES_CTX *)ctx)->dks.ks); - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; if (inl < chunk) chunk = inl; diff --git a/providers/implementations/ciphers/cipher_tdes_default_hw.c b/providers/implementations/ciphers/cipher_tdes_default_hw.c index 53cbbad57..ccdf3941c 100644 --- a/providers/implementations/ciphers/cipher_tdes_default_hw.c +++ b/providers/implementations/ciphers/cipher_tdes_default_hw.c @@ -99,7 +99,8 @@ static int ossl_cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out, { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; size_t n; - unsigned char c[1], d[1]; + unsigned char c[1]; + unsigned char d[1] = { 0 }; if (ctx->use_bits == 0) inl *= 8; diff --git a/test/evp_fetch_prov_test.c b/test/evp_fetch_prov_test.c index d237082bd..422665d31 100644 --- a/test/evp_fetch_prov_test.c +++ b/test/evp_fetch_prov_test.c @@ -212,7 +212,7 @@ static int test_explicit_EVP_MD_fetch_by_X509_ALGOR(int idx) int ret = 0; X509_ALGOR *algor = make_algor(NID_sha256); const ASN1_OBJECT *obj; - char id[OSSL_MAX_NAME_SIZE]; + char id[OSSL_MAX_NAME_SIZE] = { 0 }; if (algor == NULL) return 0; @@ -328,7 +328,7 @@ static int test_explicit_EVP_CIPHER_fetch_by_X509_ALGOR(int idx) int ret = 0; X509_ALGOR *algor = make_algor(NID_aes_128_cbc); const ASN1_OBJECT *obj; - char id[OSSL_MAX_NAME_SIZE]; + char id[OSSL_MAX_NAME_SIZE] = { 0 }; if (algor == NULL) return 0; diff --git a/test/siphash_internal_test.c b/test/siphash_internal_test.c index 76ae5ecab..3ab1677d2 100644 --- a/test/siphash_internal_test.c +++ b/test/siphash_internal_test.c @@ -257,7 +257,7 @@ static int test_siphash(int idx) static int test_siphash_basic(void) { SIPHASH siphash = { 0, }; - unsigned char key[SIPHASH_KEY_SIZE]; + static const unsigned char key[SIPHASH_KEY_SIZE] = {0}; unsigned char output[SIPHASH_MAX_DIGEST_SIZE]; /* Use invalid hash size */ From 2a0984f8baa432a44f32917c91abcf9acce2a874 Mon Sep 17 00:00:00 2001 From: K1 Date: Thu, 20 Jun 2024 17:53:29 +0800 Subject: [PATCH 2/4] Fix coverity issues, CID 471315 and 356192 471315, EC_POINTS_new: Reads target of a freed pointer 356192, pkey_dh_derive: Out-of-bounds access to a buffer --- crypto/dh/dh_pmeth.c | 2 +- crypto/ec/ec_lib.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c index 1ad50b850..ea344fbb0 100644 --- a/crypto/dh/dh_pmeth.c +++ b/crypto/dh/dh_pmeth.c @@ -432,7 +432,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; - size_t Zlen = 0; + int Zlen = 0; if (!dctx->kdf_outlen || !dctx->kdf_oid) return 0; if (key == NULL) { diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index e92f582db..62d3b5d56 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -795,8 +795,10 @@ EC_POINTS *EC_POINTS_new(const EC_GROUP *group, int count) for (i = 0; i < count; i++) { point = EC_POINT_new(group); - if (point == NULL) + if (point == NULL) { EC_POINTS_free(ret); + return NULL; + } ret->items[i] = point; } From 74c8c6731c7448fe76d502ce8681bd9adc7fbc52 Mon Sep 17 00:00:00 2001 From: K1 Date: Fri, 21 Jun 2024 12:08:34 +0800 Subject: [PATCH 3/4] Fix coverity issues; Delete unused TLSEXT code in NTLS. Fix cid:471326, 471309, 471255, 356194, 356186, 356175. Delete unused TLSEXT code in NTLS. --- crypto/packet.c | 6 +- include/internal/packet.h | 37 +- ssl/statem/extensions_clnt.c | 5 +- ssl/statem/extensions_srvr.c | 19 +- ssl/statem_ntls/ntls_extensions.c | 214 +----- ssl/statem_ntls/ntls_extensions_clnt.c | 797 --------------------- ssl/statem_ntls/ntls_extensions_srvr.c | 950 ------------------------- ssl/statem_ntls/ntls_statem_local.h | 49 -- 8 files changed, 60 insertions(+), 2017 deletions(-) diff --git a/crypto/packet.c b/crypto/packet.c index 09f6a9cea..a9eb1ec4e 100644 --- a/crypto/packet.c +++ b/crypto/packet.c @@ -207,7 +207,7 @@ int WPACKET_set_flags(WPACKET *pkt, unsigned int flags) } /* Store the |value| of length |len| at location |data| */ -static int put_value(unsigned char *data, size_t value, size_t len) +static int put_value(unsigned char *data, uint64_t value, size_t len) { if (data == NULL) return 1; @@ -379,12 +379,12 @@ int WPACKET_start_sub_packet(WPACKET *pkt) return WPACKET_start_sub_packet_len__(pkt, 0); } -int WPACKET_put_bytes__(WPACKET *pkt, unsigned int val, size_t size) +int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t size) { unsigned char *data; /* Internal API, so should not fail */ - if (!ossl_assert(size <= sizeof(unsigned int)) + if (!ossl_assert(size <= sizeof(uint64_t)) || !WPACKET_allocate_bytes(pkt, size, &data) || !put_value(data, val, size)) return 0; diff --git a/include/internal/packet.h b/include/internal/packet.h index 170997db6..b7bb59d7a 100644 --- a/include/internal/packet.h +++ b/include/internal/packet.h @@ -228,6 +228,28 @@ __owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt, return 1; } +/* + * Peek ahead at 8 bytes in network order from |pkt| and store the value in + * |*data| + */ +__owur static ossl_inline int PACKET_peek_net_8(const PACKET *pkt, + uint64_t *data) +{ + if (PACKET_remaining(pkt) < 8) + return 0; + + *data = ((uint64_t)(*pkt->curr)) << 56; + *data |= ((uint64_t)(*(pkt->curr + 1))) << 48; + *data |= ((uint64_t)(*(pkt->curr + 2))) << 40; + *data |= ((uint64_t)(*(pkt->curr + 3))) << 32; + *data |= ((uint64_t)(*(pkt->curr + 4))) << 24; + *data |= ((uint64_t)(*(pkt->curr + 5))) << 16; + *data |= ((uint64_t)(*(pkt->curr + 6))) << 8; + *data |= *(pkt->curr + 7); + + return 1; +} + /* Equivalent of n2l */ /* Get 4 bytes in network order from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data) @@ -252,6 +274,17 @@ __owur static ossl_inline int PACKET_get_net_4_len(PACKET *pkt, size_t *data) return ret; } +/* Get 8 bytes in network order from |pkt| and store the value in |*data| */ +__owur static ossl_inline int PACKET_get_net_8(PACKET *pkt, uint64_t *data) +{ + if (!PACKET_peek_net_8(pkt, data)) + return 0; + + packet_forward(pkt, 8); + + return 1; +} + /* Peek ahead at 1 byte from |pkt| and store the value in |*data| */ __owur static ossl_inline int PACKET_peek_1(const PACKET *pkt, unsigned int *data) @@ -833,7 +866,7 @@ int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, * 1 byte will fail. Don't call this directly. Use the convenience macros below * instead. */ -int WPACKET_put_bytes__(WPACKET *pkt, unsigned int val, size_t bytes); +int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t bytes); /* * Convenience macros for calling WPACKET_put_bytes with different @@ -847,6 +880,8 @@ int WPACKET_put_bytes__(WPACKET *pkt, unsigned int val, size_t bytes); WPACKET_put_bytes__((pkt), (val), 3) #define WPACKET_put_bytes_u32(pkt, val) \ WPACKET_put_bytes__((pkt), (val), 4) +#define WPACKET_put_bytes_u64(pkt, val) \ + WPACKET_put_bytes__((pkt), (val), 8) /* Set a maximum size that we will not allow the WPACKET to grow beyond */ int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize); diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 2bc61eb6f..3f914dba5 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1038,7 +1038,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 - uint32_t now, agesec, agems = 0; + uint32_t agesec, agems = 0; size_t reshashsize = 0, pskhashsize = 0, binderoffset, msglen; unsigned char *resbinder = NULL, *pskbinder = NULL, *msgstart = NULL; const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL; @@ -1094,8 +1094,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, * this in multiple places in the code, so portability shouldn't be an * issue. */ - now = (uint32_t)time(NULL); - agesec = now - (uint32_t)s->session->time; + agesec = (uint32_t)(time(NULL) - s->session->time); /* * We calculate the age in seconds but the server may work in ms. Due to * rounding errors we could overestimate the age by up to 1s. It is diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index a025c1313..84bc87f2e 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -12,16 +12,16 @@ #include "statem_local.h" #include "internal/cryptlib.h" -#define COOKIE_STATE_FORMAT_VERSION 0 +#define COOKIE_STATE_FORMAT_VERSION 1 /* * 2 bytes for packet length, 2 bytes for format version, 2 bytes for * protocol version, 2 bytes for group id, 2 bytes for cipher id, 1 byte for - * key_share present flag, 4 bytes for timestamp, 2 bytes for the hashlen, + * key_share present flag, 8 bytes for timestamp, 2 bytes for the hashlen, * EVP_MAX_MD_SIZE for transcript hash, 1 byte for app cookie length, app cookie * length bytes, SHA256_DIGEST_LENGTH bytes for the HMAC of the whole thing. */ -#define MAX_COOKIE_SIZE (2 + 2 + 2 + 2 + 2 + 1 + 4 + 2 + EVP_MAX_MD_SIZE + 1 \ +#define MAX_COOKIE_SIZE (2 + 2 + 2 + 2 + 2 + 1 + 8 + 2 + EVP_MAX_MD_SIZE + 1 \ + SSL_COOKIE_LENGTH + SHA256_DIGEST_LENGTH) /* @@ -694,7 +694,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, unsigned char hmac[SHA256_DIGEST_LENGTH]; unsigned char hrr[MAX_HRR_SIZE]; size_t rawlen, hmaclen, hrrlen, ciphlen; - unsigned long tm, now; + uint64_t tm, now; /* Ignore any cookie if we're not set up to verify it */ if (s->ctx->verify_stateless_cookie_cb == NULL @@ -795,7 +795,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } if (!PACKET_get_1(&cookie, &key_share) - || !PACKET_get_net_4(&cookie, &tm) + || !PACKET_get_net_8(&cookie, &tm) || !PACKET_get_length_prefixed_2(&cookie, &chhash) || !PACKET_get_length_prefixed_1(&cookie, &appcookie) || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) { @@ -804,7 +804,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } /* We tolerate a cookie age of up to 10 minutes (= 60 * 10 seconds) */ - now = (unsigned long)time(NULL); + now = time(NULL); if (tm > now || (now - tm) > 600) { /* Cookie is stale. Ignore it */ return 1; @@ -1135,7 +1135,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->ext.early_data_ok = 1; s->ext.ticket_expected = 1; } else { - uint32_t ticket_age = 0, now, agesec, agems; + uint32_t ticket_age = 0, agesec, agems; int ret; /* @@ -1175,8 +1175,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } ticket_age = (uint32_t)ticket_agel; - now = (uint32_t)time(NULL); - agesec = now - (uint32_t)sess->time; + agesec = (uint32_t)(time(NULL) - sess->time); agems = agesec * (uint32_t)1000; ticket_age -= sess->ext.tick_age_add; @@ -1856,7 +1855,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, &ciphlen) /* Is there a key_share extension present in this HRR? */ || !WPACKET_put_bytes_u8(pkt, s->s3.peer_tmp == NULL) - || !WPACKET_put_bytes_u32(pkt, (unsigned int)time(NULL)) + || !WPACKET_put_bytes_u64(pkt, time(NULL)) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &hashval1)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); diff --git a/ssl/statem_ntls/ntls_extensions.c b/ssl/statem_ntls/ntls_extensions.c index 75c3d76a1..3b7978d16 100644 --- a/ssl/statem_ntls/ntls_extensions.c +++ b/ssl/statem_ntls/ntls_extensions.c @@ -29,29 +29,15 @@ static int init_alpn(SSL *s, unsigned int context); static int final_alpn(SSL *s, unsigned int context, int sent); static int init_sig_algs_cert(SSL *s, unsigned int context); static int init_sig_algs(SSL *s, unsigned int context); -static int init_certificate_authorities(SSL *s, unsigned int context); -static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, - unsigned int context, - X509 *x, - size_t chainidx); -static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); - static int init_ec_point_formats(SSL *s, unsigned int context); static int init_etm(SSL *s, unsigned int context); static int init_ems(SSL *s, unsigned int context); static int final_ems(SSL *s, unsigned int context, int sent); -static int init_psk_kex_modes(SSL *s, unsigned int context); -static int final_key_share(SSL *s, unsigned int context, int sent); #ifndef OPENSSL_NO_SRTP static int init_srtp(SSL *s, unsigned int context); #endif static int final_sig_algs(SSL *s, unsigned int context, int sent); -static int final_early_data(SSL *s, unsigned int context, int sent); static int final_maxfragmentlen(SSL *s, unsigned int context, int sent); -static int init_post_handshake_auth(SSL *s, unsigned int context); -static int final_psk(SSL *s, unsigned int context, int sent); /* Structure to define a built-in extension */ typedef struct extensions_definition_st { @@ -267,14 +253,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { /* We do not generate signature_algorithms_cert at present. */ NULL, NULL, NULL }, - { - TLSEXT_TYPE_post_handshake_auth, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ONLY, - init_post_handshake_auth, - tls_parse_ctos_post_handshake_auth_ntls, NULL, - NULL, tls_construct_ctos_post_handshake_auth_ntls, - NULL, - }, + INVALID_EXTENSION, /* TLSEXT_IDX_post_handshake_auth */ { TLSEXT_TYPE_signature_algorithms, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST, @@ -292,54 +271,14 @@ static const EXTENSION_DEFINITION ext_defs[] = { tls_construct_stoc_supported_versions_ntls, tls_construct_ctos_supported_versions_ntls, NULL }, - { - TLSEXT_TYPE_psk_kex_modes, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS_IMPLEMENTATION_ONLY - | SSL_EXT_TLS1_3_ONLY, - init_psk_kex_modes, tls_parse_ctos_psk_kex_modes_ntls, NULL, NULL, - tls_construct_ctos_psk_kex_modes_ntls, NULL - }, - { - /* - * Must be in this list after supported_groups. We need that to have - * been parsed before we do this one. - */ - TLSEXT_TYPE_key_share, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY - | SSL_EXT_TLS1_3_ONLY, - NULL, tls_parse_ctos_key_share_ntls, tls_parse_stoc_key_share_ntls, - tls_construct_stoc_key_share_ntls, tls_construct_ctos_key_share_ntls, - final_key_share - }, - { - /* Must be after key_share */ - TLSEXT_TYPE_cookie, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, - NULL, tls_parse_ctos_cookie_ntls, tls_parse_stoc_cookie_ntls, - tls_construct_stoc_cookie_ntls, tls_construct_ctos_cookie_ntls, NULL - }, - { - TLSEXT_TYPE_early_data, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS - | SSL_EXT_TLS1_3_NEW_SESSION_TICKET | SSL_EXT_TLS1_3_ONLY, - NULL, tls_parse_ctos_early_data_ntls, tls_parse_stoc_early_data_ntls, - tls_construct_stoc_early_data_ntls, tls_construct_ctos_early_data_ntls, - final_early_data - }, - { - TLSEXT_TYPE_certificate_authorities, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST - | SSL_EXT_TLS1_3_ONLY, - init_certificate_authorities, - tls_parse_certificate_authorities, tls_parse_certificate_authorities, - tls_construct_certificate_authorities, - tls_construct_certificate_authorities, NULL, - }, - INVALID_EXTENSION, /* TLSEXT_TYPE_quic_transport_parameters_draft */ - INVALID_EXTENSION, /* TLSEXT_TYPE_quic_transport_parameters */ - INVALID_EXTENSION, /* TLSEXT_TYPE_compress_certificate */ + INVALID_EXTENSION, /* TLSEXT_IDX_psk_kex_modes */ + INVALID_EXTENSION, /* TLSEXT_IDX_key_share */ + INVALID_EXTENSION, /* TLSEXT_IDX_cookie */ + INVALID_EXTENSION, /* TLSEXT_IDX_early_data */ + INVALID_EXTENSION, /* TLSEXT_IDX_certificate_authorities */ + INVALID_EXTENSION, /* TLSEXT_IDX_quic_transport_params_draft */ + INVALID_EXTENSION, /* TLSEXT_IDX_quic_transport_params */ + INVALID_EXTENSION, /* TLSEXT_IDX_compress_certificate */ { /* Must be immediately before pre_shared_key */ TLSEXT_TYPE_padding, @@ -348,14 +287,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { /* We send this, but don't read it */ NULL, NULL, NULL, tls_construct_ctos_padding_ntls, NULL }, - { - /* Required by the TLSv1.3 spec to always be the last extension */ - TLSEXT_TYPE_psk, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, - NULL, tls_parse_ctos_psk_ntls, tls_parse_stoc_psk_ntls, tls_construct_stoc_psk_ntls, - tls_construct_ctos_psk_ntls, final_psk - } + INVALID_EXTENSION /* TLSEXT_IDX_psk */ }; /* Check whether an extension's context matches the current context */ @@ -1077,55 +1009,6 @@ static int final_ems(SSL *s, unsigned int context, int sent) return 1; } -static int init_certificate_authorities(SSL *s, unsigned int context) -{ - sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); - s->s3.tmp.peer_ca_names = NULL; - return 1; -} - -static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, - unsigned int context, - X509 *x, - size_t chainidx) -{ - const STACK_OF(X509_NAME) *ca_sk = get_ca_names_ntls(s); - - if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0) - return EXT_RETURN_NOT_SENT; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_certificate_authorities) - || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - if (!construct_ca_names_ntls(s, ca_sk, pkt)) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - - if (!WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - return EXT_RETURN_SENT; -} - -static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ - if (!parse_ca_names_ntls(s, pkt)) - return 0; - if (PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - return 1; -} - #ifndef OPENSSL_NO_SRTP static int init_srtp(SSL *s, unsigned int context) { @@ -1141,17 +1024,6 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent) return 1; } -static int final_key_share(SSL *s, unsigned int context, int sent) -{ - return 1; -} - -static int init_psk_kex_modes(SSL *s, unsigned int context) -{ - s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_NONE; - return 1; -} - int tls_psk_do_binder_ntls(SSL *s, const EVP_MD *md, const unsigned char *msgstart, size_t binderoffset, const unsigned char *binderin, unsigned char *binderout, SSL_SESSION *sess, int sign, @@ -1332,49 +1204,6 @@ int tls_psk_do_binder_ntls(SSL *s, const EVP_MD *md, const unsigned char *msgsta return ret; } -static int final_early_data(SSL *s, unsigned int context, int sent) -{ - if (!sent) - return 1; - - if (!s->server) { - if (context == SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS - && sent - && !s->ext.early_data_ok) { - /* - * If we get here then the server accepted our early_data but we - * later realised that it shouldn't have done (e.g. inconsistent - * ALPN) - */ - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EARLY_DATA); - return 0; - } - - return 1; - } - - if (s->max_early_data == 0 - || !s->hit - || s->early_data_state != SSL_EARLY_DATA_ACCEPTING - || !s->ext.early_data_ok - || s->hello_retry_request != SSL_HRR_NONE - || (s->allow_early_data_cb != NULL - && !s->allow_early_data_cb(s, - s->allow_early_data_cb_data))) { - s->ext.early_data = SSL_EARLY_DATA_REJECTED; - } else { - s->ext.early_data = SSL_EARLY_DATA_ACCEPTED; - - if (!tls13_change_cipher_state(s, - SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_SERVER_READ)) { - /* SSLfatal_ntls() already called */ - return 0; - } - } - - return 1; -} - static int final_maxfragmentlen(SSL *s, unsigned int context, int sent) { /* @@ -1398,26 +1227,3 @@ static int final_maxfragmentlen(SSL *s, unsigned int context, int sent) return 1; } - -static int init_post_handshake_auth(SSL *s, ossl_unused unsigned int context) -{ - s->post_handshake_auth = SSL_PHA_NONE; - - return 1; -} - -/* - * If clients offer "pre_shared_key" without a "psk_key_exchange_modes" - * extension, servers MUST abort the handshake. - */ -static int final_psk(SSL *s, unsigned int context, int sent) -{ - if (s->server && sent && s->clienthello != NULL - && !s->clienthello->pre_proc_exts[TLSEXT_IDX_psk_kex_modes].present) { - SSLfatal(s, TLS13_AD_MISSING_EXTENSION, - SSL_R_MISSING_PSK_KEX_MODES_EXTENSION); - return 0; - } - - return 1; -} diff --git a/ssl/statem_ntls/ntls_extensions_clnt.c b/ssl/statem_ntls/ntls_extensions_clnt.c index a8872eaf5..75c0812f1 100644 --- a/ssl/statem_ntls/ntls_extensions_clnt.c +++ b/ssl/statem_ntls/ntls_extensions_clnt.c @@ -321,330 +321,6 @@ EXT_RETURN tls_construct_ctos_supported_versions_ntls(SSL *s, WPACKET *pkt, return EXT_RETURN_NOT_SENT; } -/* - * Construct a psk_kex_modes extension. - */ -EXT_RETURN tls_construct_ctos_psk_kex_modes_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - int nodhe = s->options & SSL_OP_ALLOW_NO_DHE_KEX; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk_kex_modes) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_start_sub_packet_u8(pkt) - || !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE_DHE) - || (nodhe && !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE)) - || !WPACKET_close(pkt) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_KE_DHE; - if (nodhe) - s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE; -#endif - - return EXT_RETURN_SENT; -} - -#ifndef OPENSSL_NO_TLS1_3 -static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) -{ - unsigned char *encoded_point = NULL; - EVP_PKEY *key_share_key = NULL; - size_t encodedlen; - - if (s->s3.tmp.pkey != NULL) { - if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING)) { - SSLfatal_ntls(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; - } else { - key_share_key = ssl_generate_pkey_group(s, curve_id); - if (key_share_key == NULL) { - /* SSLfatal_ntls() already called */ - return 0; - } - } - - /* Encode the public key. */ - encodedlen = EVP_PKEY_get1_encoded_public_key(key_share_key, - &encoded_point); - if (encodedlen == 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); - goto err; - } - - /* Create KeyShareEntry */ - if (!WPACKET_put_bytes_u16(pkt, curve_id) - || !WPACKET_sub_memcpy_u16(pkt, encoded_point, encodedlen)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* - * When changing to send more than one key_share we're - * going to need to be able to save more than one EVP_PKEY. For now - * we reuse the existing tmp.pkey - */ - s->s3.tmp.pkey = key_share_key; - s->s3.group_id = curve_id; - OPENSSL_free(encoded_point); - - return 1; - err: - if (s->s3.tmp.pkey == NULL) - EVP_PKEY_free(key_share_key); - OPENSSL_free(encoded_point); - return 0; -} -#endif - -EXT_RETURN tls_construct_ctos_key_share_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - size_t i, num_groups = 0; - const uint16_t *pgroups = NULL; - uint16_t curve_id = 0; - - /* key_share extension */ - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) - /* Extension data sub-packet */ - || !WPACKET_start_sub_packet_u16(pkt) - /* KeyShare list sub-packet */ - || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - tls1_get_supported_groups(s, &pgroups, &num_groups); - - /* - * Make the number of key_shares sent configurable. For - * now, we just send one - */ - if (s->s3.group_id != 0) { - curve_id = s->s3.group_id; - } else { - for (i = 0; i < num_groups; i++) { - - if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) - continue; - - curve_id = pgroups[i]; - break; - } - } - - if (curve_id == 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_KEY_SHARE); - return EXT_RETURN_FAIL; - } - - if (!add_key_share(s, pkt, curve_id)) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - - if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - return EXT_RETURN_SENT; -#else - return EXT_RETURN_NOT_SENT; -#endif -} - -EXT_RETURN tls_construct_ctos_cookie_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ - EXT_RETURN ret = EXT_RETURN_FAIL; - - /* Should only be set if we've had an HRR */ - if (s->ext.tls13_cookie_len == 0) - return EXT_RETURN_NOT_SENT; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie) - /* Extension data sub-packet */ - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_sub_memcpy_u16(pkt, s->ext.tls13_cookie, - s->ext.tls13_cookie_len) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto end; - } - - ret = EXT_RETURN_SENT; - end: - OPENSSL_free(s->ext.tls13_cookie); - s->ext.tls13_cookie = NULL; - s->ext.tls13_cookie_len = 0; - - return ret; -} - -EXT_RETURN tls_construct_ctos_early_data_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_PSK - char identity[PSK_MAX_IDENTITY_LEN + 1]; -#endif /* OPENSSL_NO_PSK */ - const unsigned char *id = NULL; - size_t idlen = 0; - SSL_SESSION *psksess = NULL; - SSL_SESSION *edsess = NULL; - const EVP_MD *handmd = NULL; - - if (s->hello_retry_request == SSL_HRR_PENDING) - handmd = ssl_handshake_md(s); - - if (s->psk_use_session_cb != NULL - && (!s->psk_use_session_cb(s, handmd, &id, &idlen, &psksess) - || (psksess != NULL - && psksess->ssl_version != TLS1_3_VERSION))) { - SSL_SESSION_free(psksess); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); - return EXT_RETURN_FAIL; - } - -#ifndef OPENSSL_NO_PSK - if (psksess == NULL && s->psk_client_callback != NULL) { - unsigned char psk[PSK_MAX_PSK_LEN]; - size_t psklen = 0; - - memset(identity, 0, sizeof(identity)); - psklen = s->psk_client_callback(s, NULL, identity, sizeof(identity) - 1, - psk, sizeof(psk)); - - if (psklen > PSK_MAX_PSK_LEN) { - SSLfatal_ntls(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } else if (psklen > 0) { - const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; - const SSL_CIPHER *cipher; - - idlen = strlen(identity); - if (idlen > PSK_MAX_IDENTITY_LEN) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - id = (unsigned char *)identity; - - /* - * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec - */ - cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id); - if (cipher == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - psksess = SSL_SESSION_new(); - if (psksess == NULL - || !SSL_SESSION_set1_master_key(psksess, psk, psklen) - || !SSL_SESSION_set_cipher(psksess, cipher) - || !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - OPENSSL_cleanse(psk, psklen); - return EXT_RETURN_FAIL; - } - OPENSSL_cleanse(psk, psklen); - } - } -#endif /* OPENSSL_NO_PSK */ - - SSL_SESSION_free(s->psksession); - s->psksession = psksess; - if (psksess != NULL) { - OPENSSL_free(s->psksession_id); - s->psksession_id = OPENSSL_memdup(id, idlen); - if (s->psksession_id == NULL) { - s->psksession_id_len = 0; - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - s->psksession_id_len = idlen; - } - - if (s->early_data_state != SSL_EARLY_DATA_CONNECTING - || (s->session->ext.max_early_data == 0 - && (psksess == NULL || psksess->ext.max_early_data == 0))) { - s->max_early_data = 0; - return EXT_RETURN_NOT_SENT; - } - edsess = s->session->ext.max_early_data != 0 ? s->session : psksess; - s->max_early_data = edsess->ext.max_early_data; - - if (edsess->ext.hostname != NULL) { - if (s->ext.hostname == NULL - || (s->ext.hostname != NULL - && strcmp(s->ext.hostname, edsess->ext.hostname) != 0)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, - SSL_R_INCONSISTENT_EARLY_DATA_SNI); - return EXT_RETURN_FAIL; - } - } - - if ((s->ext.alpn == NULL && edsess->ext.alpn_selected != NULL)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_INCONSISTENT_EARLY_DATA_ALPN); - return EXT_RETURN_FAIL; - } - - /* - * Verify that we are offering an ALPN protocol consistent with the early - * data. - */ - if (edsess->ext.alpn_selected != NULL) { - PACKET prots, alpnpkt; - int found = 0; - - if (!PACKET_buf_init(&prots, s->ext.alpn, s->ext.alpn_len)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - while (PACKET_get_length_prefixed_1(&prots, &alpnpkt)) { - if (PACKET_equal(&alpnpkt, edsess->ext.alpn_selected, - edsess->ext.alpn_selected_len)) { - found = 1; - break; - } - } - if (!found) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, - SSL_R_INCONSISTENT_EARLY_DATA_ALPN); - return EXT_RETURN_FAIL; - } - } - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - /* - * We set this to rejected here. Later, if the server acknowledges the - * extension, we set it to accepted. - */ - s->ext.early_data = SSL_EARLY_DATA_REJECTED; - s->ext.early_data_ok = 1; - - return EXT_RETURN_SENT; -} - #define F5_WORKAROUND_MIN_MSG_LEN 0xff #define F5_WORKAROUND_MAX_MSG_LEN 0x200 @@ -728,232 +404,6 @@ EXT_RETURN tls_construct_ctos_padding_ntls(SSL *s, WPACKET *pkt, return EXT_RETURN_SENT; } -/* - * Construct the pre_shared_key extension - */ -EXT_RETURN tls_construct_ctos_psk_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - uint32_t now, agesec, agems = 0; - size_t reshashsize = 0, pskhashsize = 0, binderoffset, msglen; - unsigned char *resbinder = NULL, *pskbinder = NULL, *msgstart = NULL; - const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL; - int dores = 0; - - s->ext.tick_identity = 0; - - /* - * Note: At this stage of the code we only support adding a single - * resumption PSK. If we add support for multiple PSKs then the length - * calculations in the padding extension will need to be adjusted. - */ - - /* - * If this is an incompatible or new session then we have nothing to resume - * so don't add this extension. - */ - if (s->session->ssl_version != TLS1_3_VERSION - || (s->session->ext.ticklen == 0 && s->psksession == NULL)) - return EXT_RETURN_NOT_SENT; - - if (s->hello_retry_request == SSL_HRR_PENDING) - handmd = ssl_handshake_md(s); - - if (s->session->ext.ticklen != 0) { - /* Get the digest associated with the ciphersuite in the session */ - if (s->session->cipher == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - mdres = ssl_md(s->ctx, s->session->cipher->algorithm2); - if (mdres == NULL) { - /* - * Don't recognize this cipher so we can't use the session. - * Ignore it - */ - goto dopsksess; - } - - if (s->hello_retry_request == SSL_HRR_PENDING && mdres != handmd) { - /* - * Selected ciphersuite hash does not match the hash for the session - * so we can't use it. - */ - goto dopsksess; - } - - /* - * Technically the C standard just says time() returns a time_t and says - * nothing about the encoding of that type. In practice most - * implementations follow POSIX which holds it as an integral type in - * seconds since epoch. We've already made the assumption that we can do - * this in multiple places in the code, so portability shouldn't be an - * issue. - */ - now = (uint32_t)time(NULL); - agesec = now - (uint32_t)s->session->time; - /* - * We calculate the age in seconds but the server may work in ms. Due to - * rounding errors we could overestimate the age by up to 1s. It is - * better to underestimate it. Otherwise, if the RTT is very short, when - * the server calculates the age reported by the client it could be - * bigger than the age calculated on the server - which should never - * happen. - */ - if (agesec > 0) - agesec--; - - if (s->session->ext.tick_lifetime_hint < agesec) { - /* Ticket is too old. Ignore it. */ - goto dopsksess; - } - - /* - * Calculate age in ms. We're just doing it to nearest second. Should be - * good enough. - */ - agems = agesec * (uint32_t)1000; - - if (agesec != 0 && agems / (uint32_t)1000 != agesec) { - /* - * Overflow. Shouldn't happen unless this is a *really* old session. - * If so we just ignore it. - */ - goto dopsksess; - } - - /* - * Obfuscate the age. Overflow here is fine, this addition is supposed - * to be mod 2^32. - */ - agems += s->session->ext.tick_age_add; - - reshashsize = EVP_MD_get_size(mdres); - s->ext.tick_identity++; - dores = 1; - } - - dopsksess: - if (!dores && s->psksession == NULL) - return EXT_RETURN_NOT_SENT; - - if (s->psksession != NULL) { - mdpsk = ssl_md(s->ctx, s->psksession->cipher->algorithm2); - if (mdpsk == NULL) { - /* - * Don't recognize this cipher so we can't use the session. - * If this happens it's an application bug. - */ - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); - return EXT_RETURN_FAIL; - } - - if (s->hello_retry_request == SSL_HRR_PENDING && mdpsk != handmd) { - /* - * Selected ciphersuite hash does not match the hash for the PSK - * session. This is an application bug. - */ - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); - return EXT_RETURN_FAIL; - } - - pskhashsize = EVP_MD_get_size(mdpsk); - } - - /* Create the extension, but skip over the binder for now */ - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - if (dores) { - if (!WPACKET_sub_memcpy_u16(pkt, s->session->ext.tick, - s->session->ext.ticklen) - || !WPACKET_put_bytes_u32(pkt, agems)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - } - - if (s->psksession != NULL) { - if (!WPACKET_sub_memcpy_u16(pkt, s->psksession_id, - s->psksession_id_len) - || !WPACKET_put_bytes_u32(pkt, 0)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - s->ext.tick_identity++; - } - - if (!WPACKET_close(pkt) - || !WPACKET_get_total_written(pkt, &binderoffset) - || !WPACKET_start_sub_packet_u16(pkt) - || (dores - && !WPACKET_sub_allocate_bytes_u8(pkt, reshashsize, &resbinder)) - || (s->psksession != NULL - && !WPACKET_sub_allocate_bytes_u8(pkt, pskhashsize, &pskbinder)) - || !WPACKET_close(pkt) - || !WPACKET_close(pkt) - || !WPACKET_get_total_written(pkt, &msglen) - /* - * We need to fill in all the sub-packet lengths now so we can - * calculate the HMAC of the message up to the binders - */ - || !WPACKET_fill_lengths(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - msgstart = WPACKET_get_curr(pkt) - msglen; - - if (dores - && tls_psk_do_binder_ntls(s, mdres, msgstart, binderoffset, NULL, - resbinder, s->session, 1, 0) != 1) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - - if (s->psksession != NULL - && tls_psk_do_binder_ntls(s, mdpsk, msgstart, binderoffset, NULL, - pskbinder, s->psksession, 1, 1) != 1) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - - return EXT_RETURN_SENT; -#else - return EXT_RETURN_NOT_SENT; -#endif -} - -EXT_RETURN tls_construct_ctos_post_handshake_auth_ntls(SSL *s, WPACKET *pkt, - ossl_unused unsigned int context, - ossl_unused X509 *x, - ossl_unused size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - if (!s->pha_enabled) - return EXT_RETURN_NOT_SENT; - - /* construct extension - 0 length, no contents */ - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_post_handshake_auth) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - s->post_handshake_auth = SSL_PHA_EXT_SENT; - - return EXT_RETURN_SENT; -#else - return EXT_RETURN_NOT_SENT; -#endif -} - /* Parse the server's max fragment len extension packet */ int tls_parse_stoc_maxfragmentlen_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1353,250 +803,3 @@ int tls_parse_stoc_supported_versions_ntls(SSL *s, PACKET *pkt, unsigned int con /* Ignore supported_versions */ return 1; } - -int tls_parse_stoc_key_share_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - unsigned int group_id; - PACKET encoded_pt; - EVP_PKEY *ckey = s->s3.tmp.pkey, *skey = NULL; - const TLS_GROUP_INFO *ginf = NULL; - - /* Sanity check */ - if (ckey == NULL || s->s3.peer_tmp != NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (!PACKET_get_net_2(pkt, &group_id)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - if ((context & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) { - const uint16_t *pgroups = NULL; - size_t i, num_groups; - - if (PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - /* - * It is an error if the HelloRetryRequest wants a key_share that we - * already sent in the first ClientHello - */ - if (group_id == s->s3.group_id) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - - /* Validate the selected group is one we support */ - tls1_get_supported_groups(s, &pgroups, &num_groups); - for (i = 0; i < num_groups; i++) { - if (group_id == pgroups[i]) - break; - } - if (i >= num_groups - || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED)) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - - s->s3.group_id = group_id; - EVP_PKEY_free(s->s3.tmp.pkey); - s->s3.tmp.pkey = NULL; - return 1; - } - - if (group_id != s->s3.group_id) { - /* - * This isn't for the group that we sent in the original - * key_share! - */ - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - /* Retain this group in the SSL_SESSION */ - if (!s->hit) { - s->session->kex_group = group_id; - } else if (group_id != s->session->kex_group) { - /* - * If this is a resumption but changed what group was used, we need - * to record the new group in the session, but the session is not - * a new session and could be in use by other threads. So, make - * a copy of the session to record the new information so that it's - * useful for any sessions resumed from tickets issued on this - * connection. - */ - SSL_SESSION *new_sess; - - if ((new_sess = ssl_session_dup(s->session, 0)) == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - return 0; - } - SSL_SESSION_free(s->session); - s->session = new_sess; - s->session->kex_group = group_id; - } - - if ((ginf = tls1_group_id_lookup(s->ctx, group_id)) == NULL) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - - if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt) - || PACKET_remaining(&encoded_pt) == 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - if (!ginf->is_kem) { - /* Regular KEX */ - skey = EVP_PKEY_new(); - if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_COPY_PARAMETERS_FAILED); - EVP_PKEY_free(skey); - return 0; - } - - if (tls13_set_encoded_pub_key(skey, PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt)) <= 0) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT); - EVP_PKEY_free(skey); - return 0; - } - - if (ssl_derive(s, ckey, skey, 1) == 0) { - /* SSLfatal_ntls() already called */ - EVP_PKEY_free(skey); - return 0; - } - s->s3.peer_tmp = skey; - } else { - /* KEM Mode */ - const unsigned char *ct = PACKET_data(&encoded_pt); - size_t ctlen = PACKET_remaining(&encoded_pt); - - if (ssl_decapsulate(s, ckey, ct, ctlen, 1) == 0) { - /* SSLfatal_ntls() already called */ - return 0; - } - } - s->s3.did_kex = 1; -#endif - - return 1; -} - -int tls_parse_stoc_cookie_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) -{ - PACKET cookie; - - if (!PACKET_as_length_prefixed_2(pkt, &cookie) - || !PACKET_memdup(&cookie, &s->ext.tls13_cookie, - &s->ext.tls13_cookie_len)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - return 1; -} - -int tls_parse_stoc_early_data_ntls(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ - if (context == SSL_EXT_TLS1_3_NEW_SESSION_TICKET) { - unsigned long max_early_data; - - if (!PACKET_get_net_4(pkt, &max_early_data) - || PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_INVALID_MAX_EARLY_DATA); - return 0; - } - - s->session->ext.max_early_data = max_early_data; - - return 1; - } - - if (PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - - if (!s->ext.early_data_ok - || !s->hit) { - /* - * If we get here then we didn't send early data, or we didn't resume - * using the first identity, or the SNI/ALPN is not consistent so the - * server should not be accepting it. - */ - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); - return 0; - } - - s->ext.early_data = SSL_EARLY_DATA_ACCEPTED; - - return 1; -} - -int tls_parse_stoc_psk_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - unsigned int identity; - - if (!PACKET_get_net_2(pkt, &identity) || PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - if (identity >= (unsigned int)s->ext.tick_identity) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PSK_IDENTITY); - return 0; - } - - /* - * Session resumption tickets are always sent before PSK tickets. If the - * ticket index is 0 then it must be for a session resumption ticket if we - * sent two tickets, or if we didn't send a PSK ticket. - */ - if (identity == 0 && (s->psksession == NULL || s->ext.tick_identity == 2)) { - s->hit = 1; - SSL_SESSION_free(s->psksession); - s->psksession = NULL; - return 1; - } - - if (s->psksession == NULL) { - /* Should never happen */ - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - /* - * If we used the external PSK for sending early_data then s->early_secret - * is already set up, so don't overwrite it. Otherwise we copy the - * early_secret across that we generated earlier. - */ - if ((s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY - && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) - || s->session->ext.max_early_data > 0 - || s->psksession->ext.max_early_data == 0) - memcpy(s->early_secret, s->psksession->early_secret, EVP_MAX_MD_SIZE); - - SSL_SESSION_free(s->session); - s->session = s->psksession; - s->psksession = NULL; - s->hit = 1; - /* Early data is only allowed if we used the first ticket */ - if (identity != 0) - s->ext.early_data_ok = 0; -#endif - - return 1; -} - diff --git a/ssl/statem_ntls/ntls_extensions_srvr.c b/ssl/statem_ntls/ntls_extensions_srvr.c index 7d8aacde4..0c4e4d60d 100644 --- a/ssl/statem_ntls/ntls_extensions_srvr.c +++ b/ssl/statem_ntls/ntls_extensions_srvr.c @@ -438,357 +438,6 @@ int tls_parse_ctos_etm_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -/* - * Process a psk_kex_modes extension received in the ClientHello. |pkt| contains - * the raw PACKET data for the extension. Returns 1 on success or 0 on failure. - */ -int tls_parse_ctos_psk_kex_modes_ntls(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - PACKET psk_kex_modes; - unsigned int mode; - - if (!PACKET_as_length_prefixed_1(pkt, &psk_kex_modes) - || PACKET_remaining(&psk_kex_modes) == 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - - while (PACKET_get_1(&psk_kex_modes, &mode)) { - if (mode == TLSEXT_KEX_MODE_KE_DHE) - s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE_DHE; - else if (mode == TLSEXT_KEX_MODE_KE - && (s->options & SSL_OP_ALLOW_NO_DHE_KEX) != 0) - s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE; - } -#endif - - return 1; -} - -/* - * Process a key_share extension received in the ClientHello. |pkt| contains - * the raw PACKET data for the extension. Returns 1 on success or 0 on failure. - */ -int tls_parse_ctos_key_share_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - unsigned int group_id; - PACKET key_share_list, encoded_pt; - const uint16_t *clntgroups, *srvrgroups; - size_t clnt_num_groups, srvr_num_groups; - int found = 0; - - if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) - return 1; - - /* Sanity check */ - if (s->s3.peer_tmp != NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - /* Get our list of supported groups */ - tls1_get_supported_groups(s, &srvrgroups, &srvr_num_groups); - /* Get the clients list of supported groups. */ - tls1_get_peer_groups(s, &clntgroups, &clnt_num_groups); - if (clnt_num_groups == 0) { - /* - * This can only happen if the supported_groups extension was not sent, - * because we verify that the length is non-zero when we process that - * extension. - */ - SSLfatal_ntls(s, SSL_AD_MISSING_EXTENSION, - SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION); - return 0; - } - - if (s->s3.group_id != 0 && PACKET_remaining(&key_share_list) == 0) { - /* - * If we set a group_id already, then we must have sent an HRR - * requesting a new key_share. If we haven't got one then that is an - * error - */ - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - - while (PACKET_remaining(&key_share_list) > 0) { - if (!PACKET_get_net_2(&key_share_list, &group_id) - || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt) - || PACKET_remaining(&encoded_pt) == 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - /* - * If we already found a suitable key_share we loop through the - * rest to verify the structure, but don't process them. - */ - if (found) - continue; - - /* - * If we sent an HRR then the key_share sent back MUST be for the group - * we requested, and must be the only key_share sent. - */ - if (s->s3.group_id != 0 - && (group_id != s->s3.group_id - || PACKET_remaining(&key_share_list) != 0)) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - - /* Check if this share is in supported_groups sent from client */ - if (!check_in_list_ntls(s, group_id, clntgroups, clnt_num_groups, 0)) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); - return 0; - } - - /* Check if this share is for a group we can use */ - if (!check_in_list_ntls(s, group_id, srvrgroups, srvr_num_groups, 1)) { - /* Share not suitable */ - continue; - } - - if ((s->s3.peer_tmp = ssl_generate_param_group(s, group_id)) == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, - SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); - return 0; - } - - s->s3.group_id = group_id; - /* Cache the selected group ID in the SSL_SESSION */ - s->session->kex_group = group_id; - - if (tls13_set_encoded_pub_key(s->s3.peer_tmp, - PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt)) <= 0) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT); - return 0; - } - - found = 1; - } -#endif - - return 1; -} - -int tls_parse_ctos_cookie_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - unsigned int format, version, key_share, group_id; - EVP_MD_CTX *hctx; - EVP_PKEY *pkey; - PACKET cookie, raw, chhash, appcookie; - WPACKET hrrpkt; - const unsigned char *data, *mdin, *ciphdata; - unsigned char hmac[SHA256_DIGEST_LENGTH]; - unsigned char hrr[MAX_HRR_SIZE]; - size_t rawlen, hmaclen, hrrlen, ciphlen; - unsigned long tm, now; - - /* Ignore any cookie if we're not set up to verify it */ - if (s->ctx->verify_stateless_cookie_cb == NULL - || (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) - return 1; - - if (!PACKET_as_length_prefixed_2(pkt, &cookie)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - raw = cookie; - data = PACKET_data(&raw); - rawlen = PACKET_remaining(&raw); - if (rawlen < SHA256_DIGEST_LENGTH - || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - mdin = PACKET_data(&raw); - - /* Verify the HMAC of the cookie */ - hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", - s->ctx->propq, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext.cookie_hmac_key)); - if (hctx == NULL || pkey == NULL) { - EVP_MD_CTX_free(hctx); - EVP_PKEY_free(pkey); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - return 0; - } - - hmaclen = SHA256_DIGEST_LENGTH; - if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, - s->ctx->propq, pkey, NULL) <= 0 - || EVP_DigestSign(hctx, hmac, &hmaclen, data, - rawlen - SHA256_DIGEST_LENGTH) <= 0 - || hmaclen != SHA256_DIGEST_LENGTH) { - EVP_MD_CTX_free(hctx); - EVP_PKEY_free(pkey); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - EVP_MD_CTX_free(hctx); - EVP_PKEY_free(pkey); - - if (CRYPTO_memcmp(hmac, mdin, SHA256_DIGEST_LENGTH) != 0) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COOKIE_MISMATCH); - return 0; - } - - if (!PACKET_get_net_2(&cookie, &format)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - /* Check the cookie format is something we recognise. Ignore it if not */ - if (format != COOKIE_STATE_FORMAT_VERSION) - return 1; - - /* - * The rest of these checks really shouldn't fail since we have verified the - * HMAC above. - */ - - /* Check the version number is sane */ - if (!PACKET_get_net_2(&cookie, &version)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - if (version != TLS1_3_VERSION) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_R_BAD_PROTOCOL_VERSION_NUMBER); - return 0; - } - - if (!PACKET_get_net_2(&cookie, &group_id)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - ciphdata = PACKET_data(&cookie); - if (!PACKET_forward(&cookie, 2)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - if (group_id != s->s3.group_id - || s->s3.tmp.new_cipher - != ssl_get_cipher_by_char(s, ciphdata, 0)) { - /* - * We chose a different cipher or group id this time around to what is - * in the cookie. Something must have changed. - */ - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_CIPHER); - return 0; - } - - if (!PACKET_get_1(&cookie, &key_share) - || !PACKET_get_net_4(&cookie, &tm) - || !PACKET_get_length_prefixed_2(&cookie, &chhash) - || !PACKET_get_length_prefixed_1(&cookie, &appcookie) - || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); - return 0; - } - - /* We tolerate a cookie age of up to 10 minutes (= 60 * 10 seconds) */ - now = (unsigned long)time(NULL); - if (tm > now || (now - tm) > 600) { - /* Cookie is stale. Ignore it */ - return 1; - } - - /* Verify the app cookie */ - if (s->ctx->verify_stateless_cookie_cb(s, PACKET_data(&appcookie), - PACKET_remaining(&appcookie)) == 0) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COOKIE_MISMATCH); - return 0; - } - - /* - * Reconstruct the HRR that we would have sent in response to the original - * ClientHello so we can add it to the transcript hash. - * Note: This won't work with custom HRR extensions - */ - if (!WPACKET_init_static_len(&hrrpkt, hrr, sizeof(hrr), 0)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO) - || !WPACKET_start_sub_packet_u24(&hrrpkt) - || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION) - || !WPACKET_memcpy(&hrrpkt, hrrrandom_ntls, SSL3_RANDOM_SIZE) - || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id, - s->tmp_session_id_len) - || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, &hrrpkt, - &ciphlen) - || !WPACKET_put_bytes_u8(&hrrpkt, 0) - || !WPACKET_start_sub_packet_u16(&hrrpkt)) { - WPACKET_cleanup(&hrrpkt); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions) - || !WPACKET_start_sub_packet_u16(&hrrpkt) - || !WPACKET_put_bytes_u16(&hrrpkt, s->version) - || !WPACKET_close(&hrrpkt)) { - WPACKET_cleanup(&hrrpkt); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - if (key_share) { - if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share) - || !WPACKET_start_sub_packet_u16(&hrrpkt) - || !WPACKET_put_bytes_u16(&hrrpkt, s->s3.group_id) - || !WPACKET_close(&hrrpkt)) { - WPACKET_cleanup(&hrrpkt); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - } - if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_cookie) - || !WPACKET_start_sub_packet_u16(&hrrpkt) - || !WPACKET_sub_memcpy_u16(&hrrpkt, data, rawlen) - || !WPACKET_close(&hrrpkt) /* cookie extension */ - || !WPACKET_close(&hrrpkt) /* extension block */ - || !WPACKET_close(&hrrpkt) /* message */ - || !WPACKET_get_total_written(&hrrpkt, &hrrlen) - || !WPACKET_finish(&hrrpkt)) { - WPACKET_cleanup(&hrrpkt); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - /* Reconstruct the transcript hash */ - if (!create_synthetic_message_hash_ntls(s, PACKET_data(&chhash), - PACKET_remaining(&chhash), hrr, - hrrlen)) { - /* SSLfatal_ntls() already called */ - return 0; - } - - /* Act as if this ClientHello came after a HelloRetryRequest */ - s->hello_retry_request = 1; - - s->ext.cookieok = 1; -#endif - - return 1; -} - int tls_parse_ctos_supported_groups_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -803,299 +452,6 @@ int tls_parse_ctos_ems_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } - -int tls_parse_ctos_early_data_ntls(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ - if (PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - - if (s->hello_retry_request != SSL_HRR_NONE) { - SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); - return 0; - } - - return 1; -} - -static SSL_TICKET_STATUS tls_get_stateful_ticket(SSL *s, PACKET *tick, - SSL_SESSION **sess) -{ - SSL_SESSION *tmpsess = NULL; - - s->ext.ticket_expected = 1; - - switch (PACKET_remaining(tick)) { - case 0: - return SSL_TICKET_EMPTY; - - case SSL_MAX_SSL_SESSION_ID_LENGTH: - break; - - default: - return SSL_TICKET_NO_DECRYPT; - } - - tmpsess = lookup_sess_in_cache(s, PACKET_data(tick), - SSL_MAX_SSL_SESSION_ID_LENGTH); - - if (tmpsess == NULL) - return SSL_TICKET_NO_DECRYPT; - - *sess = tmpsess; - return SSL_TICKET_SUCCESS; -} - -int tls_parse_ctos_psk_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx) -{ - PACKET identities, binders, binder; - size_t binderoffset, hashsize; - SSL_SESSION *sess = NULL; - unsigned int id, i, ext = 0; - const EVP_MD *md = NULL; - - /* - * If we have no PSK kex mode that we recognise then we can't resume so - * ignore this extension - */ - if ((s->ext.psk_kex_mode - & (TLSEXT_KEX_MODE_FLAG_KE | TLSEXT_KEX_MODE_FLAG_KE_DHE)) == 0) - return 1; - - if (!PACKET_get_length_prefixed_2(pkt, &identities)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - - s->ext.ticket_expected = 0; - for (id = 0; PACKET_remaining(&identities) != 0; id++) { - PACKET identity; - unsigned long ticket_agel; - size_t idlen; - - if (!PACKET_get_length_prefixed_2(&identities, &identity) - || !PACKET_get_net_4(&identities, &ticket_agel)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - - idlen = PACKET_remaining(&identity); - if (s->psk_find_session_cb != NULL - && !s->psk_find_session_cb(s, PACKET_data(&identity), idlen, - &sess)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - -#ifndef OPENSSL_NO_PSK - if(sess == NULL - && s->psk_server_callback != NULL - && idlen <= PSK_MAX_IDENTITY_LEN) { - char *pskid = NULL; - unsigned char pskdata[PSK_MAX_PSK_LEN]; - unsigned int pskdatalen; - - if (!PACKET_strndup(&identity, &pskid)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - pskdatalen = s->psk_server_callback(s, pskid, pskdata, - sizeof(pskdata)); - OPENSSL_free(pskid); - if (pskdatalen > PSK_MAX_PSK_LEN) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } else if (pskdatalen > 0) { - const SSL_CIPHER *cipher; - const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; - - /* - * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec - */ - cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id); - if (cipher == NULL) { - OPENSSL_cleanse(pskdata, pskdatalen); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - - sess = SSL_SESSION_new(); - if (sess == NULL - || !SSL_SESSION_set1_master_key(sess, pskdata, - pskdatalen) - || !SSL_SESSION_set_cipher(sess, cipher) - || !SSL_SESSION_set_protocol_version(sess, - TLS1_3_VERSION)) { - OPENSSL_cleanse(pskdata, pskdatalen); - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - OPENSSL_cleanse(pskdata, pskdatalen); - } - } -#endif /* OPENSSL_NO_PSK */ - - if (sess != NULL) { - /* We found a PSK */ - SSL_SESSION *sesstmp = ssl_session_dup(sess, 0); - - if (sesstmp == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - SSL_SESSION_free(sess); - sess = sesstmp; - - /* - * We've just been told to use this session for this context so - * make sure the sid_ctx matches up. - */ - memcpy(sess->sid_ctx, s->sid_ctx, s->sid_ctx_length); - sess->sid_ctx_length = s->sid_ctx_length; - ext = 1; - if (id == 0) - s->ext.early_data_ok = 1; - s->ext.ticket_expected = 1; - } else { - uint32_t ticket_age = 0, now, agesec, agems; - int ret; - - /* - * If we are using anti-replay protection then we behave as if - * SSL_OP_NO_TICKET is set - we are caching tickets anyway so there - * is no point in using full stateless tickets. - */ - if ((s->options & SSL_OP_NO_TICKET) != 0 - || (s->max_early_data > 0 - && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0)) - ret = tls_get_stateful_ticket(s, &identity, &sess); - else - ret = tls_decrypt_ticket(s, PACKET_data(&identity), - PACKET_remaining(&identity), NULL, 0, - &sess); - - if (ret == SSL_TICKET_EMPTY) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - return 0; - } - - if (ret == SSL_TICKET_FATAL_ERR_MALLOC - || ret == SSL_TICKET_FATAL_ERR_OTHER) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - if (ret == SSL_TICKET_NONE || ret == SSL_TICKET_NO_DECRYPT) - continue; - - /* Check for replay */ - if (s->max_early_data > 0 - && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0 - && !SSL_CTX_remove_session(s->session_ctx, sess)) { - SSL_SESSION_free(sess); - sess = NULL; - continue; - } - - ticket_age = (uint32_t)ticket_agel; - now = (uint32_t)time(NULL); - agesec = now - (uint32_t)sess->time; - agems = agesec * (uint32_t)1000; - ticket_age -= sess->ext.tick_age_add; - - /* - * For simplicity we do our age calculations in seconds. If the - * client does it in ms then it could appear that their ticket age - * is longer than ours (our ticket age calculation should always be - * slightly longer than the client's due to the network latency). - * Therefore we add 1000ms to our age calculation to adjust for - * rounding errors. - */ - if (id == 0 - && sess->timeout >= (long)agesec - && agems / (uint32_t)1000 == agesec - && ticket_age <= agems + 1000 - && ticket_age + TICKET_AGE_ALLOWANCE >= agems + 1000) { - /* - * Ticket age is within tolerance and not expired. We allow it - * for early data - */ - s->ext.early_data_ok = 1; - } - } - - md = ssl_md(s->ctx, sess->cipher->algorithm2); - if (!EVP_MD_is_a(md, - EVP_MD_get0_name(ssl_md(s->ctx, - s->s3.tmp.new_cipher->algorithm2)))) { - /* The ciphersuite is not compatible with this session. */ - SSL_SESSION_free(sess); - sess = NULL; - s->ext.early_data_ok = 0; - s->ext.ticket_expected = 0; - continue; - } - break; - } - - if (sess == NULL) - return 1; - - binderoffset = PACKET_data(pkt) - (const unsigned char *)s->init_buf->data; - hashsize = EVP_MD_get_size(md); - - if (!PACKET_get_length_prefixed_2(pkt, &binders)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - goto err; - } - - for (i = 0; i <= id; i++) { - if (!PACKET_get_length_prefixed_1(&binders, &binder)) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - goto err; - } - } - - if (PACKET_remaining(&binder) != hashsize) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); - goto err; - } - if (tls_psk_do_binder_ntls(s, md, (const unsigned char *)s->init_buf->data, - binderoffset, PACKET_data(&binder), NULL, sess, 0, - ext) != 1) { - /* SSLfatal_ntls() already called */ - goto err; - } - - s->ext.tick_identity = id; - - SSL_SESSION_free(s->session); - s->session = sess; - return 1; -err: - SSL_SESSION_free(sess); - return 0; -} - -int tls_parse_ctos_post_handshake_auth_ntls(SSL *s, PACKET *pkt, - ossl_unused unsigned int context, - ossl_unused X509 *x, - ossl_unused size_t chainidx) -{ - if (PACKET_remaining(pkt) != 0) { - SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, - SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR); - return 0; - } - - s->post_handshake_auth = SSL_PHA_EXT_RECEIVED; - - return 1; -} - EXT_RETURN tls_construct_stoc_server_name_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1301,309 +657,3 @@ EXT_RETURN tls_construct_stoc_supported_versions_ntls(SSL *s, WPACKET *pkt, /* No supported_versions */ return EXT_RETURN_NOT_SENT; } - -EXT_RETURN tls_construct_stoc_key_share_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - unsigned char *encodedPoint; - size_t encoded_pt_len = 0; - EVP_PKEY *ckey = s->s3.peer_tmp, *skey = NULL; - const TLS_GROUP_INFO *ginf = NULL; - - if (s->hello_retry_request == SSL_HRR_PENDING) { - if (ckey != NULL) { - /* Original key_share was acceptable so don't ask for another one */ - return EXT_RETURN_NOT_SENT; - } - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - return EXT_RETURN_SENT; - } - - if (ckey == NULL) { - /* No key_share received from client - must be resuming */ - if (!s->hit || !tls13_generate_handshake_secret(s, NULL, 0)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - return EXT_RETURN_NOT_SENT; - } - if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) { - /* - * PSK ('hit') and explicitly not doing DHE (if the client sent the - * DHE option we always take it); don't send key share. - */ - return EXT_RETURN_NOT_SENT; - } - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->s3.group_id)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - if ((ginf = tls1_group_id_lookup(s->ctx, s->s3.group_id)) == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - if (!ginf->is_kem) { - /* Regular KEX */ - skey = ssl_generate_pkey(s, ckey); - if (skey == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - return EXT_RETURN_FAIL; - } - - /* Generate encoding of server key */ - encoded_pt_len = EVP_PKEY_get1_encoded_public_key(skey, &encodedPoint); - if (encoded_pt_len == 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); - EVP_PKEY_free(skey); - return EXT_RETURN_FAIL; - } - - if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(skey); - OPENSSL_free(encodedPoint); - return EXT_RETURN_FAIL; - } - OPENSSL_free(encodedPoint); - - /* - * This causes the crypto state to be updated based on the derived keys - */ - s->s3.tmp.pkey = skey; - if (ssl_derive(s, skey, ckey, 1) == 0) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - } else { - /* KEM mode */ - unsigned char *ct = NULL; - size_t ctlen = 0; - - /* - * This does not update the crypto state. - * - * The generated pms is stored in `s->s3.tmp.pms` to be later used via - * ssl_gensecret(). - */ - if (ssl_encapsulate(s, ckey, &ct, &ctlen, 0) == 0) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - - if (ctlen == 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - OPENSSL_free(ct); - return EXT_RETURN_FAIL; - } - - if (!WPACKET_sub_memcpy_u16(pkt, ct, ctlen) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - OPENSSL_free(ct); - return EXT_RETURN_FAIL; - } - OPENSSL_free(ct); - - /* - * This causes the crypto state to be updated based on the generated pms - */ - if (ssl_gensecret(s, s->s3.tmp.pms, s->s3.tmp.pmslen) == 0) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - } - s->s3.did_kex = 1; - return EXT_RETURN_SENT; -#else - return EXT_RETURN_FAIL; -#endif -} - -EXT_RETURN tls_construct_stoc_cookie_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ -#ifndef OPENSSL_NO_TLS1_3 - unsigned char *hashval1, *hashval2, *appcookie1, *appcookie2, *cookie; - unsigned char *hmac, *hmac2; - size_t startlen, ciphlen, totcookielen, hashlen, hmaclen, appcookielen; - EVP_MD_CTX *hctx; - EVP_PKEY *pkey; - int ret = EXT_RETURN_FAIL; - - if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) - return EXT_RETURN_NOT_SENT; - - if (s->ctx->gen_stateless_cookie_cb == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_COOKIE_CALLBACK_SET); - return EXT_RETURN_FAIL; - } - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_get_total_written(pkt, &startlen) - || !WPACKET_reserve_bytes(pkt, MAX_COOKIE_SIZE, &cookie) - || !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION) - || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION) - || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) - || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, - &ciphlen) - /* Is there a key_share extension present in this HRR? */ - || !WPACKET_put_bytes_u8(pkt, s->s3.peer_tmp == NULL) - || !WPACKET_put_bytes_u32(pkt, (unsigned int)time(NULL)) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &hashval1)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - /* - * Get the hash of the initial ClientHello. ssl_handshake_hash() operates - * on raw buffers, so we first reserve sufficient bytes (above) and then - * subsequently allocate them (below) - */ - if (!ssl3_digest_cached_records(s, 0) - || !ssl_handshake_hash(s, hashval1, EVP_MAX_MD_SIZE, &hashlen)) { - /* SSLfatal_ntls() already called */ - return EXT_RETURN_FAIL; - } - - if (!WPACKET_allocate_bytes(pkt, hashlen, &hashval2) - || !ossl_assert(hashval1 == hashval2) - || !WPACKET_close(pkt) - || !WPACKET_start_sub_packet_u8(pkt) - || !WPACKET_reserve_bytes(pkt, SSL_COOKIE_LENGTH, &appcookie1)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - /* Generate the application cookie */ - if (s->ctx->gen_stateless_cookie_cb(s, appcookie1, &appcookielen) == 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); - return EXT_RETURN_FAIL; - } - - if (!WPACKET_allocate_bytes(pkt, appcookielen, &appcookie2) - || !ossl_assert(appcookie1 == appcookie2) - || !WPACKET_close(pkt) - || !WPACKET_get_total_written(pkt, &totcookielen) - || !WPACKET_reserve_bytes(pkt, SHA256_DIGEST_LENGTH, &hmac)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - hmaclen = SHA256_DIGEST_LENGTH; - - totcookielen -= startlen; - if (!ossl_assert(totcookielen <= MAX_COOKIE_SIZE - SHA256_DIGEST_LENGTH)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - /* HMAC the cookie */ - hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", - s->ctx->propq, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext.cookie_hmac_key)); - if (hctx == NULL || pkey == NULL) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, - s->ctx->propq, pkey, NULL) <= 0 - || EVP_DigestSign(hctx, hmac, &hmaclen, cookie, - totcookielen) <= 0) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!ossl_assert(totcookielen + hmaclen <= MAX_COOKIE_SIZE)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!WPACKET_allocate_bytes(pkt, hmaclen, &hmac2) - || !ossl_assert(hmac == hmac2) - || !ossl_assert(cookie == hmac - totcookielen) - || !WPACKET_close(pkt) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; - } - - ret = EXT_RETURN_SENT; - - err: - EVP_MD_CTX_free(hctx); - EVP_PKEY_free(pkey); - return ret; -#else - return EXT_RETURN_FAIL; -#endif -} - -EXT_RETURN tls_construct_stoc_early_data_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ - if (context == SSL_EXT_TLS1_3_NEW_SESSION_TICKET) { - if (s->max_early_data == 0) - return EXT_RETURN_NOT_SENT; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u32(pkt, s->max_early_data) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - return EXT_RETURN_SENT; - } - - if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED) - return EXT_RETURN_NOT_SENT; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - return EXT_RETURN_SENT; -} - -EXT_RETURN tls_construct_stoc_psk_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) -{ - if (!s->hit) - return EXT_RETURN_NOT_SENT; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk) - || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->ext.tick_identity) - || !WPACKET_close(pkt)) { - SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - return EXT_RETURN_SENT; -} - diff --git a/ssl/statem_ntls/ntls_statem_local.h b/ssl/statem_ntls/ntls_statem_local.h index c48ad6481..0cffbbe93 100644 --- a/ssl/statem_ntls/ntls_statem_local.h +++ b/ssl/statem_ntls/ntls_statem_local.h @@ -205,8 +205,6 @@ int tls_parse_ctos_server_name_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_ctos_maxfragmentlen_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_early_data_ntls(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); int tls_parse_ctos_ec_pt_formats_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_ctos_supported_groups_ntls(SSL *s, PACKET *pkt, unsigned int context, @@ -233,24 +231,11 @@ int tls_parse_ctos_use_srtp_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 #endif int tls_parse_ctos_etm_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_key_share_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_cookie_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); int tls_parse_ctos_ems_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -int tls_parse_ctos_psk_kex_modes_ntls(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); -int tls_parse_ctos_psk_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_ctos_post_handshake_auth_ntls(SSL *, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); EXT_RETURN tls_construct_stoc_server_name_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_early_data_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); EXT_RETURN tls_construct_stoc_maxfragmentlen_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); @@ -286,15 +271,6 @@ EXT_RETURN tls_construct_stoc_ems_ntls(SSL *s, WPACKET *pkt, unsigned int contex EXT_RETURN tls_construct_stoc_supported_versions_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_stoc_key_share_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); -EXT_RETURN tls_construct_stoc_cookie_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); - -EXT_RETURN tls_construct_stoc_psk_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); - /* Client Extension processing */ EXT_RETURN tls_construct_ctos_server_name_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); @@ -307,9 +283,6 @@ EXT_RETURN tls_construct_ctos_ec_pt_formats_ntls(SSL *s, WPACKET *pkt, EXT_RETURN tls_construct_ctos_supported_groups_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_early_data_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); EXT_RETURN tls_construct_ctos_session_ticket_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); @@ -342,26 +315,11 @@ EXT_RETURN tls_construct_ctos_ems_ntls(SSL *s, WPACKET *pkt, unsigned int contex EXT_RETURN tls_construct_ctos_supported_versions_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_key_share_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); -EXT_RETURN tls_construct_ctos_psk_kex_modes_ntls(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); -EXT_RETURN tls_construct_ctos_cookie_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); EXT_RETURN tls_construct_ctos_padding_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_psk_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_post_handshake_auth_ntls(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); - int tls_parse_stoc_server_name_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_early_data_ntls(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx); int tls_parse_stoc_maxfragmentlen_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_stoc_ec_pt_formats_ntls(SSL *s, PACKET *pkt, unsigned int context, @@ -392,13 +350,6 @@ int tls_parse_stoc_ems_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_stoc_supported_versions_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -int tls_parse_stoc_key_share_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_stoc_cookie_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); -int tls_parse_stoc_psk_ntls(SSL *s, PACKET *pkt, unsigned int context, X509 *x, - size_t chainidx); - int tls_handle_alpn_ntls(SSL *s); int tls13_save_handshake_digest_for_pha_ntls(SSL *s); From e0d987b75176ad842bc605faf6d8764e1a326199 Mon Sep 17 00:00:00 2001 From: K1 Date: Wed, 19 Jun 2024 22:58:52 +0800 Subject: [PATCH 4/4] Fix coverity issues, resource leaks CID: 488393, 471339, 471290, 471289, 471287, 471282, 471281, 471279, 471246, 471237, 471221, 471204, 471196, 471180, 471171, 471169, 471162, 278385, 21756. --- apps/speed.c | 1 + crypto/ec/ec_elgamal_crypt.c | 2 +- crypto/ec/ec_lib.c | 18 ++++++++---------- crypto/zkp/bulletproofs/bulletproofs_encode.c | 4 +++- crypto/zkp/gadget/zkp_range_proof.c | 1 + crypto/zkp/nizk/nizk_encode.c | 2 +- test/bntest.c | 1 + test/bulletproofs_test.c | 2 ++ test/nizk_test.c | 4 ++++ test/paillier_internal_test.c | 2 ++ test/pkcs12_format_test.c | 1 + test/zkp_gadget_test.c | 3 --- 12 files changed, 25 insertions(+), 16 deletions(-) diff --git a/apps/speed.c b/apps/speed.c index 8a013a96b..f1d1e5543 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -4883,6 +4883,7 @@ static int do_multi(int multi, int size_num) close(1); if (dup(fd[1]) == -1) { BIO_printf(bio_err, "dup failed\n"); + close(fd[1]); exit(1); } close(fd[1]); diff --git a/crypto/ec/ec_elgamal_crypt.c b/crypto/ec/ec_elgamal_crypt.c index a6fe59749..6661e8bff 100644 --- a/crypto/ec/ec_elgamal_crypt.c +++ b/crypto/ec/ec_elgamal_crypt.c @@ -199,7 +199,7 @@ EC_ELGAMAL_MR_CTX *EC_ELGAMAL_MR_CTX_new(STACK_OF(EC_KEY) *keys, const EC_POINT if (h != NULL) { if (!(ctx->h = EC_POINT_dup(h, ctx->group))) - return 0; + goto err; } else { ctx->h = EC_POINT_new(group); if (ctx->h == NULL) { diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 62d3b5d56..914fd163d 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -1546,13 +1546,13 @@ int EC_POINTs_from_strings(const EC_GROUP *group, EC_POINTS **r, { int ret = 0; BN_CTX *new_ctx = NULL; - EC_POINTS *result = NULL; + EC_POINTS *result = NULL, *new_r = NULL; if (r == NULL || strings == NULL || num <= 0) return 0; if (*r == NULL) { - result = EC_POINTS_new(group, (uint32_t)num); + new_r = result = EC_POINTS_new(group, (uint32_t)num); if (result == NULL) return 0; } else { @@ -1576,14 +1576,13 @@ int EC_POINTs_from_strings(const EC_GROUP *group, EC_POINTS **r, } #endif - result = NULL; - /* * TODO */ err: BN_CTX_free(new_ctx); - EC_POINTS_free(result); + if (*r != new_r) + EC_POINTS_free(new_r); return ret; } @@ -1602,13 +1601,13 @@ int EC_POINTs_from_strings_scalar_mul(const EC_GROUP *group, EC_POINTS **r, { int ret = 0; BN_CTX *new_ctx = NULL; - EC_POINTS *result = NULL; + EC_POINTS *result, *new_r = NULL; if (r == NULL || strings == NULL || num <= 0) return 0; if (*r == NULL) { - result = EC_POINTS_new(group, (uint32_t)num); + new_r = result = EC_POINTS_new(group, (uint32_t)num); if (result == NULL) return 0; } else { @@ -1634,14 +1633,13 @@ int EC_POINTs_from_strings_scalar_mul(const EC_GROUP *group, EC_POINTS **r, } #endif - result = NULL; - /* * TODO */ err: BN_CTX_free(new_ctx); - EC_POINTS_free(result); + if (*r != new_r) + EC_POINTS_free(new_r); return ret; } diff --git a/crypto/zkp/bulletproofs/bulletproofs_encode.c b/crypto/zkp/bulletproofs/bulletproofs_encode.c index 94556c266..a208ef26a 100644 --- a/crypto/zkp/bulletproofs/bulletproofs_encode.c +++ b/crypto/zkp/bulletproofs/bulletproofs_encode.c @@ -184,8 +184,10 @@ static int bp_inner_product_proof_encode(bp_inner_product_proof_t *ip_proof, len += sk_len; - if (out == NULL) + if (out == NULL) { + sk_BIGNUM_free(sk_bn); return len; + } sk_len = zkp_stack_of_bignum_encode(sk_bn, p, bn_len); if (sk_len == 0) diff --git a/crypto/zkp/gadget/zkp_range_proof.c b/crypto/zkp/gadget/zkp_range_proof.c index 5a3235086..b27491bf2 100644 --- a/crypto/zkp/gadget/zkp_range_proof.c +++ b/crypto/zkp/gadget/zkp_range_proof.c @@ -410,6 +410,7 @@ void ZKP_RANGE_PROOF_free(ZKP_RANGE_PROOF *proof) NIZK_PLAINTEXT_KNOWLEDGE_PROOF_free(proof->ptke_proof); BP_RANGE_PROOF_free(proof->bp_proof); + OPENSSL_free(proof); } ZKP_RANGE_PROOF *ZKP_RANGE_PROOF_prove(ZKP_RANGE_CTX *ctx, int left_bound_bits, diff --git a/crypto/zkp/nizk/nizk_encode.c b/crypto/zkp/nizk/nizk_encode.c index 4305d44ca..d6ec1ba17 100644 --- a/crypto/zkp/nizk/nizk_encode.c +++ b/crypto/zkp/nizk/nizk_encode.c @@ -296,7 +296,7 @@ NIZK_WITNESS *NIZK_WITNESS_decode(const unsigned char *in, size_t size, int flag if (flag == 1) { if (size < (sizeof(int) + bn_len * 3)) { ERR_raise(ERR_LIB_ZKP_NIZK, ERR_R_PASSED_INVALID_ARGUMENT); - return NULL; + goto err; } witness->v = zkp_bignum_decode(p, NULL, bn_len); diff --git a/test/bntest.c b/test/bntest.c index c5894c157..2ad00d65a 100644 --- a/test/bntest.c +++ b/test/bntest.c @@ -101,6 +101,7 @@ static BIGNUM *getBN(STANZA *s, const char *attribute) if (parseBN(&ret, hex) != (int)strlen(hex)) { TEST_error("Could not decode '%s'", hex); + BN_free(ret); return NULL; } return ret; diff --git a/test/bulletproofs_test.c b/test/bulletproofs_test.c index e54791188..84de4c480 100644 --- a/test/bulletproofs_test.c +++ b/test/bulletproofs_test.c @@ -1134,9 +1134,11 @@ static BP_R1CS_PROOF *r1cs_range_prove(BP_R1CS_CTX *ctx, BP_WITNESS *witness, if (!(proof = BP_R1CS_PROOF_prove(ctx))) goto err; + BN_free(v); return proof; err: + BN_free(v); BP_R1CS_LINEAR_COMBINATION_free(lc); BP_R1CS_PROOF_free(proof); return NULL; diff --git a/test/nizk_test.c b/test/nizk_test.c index 64d0da58d..2bf4ce31c 100644 --- a/test/nizk_test.c +++ b/test/nizk_test.c @@ -93,6 +93,8 @@ static int nizk_plaintext_knowledge_test(int plaintext) ret = 1; err: + EC_ELGAMAL_CIPHERTEXT_free(enc_ct); + EC_ELGAMAL_CTX_free(enc_ctx); NIZK_PLAINTEXT_KNOWLEDGE_PROOF_free(proof); NIZK_PLAINTEXT_KNOWLEDGE_CTX_free(ctx); NIZK_WITNESS_free(witness); @@ -176,6 +178,8 @@ static int nizk_plaintext_equality_test(int plaintext) ret = 1; err: + EC_ELGAMAL_MR_CTX_free(enc_ctx); + EC_ELGAMAL_MR_CIPHERTEXT_free(enc_ct); NIZK_PLAINTEXT_EQUALITY_PROOF_free(proof); NIZK_PLAINTEXT_EQUALITY_CTX_free(ctx); NIZK_WITNESS_free(witness); diff --git a/test/paillier_internal_test.c b/test/paillier_internal_test.c index e099f53ce..33f2389b6 100644 --- a/test/paillier_internal_test.c +++ b/test/paillier_internal_test.c @@ -189,6 +189,7 @@ static size_t paillier_add_plain(PAILLIER_CTX *ctx, unsigned char **out, ret = size; err: + OPENSSL_free(buf); PAILLIER_CIPHERTEXT_free(c); PAILLIER_CIPHERTEXT_free(r); return ret; @@ -270,6 +271,7 @@ static size_t paillier_mul(PAILLIER_CTX *ctx, unsigned char **out, ret = size; err: + OPENSSL_free(buf); PAILLIER_CIPHERTEXT_free(c); PAILLIER_CIPHERTEXT_free(r); return ret; diff --git a/test/pkcs12_format_test.c b/test/pkcs12_format_test.c index 258a78d80..77e3f2c17 100644 --- a/test/pkcs12_format_test.c +++ b/test/pkcs12_format_test.c @@ -776,6 +776,7 @@ static int test_set0_attrs(void) return end_pkcs12_builder(pb); err: + (void)end_pkcs12_builder(pb); return 0; } diff --git a/test/zkp_gadget_test.c b/test/zkp_gadget_test.c index 8d85ce941..c7b127d76 100644 --- a/test/zkp_gadget_test.c +++ b/test/zkp_gadget_test.c @@ -37,9 +37,6 @@ static int zkp_poly3_eval_test(void) BN_CTX *bn_ctx = NULL; STACK_OF(BIGNUM) *sk_eval = NULL; - if (!(sk_eval = sk_BIGNUM_new_reserve(NULL, n))) - goto err; - bn_ctx = BN_CTX_new(); if (bn_ctx == NULL) goto err;