From fc213217e8db600093bb7976a11e738c8b4bb948 Mon Sep 17 00:00:00 2001 From: Scott Deboy Date: Thu, 12 Sep 2013 12:03:40 -0700 Subject: [PATCH] Update custom TLS extension and supplemental data 'generate' callbacks to support sending an alert. If multiple TLS extensions are expected but not received, the TLS extension and supplemental data 'generate' callbacks are the only chance for the receive-side to trigger a specific TLS alert during the handshake. Removed logic which no-op'd TLS extension generate callbacks (as the generate callbacks need to always be called in order to trigger alerts), and updated the serverinfo-specific custom TLS extension callbacks to track which custom TLS extensions were received by the client, where no-ops for 'generate' callbacks are appropriate. (cherry picked from commit ac20719d994729970eb3b775c7bffa81f0e9f960) Conflicts: ssl/t1_lib.c --- apps/s_client.c | 8 ++-- apps/s_server.c | 8 ++-- ssl/s23_clnt.c | 3 +- ssl/s3_clnt.c | 14 +++++-- ssl/s3_lib.c | 12 +++--- ssl/s3_srvr.c | 13 ++++-- ssl/ssl.h | 8 ++-- ssl/ssl3.h | 10 ++--- ssl/ssl_locl.h | 4 +- ssl/ssl_rsa.c | 41 ++++++++++++++++++- ssl/ssltest.c | 30 +++++++------- ssl/t1_lib.c | 103 +++++++++++++++--------------------------------- 12 files changed, 131 insertions(+), 123 deletions(-) diff --git a/apps/s_client.c b/apps/s_client.c index e06c9486e0..b9feec73a5 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -242,11 +242,11 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type, static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg); + unsigned short *outlen, int *al, void *arg); static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, const unsigned char **out, unsigned short *outlen, - void *arg); + int *al, void *arg); static int authz_tlsext_cb(SSL *s, unsigned short ext_type, const unsigned char *in, @@ -2458,7 +2458,7 @@ static int authz_tlsext_cb(SSL *s, unsigned short ext_type, static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, const unsigned char **out, unsigned short *outlen, - void *arg) + int *al, void *arg) { if (c_auth) { @@ -2490,7 +2490,7 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type, static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { if (c_auth && server_provided_client_authz && server_provided_server_authz) { diff --git a/apps/s_server.c b/apps/s_server.c index 576daac696..9bd00431bf 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -336,11 +336,11 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type, static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg); + unsigned short *outlen, int *al, void *arg); static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, const unsigned char **out, unsigned short *outlen, - void *arg); + int *al, void *arg); static int authz_tlsext_cb(SSL *s, unsigned short ext_type, const unsigned char *in, @@ -3576,7 +3576,7 @@ static int authz_tlsext_cb(SSL *s, unsigned short ext_type, static int authz_tlsext_generate_cb(SSL *s, unsigned short ext_type, const unsigned char **out, unsigned short *outlen, - void *arg) + int *al, void *arg) { if (c_auth && client_provided_client_authz && client_provided_server_authz) { @@ -3609,7 +3609,7 @@ static int suppdata_cb(SSL *s, unsigned short supp_data_type, static int auth_suppdata_generate_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { if (c_auth && client_provided_client_authz && client_provided_server_authz) { diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index a101bce161..99d5dfe6d3 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -553,8 +553,9 @@ static int ssl23_client_hello(SSL *s) SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); return -1; } - if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL) { + ssl3_send_alert(s,SSL3_AL_FATAL,al); SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); return -1; } diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index d7178793ab..d39cbba49b 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -891,8 +891,9 @@ int ssl3_client_hello(SSL *s) SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; } - if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL) { + ssl3_send_alert(s,SSL3_AL_FATAL,al); SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); goto err; } @@ -3617,6 +3618,7 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) #ifndef OPENSSL_NO_TLSEXT int tls1_send_client_supplemental_data(SSL *s, int *skip) { + int al = 0; if (s->ctx->cli_supp_data_records_count) { unsigned char *p = NULL; @@ -3636,14 +3638,14 @@ int tls1_send_client_supplemental_data(SSL *s, int *skip) if (!record->fn2) continue; cb_retval = record->fn2(s, record->supp_data_type, - &out, &outlen, + &out, &outlen, &al, record->arg); if (cb_retval == -1) continue; /* skip this supp data entry */ if (cb_retval == 0) { SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; + goto f_err; } if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length) { @@ -3695,7 +3697,11 @@ int tls1_send_client_supplemental_data(SSL *s, int *skip) s->init_num = 0; s->init_off = 0; return 1; - } + +f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return 0; +} int tls1_get_server_supplemental_data(SSL *s) { diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index b03601d6ea..e99b048e4c 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -3029,8 +3029,8 @@ void ssl3_free(SSL *s) SSL_SRP_CTX_free(s); #endif #ifndef OPENSSL_NO_TLSEXT - if (s->s3->tlsext_custom_types != NULL) - OPENSSL_free(s->s3->tlsext_custom_types); + if (s->s3->serverinfo_client_tlsext_custom_types != NULL) + OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types); #endif OPENSSL_cleanse(s->s3,sizeof *s->s3); OPENSSL_free(s->s3); @@ -3076,12 +3076,12 @@ void ssl3_clear(SSL *s) } #endif #ifndef OPENSSL_NO_TLSEXT - if (s->s3->tlsext_custom_types != NULL) + if (s->s3->serverinfo_client_tlsext_custom_types != NULL) { - OPENSSL_free(s->s3->tlsext_custom_types); - s->s3->tlsext_custom_types = NULL; + OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types); + s->s3->serverinfo_client_tlsext_custom_types = NULL; } - s->s3->tlsext_custom_types_count = 0; + s->s3->serverinfo_client_tlsext_custom_types_count = 0; #ifndef OPENSSL_NO_EC s->s3->is_probably_safari = 0; #endif /* !OPENSSL_NO_EC */ diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 3699524eb3..15061aef30 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -1500,7 +1500,7 @@ int ssl3_send_server_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; - int i,sl; + int i,sl,al; unsigned long l; if (s->state == SSL3_ST_SW_SRVR_HELLO_A) @@ -1569,8 +1569,9 @@ int ssl3_send_server_hello(SSL *s) SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT); return -1; } - if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); return -1; } @@ -3654,6 +3655,7 @@ int ssl3_get_next_proto(SSL *s) int tls1_send_server_supplemental_data(SSL *s, int *skip) { + int al = 0; if (s->ctx->srv_supp_data_records_count) { unsigned char *p = NULL; @@ -3673,14 +3675,14 @@ int tls1_send_server_supplemental_data(SSL *s, int *skip) if (!record->fn1) continue; cb_retval = record->fn1(s, record->supp_data_type, - &out, &outlen, + &out, &outlen, &al, record->arg); if (cb_retval == -1) continue; /* skip this supp data entry */ if (cb_retval == 0) { SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); - return 0; + goto f_err; } if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length) { @@ -3738,6 +3740,9 @@ int tls1_send_server_supplemental_data(SSL *s, int *skip) s->init_num = 0; s->init_off = 0; return 1; +f_err: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return 0; } int tls1_get_client_supplemental_data(SSL *s) diff --git a/ssl/ssl.h b/ssl/ssl.h index 2f590fe5de..7b6af00ff2 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -406,7 +406,7 @@ typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, S */ typedef int (*custom_cli_ext_first_cb_fn)(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg); + unsigned short *outlen, int *al, void *arg); typedef int (*custom_cli_ext_second_cb_fn)(SSL *s, unsigned short ext_type, const unsigned char *in, unsigned short inlen, int *al, @@ -418,7 +418,7 @@ typedef int (*custom_srv_ext_first_cb_fn)(SSL *s, unsigned short ext_type, void *arg); typedef int (*custom_srv_ext_second_cb_fn)(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg); + unsigned short *outlen, int *al, void *arg); typedef struct { unsigned short ext_type; @@ -457,7 +457,7 @@ typedef struct { */ typedef int (*srv_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg); + unsigned short *outlen, int *al, void *arg); typedef int (*srv_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type, const unsigned char *in, unsigned short inlen, int *al, @@ -469,7 +469,7 @@ typedef int (*cli_supp_data_first_cb_fn)(SSL *s, unsigned short supp_data_type, void *arg); typedef int (*cli_supp_data_second_cb_fn)(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg); + unsigned short *outlen, int *al, void *arg); typedef struct { unsigned short supp_data_type; diff --git a/ssl/ssl3.h b/ssl/ssl3.h index 6e7bd0f62c..2e46410fd3 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -560,14 +560,12 @@ typedef struct ssl3_state_st #endif #ifndef OPENSSL_NO_TLSEXT - /* tlsext_custom_types contains an array of TLS Extension types which - * were advertised by the client in its ClientHello, which were not - * otherwise handled by OpenSSL, and which the server has registered - * a custom_srv_ext_record to handle. + /* serverinfo_client_tlsext_custom_types contains an array of TLS Extension types which + * were advertised by the client in its ClientHello and leveraged by ServerInfo TLS extension callbacks. * The array does not contain any duplicates, and is in the same order * as the types were received in the client hello. */ - unsigned short *tlsext_custom_types; - size_t tlsext_custom_types_count; /* how many tlsext_custom_types */ + unsigned short *serverinfo_client_tlsext_custom_types; + size_t serverinfo_client_tlsext_custom_types_count; /* how many serverinfo_client_tlsext_custom_types */ #ifndef OPENSSL_NO_EC /* This is set to true if we believe that this is a version of Safari diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 6f1209cbbb..1e67a56295 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1263,8 +1263,8 @@ int tls1_shared_list(SSL *s, const unsigned char *l1, size_t l1len, const unsigned char *l2, size_t l2len, int nmatch); -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); -unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al); +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al); int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n); int ssl_check_clienthello_tlsext_late(SSL *s); int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n); diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 7fcd8460a3..063eea5ecb 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -848,20 +848,59 @@ static int serverinfo_srv_first_cb(SSL *s, unsigned short ext_type, unsigned short inlen, int *al, void *arg) { + size_t i = 0; if (inlen != 0) { *al = SSL_AD_DECODE_ERROR; return 0; } + //if already in list, error out + for (i = 0; i < s->s3->serverinfo_client_tlsext_custom_types_count; i++) + { + if (s->s3->serverinfo_client_tlsext_custom_types[i] == ext_type) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + s->s3->serverinfo_client_tlsext_custom_types_count++; + s->s3->serverinfo_client_tlsext_custom_types = OPENSSL_realloc( + s->s3->serverinfo_client_tlsext_custom_types, + s->s3->serverinfo_client_tlsext_custom_types_count * 2); + if (s->s3->serverinfo_client_tlsext_custom_types == NULL) + { + s->s3->serverinfo_client_tlsext_custom_types_count = 0; + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->s3->serverinfo_client_tlsext_custom_types[ + s->s3->serverinfo_client_tlsext_custom_types_count - 1] = ext_type; + return 1; } static int serverinfo_srv_second_cb(SSL *s, unsigned short ext_type, const unsigned char **out, unsigned short *outlen, - void *arg) + int *al, void *arg) { const unsigned char *serverinfo = NULL; size_t serverinfo_length = 0; + size_t i = 0; + unsigned int match = 0; + /* Did the client send a TLS extension for this type? */ + for (i = 0; i < s->s3->serverinfo_client_tlsext_custom_types_count; i++) + { + if (s->s3->serverinfo_client_tlsext_custom_types[i] == ext_type) + { + match = 1; + break; + } + } + if (!match) + { + //extension not sent by client...don't send extension + return -1; + } /* Is there serverinfo data for the chosen server cert? */ if ((ssl_get_server_cert_serverinfo(s, &serverinfo, diff --git a/ssl/ssltest.c b/ssl/ssltest.c index 3755e06905..2af5710f90 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -489,7 +489,7 @@ static int verify_serverinfo() static int custom_ext_0_cli_first_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { if (ext_type != CUSTOM_EXT_TYPE_0) custom_ext_error = 1; @@ -507,7 +507,7 @@ static int custom_ext_0_cli_second_cb(SSL *s, unsigned short ext_type, static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { if (ext_type != CUSTOM_EXT_TYPE_1) custom_ext_error = 1; @@ -527,7 +527,7 @@ static int custom_ext_1_cli_second_cb(SSL *s, unsigned short ext_type, static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { if (ext_type != CUSTOM_EXT_TYPE_2) custom_ext_error = 1; @@ -550,7 +550,7 @@ static int custom_ext_2_cli_second_cb(SSL *s, unsigned short ext_type, static int custom_ext_3_cli_first_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { if (ext_type != CUSTOM_EXT_TYPE_3) custom_ext_error = 1; @@ -573,7 +573,7 @@ static int custom_ext_3_cli_second_cb(SSL *s, unsigned short ext_type, return 1; } - +//custom_ext_0_cli_first_cb returns -1 - the server won't receive a callback for this extension static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type, const unsigned char *in, unsigned short inlen, int *al, @@ -583,12 +583,12 @@ static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type, return 0; /* Shouldn't be called */ } +//'generate' callbacks are always called, even if the 'receive' callback isn't called static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { - custom_ext_error = 1; - return 0; /* Shouldn't be called */ + return -1; /* Don't send an extension */ } static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type, @@ -608,7 +608,7 @@ static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type, static int custom_ext_1_srv_second_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { return -1; /* Don't send an extension */ } @@ -630,7 +630,7 @@ static int custom_ext_2_srv_first_cb(SSL *s, unsigned short ext_type, static int custom_ext_2_srv_second_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { *out = NULL; *outlen = 0; @@ -654,7 +654,7 @@ static int custom_ext_3_srv_first_cb(SSL *s, unsigned short ext_type, static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { *out = (const unsigned char*)custom_ext_srv_string; *outlen = strlen(custom_ext_srv_string); @@ -663,7 +663,7 @@ static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type, static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { *out = (const unsigned char*)supp_data_0_string; *outlen = strlen(supp_data_0_string); @@ -690,7 +690,7 @@ static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type, static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { return -1; } @@ -731,7 +731,7 @@ static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type, static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { *out = (const unsigned char*)supp_data_0_string; *outlen = strlen(supp_data_0_string); @@ -751,7 +751,7 @@ static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type, static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type, const unsigned char **out, - unsigned short *outlen, void *arg) + unsigned short *outlen, int *al, void *arg) { return -1; } diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 291f4ab00f..f3f6f82184 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1102,7 +1102,7 @@ static int byte_compare(const void *in_a, const void *in_b) return 0; } -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al) { int extdatalen=0; unsigned char *ret = p; @@ -1466,7 +1466,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha { int cb_retval = 0; cb_retval = record->fn1(s, record->ext_type, - &out, &outlen, + &out, &outlen, al, record->arg); if (cb_retval == 0) return NULL; /* error */ @@ -1519,10 +1519,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha return ret; } -unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit, int *al) { int extdatalen=0; unsigned char *ret = p; + size_t i; + custom_srv_ext_record *record; #ifndef OPENSSL_NO_NEXTPROTONEG int next_proto_neg_seen; #endif @@ -1706,45 +1708,29 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } #endif - /* If custom types were sent in ClientHello, add ServerHello responses */ - if (s->s3->tlsext_custom_types_count) + for (i = 0; i < s->ctx->custom_srv_ext_records_count; i++) { - size_t i; - - for (i = 0; i < s->s3->tlsext_custom_types_count; i++) - { - size_t j; - custom_srv_ext_record *record; - - for (j = 0; j < s->ctx->custom_srv_ext_records_count; j++) - { - record = &s->ctx->custom_srv_ext_records[j]; - if (s->s3->tlsext_custom_types[i] == record->ext_type) - { - const unsigned char *out = NULL; - unsigned short outlen = 0; - int cb_retval = 0; - - /* NULL callback or -1 omits extension */ - if (!record->fn2) - break; - cb_retval = record->fn2(s, record->ext_type, - &out, &outlen, - record->arg); - if (cb_retval == 0) - return NULL; /* error */ - if (cb_retval == -1) - break; /* skip this extension */ - if (limit < ret + 4 + outlen) - return NULL; - s2n(record->ext_type, ret); - s2n(outlen, ret); - memcpy(ret, out, outlen); - ret += outlen; - break; - } - } - } + record = &s->ctx->custom_srv_ext_records[i]; + const unsigned char *out = NULL; + unsigned short outlen = 0; + int cb_retval = 0; + + /* NULL callback or -1 omits extension */ + if (!record->fn2) + break; + cb_retval = record->fn2(s, record->ext_type, + &out, &outlen, al, + record->arg); + if (cb_retval == 0) + return NULL; /* error */ + if (cb_retval == -1) + break; /* skip this extension */ + if (limit < ret + 4 + outlen) + return NULL; + s2n(record->ext_type, ret); + s2n(outlen, ret); + memcpy(ret, out, outlen); + ret += outlen; } if (s->s3->alpn_selected) @@ -1938,11 +1924,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char #endif /* Clear observed custom extensions */ - s->s3->tlsext_custom_types_count = 0; - if (s->s3->tlsext_custom_types != NULL) + s->s3->serverinfo_client_tlsext_custom_types_count = 0; + if (s->s3->serverinfo_client_tlsext_custom_types != NULL) { - OPENSSL_free(s->s3->tlsext_custom_types); - s->s3->tlsext_custom_types = NULL; + OPENSSL_free(s->s3->serverinfo_client_tlsext_custom_types); + s->s3->serverinfo_client_tlsext_custom_types = NULL; } if (s->s3->alpn_selected) @@ -2467,35 +2453,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char record = &s->ctx->custom_srv_ext_records[i]; if (type == record->ext_type) { - size_t j; - - /* Error on duplicate TLS Extensions */ - for (j = 0; j < s->s3->tlsext_custom_types_count; j++) - { - if (type == s->s3->tlsext_custom_types[j]) - { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - } - - /* NULL callback still notes the extension */ if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg)) return 0; - - /* Add the (non-duplicated) entry */ - s->s3->tlsext_custom_types_count++; - s->s3->tlsext_custom_types = OPENSSL_realloc( - s->s3->tlsext_custom_types, - s->s3->tlsext_custom_types_count * 2); - if (s->s3->tlsext_custom_types == NULL) - { - s->s3->tlsext_custom_types = 0; - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->s3->tlsext_custom_types[ - s->s3->tlsext_custom_types_count - 1] = type; } } } -- 2.34.1