Add support for the psk_key_exchange_modes extension
This is required for the later addition of resumption support. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2259)
This commit is contained in:
parent
cc2455bfa8
commit
b2f7e8c0fe
11 changed files with 112 additions and 0 deletions
|
@ -2281,6 +2281,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE 470
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_NPN 471
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_PADDING 472
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES 509
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE 473
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_SCT 474
|
||||
# define SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME 475
|
||||
|
|
|
@ -178,6 +178,7 @@ extern "C" {
|
|||
/* As defined for TLS1.3 */
|
||||
# define TLSEXT_TYPE_key_share 40
|
||||
# define TLSEXT_TYPE_supported_versions 43
|
||||
# define TLSEXT_TYPE_psk_kex_modes 45
|
||||
|
||||
/* Temporary extension type */
|
||||
# define TLSEXT_TYPE_renegotiate 0xff01
|
||||
|
|
|
@ -300,6 +300,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_NPN), "tls_construct_ctos_npn"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_PADDING),
|
||||
"tls_construct_ctos_padding"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES),
|
||||
"tls_construct_ctos_psk_kex_modes"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE),
|
||||
"tls_construct_ctos_renegotiate"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CTOS_SCT), "tls_construct_ctos_sct"},
|
||||
|
|
|
@ -1105,6 +1105,9 @@ struct ssl_st {
|
|||
*/
|
||||
unsigned char *npn;
|
||||
size_t npn_len;
|
||||
|
||||
/* The selected PSK key exchange mode */
|
||||
int psk_kex_mode;
|
||||
} ext;
|
||||
|
||||
/*-
|
||||
|
@ -1680,6 +1683,7 @@ typedef enum tlsext_index_en {
|
|||
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_cryptopro_bug,
|
||||
TLSEXT_IDX_padding
|
||||
|
@ -1711,6 +1715,17 @@ typedef enum tlsext_index_en {
|
|||
#define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 0xefef
|
||||
#define TLSEXT_SIGALG_gostr34102001_gostr3411 0xeded
|
||||
|
||||
/* Known PSK key exchange modes */
|
||||
#define TLSEXT_KEX_MODE_KE 0x00
|
||||
#define TLSEXT_KEX_MODE_KE_DHE 0x01
|
||||
|
||||
/*
|
||||
* Internal representations of key exchange modes
|
||||
*/
|
||||
#define TLSEXT_KEX_MODE_FLAG_NONE 0
|
||||
#define TLSEXT_KEX_MODE_FLAG_KE 1
|
||||
#define TLSEXT_KEX_MODE_FLAG_KE_DHE 2
|
||||
|
||||
#define SIGID_IS_PSS(sigid) ((sigid) == TLSEXT_SIGALG_rsa_pss_sha256 \
|
||||
|| (sigid) == TLSEXT_SIGALG_rsa_pss_sha384 \
|
||||
|| (sigid) == TLSEXT_SIGALG_rsa_pss_sha512)
|
||||
|
|
|
@ -35,6 +35,7 @@ static int init_srp(SSL *s, unsigned int context);
|
|||
static int init_etm(SSL *s, unsigned int context);
|
||||
static int init_ems(SSL *s, unsigned int context);
|
||||
static int final_ems(SSL *s, unsigned int context, int sent, int *al);
|
||||
static int init_psk_kex_modes(SSL *s, unsigned int context);
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
static int init_srtp(SSL *s, unsigned int context);
|
||||
#endif
|
||||
|
@ -234,6 +235,13 @@ static const EXTENSION_DEFINITION ext_defs[] = {
|
|||
/* Processed inline as part of version selection */
|
||||
NULL, NULL, NULL, tls_construct_ctos_supported_versions, NULL
|
||||
},
|
||||
{
|
||||
/* Must be before key_share */
|
||||
TLSEXT_TYPE_psk_kex_modes,
|
||||
EXT_CLIENT_HELLO | EXT_TLS_IMPLEMENTATION_ONLY | EXT_TLS1_3_ONLY,
|
||||
init_psk_kex_modes, tls_parse_ctos_psk_kex_modes, NULL, NULL,
|
||||
tls_construct_ctos_psk_kex_modes, NULL
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Must be in this list after supported_groups. We need that to have
|
||||
|
@ -938,3 +946,10 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent, int *al)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int init_psk_kex_modes(SSL *s, unsigned int context)
|
||||
{
|
||||
s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_NONE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -494,6 +494,33 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, X509 *x,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, X509 *x,
|
||||
size_t chainidx, int *al)
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLS1_3
|
||||
/*
|
||||
* TODO(TLS1.3): Do we want this list to be configurable? For now we always
|
||||
* just send both supported modes
|
||||
*/
|
||||
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk_kex_modes)
|
||||
|| !WPACKET_start_sub_packet_u16(pkt)
|
||||
|| !WPACKET_start_sub_packet_u8(pkt)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE_DHE)
|
||||
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE)
|
||||
|| !WPACKET_close(pkt)
|
||||
|| !WPACKET_close(pkt)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
|
||||
int *al)
|
||||
{
|
||||
|
|
|
@ -478,6 +478,35 @@ static int check_in_list(SSL *s, unsigned int group_id,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Process a psk_kex_modes extension received in the ClientHello. |pkt| contains
|
||||
* the raw PACKET data for the extension. Returns 1 on success or 0 on failure.
|
||||
* If a failure occurs then |*al| is set to an appropriate alert value.
|
||||
*/
|
||||
int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
|
||||
int *al)
|
||||
{
|
||||
#ifndef OPENSSL_NO_TLS1_3
|
||||
PACKET psk_kex_modes;
|
||||
unsigned int mode;
|
||||
|
||||
if (!PACKET_as_length_prefixed_1(pkt, &psk_kex_modes)
|
||||
|| PACKET_remaining(&psk_kex_modes) == 0) {
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (PACKET_get_1(&psk_kex_modes, &mode)) {
|
||||
if (mode == TLSEXT_KEX_MODE_KE_DHE)
|
||||
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE_DHE;
|
||||
else if (mode == TLSEXT_KEX_MODE_KE)
|
||||
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a key_share extension received in the ClientHello. |pkt| contains
|
||||
* the raw PACKET data for the extension. Returns 1 on success or 0 on failure.
|
||||
|
|
|
@ -201,6 +201,8 @@ int tls_parse_ctos_etm(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al);
|
|||
int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
|
||||
int *al);
|
||||
int tls_parse_ctos_ems(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al);
|
||||
int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
|
||||
int *al);
|
||||
|
||||
int tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, X509 *x,
|
||||
size_t chainidx, int *al);
|
||||
|
@ -285,6 +287,8 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, X509 *x,
|
|||
size_t chainidx, int *al);
|
||||
int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
|
||||
int *al);
|
||||
int tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, X509 *x,
|
||||
size_t chainidx, int *al);
|
||||
int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
|
||||
int *al);
|
||||
int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
|
||||
|
|
|
@ -449,6 +449,7 @@ static ssl_trace_tbl ssl_exts_tbl[] = {
|
|||
{TLSEXT_TYPE_server_authz, "server_authz"},
|
||||
{TLSEXT_TYPE_cert_type, "cert_type"},
|
||||
{TLSEXT_TYPE_key_share, "key_share"},
|
||||
{TLSEXT_TYPE_psk_kex_modes, "psk_key_exchange_modes"},
|
||||
{TLSEXT_TYPE_supported_groups, "supported_groups"},
|
||||
{TLSEXT_TYPE_ec_point_formats, "ec_point_formats"},
|
||||
{TLSEXT_TYPE_srp, "srp"},
|
||||
|
@ -540,6 +541,11 @@ static ssl_trace_tbl ssl_ctype_tbl[] = {
|
|||
{66, "ecdsa_fixed_ecdh"}
|
||||
};
|
||||
|
||||
static ssl_trace_tbl ssl_psk_kex_modes_tbl[] = {
|
||||
{TLSEXT_KEX_MODE_KE, "psk_ke"},
|
||||
{TLSEXT_KEX_MODE_KE_DHE, "psk_dhe_ke"}
|
||||
};
|
||||
|
||||
static ssl_trace_tbl ssl_crypto_tbl[] = {
|
||||
{TLS1_RT_CRYPTO_PREMASTER, "Premaster Secret"},
|
||||
{TLS1_RT_CRYPTO_CLIENT_RANDOM, "Client Random"},
|
||||
|
@ -760,6 +766,15 @@ static int ssl_print_extension(BIO *bio, int indent, int server, int extype,
|
|||
return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 2,
|
||||
ssl_version_tbl);
|
||||
|
||||
case TLSEXT_TYPE_psk_kex_modes:
|
||||
if (extlen < 1)
|
||||
return 0;
|
||||
xlen = ext[0];
|
||||
if (extlen != xlen + 1)
|
||||
return 0;
|
||||
return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 1,
|
||||
ssl_psk_kex_modes_tbl);
|
||||
|
||||
default:
|
||||
BIO_dump_indent(bio, (const char *)ext, extlen, indent + 2);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ $ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
|
|||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS,
|
||||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES,
|
||||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
|
||||
[TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE,
|
||||
checkhandshake::DEFAULT_EXTENSIONS],
|
||||
|
|
|
@ -75,6 +75,7 @@ use constant {
|
|||
EXT_SESSION_TICKET => 35,
|
||||
EXT_KEY_SHARE => 40,
|
||||
EXT_SUPPORTED_VERSIONS => 43,
|
||||
EXT_PSK_KEX_MODES => 45,
|
||||
EXT_RENEGOTIATE => 65281,
|
||||
EXT_NPN => 13172,
|
||||
# This extension is an unofficial extension only ever written by OpenSSL
|
||||
|
|
Loading…
Reference in a new issue