Do not allow non-dhe kex_modes by default
Allow that mode to be configured if desired. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3833)
This commit is contained in:
parent
5159821540
commit
e3c0d76bc7
6 changed files with 28 additions and 16 deletions
12
apps/apps.h
12
apps/apps.h
|
@ -214,10 +214,11 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
||||||
OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \
|
OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \
|
||||||
OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
|
OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
|
||||||
OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \
|
OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \
|
||||||
OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_STRICT, OPT_S_SIGALGS, \
|
OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \
|
||||||
OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, OPT_S_CURVES, OPT_S_NAMEDCURVE, \
|
OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \
|
||||||
OPT_S_CIPHER, OPT_S_DHPARAM, OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, \
|
OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_DHPARAM, \
|
||||||
OPT_S_COMP, OPT_S_NO_RENEGOTIATION, OPT_S__LAST
|
OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \
|
||||||
|
OPT_S_NO_RENEGOTIATION, OPT_S__LAST
|
||||||
|
|
||||||
# define OPT_S_OPTIONS \
|
# define OPT_S_OPTIONS \
|
||||||
{"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \
|
{"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \
|
||||||
|
@ -241,6 +242,8 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
||||||
"Disallow session resumption on renegotiation"}, \
|
"Disallow session resumption on renegotiation"}, \
|
||||||
{"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-', \
|
{"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-', \
|
||||||
"Disallow initial connection to servers that don't support RI"}, \
|
"Disallow initial connection to servers that don't support RI"}, \
|
||||||
|
{"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \
|
||||||
|
"In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \
|
||||||
{"strict", OPT_S_STRICT, '-', \
|
{"strict", OPT_S_STRICT, '-', \
|
||||||
"Enforce strict certificate checks as per TLS standard"}, \
|
"Enforce strict certificate checks as per TLS standard"}, \
|
||||||
{"sigalgs", OPT_S_SIGALGS, 's', \
|
{"sigalgs", OPT_S_SIGALGS, 's', \
|
||||||
|
@ -279,6 +282,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
||||||
case OPT_S_LEGACYCONN: \
|
case OPT_S_LEGACYCONN: \
|
||||||
case OPT_S_ONRESUMP: \
|
case OPT_S_ONRESUMP: \
|
||||||
case OPT_S_NOLEGACYCONN: \
|
case OPT_S_NOLEGACYCONN: \
|
||||||
|
case OPT_S_ALLOW_NO_DHE_KEX: \
|
||||||
case OPT_S_STRICT: \
|
case OPT_S_STRICT: \
|
||||||
case OPT_S_SIGALGS: \
|
case OPT_S_SIGALGS: \
|
||||||
case OPT_S_CLIENTSIGALGS: \
|
case OPT_S_CLIENTSIGALGS: \
|
||||||
|
|
|
@ -282,6 +282,9 @@ typedef int (*SSL_custom_ext_parse_cb_ex) (SSL *s, unsigned int ext_type,
|
||||||
/* Typedef for verification callback */
|
/* Typedef for verification callback */
|
||||||
typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
|
typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
|
||||||
|
|
||||||
|
/* In TLSv1.3 allow a non-(ec)dhe based kex_mode */
|
||||||
|
# define SSL_OP_ALLOW_NO_DHE_KEX 0x00000001U
|
||||||
|
|
||||||
/* Allow initial connection to servers that don't support RI */
|
/* Allow initial connection to servers that don't support RI */
|
||||||
# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U
|
# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U
|
||||||
# define SSL_OP_TLSEXT_PADDING 0x00000010U
|
# define SSL_OP_TLSEXT_PADDING 0x00000010U
|
||||||
|
|
|
@ -367,6 +367,7 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
|
||||||
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
|
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
|
||||||
SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC),
|
SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC),
|
||||||
SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION),
|
SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION),
|
||||||
|
SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX)
|
||||||
};
|
};
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return -3;
|
return -3;
|
||||||
|
@ -585,6 +586,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
|
||||||
SSL_CONF_CMD_SWITCH("no_renegotiation", 0),
|
SSL_CONF_CMD_SWITCH("no_renegotiation", 0),
|
||||||
SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
|
SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
|
||||||
SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER),
|
SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER),
|
||||||
|
SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0),
|
||||||
SSL_CONF_CMD_SWITCH("strict", 0),
|
SSL_CONF_CMD_SWITCH("strict", 0),
|
||||||
SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
|
SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
|
||||||
SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
|
SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
|
||||||
|
@ -655,6 +657,8 @@ static const ssl_switch_tbl ssl_cmd_switches[] = {
|
||||||
{SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
|
{SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
|
||||||
/* no_legacy_server_connect */
|
/* no_legacy_server_connect */
|
||||||
{SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
|
{SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
|
||||||
|
/* allow_no_dhe_kex */
|
||||||
|
{SSL_OP_ALLOW_NO_DHE_KEX, 0},
|
||||||
{SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
|
{SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -503,30 +503,29 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct a psk_kex_modes extension. We only have two modes we know about
|
* Construct a psk_kex_modes extension.
|
||||||
* at this stage, so we send both.
|
|
||||||
*/
|
*/
|
||||||
EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt,
|
EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt,
|
||||||
unsigned int context, X509 *x,
|
unsigned int context, X509 *x,
|
||||||
size_t chainidx, int *al)
|
size_t chainidx, int *al)
|
||||||
{
|
{
|
||||||
#ifndef OPENSSL_NO_TLS1_3
|
#ifndef OPENSSL_NO_TLS1_3
|
||||||
/*
|
int nodhe = s->options & SSL_OP_ALLOW_NO_DHE_KEX;
|
||||||
* 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)
|
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk_kex_modes)
|
||||||
|| !WPACKET_start_sub_packet_u16(pkt)
|
|| !WPACKET_start_sub_packet_u16(pkt)
|
||||||
|| !WPACKET_start_sub_packet_u8(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_DHE)
|
||||||
|| !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE)
|
|| (nodhe && !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE))
|
||||||
|| !WPACKET_close(pkt)
|
|| !WPACKET_close(pkt)
|
||||||
|| !WPACKET_close(pkt)) {
|
|| !WPACKET_close(pkt)) {
|
||||||
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, ERR_R_INTERNAL_ERROR);
|
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, ERR_R_INTERNAL_ERROR);
|
||||||
return EXT_RETURN_FAIL;
|
return EXT_RETURN_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_KE | TLSEXT_KEX_MODE_FLAG_KE_DHE;
|
s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_KE_DHE;
|
||||||
|
if (nodhe)
|
||||||
|
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return EXT_RETURN_SENT;
|
return EXT_RETURN_SENT;
|
||||||
|
|
|
@ -477,7 +477,8 @@ int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context,
|
||||||
while (PACKET_get_1(&psk_kex_modes, &mode)) {
|
while (PACKET_get_1(&psk_kex_modes, &mode)) {
|
||||||
if (mode == TLSEXT_KEX_MODE_KE_DHE)
|
if (mode == TLSEXT_KEX_MODE_KE_DHE)
|
||||||
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE_DHE;
|
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE_DHE;
|
||||||
else if (mode == TLSEXT_KEX_MODE_KE)
|
else if (mode == TLSEXT_KEX_MODE_KE
|
||||||
|
&& (s->options & SSL_OP_ALLOW_NO_DHE_KEX) != 0)
|
||||||
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE;
|
s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -171,7 +171,8 @@ ok(TLSProxy::Message->fail(), "Resume with empty kex modes");
|
||||||
#Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a
|
#Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a
|
||||||
# key_share
|
# key_share
|
||||||
$proxy->clear();
|
$proxy->clear();
|
||||||
$proxy->clientflags("-sess_in ".$session);
|
$proxy->clientflags("-allow_no_dhe_kex -sess_in ".$session);
|
||||||
|
$proxy->serverflags("-allow_no_dhe_kex");
|
||||||
$testtype = NON_DHE_KEX_MODE_ONLY;
|
$testtype = NON_DHE_KEX_MODE_ONLY;
|
||||||
$proxy->start();
|
$proxy->start();
|
||||||
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
|
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
|
||||||
|
@ -256,8 +257,8 @@ checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE,
|
||||||
# initial key_share and no overlapping groups. Should resume without a
|
# initial key_share and no overlapping groups. Should resume without a
|
||||||
# key_share
|
# key_share
|
||||||
$proxy->clear();
|
$proxy->clear();
|
||||||
$proxy->clientflags("-curves P-384 -sess_in ".$session);
|
$proxy->clientflags("-allow_no_dhe_kex -curves P-384 -sess_in ".$session);
|
||||||
$proxy->serverflags("-curves P-256");
|
$proxy->serverflags("-allow_no_dhe_kex -curves P-256");
|
||||||
$testtype = BOTH_KEX_MODES;
|
$testtype = BOTH_KEX_MODES;
|
||||||
$proxy->start();
|
$proxy->start();
|
||||||
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
|
checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE,
|
||||||
|
|
Loading…
Reference in a new issue