From 8e75f4777d7418719819df1063446cad1105239f Mon Sep 17 00:00:00 2001 From: fury_fox Date: Tue, 9 May 2023 18:46:12 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9window=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8895ee3a4..e05b7b237 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ make install 如果是Windows,则需要: ~~~ -perl config +perl Configure enable-ntls nmake nmake install ~~~ From f10d44c554786ff2b5bcdaf1d12ff983b40ed778 Mon Sep 17 00:00:00 2001 From: Fury-Fox Date: Wed, 23 Aug 2023 21:15:14 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=87=8D=E5=8D=8F?= =?UTF-8?q?=E5=95=86=E6=89=A9=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ssl/statem_ntls/ntls_extensions.c | 48 +++++++++++++++- ssl/statem_ntls/ntls_extensions_clnt.c | 76 ++++++++++++++++++++++++++ ssl/statem_ntls/ntls_extensions_srvr.c | 59 ++++++++++++++++++++ ssl/statem_ntls/ntls_statem_local.h | 9 +++ 4 files changed, 191 insertions(+), 1 deletion(-) diff --git a/ssl/statem_ntls/ntls_extensions.c b/ssl/statem_ntls/ntls_extensions.c index 75c3d76a1..56697056b 100644 --- a/ssl/statem_ntls/ntls_extensions.c +++ b/ssl/statem_ntls/ntls_extensions.c @@ -15,6 +15,7 @@ #include "ntls_statem_local.h" #include "internal/cryptlib.h" +static int final_renegotiate(SSL *s, unsigned int context, int sent); static int init_server_name(SSL *s, unsigned int context); static int final_server_name(SSL *s, unsigned int context, int sent); static int final_ec_pt_formats(SSL *s, unsigned int context, int sent); @@ -115,7 +116,14 @@ typedef struct extensions_definition_st { */ #define INVALID_EXTENSION { 0x10000, 0, NULL, NULL, NULL, NULL, NULL, NULL } static const EXTENSION_DEFINITION ext_defs[] = { - INVALID_EXTENSION, /* TLSEXT_IDX_renegotiate */ + { + TLSEXT_TYPE_renegotiate, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO + | SSL_EXT_SSL3_ALLOWED | SSL_EXT_TLS1_2_AND_BELOW_ONLY, + NULL, tls_parse_ctos_renegotiate_ntls, tls_parse_stoc_renegotiate_ntls, + tls_construct_stoc_renegotiate_ntls, tls_construct_ctos_renegotiate_ntls, + final_renegotiate + }, { TLSEXT_TYPE_server_name, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO @@ -844,6 +852,44 @@ static ossl_inline void ssl_tsan_decr(const SSL_CTX *ctx, } } +/* + * Built in extension finalisation and initialisation functions. All initialise + * or finalise the associated extension type for the given |context|. For + * finalisers |sent| is set to 1 if we saw the extension during parsing, and 0 + * otherwise. These functions return 1 on success or 0 on failure. + */ + +static int final_renegotiate(SSL *s, unsigned int context, int sent) +{ + if (!s->server) { + /* + * Check if we can connect to a server that doesn't support safe + * renegotiation + */ + if (!(s->options & SSL_OP_LEGACY_SERVER_CONNECT) + && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) + && !sent) { + SSLfatal_ntls(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; + } + + /* Need RI if renegotiating */ + if (s->renegotiate + && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) + && !sent) { + SSLfatal_ntls(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + + return 1; +} + static int init_server_name(SSL *s, unsigned int context) { if (s->server) { diff --git a/ssl/statem_ntls/ntls_extensions_clnt.c b/ssl/statem_ntls/ntls_extensions_clnt.c index a8872eaf5..870da5db3 100644 --- a/ssl/statem_ntls/ntls_extensions_clnt.c +++ b/ssl/statem_ntls/ntls_extensions_clnt.c @@ -12,6 +12,26 @@ #include "internal/cryptlib.h" #include "ntls_statem_local.h" +EXT_RETURN tls_construct_ctos_renegotiate_ntls(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx) +{ + /* Add RI if renegotiating */ + if (!s->renegotiate) + return EXT_RETURN_NOT_SENT; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u8(pkt, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) + || !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_ctos_server_name_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -954,6 +974,62 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth_ntls(SSL *s, WPACKET *pkt, #endif } +/* + * Parse the server's renegotiation binding and abort if it's not right + */ +int tls_parse_stoc_renegotiate_ntls(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) +{ + size_t expected_len = s->s3.previous_client_finished_len + + s->s3.previous_server_finished_len; + size_t ilen; + const unsigned char *data; + + /* Check for logic errors */ + if (!ossl_assert(expected_len == 0 + || s->s3.previous_client_finished_len != 0) + || !ossl_assert(expected_len == 0 + || s->s3.previous_server_finished_len != 0)) { + SSLfatal_ntls(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + /* Parse the length byte */ + if (!PACKET_get_1_len(pkt, &ilen)) { + SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + + /* Consistency check */ + if (PACKET_remaining(pkt) != ilen) { + SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + + /* Check that the extension matches */ + if (ilen != expected_len) { + SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_RENEGOTIATION_MISMATCH); + return 0; + } + + if (!PACKET_get_bytes(pkt, &data, s->s3.previous_client_finished_len) + || memcmp(data, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) != 0) { + SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_RENEGOTIATION_MISMATCH); + return 0; + } + + if (!PACKET_get_bytes(pkt, &data, s->s3.previous_server_finished_len) + || memcmp(data, s->s3.previous_server_finished, + s->s3.previous_server_finished_len) != 0) { + SSLfatal_ntls(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_RENEGOTIATION_MISMATCH); + return 0; + } + s->s3.send_connection_binding = 1; + + return 1; +} + /* 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) diff --git a/ssl/statem_ntls/ntls_extensions_srvr.c b/ssl/statem_ntls/ntls_extensions_srvr.c index 7d8aacde4..e38a33025 100644 --- a/ssl/statem_ntls/ntls_extensions_srvr.c +++ b/ssl/statem_ntls/ntls_extensions_srvr.c @@ -35,6 +35,38 @@ + SSL_MAX_SSL_SESSION_ID_LENGTH + 2 + 1 + 2 + 6 + 4 \ + MAX_COOKIE_SIZE) +/* + * Parse the client's renegotiation binding and abort if it's not right + */ +int tls_parse_ctos_renegotiate_ntls(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) +{ + unsigned int ilen; + const unsigned char *data; + + /* Parse the length byte */ + if (!PACKET_get_1(pkt, &ilen) + || !PACKET_get_bytes(pkt, &data, ilen)) { + SSLfatal_ntls(s, SSL_AD_DECODE_ERROR, SSL_R_RENEGOTIATION_ENCODING_ERR); + return 0; + } + + /* Check that the extension matches */ + if (ilen != s->s3.previous_client_finished_len) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_RENEGOTIATION_MISMATCH); + return 0; + } + + if (memcmp(data, s->s3.previous_client_finished, + s->s3.previous_client_finished_len)) { + SSLfatal_ntls(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_RENEGOTIATION_MISMATCH); + return 0; + } + + s->s3.send_connection_binding = 1; + + return 1; +} /*- * The servername extension is treated as follows: @@ -1096,6 +1128,33 @@ int tls_parse_ctos_post_handshake_auth_ntls(SSL *s, PACKET *pkt, return 1; } +/* + * Add the server's renegotiation binding + */ +EXT_RETURN tls_construct_stoc_renegotiate_ntls(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx) +{ + if (!s->s3.send_connection_binding) + return EXT_RETURN_NOT_SENT; + + /* Still add this even if SSL_OP_NO_RENEGOTIATION is set */ + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_start_sub_packet_u8(pkt) + || !WPACKET_memcpy(pkt, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) + || !WPACKET_memcpy(pkt, s->s3.previous_server_finished, + s->s3.previous_server_finished_len) + || !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; +} + EXT_RETURN tls_construct_stoc_server_name_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) diff --git a/ssl/statem_ntls/ntls_statem_local.h b/ssl/statem_ntls/ntls_statem_local.h index c48ad6481..789d30a21 100644 --- a/ssl/statem_ntls/ntls_statem_local.h +++ b/ssl/statem_ntls/ntls_statem_local.h @@ -201,6 +201,8 @@ __owur int tls_psk_do_binder_ntls(SSL *s, const EVP_MD *md, SSL_SESSION *sess, int sign, int external); /* Server Extension processing */ +int tls_parse_ctos_renegotiate_ntls(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); 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, @@ -245,6 +247,9 @@ 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_renegotiate_ntls(SSL *s, WPACKET *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); @@ -296,6 +301,8 @@ EXT_RETURN tls_construct_stoc_psk_ntls(SSL *s, WPACKET *pkt, unsigned int contex X509 *x, size_t chainidx); /* Client Extension processing */ +EXT_RETURN tls_construct_ctos_renegotiate_ntls(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); EXT_RETURN tls_construct_ctos_server_name_ntls(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); EXT_RETURN tls_construct_ctos_maxfragmentlen_ntls(SSL *s, WPACKET *pkt, unsigned int context, @@ -358,6 +365,8 @@ EXT_RETURN tls_construct_ctos_psk_ntls(SSL *s, WPACKET *pkt, unsigned int contex 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_renegotiate_ntls(SSL *s, PACKET *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, From 680c2edd0d82e90de73b4ea065e532b7fc55080b Mon Sep 17 00:00:00 2001 From: Fury-Fox Date: Wed, 23 Aug 2023 21:19:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=87=8D=E5=8D=8F?= =?UTF-8?q?=E5=95=86=E6=89=A9=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 62d8e7f81..06cab94d9 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,8 @@ *) 实现基于SM2曲线参数特化的快速模约减和快速模逆元算法 + *) 新增RFC5746 重协商扩展 0xff01 + Changes between 8.3.0 and 8.4.0-pre1 [07 Jun 2023] *) 修复CVE-2023-2650