summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2018-06-07 09:11:05 +0100
committerMatt Caswell <matt@openssl.org>2018-07-02 15:06:12 +0100
commit5d263fb78b51f96753056f21abc4d992d0219df2 (patch)
tree6027b7132a4d5db2050ebd820bb2e163a4247641
parentb6ff436fcb597663ffcfe6d724d207cf120e7250 (diff)
Make the anti-replay feature optional
Fixes #6389 Reviewed-by: Viktor Dukhovni <viktor@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6469)
-rw-r--r--include/openssl/ssl.h6
-rw-r--r--ssl/ssl_lib.c3
-rw-r--r--ssl/ssl_locl.h3
-rw-r--r--ssl/statem/extensions_srvr.c4
-rw-r--r--ssl/statem/statem_srvr.c6
5 files changed, 18 insertions, 4 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 943a8d6c9f..dca4f3d2d8 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -368,6 +368,12 @@ typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
*/
# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000U
+/*
+ * Switches off automatic TLSv1.3 anti-replay protection for early data. This
+ * is a server-side option only (no effect on the client).
+ */
+# define SSL_OP_NO_ANTI_REPLAY 0x01000000U
+
# define SSL_OP_NO_SSLv3 0x02000000U
# define SSL_OP_NO_TLSv1 0x04000000U
# define SSL_OP_NO_TLSv1_2 0x08000000U
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 6ced147ab8..e28e2b5eb1 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3381,7 +3381,8 @@ void ssl_update_cache(SSL *s, int mode)
if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0
&& (!SSL_IS_TLS13(s)
|| !s->server
- || s->max_early_data > 0
+ || (s->max_early_data > 0
+ && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0)
|| s->session_ctx->remove_session_cb != NULL
|| (s->options & SSL_OP_NO_TICKET) != 0))
SSL_CTX_add_session(s->session_ctx, s->session);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index a4d1376cc3..7295a9f0d7 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1205,6 +1205,9 @@ struct ssl_st {
# endif
SSL_psk_find_session_cb_func psk_find_session_cb;
SSL_psk_use_session_cb_func psk_use_session_cb;
+
+ int (*allow_early_data_cb)(SSL *s, SSL_SESSION *sess);
+
SSL_CTX *ctx;
/* Verified chain of peer */
STACK_OF(X509) *verified_chain;
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index f58ed0b582..ab38a4f11e 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1165,7 +1165,8 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
* is no point in using full stateless tickets.
*/
if ((s->options & SSL_OP_NO_TICKET) != 0
- || s->max_early_data > 0)
+ || (s->max_early_data > 0
+ && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0))
ret = tls_get_stateful_ticket(s, &identity, &sess);
else
ret = tls_decrypt_ticket(s, PACKET_data(&identity),
@@ -1189,6 +1190,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
/* Check for replay */
if (s->max_early_data > 0
+ && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0
&& !SSL_CTX_remove_session(s->session_ctx, sess)) {
SSL_SESSION_free(sess);
sess = NULL;
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 26cd850d12..5c59eb8b1e 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -4086,8 +4086,10 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
* SSL_OP_NO_TICKET is set - we are caching tickets anyway so there
* is no point in using full stateless tickets.
*/
- if (((s->options & SSL_OP_NO_TICKET) != 0 || s->max_early_data > 0)
- && SSL_IS_TLS13(s)) {
+ if (SSL_IS_TLS13(s)
+ && ((s->options & SSL_OP_NO_TICKET) != 0
+ || (s->max_early_data > 0
+ && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0))) {
if (!construct_stateful_ticket(s, pkt, age_add_u.age_add, tick_nonce)) {
/* SSLfatal() already called */
goto err;