summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2018-03-16 09:25:34 +0000
committerMatt Caswell <matt@openssl.org>2018-03-19 12:21:41 +0000
commit66d7de163491bfa5819fb80b77d321beb58384d4 (patch)
treeb2a5fcb49174f0d108ed54d15218c64dd74a0afc /ssl
parentf023ba2df821d186d73fefda6fa5cafcc5a3ee39 (diff)
Add an anti-replay mechanism
If the server is configured to allow early data then we check if the PSK session presented by the client is available in the cache or not. If it isn't then this may be a replay and we disallow it. If it is then we allow it and remove the session from the cache. Note: the anti-replay protection is not used for externally established PSKs. Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5644)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_sess.c6
-rw-r--r--ssl/statem/extensions_srvr.c8
2 files changed, 11 insertions, 3 deletions
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 5e44d4c41f..6513bf84cc 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -761,10 +761,10 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
if ((c != NULL) && (c->session_id_length != 0)) {
if (lck)
CRYPTO_THREAD_write_lock(ctx->lock);
- if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) {
+ if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) {
ret = 1;
- r = lh_SSL_SESSION_delete(ctx->sessions, c);
- SSL_SESSION_list_remove(ctx, c);
+ r = lh_SSL_SESSION_delete(ctx->sessions, r);
+ SSL_SESSION_list_remove(ctx, r);
}
c->not_resumable = 1;
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 7c9a3f7a6a..ee4cad124c 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1134,6 +1134,14 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
if (ret == SSL_TICKET_NO_DECRYPT)
continue;
+ /* Check for replay */
+ if (s->max_early_data > 0
+ && !SSL_CTX_remove_session(s->session_ctx, sess)) {
+ SSL_SESSION_free(sess);
+ sess = NULL;
+ continue;
+ }
+
ticket_age = (uint32_t)ticket_agel;
now = (uint32_t)time(NULL);
agesec = now - (uint32_t)sess->time;