Add the ability to configure anti-replay via SSL_CONF
This also adds the ability to control this through s_server Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6469)
This commit is contained in:
parent
5a42141565
commit
3bb5e5b09e
5 changed files with 71 additions and 8 deletions
|
@ -749,6 +749,7 @@ typedef enum OPTION_choice {
|
||||||
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
||||||
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
||||||
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS,
|
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS,
|
||||||
|
OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY,
|
||||||
OPT_R_ENUM,
|
OPT_R_ENUM,
|
||||||
OPT_S_ENUM,
|
OPT_S_ENUM,
|
||||||
OPT_V_ENUM,
|
OPT_V_ENUM,
|
||||||
|
@ -958,6 +959,8 @@ const OPTIONS s_server_options[] = {
|
||||||
{"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"},
|
{"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"},
|
||||||
{"num_tickets", OPT_S_NUM_TICKETS, 'n',
|
{"num_tickets", OPT_S_NUM_TICKETS, 'n',
|
||||||
"The number of TLSv1.3 session tickets that a server will automatically issue" },
|
"The number of TLSv1.3 session tickets that a server will automatically issue" },
|
||||||
|
{"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"},
|
||||||
|
{"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"},
|
||||||
{NULL, OPT_EOF, 0, NULL}
|
{NULL, OPT_EOF, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1258,6 +1261,8 @@ int s_server_main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
case OPT_S_CASES:
|
case OPT_S_CASES:
|
||||||
case OPT_S_NUM_TICKETS:
|
case OPT_S_NUM_TICKETS:
|
||||||
|
case OPT_ANTI_REPLAY:
|
||||||
|
case OPT_NO_ANTI_REPLAY:
|
||||||
if (ssl_args == NULL)
|
if (ssl_args == NULL)
|
||||||
ssl_args = sk_OPENSSL_STRING_new_null();
|
ssl_args = sk_OPENSSL_STRING_new_null();
|
||||||
if (ssl_args == NULL
|
if (ssl_args == NULL
|
||||||
|
|
|
@ -180,6 +180,8 @@ B<openssl> B<s_server>
|
||||||
[B<-keylogfile outfile>]
|
[B<-keylogfile outfile>]
|
||||||
[B<-max_early_data int>]
|
[B<-max_early_data int>]
|
||||||
[B<-early_data>]
|
[B<-early_data>]
|
||||||
|
[B<-anti_replay>]
|
||||||
|
[B<-no_anti_replay>]
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
@ -709,6 +711,15 @@ greater than or equal to 0.
|
||||||
|
|
||||||
Accept early data where possible.
|
Accept early data where possible.
|
||||||
|
|
||||||
|
=item B<-anti_replay>, B<-no_anti_replay>
|
||||||
|
|
||||||
|
Switches replay protection on or off, respectively. Replay protection is on by
|
||||||
|
default unless overridden by a configuration file. When it is on, OpenSSL will
|
||||||
|
automatically detect if a session ticket has been used more than once, TLSv1.3
|
||||||
|
has been negotiated, and early data is enabled on the server. A full handshake
|
||||||
|
is forced if a session ticket is used a second or subsequent time. Any early
|
||||||
|
data that was sent will be rejected.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 CONNECTED COMMANDS
|
=head1 CONNECTED COMMANDS
|
||||||
|
|
|
@ -211,6 +211,18 @@ that there will be no forward secrecy for the resumed session.
|
||||||
enables strict mode protocol handling. Equivalent to setting
|
enables strict mode protocol handling. Equivalent to setting
|
||||||
B<SSL_CERT_FLAG_TLS_STRICT>.
|
B<SSL_CERT_FLAG_TLS_STRICT>.
|
||||||
|
|
||||||
|
=item B<-anti_replay>, B<-no_anti_replay>
|
||||||
|
|
||||||
|
Switches replay protection, on or off respectively. With replay protection on,
|
||||||
|
OpenSSL will automatically detect if a session ticket has been used more than
|
||||||
|
once, TLSv1.3 has been negotiated, and early data is enabled on the server. A
|
||||||
|
full handshake is forced if a session ticket is used a second or subsequent
|
||||||
|
time. Anti-Replay is on by default unless overridden by a configuration file and
|
||||||
|
is only used by servers. Anti-replay measures are required for compliance with
|
||||||
|
the TLSv1.3 specification. Some applications may be able to mitigate the replay
|
||||||
|
risks in other ways and in such cases the built-in OpenSSL functionality is not
|
||||||
|
required. Switching off anti-replay is equivalent to B<SSL_OP_NO_ANTI_REPLAY>.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 SUPPORTED CONFIGURATION FILE COMMANDS
|
=head1 SUPPORTED CONFIGURATION FILE COMMANDS
|
||||||
|
@ -441,6 +453,15 @@ middleboxes that do not understand TLSv1.3 will not drop the connection. This
|
||||||
option is set by default. A future version of OpenSSL may not set this by
|
option is set by default. A future version of OpenSSL may not set this by
|
||||||
default. Equivalent to B<SSL_OP_ENABLE_MIDDLEBOX_COMPAT>.
|
default. Equivalent to B<SSL_OP_ENABLE_MIDDLEBOX_COMPAT>.
|
||||||
|
|
||||||
|
B<AntiReplay>: If set then OpenSSL will automatically detect if a session ticket
|
||||||
|
has been used more than once, TLSv1.3 has been negotiated, and early data is
|
||||||
|
enabled on the server. A full handshake is forced if a session ticket is used a
|
||||||
|
second or subsequent time. This option is set by default and is only used by
|
||||||
|
servers. Anti-replay measures are required to comply with the TLSv1.3
|
||||||
|
specification. Some applications may be able to mitigate the replay risks in
|
||||||
|
other ways and in such cases the built-in OpenSSL functionality is not required.
|
||||||
|
Disabling anti-replay is equivalent to setting B<SSL_OP_NO_ANTI_REPLAY>.
|
||||||
|
|
||||||
=item B<VerifyMode>
|
=item B<VerifyMode>
|
||||||
|
|
||||||
The B<value> argument is a comma separated list of flags to set.
|
The B<value> argument is a comma separated list of flags to set.
|
||||||
|
|
|
@ -383,7 +383,8 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
|
||||||
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),
|
SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX),
|
||||||
SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA),
|
SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA),
|
||||||
SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT)
|
SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT),
|
||||||
|
SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY)
|
||||||
};
|
};
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return -3;
|
return -3;
|
||||||
|
@ -626,6 +627,8 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
|
||||||
SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER),
|
SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER),
|
||||||
SSL_CONF_CMD_SWITCH("strict", 0),
|
SSL_CONF_CMD_SWITCH("strict", 0),
|
||||||
SSL_CONF_CMD_SWITCH("no_middlebox", 0),
|
SSL_CONF_CMD_SWITCH("no_middlebox", 0),
|
||||||
|
SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER),
|
||||||
|
SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER),
|
||||||
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),
|
||||||
SSL_CONF_CMD_STRING(Curves, "curves", 0),
|
SSL_CONF_CMD_STRING(Curves, "curves", 0),
|
||||||
|
@ -671,7 +674,7 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
|
||||||
SSL_CONF_TYPE_FILE),
|
SSL_CONF_TYPE_FILE),
|
||||||
#endif
|
#endif
|
||||||
SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
|
SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0),
|
||||||
SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER)
|
SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Supported switches: must match order of switches in ssl_conf_cmds */
|
/* Supported switches: must match order of switches in ssl_conf_cmds */
|
||||||
|
@ -704,6 +707,10 @@ static const ssl_switch_tbl ssl_cmd_switches[] = {
|
||||||
{SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
|
{SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
|
||||||
/* no_middlebox */
|
/* no_middlebox */
|
||||||
{SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV},
|
{SSL_OP_ENABLE_MIDDLEBOX_COMPAT, SSL_TFLAG_INV},
|
||||||
|
/* anti_replay */
|
||||||
|
{SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV},
|
||||||
|
/* no_anti_replay */
|
||||||
|
{SSL_OP_NO_ANTI_REPLAY, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
|
static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
|
||||||
|
|
|
@ -2179,8 +2179,10 @@ static int allow_early_data_cb(SSL *s, void *arg)
|
||||||
* usecb == 0: Don't use a custom early data callback
|
* usecb == 0: Don't use a custom early data callback
|
||||||
* usecb == 1: Use a custom early data callback and reject the early data
|
* usecb == 1: Use a custom early data callback and reject the early data
|
||||||
* usecb == 2: Use a custom early data callback and accept the early data
|
* usecb == 2: Use a custom early data callback and accept the early data
|
||||||
|
* confopt == 0: Configure anti-replay directly
|
||||||
|
* confopt == 1: Configure anti-replay using SSL_CONF
|
||||||
*/
|
*/
|
||||||
static int test_early_data_replay_int(int idx, int usecb)
|
static int test_early_data_replay_int(int idx, int usecb, int confopt)
|
||||||
{
|
{
|
||||||
SSL_CTX *cctx = NULL, *sctx = NULL;
|
SSL_CTX *cctx = NULL, *sctx = NULL;
|
||||||
SSL *clientssl = NULL, *serverssl = NULL;
|
SSL *clientssl = NULL, *serverssl = NULL;
|
||||||
|
@ -2197,7 +2199,23 @@ static int test_early_data_replay_int(int idx, int usecb)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (usecb > 0) {
|
if (usecb > 0) {
|
||||||
|
if (confopt == 0) {
|
||||||
SSL_CTX_set_options(sctx, SSL_OP_NO_ANTI_REPLAY);
|
SSL_CTX_set_options(sctx, SSL_OP_NO_ANTI_REPLAY);
|
||||||
|
} else {
|
||||||
|
SSL_CONF_CTX *confctx = SSL_CONF_CTX_new();
|
||||||
|
|
||||||
|
if (!TEST_ptr(confctx))
|
||||||
|
goto end;
|
||||||
|
SSL_CONF_CTX_set_flags(confctx, SSL_CONF_FLAG_FILE
|
||||||
|
| SSL_CONF_FLAG_SERVER);
|
||||||
|
SSL_CONF_CTX_set_ssl_ctx(confctx, sctx);
|
||||||
|
if (!TEST_int_eq(SSL_CONF_cmd(confctx, "Options", "-AntiReplay"),
|
||||||
|
2)) {
|
||||||
|
SSL_CONF_CTX_free(confctx);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
SSL_CONF_CTX_free(confctx);
|
||||||
|
}
|
||||||
SSL_CTX_set_allow_early_data_cb(sctx, allow_early_data_cb, &usecb);
|
SSL_CTX_set_allow_early_data_cb(sctx, allow_early_data_cb, &usecb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2282,11 +2300,12 @@ static int test_early_data_replay_int(int idx, int usecb)
|
||||||
|
|
||||||
static int test_early_data_replay(int idx)
|
static int test_early_data_replay(int idx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 1, usecb, confopt;
|
||||||
|
|
||||||
ret = test_early_data_replay_int(idx, 0);
|
for (usecb = 0; usecb < 3; usecb++) {
|
||||||
ret &= test_early_data_replay_int(idx, 1);
|
for (confopt = 0; confopt < 2; confopt++)
|
||||||
ret &= test_early_data_replay_int(idx, 2);
|
ret &= test_early_data_replay_int(idx, usecb, confopt);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue