From b186a592833ea4efd8e18d053955abde179e1b3d Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 9 May 2017 13:44:25 +0100 Subject: [PATCH] Fail if we receive a response to an extension that we didn't request We already did this on an ad-hoc per extension basis (for some extensions). This centralises it and makes sure we do it for all extensions. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/3418) --- ssl/ssl_locl.h | 64 ++++---- ssl/statem/extensions.c | 74 ++++++--- ssl/statem/extensions_clnt.c | 295 +++++++++++++++++++---------------- ssl/statem/extensions_srvr.c | 201 ++++++++++++------------ ssl/statem/statem_lib.c | 3 + ssl/statem/statem_locl.h | 168 +++++++++++--------- 6 files changed, 449 insertions(+), 356 deletions(-) diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 0644c7fae0..f113854925 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -686,6 +686,38 @@ typedef struct { RAW_EXTENSION *pre_proc_exts; } CLIENTHELLO_MSG; +/* + * Extension index values NOTE: Any updates to these defines should be mirrored + * with equivalent updates to ext_defs in extensions.c + */ +typedef enum tlsext_index_en { + TLSEXT_IDX_renegotiate, + TLSEXT_IDX_server_name, + TLSEXT_IDX_srp, + TLSEXT_IDX_ec_point_formats, + TLSEXT_IDX_supported_groups, + TLSEXT_IDX_session_ticket, + TLSEXT_IDX_signature_algorithms, + TLSEXT_IDX_status_request, + TLSEXT_IDX_next_proto_neg, + TLSEXT_IDX_application_layer_protocol_negotiation, + TLSEXT_IDX_use_srtp, + TLSEXT_IDX_encrypt_then_mac, + TLSEXT_IDX_signed_certificate_timestamp, + TLSEXT_IDX_extended_master_secret, + TLSEXT_IDX_supported_versions, + TLSEXT_IDX_psk_kex_modes, + TLSEXT_IDX_key_share, + TLSEXT_IDX_cookie, + TLSEXT_IDX_cryptopro_bug, + TLSEXT_IDX_early_data, + TLSEXT_IDX_certificate_authorities, + TLSEXT_IDX_padding, + TLSEXT_IDX_psk, + /* Dummy index - must always be the last entry */ + TLSEXT_IDX_num_builtins +} TLSEXT_INDEX; + DEFINE_LHASH_OF(SSL_SESSION); /* Needed in ssl_cert.c */ DEFINE_LHASH_OF(X509_NAME); @@ -1153,6 +1185,8 @@ struct ssl_st { size_t max_pipelines; struct { + /* Built-in extension flags */ + uint8_t extflags[TLSEXT_IDX_num_builtins]; /* TLS extension debug callback */ void (*debug_cb)(SSL *s, int client_server, int type, const unsigned char *data, int len, void *arg); @@ -1813,36 +1847,6 @@ typedef enum downgrade_en { DOWNGRADE_TO_1_1 } DOWNGRADE; -/* - * Extension index values NOTE: Any updates to these defines should be mirrored - * with equivalent updates to ext_defs in extensions.c - */ -typedef enum tlsext_index_en { - TLSEXT_IDX_renegotiate, - TLSEXT_IDX_server_name, - TLSEXT_IDX_srp, - TLSEXT_IDX_ec_point_formats, - TLSEXT_IDX_supported_groups, - TLSEXT_IDX_session_ticket, - TLSEXT_IDX_signature_algorithms, - TLSEXT_IDX_status_request, - TLSEXT_IDX_next_proto_neg, - TLSEXT_IDX_application_layer_protocol_negotiation, - TLSEXT_IDX_use_srtp, - TLSEXT_IDX_encrypt_then_mac, - TLSEXT_IDX_signed_certificate_timestamp, - TLSEXT_IDX_extended_master_secret, - TLSEXT_IDX_supported_versions, - TLSEXT_IDX_psk_kex_modes, - TLSEXT_IDX_key_share, - TLSEXT_IDX_cookie, - TLSEXT_IDX_cryptopro_bug, - TLSEXT_IDX_early_data, - TLSEXT_IDX_certificate_authorities, - TLSEXT_IDX_padding, - TLSEXT_IDX_psk -} TLSEXT_INDEX; - /* * Dummy status type for the status_type extension. Indicates no status type * set diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 578ca13a74..9854cf0db9 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,9 +31,11 @@ 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 EXT_RETURN 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); @@ -74,11 +76,11 @@ typedef struct extensions_definition_st { int (*parse_stoc)(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); /* Construct extension sent from server to client */ - int (*construct_stoc)(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); + EXT_RETURN (*construct_stoc)(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); /* Construct extension sent from client to server */ - int (*construct_ctos)(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); + EXT_RETURN (*construct_ctos)(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); /* * Finalise extension after parsing. Always called where an extensions was * initialised even if the extension was not present. |sent| is set to 1 if @@ -461,7 +463,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, } while (PACKET_remaining(&extensions) > 0) { - unsigned int type; + unsigned int type, idx; PACKET extension; RAW_EXTENSION *thisex; @@ -485,6 +487,33 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, *al = SSL_AD_ILLEGAL_PARAMETER; goto err; } + idx = thisex - raw_extensions; + /*- + * Check that we requested this extension (if appropriate). Requests can + * be sent in the ClientHello and CertificateRequest. Unsolicited + * extensions can be sent in the NewSessionTicket. We only do this for + * the built-in extensions. Custom extensions have a different but + * similar check elsewhere. + * Special cases: + * - The HRR cookie extension is unsolicited + * - The renegotiate extension is unsolicited (the client signals + * support via an SCSV) + * - The signed_certificate_timestamp extension can be provided by a + * custom extension or by the built-in version. We let the extension + * itself handle unsolicited response checks. + */ + if (idx < OSSL_NELEM(ext_defs) + && (context & (SSL_EXT_CLIENT_HELLO + | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST + | SSL_EXT_TLS1_3_NEW_SESSION_TICKET)) == 0 + && type != TLSEXT_TYPE_cookie + && type != TLSEXT_TYPE_renegotiate + && type != TLSEXT_TYPE_signed_certificate_timestamp + && (s->ext.extflags[idx] & SSL_EXT_FLAG_SENT) == 0) { + SSLerr(SSL_F_TLS_COLLECT_EXTENSIONS, SSL_R_BAD_EXTENSION); + *al = SSL_AD_UNSUPPORTED_EXTENSION; + goto err; + } if (thisex != NULL) { thisex->data = extension; thisex->present = 1; @@ -699,8 +728,9 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, } for (i = 0, thisexd = ext_defs; i < OSSL_NELEM(ext_defs); i++, thisexd++) { - int (*construct)(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); + EXT_RETURN (*construct)(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); + EXT_RETURN ret; /* Skip if not relevant for our context */ if (!should_add_extension(s, thisexd->context, context, max_version)) @@ -712,8 +742,14 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, if (construct == NULL) continue; - if (!construct(s, pkt, context, x, chainidx, &tmpal)) + ret = construct(s, pkt, context, x, chainidx, &tmpal); + if (ret == EXT_RETURN_FAIL) goto err; + if (ret == EXT_RETURN_SENT + && (context & (SSL_EXT_CLIENT_HELLO + | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST + | SSL_EXT_TLS1_3_NEW_SESSION_TICKET)) != 0) + s->ext.extflags[i] |= SSL_EXT_FLAG_SENT; } if (!WPACKET_close(pkt)) { @@ -997,14 +1033,16 @@ static int init_certificate_authorities(SSL *s, unsigned int context) return 1; } -static int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +static EXT_RETURN 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; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_certificate_authorities) || !WPACKET_start_sub_packet_u16(pkt) @@ -1012,10 +1050,10 @@ static int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 2d7bcd3e11..f2626a35b3 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,12 +12,13 @@ #include "../ssl_locl.h" #include "statem_locl.h" -int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { /* Add RI if renegotiating */ if (!s->renegotiate) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) || !WPACKET_start_sub_packet_u16(pkt) @@ -25,17 +26,18 @@ int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, s->s3->previous_client_finished_len) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (s->ext.hostname == NULL) - return 1; + return EXT_RETURN_NOT_SENT; /* Add TLS extension servername to the Client Hello message */ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) @@ -49,19 +51,19 @@ int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_SRP -int tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { /* Add SRP username if there is one */ if (s->srp_ctx.login == NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp) /* Sub-packet for SRP extension */ @@ -74,10 +76,10 @@ int tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SRP, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif @@ -108,14 +110,15 @@ static int use_ecc(SSL *s) return 0; } -int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { const unsigned char *pformats; size_t num_formats; if (!use_ecc(s)) - return 1; + return EXT_RETURN_NOT_SENT; /* Add TLS extension ECPointFormats to the ClientHello message */ tls1_get_formatlist(s, &pformats, &num_formats); @@ -126,21 +129,21 @@ int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { const unsigned char *pcurves = NULL, *pcurvestmp; size_t num_curves = 0, i; if (!use_ecc(s)) - return 1; + return EXT_RETURN_NOT_SENT; /* * Add TLS extension supported_groups to the ClientHello message @@ -149,7 +152,7 @@ int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } pcurvestmp = pcurves; @@ -159,7 +162,7 @@ int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* Copy curve ID if supported */ for (i = 0; i < num_curves; i++, pcurvestmp += 2) { @@ -168,28 +171,28 @@ int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, || !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { size_t ticklen; if (!tls_use_ticket(s)) - return 1; + return EXT_RETURN_NOT_SENT; if (!s->new_session && s->session != NULL && s->session->ext.tick != NULL @@ -202,7 +205,7 @@ int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, if (s->session->ext.tick == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } memcpy(s->session->ext.tick, s->ext.session_ticket->data, ticklen); @@ -213,25 +216,26 @@ int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, if (ticklen == 0 && s->ext.session_ticket != NULL && s->ext.session_ticket->data == NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket) || !WPACKET_sub_memcpy_u16(pkt, s->session->ext.tick, ticklen)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { size_t salglen; const uint16_t *salg; if (!SSL_CLIENT_USE_SIGALGS(s)) - return 1; + return EXT_RETURN_NOT_SENT; salglen = tls12_get_psigalgs(s, 1, &salg); if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms) @@ -243,25 +247,25 @@ int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_OCSP -int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { int i; /* This extension isn't defined for client Certificates */ if (x != NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) /* Sub-packet for status request extension */ @@ -270,7 +274,7 @@ int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, /* Sub-packet for the ids */ || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } for (i = 0; i < sk_OCSP_RESPID_num(s->ext.ocsp.ids); i++) { unsigned char *idbytes; @@ -283,13 +287,13 @@ int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, || i2d_OCSP_RESPID(id, &idbytes) != idlen) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } if (s->ext.ocsp.exts) { unsigned char *extbytes; @@ -298,31 +302,31 @@ int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, if (extlen < 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes) || i2d_X509_EXTENSIONS(s->ext.ocsp.exts, &extbytes) != extlen) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (s->ctx->ext.npn_select_cb == NULL || !SSL_IS_FIRST_HANDSHAKE(s)) - return 1; + return EXT_RETURN_NOT_SENT; /* * The client advertises an empty extension to indicate its support @@ -331,20 +335,20 @@ int tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_NPN, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { s->s3->alpn_sent = 0; if (s->ext.alpn == NULL || !SSL_IS_FIRST_HANDSHAKE(s)) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_application_layer_protocol_negotiation) @@ -353,23 +357,24 @@ int tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, || !WPACKET_sub_memcpy_u16(pkt, s->ext.alpn, s->ext.alpn_len) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_ALPN, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } s->s3->alpn_sent = 1; - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_SRTP -int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s); int i, end; if (clnt == NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp) /* Sub-packet for SRTP extension */ @@ -377,7 +382,7 @@ int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, /* Sub-packet for the protection profile list */ || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } end = sk_SRTP_PROTECTION_PROFILE_num(clnt); @@ -387,7 +392,7 @@ int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) @@ -395,64 +400,64 @@ int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_ETM, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_CT -int tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (s->ct_validation_callback == NULL) - return 1; + return EXT_RETURN_NOT_SENT; /* Not defined for client Certificates */ if (x != NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SCT, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EMS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { int currv, min_version, max_version, reason; @@ -461,13 +466,13 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u8(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } reason = ssl_get_min_max_version(s, &min_version, &max_version); if (reason != 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, reason); - return 0; + return EXT_RETURN_FAIL; } /* @@ -481,29 +486,30 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } else if (!WPACKET_put_bytes_u16(pkt, currv)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } /* * Construct a psk_kex_modes extension. We only have two modes we know about * at this stage, so we send both. */ -int tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { #ifndef OPENSSL_NO_TLS1_3 /* @@ -518,13 +524,13 @@ int tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_KE | TLSEXT_KEX_MODE_FLAG_KE_DHE; #endif - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_TLS1_3 @@ -538,7 +544,7 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) assert(s->hello_retry_request); if (!s->hello_retry_request) { SSLerr(SSL_F_ADD_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* * Could happen if we got an HRR that wasn't requesting a new key_share @@ -548,7 +554,7 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) key_share_key = ssl_generate_pkey_curve(curve_id); if (key_share_key == NULL) { SSLerr(SSL_F_ADD_KEY_SHARE, ERR_R_EVP_LIB); - return 0; + return EXT_RETURN_FAIL; } } @@ -576,17 +582,18 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) s->s3->group_id = curve_id; OPENSSL_free(encoded_point); - return 1; + return EXT_RETURN_SENT; err: if (s->s3->tmp.pkey == NULL) EVP_PKEY_free(key_share_key); OPENSSL_free(encoded_point); - return 0; + return EXT_RETURN_FAIL; } #endif -int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { #ifndef OPENSSL_NO_TLS1_3 size_t i, num_curves = 0; @@ -600,12 +607,12 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context, /* KeyShare list sub-packet */ || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* @@ -627,29 +634,29 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context, if (curve_id == 0) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, SSL_R_NO_SUITABLE_KEY_SHARE); - return 0; + return EXT_RETURN_FAIL; } if (!add_key_share(s, pkt, curve_id)) - return 0; + return EXT_RETURN_FAIL; if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } #endif - return 1; + return EXT_RETURN_SENT; } -int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { - int ret = 0; + EXT_RETURN ret = EXT_RETURN_FAIL; /* Should only be set if we've had an HRR */ if (s->ext.tls13_cookie_len == 0) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_cookie) /* Extension data sub-packet */ @@ -661,7 +668,7 @@ int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, goto end; } - ret = 1; + ret = EXT_RETURN_SENT; end: OPENSSL_free(s->ext.tls13_cookie); s->ext.tls13_cookie = NULL; @@ -670,13 +677,14 @@ int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, return ret; } -int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (s->early_data_state != SSL_EARLY_DATA_CONNECTING || s->session->ext.max_early_data == 0) { s->max_early_data = 0; - return 1; + return EXT_RETURN_NOT_SENT; } s->max_early_data = s->session->ext.max_early_data; @@ -684,7 +692,7 @@ int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* @@ -693,7 +701,7 @@ int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, */ s->ext.early_data = SSL_EARLY_DATA_REJECTED; - return 1; + return EXT_RETURN_SENT; } #define F5_WORKAROUND_MIN_MSG_LEN 0xff @@ -713,14 +721,15 @@ int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, */ #define PSK_PRE_BINDER_OVERHEAD (2 + 2 + 2 + 2 + 4 + 2 + 1) -int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { unsigned char *padbytes; size_t hlen; if ((s->options & SSL_OP_TLSEXT_PADDING) == 0) - return 1; + return EXT_RETURN_NOT_SENT; /* * Add padding to workaround bugs in F5 terminators. See RFC7685. @@ -730,7 +739,7 @@ int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, unsigned int context, */ if (!WPACKET_get_total_written(pkt, &hlen)) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PADDING, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* @@ -773,21 +782,21 @@ int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, unsigned int context, memset(padbytes, 0, hlen); } - return 1; + return EXT_RETURN_SENT; } /* * Construct the pre_shared_key extension */ -int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { #ifndef OPENSSL_NO_TLS1_3 uint32_t now, agesec, agems; size_t hashsize, binderoffset, msglen; unsigned char *binder = NULL, *msgstart = NULL; const EVP_MD *md; - int ret = 0; + EXT_RETURN ret = EXT_RETURN_FAIL; s->session->ext.tick_identity = TLSEXT_PSK_BAD_IDENTITY; @@ -803,7 +812,7 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, */ if (s->session->ssl_version != TLS1_3_VERSION || s->session->ext.ticklen == 0) - return 1; + return EXT_RETURN_NOT_SENT; if (s->session->cipher == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PSK, ERR_R_INTERNAL_ERROR); @@ -813,7 +822,7 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, md = ssl_md(s->session->cipher->algorithm2); if (md == NULL) { /* Don't recognize this cipher so we can't use the session. Ignore it */ - return 1; + return EXT_RETURN_NOT_SENT; } if (s->hello_retry_request && md != ssl_handshake_md(s)) { @@ -821,7 +830,7 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, * Selected ciphersuite hash does not match the hash for the session so * we can't use it. */ - return 1; + return EXT_RETURN_NOT_SENT; } /* @@ -836,7 +845,7 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, if (s->session->ext.tick_lifetime_hint < agesec) { /* Ticket is too old. Ignore it. */ - return 1; + return EXT_RETURN_NOT_SENT; } /* @@ -850,7 +859,7 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, * Overflow. Shouldn't happen unless this is a *really* old session. If * so we just ignore it. */ - return 1; + return EXT_RETURN_NOT_SENT; } /* @@ -894,7 +903,7 @@ int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, s->session->ext.tick_identity = 0; - ret = 1; + ret = EXT_RETURN_SENT; err: return ret; #else @@ -1100,6 +1109,20 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } } } else { + ENDPOINT role = (context & SSL_EXT_TLS1_2_SERVER_HELLO) != 0 + ? ENDPOINT_CLIENT : ENDPOINT_BOTH; + + /* + * If we didn't ask for it then there must be a custom extension, + * otherwise this is unsolicited. + */ + if (custom_ext_find(&s->cert->custext, role, + TLSEXT_TYPE_signed_certificate_timestamp, + NULL) == NULL) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + if (custom_ext_parse(s, context, TLSEXT_TYPE_signed_certificate_timestamp, PACKET_data(pkt), PACKET_remaining(pkt), diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index f85477c8f4..9cde6955d3 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -810,11 +810,12 @@ err: /* * Add the server's renegotiation binding */ -int tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (!s->s3->send_connection_binding) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) || !WPACKET_start_sub_packet_u16(pkt) @@ -826,31 +827,33 @@ int tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (s->hit || s->servername_done != 1 || s->session->ext.hostname == NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_EC -int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; @@ -860,7 +863,7 @@ int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, size_t plistlen; if (!using_ecc) - return 1; + return EXT_RETURN_NOT_SENT; tls1_get_formatlist(s, &plist, &plistlen); if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats) @@ -868,29 +871,29 @@ int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif #ifndef OPENSSL_NO_EC -int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { const unsigned char *groups; size_t numgroups, i, first = 1; /* s->s3->group_id is non zero if we accepted a key_share */ if (s->s3->group_id == 0) - return 1; + return EXT_RETURN_NOT_SENT; /* Get our list of supported groups */ if (!tls1_get_curvelist(s, 0, &groups, &numgroups) || numgroups == 0) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* Copy group ID if supported */ @@ -902,7 +905,7 @@ int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, * so we don't need to add this extension */ if (s->s3->group_id == GET_GROUP_ID(groups, 0)) - return 1; + return EXT_RETURN_NOT_SENT; /* Add extension header */ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups) @@ -911,7 +914,7 @@ int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } first = 0; @@ -919,53 +922,53 @@ int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, GET_GROUP_ID(groups, 0))) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (!s->ext.ticket_expected || !tls_use_ticket(s)) { s->ext.ticket_expected = 0; - return 1; + return EXT_RETURN_NOT_SENT; } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_OCSP -int tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (!s->ext.status_expected) - return 1; + return EXT_RETURN_NOT_SENT; if (SSL_IS_TLS13(s) && chainidx != 0) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) || !WPACKET_start_sub_packet_u16(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } /* @@ -976,17 +979,17 @@ int tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, if ((SSL_IS_TLS13(s) && !tls_construct_cert_status_body(s, pkt)) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { const unsigned char *npa; unsigned int npalen; @@ -995,7 +998,7 @@ int tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, s->s3->npn_seen = 0; if (!npn_seen || s->ctx->ext.npn_advertised_cb == NULL) - return 1; + return EXT_RETURN_NOT_SENT; ret = s->ctx->ext.npn_advertised_cb(s, &npa, &npalen, s->ctx->ext.npn_advertised_cb_arg); @@ -1004,20 +1007,20 @@ int tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } s->s3->npn_seen = 1; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (s->s3->alpn_selected == NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_application_layer_protocol_negotiation) @@ -1028,18 +1031,19 @@ int tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_ALPN, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #ifndef OPENSSL_NO_SRTP -int tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (s->srtp_profile == NULL) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp) || !WPACKET_start_sub_packet_u16(pkt) @@ -1048,18 +1052,18 @@ int tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } #endif -int tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (!s->ext.use_etm) - return 1; + return EXT_RETURN_NOT_SENT; /* * Don't use encrypt_then_mac if AEAD or RC4 might want to disable @@ -1070,35 +1074,36 @@ int tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) { s->ext.use_etm = 0; - return 1; + return EXT_RETURN_NOT_SENT; } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_ETM, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if ((s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) || !WPACKET_put_bytes_u16(pkt, 0)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EMS, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { #ifndef OPENSSL_NO_TLS1_3 unsigned char *encodedPoint; @@ -1114,32 +1119,32 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } /* Must be resuming. */ if (!s->hit || !tls13_generate_handshake_secret(s, NULL, 0)) { *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_NOT_SENT; } 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_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } skey = ssl_generate_pkey(ckey); if (skey == NULL) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_MALLOC_FAILURE); - return 0; + return EXT_RETURN_FAIL; } /* Generate encoding of server key */ @@ -1147,7 +1152,7 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned int context, if (encoded_pt_len == 0) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_EC_LIB); EVP_PKEY_free(skey); - return 0; + return EXT_RETURN_FAIL; } if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) @@ -1155,7 +1160,7 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned int context, SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); EVP_PKEY_free(skey); OPENSSL_free(encodedPoint); - return 0; + return EXT_RETURN_FAIL; } OPENSSL_free(encodedPoint); @@ -1163,15 +1168,16 @@ int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned int context, s->s3->tmp.pkey = skey; if (ssl_derive(s, skey, ckey, 1) == 0) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } #endif - return 1; + return EXT_RETURN_SENT; } -int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { const unsigned char cryptopro_ext[36] = { 0xfd, 0xe8, /* 65000 */ @@ -1185,60 +1191,61 @@ int tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, unsigned int context, 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; + return EXT_RETURN_NOT_SENT; if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) { if (context == SSL_EXT_TLS1_3_NEW_SESSION_TICKET) { if (s->max_early_data == 0) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u32(pkt, s->max_early_data) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } -int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al) +EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al) { if (!s->hit) - return 1; + return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u16(pkt, s->session->ext.tick_identity) || !WPACKET_close(pkt)) { SSLerr(SSL_F_TLS_CONSTRUCT_STOC_PSK, ERR_R_INTERNAL_ERROR); - return 0; + return EXT_RETURN_FAIL; } - return 1; + return EXT_RETURN_SENT; } diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 5c00b0a873..4a399ca15c 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -77,6 +77,9 @@ int tls_setup_handshake(SSL *s) if (!ssl3_init_finished_mac(s)) return 0; + /* Reset any extension flags */ + memset(s->ext.extflags, 0, sizeof(s->ext.extflags)); + if (s->server) { STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s); int i, ver_min, ver_max, ok = 0; diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index 49a5ed5cef..13fe5bfd67 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -156,6 +156,12 @@ MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt); /* Extension processing */ +typedef enum { + EXT_RETURN_FAIL, + EXT_RETURN_SENT, + EXT_RETURN_NOT_SENT +} EXT_RETURN; + __owur int extension_is_relevant(SSL *s, unsigned int extctx, unsigned int thisctx); __owur int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, @@ -223,113 +229,125 @@ int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context, int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); -int tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #ifndef OPENSSL_NO_EC -int tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #endif -int tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); -int tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #ifndef OPENSSL_NO_OCSP -int tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #endif -int tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #ifndef OPENSSL_NO_SRTP -int tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); #endif -int tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); -int tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); -int tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, 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_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); /* Client Extension processing */ -int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); #ifndef OPENSSL_NO_SRP -int tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, +EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); #endif #ifndef OPENSSL_NO_EC -int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #endif -int tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); -int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #ifndef OPENSSL_NO_OCSP -int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #endif #ifndef OPENSSL_NO_NEXTPROTONEG -int tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #endif -int tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #ifndef OPENSSL_NO_SRTP -int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #endif -int tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #ifndef OPENSSL_NO_CT -int tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); #endif -int tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); -int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx, int *al); -int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, unsigned int context, +EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, unsigned int context, - X509 *x, size_t chainidx, int *al); -int tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, - size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, + X509 *x, size_t chainidx, int *al); int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al); int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context,