summaryrefslogtreecommitdiffstats
path: root/ssl/statem/extensions_clnt.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2019-03-01 15:40:20 +0000
committerMatt Caswell <matt@openssl.org>2019-03-05 14:23:36 +0000
commitc96ce52ce293785b54a42d119c457aef739cc2ce (patch)
tree6c3a2bf1228eeb93c046b025f9eac40573a81385 /ssl/statem/extensions_clnt.c
parent284d19c2ced0264bd46de61718aa4a60efa8d175 (diff)
Don't write the tick_identity to the session
Sessions must be immutable once they can be shared with multiple threads. We were breaking that rule by writing the ticket index into it during the handshake. This can lead to incorrect behaviour, including failed connections in multi-threaded environments. Reported by David Benjamin. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8383)
Diffstat (limited to 'ssl/statem/extensions_clnt.c')
-rw-r--r--ssl/statem/extensions_clnt.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index f01e9eef64..9d7a4f8304 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -996,7 +996,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL;
int dores = 0;
- s->session->ext.tick_identity = TLSEXT_PSK_BAD_IDENTITY;
+ s->ext.tick_identity = 0;
/*
* Note: At this stage of the code we only support adding a single
@@ -1086,6 +1086,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
agems += s->session->ext.tick_age_add;
reshashsize = EVP_MD_size(mdres);
+ s->ext.tick_identity++;
dores = 1;
}
@@ -1145,6 +1146,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
+ s->ext.tick_identity++;
}
if (!WPACKET_close(pkt)
@@ -1183,11 +1185,6 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
return EXT_RETURN_FAIL;
}
- if (dores)
- s->session->ext.tick_identity = 0;
- if (s->psksession != NULL)
- s->psksession->ext.tick_identity = (dores ? 1 : 0);
-
return EXT_RETURN_SENT;
#else
return EXT_RETURN_NOT_SENT;
@@ -1932,8 +1929,7 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context,
}
if (!s->ext.early_data_ok
- || !s->hit
- || s->session->ext.tick_identity != 0) {
+ || !s->hit) {
/*
* If we get here then we didn't send early data, or we didn't resume
* using the first identity, or the SNI/ALPN is not consistent so the
@@ -1961,17 +1957,28 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
return 0;
}
- if (s->session->ext.tick_identity == (int)identity) {
+ if (identity >= (unsigned int)s->ext.tick_identity) {
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_PSK,
+ SSL_R_BAD_PSK_IDENTITY);
+ return 0;
+ }
+
+ /*
+ * Session resumption tickets are always sent before PSK tickets. If the
+ * ticket index is 0 then it must be for a session resumption ticket if we
+ * sent two tickets, or if we didn't send a PSK ticket.
+ */
+ if (identity == 0 && (s->psksession == NULL || s->ext.tick_identity == 2)) {
s->hit = 1;
SSL_SESSION_free(s->psksession);
s->psksession = NULL;
return 1;
}
- if (s->psksession == NULL
- || s->psksession->ext.tick_identity != (int)identity) {
- SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_PSK,
- SSL_R_BAD_PSK_IDENTITY);
+ if (s->psksession == NULL) {
+ /* Should never happen */
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_PSK,
+ ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -1990,6 +1997,9 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
s->session = s->psksession;
s->psksession = NULL;
s->hit = 1;
+ /* Early data is only allowed if we used the first ticket */
+ if (identity != 0)
+ s->ext.early_data_ok = 0;
#endif
return 1;