Add an anti-replay mechanism
authorMatt Caswell <matt@openssl.org>
Fri, 16 Mar 2018 09:25:34 +0000 (09:25 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 19 Mar 2018 12:21:41 +0000 (12:21 +0000)
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)

ssl/ssl_sess.c
ssl/statem/extensions_srvr.c

index 5e44d4c41fccdc805d46b31a665a7ae63075fbba..6513bf84ccaee2f3e9202118f948d1b98d4db78f 100644 (file)
@@ -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;
 
index 7c9a3f7a6a66079fe6c70e8ab0d1f236cac80da4..ee4cad124c082d1324e12b06f75aec45aabfb1cb 100644 (file)
@@ -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;