Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NTLS添加RFC5746 重协商扩展 #482

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

*) 实现基于SM2曲线参数特化的快速模约减和快速模逆元算法

*) 新增RFC5746 重协商扩展 0xff01

Changes between 8.3.0 and 8.4.0-pre1 [07 Jun 2023]

*) 修复CVE-2023-2650
Expand Down
48 changes: 47 additions & 1 deletion ssl/statem_ntls/ntls_extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
76 changes: 76 additions & 0 deletions ssl/statem_ntls/ntls_extensions_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
59 changes: 59 additions & 0 deletions ssl/statem_ntls/ntls_extensions_srvr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions ssl/statem_ntls/ntls_statem_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down