diff options
author | Matt Caswell <matt@openssl.org> | 2016-11-25 10:22:02 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2016-12-08 17:18:12 +0000 |
commit | 7da160b0f46d832dbf285cb0b48ae56d4a8b884d (patch) | |
tree | 3d5adabc37eeb594df853331c6d089786f5ee790 /ssl/statem | |
parent | 25670f3e87d3a9e7ea8ffb2b717a288e2b3024f5 (diff) |
Move ServerHello extension construction into the new extensions framework
This lays the foundation for a later move to have the extensions built and
placed into the correct message for TLSv1.3 (e.g. ServerHello or
EncryptedExtensions).
Perl changes reviewed by Richard Levitte. Non-perl changes reviewed by Rich
Salz
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'ssl/statem')
-rw-r--r-- | ssl/statem/extensions.c | 51 | ||||
-rw-r--r-- | ssl/statem/extensions_srvr.c | 370 | ||||
-rw-r--r-- | ssl/statem/statem_locl.h | 19 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 11 |
4 files changed, 432 insertions, 19 deletions
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 8bea0746e1..0b82ad7ea7 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -31,7 +31,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_renegotiate, tls_parse_clienthello_renegotiate, NULL, - NULL, + tls_construct_server_renegotiate, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_SSL3_ALLOWED | EXT_TLS1_2_AND_BELOW_ONLY @@ -40,7 +40,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_server_name, tls_parse_clienthello_server_name, NULL, - NULL, + tls_construct_server_server_name, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO @@ -60,7 +60,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_ec_point_formats, tls_parse_clienthello_ec_pt_formats, NULL, - NULL, + tls_construct_server_ec_pt_formats, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_AND_BELOW_ONLY }, @@ -68,7 +68,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_supported_groups, tls_parse_clienthello_supported_groups, NULL, - NULL, + NULL /* TODO(TLS1.3): Need to add this */, NULL, EXT_CLIENT_HELLO | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO @@ -78,7 +78,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_session_ticket, tls_parse_clienthello_session_ticket, NULL, - NULL, + tls_construct_server_session_ticket, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY }, @@ -94,7 +94,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_status_request, tls_parse_clienthello_status_request, NULL, - NULL, + tls_construct_server_status_request, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | /*EXT_TLS1_3_CERTIFICATE*/EXT_TLS1_3_SERVER_HELLO @@ -104,7 +104,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_next_proto_neg, tls_parse_clienthello_npn, NULL, - NULL, + tls_construct_server_next_proto_neg, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY }, @@ -113,25 +113,27 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_application_layer_protocol_negotiation, tls_parse_clienthello_alpn, NULL, - NULL, + tls_construct_server_alpn, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | /*EXT_TLS1_3_ENCRYPTED_EXTENSIONS*/EXT_TLS1_3_SERVER_HELLO }, +#ifndef OPENSSL_NO_SRTP { TLSEXT_TYPE_use_srtp, tls_parse_clienthello_use_srtp, NULL, - NULL, + tls_construct_server_use_srtp, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_3_ENCRYPTED_EXTENSIONS | EXT_DTLS_ONLY }, +#endif { TLSEXT_TYPE_encrypt_then_mac, tls_parse_clienthello_etm, NULL, - NULL, + tls_construct_server_etm, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY }, @@ -153,7 +155,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_extended_master_secret, tls_parse_clienthello_ems, NULL, - NULL, + tls_construct_server_ems, NULL, EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY }, @@ -179,11 +181,23 @@ static const EXTENSION_DEFINITION ext_defs[] = { TLSEXT_TYPE_key_share, tls_parse_clienthello_key_share, NULL, - NULL, + tls_construct_server_key_share, NULL, EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO | EXT_TLS1_3_HELLO_RETRY_REQUEST | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY + }, + { + /* + * Special unsolicited ServerHello extension only used when + * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set + */ + TLSEXT_TYPE_cryptopro_bug, + NULL, + NULL, + tls_construct_server_cryptopro_bug, + NULL, + EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY } }; @@ -440,15 +454,21 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, size_t loop; int addcustom = 0; + /* + * Normally if something goes wrong during construction its an internal + * error. We can always override this later. + */ + *al = SSL_AD_INTERNAL_ERROR; + if (!WPACKET_start_sub_packet_u16(pkt) /* * If extensions are of zero length then we don't even add the - * extensions length bytes to a ClientHello + * extensions length bytes to a ClientHello/ServerHello in SSLv3 */ - || ((context & EXT_CLIENT_HELLO) != 0 + || ((context & (EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO)) != 0 + && s->version == SSL3_VERSION && !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))) { - *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR); return 0; } @@ -504,7 +524,6 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, } if (!WPACKET_close(pkt)) { - *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR); return 0; } diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 38a6bef862..e313e9aa5c 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -647,3 +647,373 @@ int tls_parse_clienthello_ems(SSL *s, PACKET *pkt, int *al) return 1; } + +/* + * Process the ALPN extension in a ClientHello. + * al: a pointer to the alert value to send in the event of a failure. + * returns 1 on success, 0 on error. + */ +static int tls1_alpn_handle_client_hello_late(SSL *s, int *al) +{ + const unsigned char *selected = NULL; + unsigned char selected_len = 0; + + if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) { + int r = s->ctx->alpn_select_cb(s, &selected, &selected_len, + s->s3->alpn_proposed, + (unsigned int)s->s3->alpn_proposed_len, + s->ctx->alpn_select_cb_arg); + + if (r == SSL_TLSEXT_ERR_OK) { + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len); + if (s->s3->alpn_selected == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + s->s3->alpn_selected_len = selected_len; +#ifndef OPENSSL_NO_NEXTPROTONEG + /* ALPN takes precedence over NPN. */ + s->s3->next_proto_neg_seen = 0; +#endif + } else { + *al = SSL_AD_NO_APPLICATION_PROTOCOL; + return 0; + } + } + + return 1; +} + +/* + * Upon success, returns 1. + * Upon failure, returns 0 and sets |al| to the appropriate fatal alert. + */ +int ssl_check_clienthello_tlsext_late(SSL *s, int *al) +{ + s->tlsext_status_expected = 0; + + /* + * If status request then ask callback what to do. Note: this must be + * called after servername callbacks in case the certificate has changed, + * and must be called after the cipher has been chosen because this may + * influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { + int ret; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey != NULL) { + /* + * Set current certificate to one we will use so SSL_get_certificate + * et al can pick it up. + */ + s->cert->key = certpkey; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (ret) { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + default: + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + } + + if (!tls1_alpn_handle_client_hello_late(s, al)) { + return 0; + } + + return 1; +} + +/* Add the server's renegotiation binding */ +int tls_construct_server_renegotiate(SSL *s, WPACKET *pkt, int *al) +{ + if (!s->s3->send_connection_binding) + return 1; + + 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)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_RENEGOTIATE, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int tls_construct_server_server_name(SSL *s, WPACKET *pkt, int *al) +{ + if (s->hit || s->servername_done != 1 + || s->session->tlsext_hostname == NULL) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) + || !WPACKET_put_bytes_u16(pkt, 0)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_SERVER_NAME, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +#ifndef OPENSSL_NO_EC +int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al) +{ + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA); + using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); + const unsigned char *plist; + size_t plistlen; + + if (!using_ecc) + return 1; + + tls1_get_formatlist(s, &plist, &plistlen); + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} +#endif + +int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al) +{ + if (!s->tlsext_ticket_expected || !tls_use_ticket(s)) { + s->tlsext_ticket_expected = 0; + return 1; + } + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket) + || !WPACKET_put_bytes_u16(pkt, 0)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al) +{ + if (!s->tlsext_status_expected) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) + || !WPACKET_put_bytes_u16(pkt, 0)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + + +#ifndef OPENSSL_NO_NEXTPROTONEG +int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al) +{ + const unsigned char *npa; + unsigned int npalen; + int ret; + int next_proto_neg_seen = s->s3->next_proto_neg_seen; + + s->s3->next_proto_neg_seen = 0; + if (!next_proto_neg_seen || s->ctx->next_protos_advertised_cb == NULL) + return 1; + + ret = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, + s->ctx->next_protos_advertised_cb_arg); + if (ret == SSL_TLSEXT_ERR_OK) { + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg) + || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_NEXT_PROTO_NEG, + ERR_R_INTERNAL_ERROR); + return 0; + } + s->s3->next_proto_neg_seen = 1; + } + + return 1; +} +#endif + +int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al) +{ + if (s->s3->alpn_selected == NULL) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, + TLSEXT_TYPE_application_layer_protocol_negotiation) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected, + s->s3->alpn_selected_len) + || !WPACKET_close(pkt) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_ALPN, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +#ifndef OPENSSL_NO_SRTP +int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al) +{ + if (s->srtp_profile == NULL) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp) + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_put_bytes_u16(pkt, 2) + || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id) + || !WPACKET_put_bytes_u8(pkt, 0) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_USE_SRTP, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} +#endif + +int tls_construct_server_etm(SSL *s, WPACKET *pkt, int *al) +{ + if ((s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) == 0) + return 1; + + /* + * Don't use encrypt_then_mac if AEAD or RC4 might want to disable + * for other cases too. + */ + if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD + || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4 + || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT + || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) { + s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC; + return 1; + } + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac) + || !WPACKET_put_bytes_u16(pkt, 0)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_ETM, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int tls_construct_server_ems(SSL *s, WPACKET *pkt, int *al) +{ + if ((s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) + || !WPACKET_put_bytes_u16(pkt, 0)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_EMS, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al) +{ + unsigned char *encodedPoint; + size_t encoded_pt_len = 0; + EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL; + + if (s->hit) + return 1; + + if (ckey == NULL) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR); + return 0; + } + + 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)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR); + return 0; + } + + skey = ssl_generate_pkey(ckey); + if (skey == NULL) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Generate encoding of server key */ + encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); + if (encoded_pt_len == 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_EC_LIB); + EVP_PKEY_free(skey); + return 0; + } + + if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(skey); + OPENSSL_free(encodedPoint); + return 0; + } + 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) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_SHARE, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al) +{ + const unsigned char cryptopro_ext[36] = { + 0xfd, 0xe8, /* 65000 */ + 0x00, 0x20, /* 32 bytes length */ + 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, + 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, + 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 + }; + + if (((s->s3->tmp.new_cipher->id & 0xFFFF) != 0x80 + && (s->s3->tmp.new_cipher->id & 0xFFFF) != 0x81) + || (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG) == 0) + return 1; + + if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CRYPTOPRO_BUG, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index c884eab676..7032ab4eb4 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -179,3 +179,22 @@ int tls_parse_clienthello_use_srtp(SSL *s, PACKET *pkt, int *al); int tls_parse_clienthello_etm(SSL *s, PACKET *pkt, int *al); int tls_parse_clienthello_key_share(SSL *s, PACKET *pkt, int *al); int tls_parse_clienthello_ems(SSL *s, PACKET *pkt, int *al); + +int tls_construct_server_renegotiate(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_server_name(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_etm(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_ems(SSL *s, WPACKET *pkt, int *al); +int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al); + +/* + * Not in public headers as this is not an official extension. Only used when + * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set. + */ +#define TLSEXT_TYPE_cryptopro_bug 0xfde8 +int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 773e732642..cc4b8c3153 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -1980,15 +1980,20 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len) || (!SSL_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, compm)) - || !ssl_prepare_serverhello_tlsext(s) - || !ssl_add_serverhello_tlsext(s, pkt, &al)) { + /* + * TODO(TLS1.3): For now we add all 1.2 and 1.3 extensions. Later + * we will do this based on the actual protocol + */ + || !tls_construct_extensions(s, pkt, + EXT_TLS1_2_SERVER_HELLO + | EXT_TLS1_3_SERVER_HELLO, &al)) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR); goto err; } return 1; err: - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, al); return 0; } |