X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fstatem%2Fextensions.c;h=96c5394bd67a90999fe1117e44afbefd3f2d5830;hb=9784ec04745a8c8ecbf5610c0a2f5540e1e0f2cd;hp=8c4013e416e87d26d3dfcfc24225e6e29f368e89;hpb=cfef5027bf27a74098588e48829f0d058b4b0aea;p=oweals%2Fopenssl.git diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 8c4013e416..96c5394bd6 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -30,6 +30,13 @@ static int init_npn(SSL *s, unsigned int context); static int init_alpn(SSL *s, unsigned int context); static int final_alpn(SSL *s, unsigned int context, int sent, int *al); static int init_sig_algs(SSL *s, unsigned int context); +static int init_certificate_authorities(SSL *s, unsigned int context); +static int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #ifndef OPENSSL_NO_SRP static int init_srp(SSL *s, unsigned int context); #endif @@ -131,12 +138,6 @@ static const EXTENSION_DEFINITION ext_defs[] = { #else INVALID_EXTENSION, #endif - { - TLSEXT_TYPE_early_data_info, - EXT_TLS1_3_NEW_SESSION_TICKET, - NULL, NULL, tls_parse_stoc_early_data_info, - tls_construct_stoc_early_data_info, NULL, NULL - }, #ifndef OPENSSL_NO_EC { TLSEXT_TYPE_ec_point_formats, @@ -165,8 +166,9 @@ static const EXTENSION_DEFINITION ext_defs[] = { }, { TLSEXT_TYPE_signature_algorithms, - EXT_CLIENT_HELLO, - init_sig_algs, tls_parse_ctos_sig_algs, NULL, NULL, + EXT_CLIENT_HELLO | EXT_TLS1_3_CERTIFICATE_REQUEST, + init_sig_algs, tls_parse_ctos_sig_algs, + tls_parse_ctos_sig_algs, tls_construct_ctos_sig_algs, tls_construct_ctos_sig_algs, final_sig_algs }, #ifndef OPENSSL_NO_OCSP @@ -287,14 +289,22 @@ static const EXTENSION_DEFINITION ext_defs[] = { }, { TLSEXT_TYPE_early_data, - EXT_CLIENT_HELLO | EXT_TLS1_3_ENCRYPTED_EXTENSIONS, + EXT_CLIENT_HELLO | EXT_TLS1_3_ENCRYPTED_EXTENSIONS + | EXT_TLS1_3_NEW_SESSION_TICKET, NULL, tls_parse_ctos_early_data, tls_parse_stoc_early_data, tls_construct_stoc_early_data, tls_construct_ctos_early_data, final_early_data }, + { + TLSEXT_TYPE_certificate_authorities, + EXT_CLIENT_HELLO | EXT_TLS1_3_CERTIFICATE_REQUEST | EXT_TLS1_3_ONLY, + init_certificate_authorities, + tls_parse_certificate_authorities, tls_parse_certificate_authorities, + tls_construct_certificate_authorities, + tls_construct_certificate_authorities, NULL, + }, { /* Must be immediately before pre_shared_key */ - /* TODO(TLS1.3): Fix me */ TLSEXT_TYPE_padding, EXT_CLIENT_HELLO, NULL, @@ -315,7 +325,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * Verify whether we are allowed to use the extension |type| in the current * |context|. Returns 1 to indicate the extension is allowed or unknown or 0 to * indicate the extension is not allowed. If returning 1 then |*found| is set to - * 1 if we found a definition for the extension, and |*idx| is set to its index + * the definition for the extension we found. */ static int verify_extension(SSL *s, unsigned int context, unsigned int type, custom_ext_methods *meths, RAW_EXTENSION *rawexlist, @@ -447,10 +457,14 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, } /* * Verify this extension is allowed. We only check duplicates for - * extensions that we recognise. + * extensions that we recognise. We also have a special case for the + * PSK extension, which must be the last one in the ClientHello. */ if (!verify_extension(s, context, type, exts, raw_extensions, &thisex) - || (thisex != NULL && thisex->present == 1)) { + || (thisex != NULL && thisex->present == 1) + || (type == TLSEXT_TYPE_psk + && (context & EXT_CLIENT_HELLO) != 0 + && PACKET_remaining(&extensions) != 0)) { SSLerr(SSL_F_TLS_COLLECT_EXTENSIONS, SSL_R_BAD_EXTENSION); *al = SSL_AD_ILLEGAL_PARAMETER; goto err; @@ -871,8 +885,8 @@ static int init_alpn(SSL *s, unsigned int context) { OPENSSL_free(s->s3->alpn_selected); s->s3->alpn_selected = NULL; + s->s3->alpn_selected_len = 0; if (s->server) { - s->s3->alpn_selected_len = 0; OPENSSL_free(s->s3->alpn_proposed); s->s3->alpn_proposed = NULL; s->s3->alpn_proposed_len = 0; @@ -967,6 +981,47 @@ static int final_ems(SSL *s, unsigned int context, int sent, int *al) 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 int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s); + + if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_certificate_authorities) + || !WPACKET_start_sub_packet_u16(pkt) + || !construct_ca_names(s, pkt) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES, + ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + if (!parse_ca_names(s, pkt, al)) + return 0; + if (PACKET_remaining(pkt) != 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + return 1; +} + #ifndef OPENSSL_NO_SRTP static int init_srtp(SSL *s, unsigned int context) { @@ -1187,11 +1242,18 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, * ClientHello - which we don't want - so we need to take that bit off. */ if (s->server) { - if (hdatalen < s->init_num + SSL3_HM_HEADER_LENGTH) { + PACKET hashprefix, msg; + + /* Find how many bytes are left after the first two messages */ + if (!PACKET_buf_init(&hashprefix, hdata, hdatalen) + || !PACKET_forward(&hashprefix, 1) + || !PACKET_get_length_prefixed_3(&hashprefix, &msg) + || !PACKET_forward(&hashprefix, 1) + || !PACKET_get_length_prefixed_3(&hashprefix, &msg)) { SSLerr(SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR); goto err; } - hdatalen -= s->init_num + SSL3_HM_HEADER_LENGTH; + hdatalen -= PACKET_remaining(&hashprefix); } if (EVP_DigestUpdate(mctx, hdata, hdatalen) <= 0) { @@ -1252,8 +1314,9 @@ static int final_early_data(SSL *s, unsigned int context, int sent, int *al) || !s->ext.early_data_ok || s->hello_retry_request || s->s3->alpn_selected_len != s->session->ext.alpn_selected_len - || memcmp(s->s3->alpn_selected, s->session->ext.alpn_selected, - s->s3->alpn_selected_len) != 0){ + || (s->s3->alpn_selected_len > 0 + && memcmp(s->s3->alpn_selected, s->session->ext.alpn_selected, + s->s3->alpn_selected_len) != 0)) { s->ext.early_data = SSL_EARLY_DATA_REJECTED; } else { s->ext.early_data = SSL_EARLY_DATA_ACCEPTED;