提交 ab83e314 编写于 作者: M Matt Caswell

Move client construction of ClientHello extensions into new framework

Perl changes reviewed by Richard Levitte. Non-perl changes reviewed by Rich
Salz
Reviewed-by: NRich Salz <rsalz@openssl.org>
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 6dd083fd
......@@ -2265,9 +2265,26 @@ int ERR_load_SSL_strings(void);
# define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407
# define SSL_F_TLS_CONSTRUCT_CKE_RSA 409
# define SSL_F_TLS_CONSTRUCT_CKE_SRP 410
# define SSL_F_TLS_CONSTRUCT_CLIENT_ALPN 466
# define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE 355
# define SSL_F_TLS_CONSTRUCT_CLIENT_EC_PT_FORMATS 467
# define SSL_F_TLS_CONSTRUCT_CLIENT_EMS 468
# define SSL_F_TLS_CONSTRUCT_CLIENT_ETM 469
# define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO 356
# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE 357
# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE 470
# define SSL_F_TLS_CONSTRUCT_CLIENT_NPN 471
# define SSL_F_TLS_CONSTRUCT_CLIENT_PADDING 472
# define SSL_F_TLS_CONSTRUCT_CLIENT_RENEGOTIATE 473
# define SSL_F_TLS_CONSTRUCT_CLIENT_SCT 474
# define SSL_F_TLS_CONSTRUCT_CLIENT_SERVER_NAME 475
# define SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET 476
# define SSL_F_TLS_CONSTRUCT_CLIENT_SIG_ALGS 477
# define SSL_F_TLS_CONSTRUCT_CLIENT_SRP 478
# define SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST 479
# define SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS 480
# define SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS 481
# define SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP 482
# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 358
# define SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS 443
# define SSL_F_TLS_CONSTRUCT_EXTENSIONS 447
......
......@@ -265,12 +265,40 @@ static ERR_STRING_DATA SSL_str_functs[] = {
"tls_construct_cke_psk_preamble"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_RSA), "tls_construct_cke_rsa"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_SRP), "tls_construct_cke_srp"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_ALPN), "tls_construct_client_alpn"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE),
"tls_construct_client_certificate"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_EC_PT_FORMATS),
"tls_construct_client_ec_pt_formats"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_EMS), "tls_construct_client_ems"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_ETM), "tls_construct_client_etm"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO),
"tls_construct_client_hello"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE),
"tls_construct_client_key_exchange"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE),
"tls_construct_client_key_share"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_NPN), "tls_construct_client_npn"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_PADDING),
"tls_construct_client_padding"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_RENEGOTIATE),
"tls_construct_client_renegotiate"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SCT), "tls_construct_client_sct"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SERVER_NAME),
"tls_construct_client_server_name"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET),
"tls_construct_client_session_ticket"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SIG_ALGS),
"tls_construct_client_sig_algs"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SRP), "tls_construct_client_srp"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST),
"tls_construct_client_status_request"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS),
"tls_construct_client_supported_groups"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS),
"tls_construct_client_supported_versions"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP),
"tls_construct_client_use_srtp"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY),
"tls_construct_client_verify"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS),
......
......@@ -2077,12 +2077,10 @@ __owur int tls_curve_allowed(SSL *s, const unsigned char *curve, int op);
__owur int tls1_get_curvelist(SSL *s, int sess, const unsigned char **pcurves,
size_t *num_curves);
__owur int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al);
void ssl_set_default_md(SSL *s);
__owur int tls1_set_server_sigalgs(SSL *s);
__owur int ssl_check_clienthello_tlsext_late(SSL *s, int *al);
__owur int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt);
__owur int ssl_prepare_clienthello_tlsext(SSL *s);
__owur RAW_EXTENSION *tls_get_extension_by_type(RAW_EXTENSION *exts,
size_t numexts,
unsigned int type);
......
......@@ -36,7 +36,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_renegotiate,
tls_parse_server_renegotiate,
tls_construct_server_renegotiate,
NULL,
tls_construct_client_renegotiate,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_SSL3_ALLOWED
| EXT_TLS1_2_AND_BELOW_ONLY
},
......@@ -45,7 +45,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_server_name,
tls_parse_server_server_name,
tls_construct_server_server_name,
NULL,
tls_construct_client_server_name,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
| EXT_TLS1_3_ENCRYPTED_EXTENSIONS
},
......@@ -55,7 +55,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_srp,
NULL,
NULL,
NULL,
tls_construct_client_srp,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
#endif
......@@ -65,7 +65,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_ec_pt_formats,
tls_parse_server_ec_pt_formats,
tls_construct_server_ec_pt_formats,
NULL,
tls_construct_client_ec_pt_formats,
EXT_CLIENT_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
{
......@@ -73,7 +73,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_supported_groups,
NULL,
NULL /* TODO(TLS1.3): Need to add this */,
NULL,
tls_construct_client_supported_groups,
EXT_CLIENT_HELLO
| EXT_TLS1_3_ENCRYPTED_EXTENSIONS
},
......@@ -83,7 +83,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_session_ticket,
tls_parse_server_session_ticket,
tls_construct_server_session_ticket,
NULL,
tls_construct_client_session_ticket,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
{
......@@ -91,25 +91,27 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_sig_algs,
NULL,
NULL,
NULL,
tls_construct_client_sig_algs,
EXT_CLIENT_HELLO
},
#ifndef OPENSSL_NO_OCSP
{
TLSEXT_TYPE_status_request,
tls_parse_client_status_request,
tls_parse_server_status_request,
tls_construct_server_status_request,
NULL,
tls_construct_client_status_request,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
| EXT_TLS1_3_CERTIFICATE
},
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
{
TLSEXT_TYPE_next_proto_neg,
tls_parse_client_npn,
tls_parse_server_npn,
tls_construct_server_next_proto_neg,
NULL,
tls_construct_client_npn,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
#endif
......@@ -118,7 +120,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_alpn,
tls_parse_server_alpn,
tls_construct_server_alpn,
NULL,
tls_construct_client_alpn,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
| EXT_TLS1_3_ENCRYPTED_EXTENSIONS
},
......@@ -128,7 +130,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_use_srtp,
tls_parse_server_use_srtp,
tls_construct_server_use_srtp,
NULL,
tls_construct_client_use_srtp,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
| EXT_TLS1_3_ENCRYPTED_EXTENSIONS | EXT_DTLS_ONLY
},
......@@ -138,7 +140,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_etm,
tls_parse_server_etm,
tls_construct_server_etm,
NULL,
tls_construct_client_etm,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
#ifndef OPENSSL_NO_CT
......@@ -152,7 +154,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
NULL,
tls_parse_server_sct,
NULL,
NULL,
tls_construct_client_sct,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO
| EXT_TLS1_3_CERTIFICATE
},
......@@ -162,7 +164,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_parse_client_ems,
tls_parse_server_ems,
tls_construct_server_ems,
NULL,
tls_construct_client_ems,
EXT_CLIENT_HELLO | EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
{
......@@ -171,24 +173,15 @@ static const EXTENSION_DEFINITION ext_defs[] = {
NULL,
NULL,
NULL,
NULL,
EXT_CLIENT_HELLO | EXT_TLS_IMPLEMENTATION_ONLY
},
{
TLSEXT_TYPE_padding,
/* We send this, but don't read it */
NULL,
NULL,
NULL,
NULL,
EXT_CLIENT_HELLO
tls_construct_client_supported_versions,
EXT_CLIENT_HELLO | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY
},
{
TLSEXT_TYPE_key_share,
tls_parse_client_key_share,
tls_parse_server_key_share,
tls_construct_server_key_share,
NULL,
tls_construct_client_key_share,
EXT_CLIENT_HELLO | EXT_TLS1_3_SERVER_HELLO
| EXT_TLS1_3_HELLO_RETRY_REQUEST | EXT_TLS_IMPLEMENTATION_ONLY
| EXT_TLS1_3_ONLY
......@@ -204,6 +197,16 @@ static const EXTENSION_DEFINITION ext_defs[] = {
tls_construct_server_cryptopro_bug,
NULL,
EXT_TLS1_2_SERVER_HELLO | EXT_TLS1_2_AND_BELOW_ONLY
},
{
/* Last in the list because it must be added as the last extension */
TLSEXT_TYPE_padding,
/* We send this, but don't read it */
NULL,
NULL,
NULL,
tls_construct_client_padding,
EXT_CLIENT_HELLO
}
};
......@@ -457,6 +460,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
{
size_t loop;
int addcustom = 0;
int min_version, max_version = 0, reason;
/*
* Normally if something goes wrong during construction its an internal
......@@ -477,6 +481,35 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
return 0;
}
if ((context & EXT_CLIENT_HELLO) != 0) {
reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
if (reason != 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, reason);
return 0;
}
}
/* Add custom extensions first */
if ((context & EXT_CLIENT_HELLO) != 0) {
custom_ext_init(&s->cert->cli_ext);
addcustom = 1;
} else if ((context & EXT_TLS1_2_SERVER_HELLO) != 0) {
/*
* We already initialised the custom extensions during ClientHello
* parsing.
*
* TODO(TLS1.3): We're going to need a new custom extension mechanism
* for TLS1.3, so that custom extensions can specify which of the
* multiple message they wish to add themselves to.
*/
addcustom = 1;
}
if (addcustom && !custom_ext_add(s, s->server, pkt, al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
return 0;
}
for (loop = 0; loop < OSSL_NELEM(ext_defs); loop++) {
int (*construct)(SSL *s, WPACKET *pkt, int *al);
......@@ -499,6 +532,9 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
|| (!SSL_IS_TLS13(s)
&& (ext_defs[loop].context & EXT_TLS1_3_ONLY) != 0
&& (context & EXT_CLIENT_HELLO) == 0)
|| ((ext_defs[loop].context & EXT_TLS1_3_ONLY) != 0
&& (context & EXT_CLIENT_HELLO) != 0
&& (SSL_IS_DTLS(s) || max_version < TLS1_3_VERSION))
|| construct == NULL)
continue;
......@@ -506,27 +542,6 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
return 0;
}
/* Add custom extensions */
if ((context & EXT_CLIENT_HELLO) != 0) {
custom_ext_init(&s->cert->cli_ext);
addcustom = 1;
} else if ((context & EXT_TLS1_2_SERVER_HELLO) != 0) {
/*
* We already initialised the custom extensions during ClientHello
* parsing.
*
* TODO(TLS1.3): We're going to need a new custom extension mechanism
* for TLS1.3, so that custom extensions can specify which of the
* multiple message they wish to add themselves to.
*/
addcustom = 1;
}
if (addcustom && !custom_ext_add(s, s->server, pkt, al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
return 0;
}
if (!WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, ERR_R_INTERNAL_ERROR);
return 0;
......
......@@ -8,9 +8,604 @@
*/
#include <assert.h>
#include <openssl/ocsp.h>
#include "../ssl_locl.h"
#include "statem_locl.h"
int tls_construct_client_renegotiate(SSL *s, WPACKET *pkt, int *al)
{
/* Add RI if renegotiating */
if (!s->renegotiate)
return 1;
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)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_RENEGOTIATE, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_client_server_name(SSL *s, WPACKET *pkt, int *al)
{
if (s->tlsext_hostname == NULL)
return 1;
/* Add TLS extension servername to the Client Hello message */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
/* Sub-packet for server_name extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for servername list (always 1 hostname)*/
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
|| !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
strlen(s->tlsext_hostname))
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SERVER_NAME, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#ifndef OPENSSL_NO_SRP
int tls_construct_client_srp(SSL *s, WPACKET *pkt, int *al)
{
/* Add SRP username if there is one */
if (s->srp_ctx.login == NULL)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
/* Sub-packet for SRP extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u8(pkt)
/* login must not be zero...internal error if so */
|| !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
|| !WPACKET_memcpy(pkt, s->srp_ctx.login,
strlen(s->srp_ctx.login))
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SRP, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
#ifndef OPENSSL_NO_EC
static int use_ecc(SSL *s)
{
int using_ecc = 0;
int i;
unsigned long alg_k, alg_a;
STACK_OF(SSL_CIPHER) *cipher_stack = NULL;
/* See if we support any ECC ciphersuites */
if (s->version == SSL3_VERSION)
return 0;
cipher_stack = SSL_get_ciphers(s);
for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
alg_k = c->algorithm_mkey;
alg_a = c->algorithm_auth;
if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
|| (alg_a & SSL_aECDSA)
|| c->min_tls >= TLS1_3_VERSION) {
using_ecc = 1;
break;
}
}
return using_ecc;
}
int tls_construct_client_ec_pt_formats(SSL *s, WPACKET *pkt, int *al)
{
const unsigned char *pformats;
size_t num_formats;
if (!use_ecc(s))
return 1;
/* Add TLS extension ECPointFormats to the ClientHello message */
tls1_get_formatlist(s, &pformats, &num_formats);
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
/* Sub-packet for formats extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_client_supported_groups(SSL *s, WPACKET *pkt, int *al)
{
const unsigned char *pcurves = NULL, *pcurvestmp;
size_t num_curves = 0, i;
if (!use_ecc(s))
return 1;
/*
* Add TLS extension supported_groups to the ClientHello message
*/
/* TODO(TLS1.3): Add support for DHE groups */
pcurves = s->tlsext_supportedgroupslist;
if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
ERR_R_INTERNAL_ERROR);
return 0;
}
pcurvestmp = pcurves;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
/* Sub-packet for supported_groups extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
ERR_R_INTERNAL_ERROR);
return 0;
}
/* Copy curve ID if supported */
for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
|| !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_GROUPS,
ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
int tls_construct_client_session_ticket(SSL *s, WPACKET *pkt, int *al)
{
size_t ticklen;
if (!tls_use_ticket(s))
return 1;
if (!s->new_session && s->session != NULL
&& s->session->tlsext_tick != NULL) {
ticklen = s->session->tlsext_ticklen;
} else if (s->session && s->tlsext_session_ticket != NULL
&& s->tlsext_session_ticket->data != NULL) {
ticklen = s->tlsext_session_ticket->length;
s->session->tlsext_tick = OPENSSL_malloc(ticklen);
if (s->session->tlsext_tick == NULL) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET,
ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(s->session->tlsext_tick,
s->tlsext_session_ticket->data, ticklen);
s->session->tlsext_ticklen = ticklen;
} else {
ticklen = 0;
}
if (ticklen == 0 && s->tlsext_session_ticket != NULL &&
s->tlsext_session_ticket->data == NULL)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
|| !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick, ticklen)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_client_sig_algs(SSL *s, WPACKET *pkt, int *al)
{
size_t salglen;
const unsigned char *salg;
if (!SSL_CLIENT_USE_SIGALGS(s))
return 1;
salglen = tls12_get_psigalgs(s, &salg);
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
/* Sub-packet for sig-algs extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for the actual list */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !tls12_copy_sigalgs(s, pkt, salg, salglen)
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SIG_ALGS, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#ifndef OPENSSL_NO_OCSP
int tls_construct_client_status_request(SSL *s, WPACKET *pkt, int *al)
{
int i;
if (s->tlsext_status_type != TLSEXT_STATUSTYPE_ocsp)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
/* Sub-packet for status request extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
/* Sub-packet for the ids */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
return 0;
}
for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
unsigned char *idbytes;
int idlen;
OCSP_RESPID *id;
id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
idlen = i2d_OCSP_RESPID(id, NULL);
if (idlen <= 0
/* Sub-packet for an individual id */
|| !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
|| i2d_OCSP_RESPID(id, &idbytes) != idlen) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt)
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
return 0;
}
if (s->tlsext_ocsp_exts) {
unsigned char *extbytes;
int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
if (extlen < 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST,
ERR_R_INTERNAL_ERROR);
return 0;
}
if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
|| i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
!= extlen) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_STATUS_REQUEST, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int tls_construct_client_npn(SSL *s, WPACKET *pkt, int *al)
{
if (s->ctx->next_proto_select_cb == NULL || s->s3->tmp.finish_md_len != 0)
return 1;
/*
* The client advertises an empty extension to indicate its support
* for Next Protocol Negotiation
*/
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_NPN, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
int tls_construct_client_alpn(SSL *s, WPACKET *pkt, int *al)
{
s->s3->alpn_sent = 0;
/*
* finish_md_len is non-zero during a renegotiation, so
* this avoids sending ALPN during the renegotiation
*/
if (s->alpn_client_proto_list == NULL || s->s3->tmp.finish_md_len != 0)
return 1;
if (!WPACKET_put_bytes_u16(pkt,
TLSEXT_TYPE_application_layer_protocol_negotiation)
/* Sub-packet ALPN extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
s->alpn_client_proto_list_len)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_ALPN, ERR_R_INTERNAL_ERROR);
return 0;
}
s->s3->alpn_sent = 1;
return 1;
}
#ifndef OPENSSL_NO_SRTP
int tls_construct_client_use_srtp(SSL *s, WPACKET *pkt, int *al)
{
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
SRTP_PROTECTION_PROFILE *prof;
int i, ct;
if (clnt == NULL)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
/* Sub-packet for SRTP extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for the protection profile list */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP, ERR_R_INTERNAL_ERROR);
return 0;
}
ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
for (i = 0; i < ct; i++) {
prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP, ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt)
/* Add an empty use_mki value */
|| !WPACKET_put_bytes_u8(pkt, 0)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_USE_SRTP, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
int tls_construct_client_etm(SSL *s, WPACKET *pkt, int *al)
{
if (s->options & SSL_OP_NO_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_CLIENT_ETM, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#ifndef OPENSSL_NO_CT
int tls_construct_client_sct(SSL *s, WPACKET *pkt, int *al)
{
if (s->ct_validation_callback == NULL)
return 1;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SCT, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
#endif
int tls_construct_client_ems(SSL *s, WPACKET *pkt, int *al)
{
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_EMS, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_client_supported_versions(SSL *s, WPACKET *pkt, int *al)
{
int currv, min_version, max_version, reason;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u8(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
ERR_R_INTERNAL_ERROR);
return 0;
}
reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
if (reason != 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS, reason);
return 0;
}
/*
* TODO(TLS1.3): There is some discussion on the TLS list as to wheter
* we should include versions <TLS1.2. For the moment we do. To be
* reviewed later.
*/
for (currv = max_version; currv >= min_version; currv--) {
/* TODO(TLS1.3): Remove this first if clause prior to release!! */
if (currv == TLS1_3_VERSION) {
if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
ERR_R_INTERNAL_ERROR);
return 0;
}
} else if (!WPACKET_put_bytes_u16(pkt, currv)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_SUPPORTED_VERSIONS,
ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_client_key_share(SSL *s, WPACKET *pkt, int *al)
{
size_t i, sharessent = 0, num_curves = 0;
const unsigned char *pcurves = NULL;
/* key_share extension */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
/* Extension data sub-packet */
|| !WPACKET_start_sub_packet_u16(pkt)
/* KeyShare list sub-packet */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
return 0;
}
pcurves = s->tlsext_supportedgroupslist;
if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* TODO(TLS1.3): Make the number of key_shares sent configurable. For
* now, just send one
*/
for (i = 0; i < num_curves && sharessent < 1; i++, pcurves += 2) {
unsigned char *encodedPoint = NULL;
unsigned int curve_id = 0;
EVP_PKEY *key_share_key = NULL;
size_t encodedlen;
if (!tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED))
continue;
if (s->s3->tmp.pkey != NULL) {
/* Shouldn't happen! */
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
return 0;
}
/* Generate a key for this key_share */
curve_id = (pcurves[0] << 8) | pcurves[1];
key_share_key = ssl_generate_pkey_curve(curve_id);
if (key_share_key == NULL) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_EVP_LIB);
return 0;
}
/* Encode the public key. */
encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key,
&encodedPoint);
if (encodedlen == 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_EC_LIB);
EVP_PKEY_free(key_share_key);
return 0;
}
/* Create KeyShareEntry */
if (!WPACKET_put_bytes_u16(pkt, curve_id)
|| !WPACKET_sub_memcpy_u16(pkt, encodedPoint, encodedlen)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
EVP_PKEY_free(key_share_key);
OPENSSL_free(encodedPoint);
return 0;
}
/*
* TODO(TLS1.3): When changing to send more than one key_share we're
* going to need to be able to save more than one EVP_PKEY. For now
* we reuse the existing tmp.pkey
*/
s->s3->group_id = curve_id;
s->s3->tmp.pkey = key_share_key;
sharessent++;
OPENSSL_free(encodedPoint);
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_SHARE, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
int tls_construct_client_padding(SSL *s, WPACKET *pkt, int *al)
{
unsigned char *padbytes;
size_t hlen;
if ((s->options & SSL_OP_TLSEXT_PADDING) == 0)
return 1;
/*
* Add padding to workaround bugs in F5 terminators. See
* https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
* code works out the length of all existing extensions it MUST always
* appear last.
*/
if (!WPACKET_get_total_written(pkt, &hlen)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_PADDING, ERR_R_INTERNAL_ERROR);
return 0;
}
if (hlen > 0xff && hlen < 0x200) {
hlen = 0x200 - hlen;
if (hlen >= 4)
hlen -= 4;
else
hlen = 0;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
|| !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_PADDING, ERR_R_INTERNAL_ERROR);
return 0;
}
memset(padbytes, 0, hlen);
}
return 1;
}
/*
* Parse the server's renegotiation binding and abort if it's not right
*/
......@@ -147,6 +742,7 @@ int tls_parse_server_session_ticket(SSL *s, PACKET *pkt, int *al)
return 1;
}
#ifndef OPENSSL_NO_OCSP
int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al)
{
/*
......@@ -162,6 +758,7 @@ int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al)
return 1;
}
#endif
#ifndef OPENSSL_NO_CT
......
......@@ -215,13 +215,14 @@ int tls_parse_client_sig_algs(SSL *s, PACKET *pkt, int *al)
return 1;
}
#ifndef OPENSSL_NO_OCSP
int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al)
{
if (!PACKET_get_1(pkt, (unsigned int *)&s->tlsext_status_type)) {
*al = SSL_AD_DECODE_ERROR;
return 0;
}
#ifndef OPENSSL_NO_OCSP
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
const unsigned char *ext_data;
PACKET responder_id_list, exts;
......@@ -297,9 +298,7 @@ int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al)
return 0;
}
}
} else
#endif
{
} else {
/*
* We don't know what to do with any other type so ignore it.
*/
......@@ -308,6 +307,7 @@ int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al)
return 1;
}
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int tls_parse_client_npn(SSL *s, PACKET *pkt, int *al)
......@@ -949,6 +949,7 @@ int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al)
return 1;
}
#ifndef OPENSSL_NO_OCSP
int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al)
{
if (!s->tlsext_status_expected)
......@@ -962,6 +963,7 @@ int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al)
return 1;
}
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
......
......@@ -1011,18 +1011,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt)
}
/* TLS extensions */
if (ssl_prepare_clienthello_tlsext(s) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
return 0;
}
if (!WPACKET_start_sub_packet_u16(pkt)
/*
* If extensions are of zero length then we don't even add the
* extensions length bytes
*/
|| !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)
|| !ssl_add_clienthello_tlsext(s, pkt, &al)
|| !WPACKET_close(pkt)) {
if (!tls_construct_extensions(s, pkt, EXT_CLIENT_HELLO, &al)) {
ssl3_send_alert(s, SSL3_AL_FATAL, al);
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
return 0;
......
......@@ -168,7 +168,9 @@ int tls_parse_client_supported_groups(SSL *s, PACKET *pkt, int *al);
#endif
int tls_parse_client_session_ticket(SSL *s, PACKET *pkt, int *al);
int tls_parse_client_sig_algs(SSL *s, PACKET *pkt, int *al);
#ifndef OPENSSL_NO_OCSP
int tls_parse_client_status_request(SSL *s, PACKET *pkt, int *al);
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int tls_parse_client_npn(SSL *s, PACKET *pkt, int *al);
#endif
......@@ -184,12 +186,20 @@ int tls_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, 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);
#ifndef OPENSSL_NO_EC
int tls_construct_server_ec_pt_formats(SSL *s, WPACKET *pkt, int *al);
#endif
int tls_construct_server_session_ticket(SSL *s, WPACKET *pkt, int *al);
#ifndef OPENSSL_NO_OCSP
int tls_construct_server_status_request(SSL *s, WPACKET *pkt, int *al);
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int tls_construct_server_next_proto_neg(SSL *s, WPACKET *pkt, int *al);
#endif
int tls_construct_server_alpn(SSL *s, WPACKET *pkt, int *al);
#ifndef OPENSSL_NO_SRTP
int tls_construct_server_use_srtp(SSL *s, WPACKET *pkt, int *al);
#endif
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);
......@@ -201,13 +211,44 @@ int tls_construct_server_key_share(SSL *s, WPACKET *pkt, int *al);
int tls_construct_server_cryptopro_bug(SSL *s, WPACKET *pkt, int *al);
/* Client Extension processing */
int tls_construct_client_renegotiate(SSL *s, WPACKET *pkt, int *al);
int tls_construct_client_server_name(SSL *s, WPACKET *pkt, int *al);
#ifndef OPENSSL_NO_SRP
int tls_construct_client_srp(SSL *s, WPACKET *pkt, int *al);
#endif
#ifndef OPENSSL_NO_EC
int tls_construct_client_ec_pt_formats(SSL *s, WPACKET *pkt, int *al);
int tls_construct_client_supported_groups(SSL *s, WPACKET *pkt, int *al);
#endif
int tls_construct_client_session_ticket(SSL *s, WPACKET *pkt, int *al);
int tls_construct_client_sig_algs(SSL *s, WPACKET *pkt, int *al);
#ifndef OPENSSL_NO_OCSP
int tls_construct_client_status_request(SSL *s, WPACKET *pkt, int *al);
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
int tls_construct_client_npn(SSL *s, WPACKET *pkt, int *al);
#endif
int tls_construct_client_alpn(SSL *s, WPACKET *pkt, int *al);
#ifndef OPENSSL_NO_SRTP
int tls_construct_client_use_srtp(SSL *s, WPACKET *pkt, int *al);
#endif
int tls_construct_client_etm(SSL *s, WPACKET *pkt, int *al);
#ifndef OPENSSL_NO_CT
int tls_construct_client_sct(SSL *s, WPACKET *pkt, int *al);
#endif
int tls_construct_client_ems(SSL *s, WPACKET *pkt, int *al);
int tls_construct_client_supported_versions(SSL *s, WPACKET *pkt, int *al);
int tls_construct_client_key_share(SSL *s, WPACKET *pkt, int *al);
int tls_construct_client_padding(SSL *s, WPACKET *pkt, int *al);
int tls_parse_server_renegotiate(SSL *s, PACKET *pkt, int *al);
int tls_parse_server_server_name(SSL *s, PACKET *pkt, int *al);
#ifndef OPENSSL_NO_EC
int tls_parse_server_ec_pt_formats(SSL *s, PACKET *pkt, int *al);
#endif
int tls_parse_server_session_ticket(SSL *s, PACKET *pkt, int *al);
#ifndef OPENSSL_NO_OCSP
int tls_parse_server_status_request(SSL *s, PACKET *pkt, int *al);
#endif
#ifndef OPENSSL_NO_CT
int tls_parse_server_sct(SSL *s, PACKET *pkt, int *al);
#endif
......
......@@ -945,503 +945,6 @@ int tls_use_ticket(SSL *s)
return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
}
int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
{
#ifndef OPENSSL_NO_EC
const unsigned char *pcurves = NULL;
size_t num_curves = 0;
int using_ecc = 0;
int min_version, max_version, reason;
/* See if we support any ECC ciphersuites */
if ((s->version >= TLS1_VERSION && s->version <= TLS1_3_VERSION)
|| SSL_IS_DTLS(s)) {
int i;
unsigned long alg_k, alg_a;
STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
alg_k = c->algorithm_mkey;
alg_a = c->algorithm_auth;
if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
|| (alg_a & SSL_aECDSA)
|| c->min_tls >= TLS1_3_VERSION) {
using_ecc = 1;
break;
}
}
}
#else
if (SSL_IS_TLS13(s)) {
/* Shouldn't happen! */
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
#endif
/* Add RI if renegotiating */
if (s->renegotiate) {
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)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
/* Only add RI for SSLv3 */
if (s->client_version == SSL3_VERSION)
goto done;
if (s->tlsext_hostname != NULL) {
/* Add TLS extension servername to the Client Hello message */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
/* Sub-packet for server_name extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for servername list (always 1 hostname)*/
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
|| !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
strlen(s->tlsext_hostname))
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#ifndef OPENSSL_NO_SRP
/* Add SRP username if there is one */
if (s->srp_ctx.login != NULL) {
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
/* Sub-packet for SRP extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u8(pkt)
/* login must not be zero...internal error if so */
|| !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
|| !WPACKET_memcpy(pkt, s->srp_ctx.login,
strlen(s->srp_ctx.login))
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#endif
#ifndef OPENSSL_NO_EC
if (using_ecc) {
/*
* Add TLS extension ECPointFormats to the ClientHello message
*/
const unsigned char *pformats, *pcurvestmp;
size_t num_formats;
size_t i;
tls1_get_formatlist(s, &pformats, &num_formats);
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
/* Sub-packet for formats extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* Add TLS extension supported_groups to the ClientHello message
*/
/* TODO(TLS1.3): Add support for DHE groups */
pcurves = s->tlsext_supportedgroupslist;
if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
pcurvestmp = pcurves;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
/* Sub-packet for supported_groups extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
/* Copy curve ID if supported */
for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
|| !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
ERR_R_INTERNAL_ERROR);
return 0;
}
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#endif /* OPENSSL_NO_EC */
if (tls_use_ticket(s)) {
size_t ticklen;
if (!s->new_session && s->session && s->session->tlsext_tick)
ticklen = s->session->tlsext_ticklen;
else if (s->session && s->tlsext_session_ticket &&
s->tlsext_session_ticket->data) {
ticklen = s->tlsext_session_ticket->length;
s->session->tlsext_tick = OPENSSL_malloc(ticklen);
if (s->session->tlsext_tick == NULL) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(s->session->tlsext_tick,
s->tlsext_session_ticket->data, ticklen);
s->session->tlsext_ticklen = ticklen;
} else
ticklen = 0;
if (ticklen == 0 && s->tlsext_session_ticket &&
s->tlsext_session_ticket->data == NULL)
goto skip_ext;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
|| !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick,
ticklen)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
skip_ext:
if (SSL_CLIENT_USE_SIGALGS(s)) {
size_t salglen;
const unsigned char *salg;
salglen = tls12_get_psigalgs(s, &salg);
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
/* Sub-packet for sig-algs extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for the actual list */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !tls12_copy_sigalgs(s, pkt, salg, salglen)
|| !WPACKET_close(pkt)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#ifndef OPENSSL_NO_OCSP
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
int i;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
/* Sub-packet for status request extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
/* Sub-packet for the ids */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
unsigned char *idbytes;
int idlen;
OCSP_RESPID *id;
id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
idlen = i2d_OCSP_RESPID(id, NULL);
if (idlen <= 0
/* Sub-packet for an individual id */
|| !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
|| i2d_OCSP_RESPID(id, &idbytes) != idlen) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt)
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
if (s->tlsext_ocsp_exts) {
unsigned char *extbytes;
int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
if (extlen < 0) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
|| i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
!= extlen) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
/*
* The client advertises an empty extension to indicate its support
* for Next Protocol Negotiation
*/
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#endif
/*
* finish_md_len is non-zero during a renegotiation, so
* this avoids sending ALPN during the renegotiation
* (see longer comment below)
*/
if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
if (!WPACKET_put_bytes_u16(pkt,
TLSEXT_TYPE_application_layer_protocol_negotiation)
/* Sub-packet ALPN extension */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
s->alpn_client_proto_list_len)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
s->s3->alpn_sent = 1;
}
#ifndef OPENSSL_NO_SRTP
if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
SRTP_PROTECTION_PROFILE *prof;
int i, ct;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
/* Sub-packet for SRTP extension */
|| !WPACKET_start_sub_packet_u16(pkt)
/* Sub-packet for the protection profile list */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
for (i = 0; i < ct; i++) {
prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt)
/* Add an empty use_mki value */
|| !WPACKET_put_bytes_u8(pkt, 0)
|| !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#endif
custom_ext_init(&s->cert->cli_ext);
/* Add custom TLS Extensions to ClientHello */
if (!custom_ext_add(s, 0, pkt, al)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) {
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#ifndef OPENSSL_NO_CT
if (s->ct_validation_callback != NULL) {
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
#endif
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
if (reason != 0) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, reason);
return 0;
}
/* TLS1.3 specific extensions */
if (!SSL_IS_DTLS(s) && max_version >= TLS1_3_VERSION) {
int currv;
size_t i, sharessent = 0;
/* TODO(TLS1.3): Should we add this extension for versions < TLS1.3? */
/* supported_versions extension */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_start_sub_packet_u8(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* TODO(TLS1.3): There is some discussion on the TLS list as to wheter
* we should include versions <TLS1.2. For the moment we do. To be
* reviewed later.
*/
for (currv = max_version; currv >= min_version; currv--) {
/* TODO(TLS1.3): Remove this first if clause prior to release!! */
if (currv == TLS1_3_VERSION) {
if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
ERR_R_INTERNAL_ERROR);
return 0;
}
} else if (!WPACKET_put_bytes_u16(pkt, currv)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
/* key_share extension */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
/* Extension data sub-packet */
|| !WPACKET_start_sub_packet_u16(pkt)
/* KeyShare list sub-packet */
|| !WPACKET_start_sub_packet_u16(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
/*
* TODO(TLS1.3): Make the number of key_shares sent configurable. For
* now, just send one
*/
for (i = 0; i < num_curves && sharessent < 1; i++, pcurves += 2) {
unsigned char *encodedPoint = NULL;
unsigned int curve_id = 0;
EVP_PKEY *key_share_key = NULL;
size_t encodedlen;
if (!tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED))
continue;
if (s->s3->tmp.pkey != NULL) {
/* Shouldn't happen! */
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
ERR_R_INTERNAL_ERROR);
return 0;
}
/* Generate a key for this key_share */
curve_id = (pcurves[0] << 8) | pcurves[1];
key_share_key = ssl_generate_pkey_curve(curve_id);
if (key_share_key == NULL) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_EVP_LIB);
return 0;
}
/* Encode the public key. */
encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key,
&encodedPoint);
if (encodedlen == 0) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_EC_LIB);
EVP_PKEY_free(key_share_key);
return 0;
}
/* Create KeyShareEntry */
if (!WPACKET_put_bytes_u16(pkt, curve_id)
|| !WPACKET_sub_memcpy_u16(pkt, encodedPoint, encodedlen)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
ERR_R_INTERNAL_ERROR);
EVP_PKEY_free(key_share_key);
OPENSSL_free(encodedPoint);
return 0;
}
/*
* TODO(TLS1.3): When changing to send more than one key_share we're
* going to need to be able to save more than one EVP_PKEY. For now
* we reuse the existing tmp.pkey
*/
s->s3->group_id = curve_id;
s->s3->tmp.pkey = key_share_key;
sharessent++;
OPENSSL_free(encodedPoint);
}
if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
}
/*
* Add padding to workaround bugs in F5 terminators. See
* https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
* code works out the length of all existing extensions it MUST always
* appear last.
*/
if (s->options & SSL_OP_TLSEXT_PADDING) {
unsigned char *padbytes;
size_t hlen;
if (!WPACKET_get_total_written(pkt, &hlen)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
if (hlen > 0xff && hlen < 0x200) {
hlen = 0x200 - hlen;
if (hlen >= 4)
hlen -= 4;
else
hlen = 0;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
|| !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return 0;
}
memset(padbytes, 0, hlen);
}
}
done:
return 1;
}
int ssl_prepare_clienthello_tlsext(SSL *s)
{
s->s3->alpn_sent = 0;
return 1;
}
/* Initialise digests to default values */
void ssl_set_default_md(SSL *s)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册