diff options
author | Matt Caswell <matt@openssl.org> | 2019-01-27 11:00:16 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2019-02-14 16:17:34 +0000 |
commit | 4af5836b55442f31795eff6c8c81ea7a1b8cf94b (patch) | |
tree | 9c0e2318753afbc715e71ad91dbf557205a2e4a5 /ssl | |
parent | 3c83c5ba4f6502c708b7a5f55c98a10e312668da (diff) | |
download | openssl-4af5836b55442f31795eff6c8c81ea7a1b8cf94b.zip openssl-4af5836b55442f31795eff6c8c81ea7a1b8cf94b.tar.gz openssl-4af5836b55442f31795eff6c8c81ea7a1b8cf94b.tar.bz2 |
Don't signal SSL_CB_HANDSHAKE_START for TLSv1.3 post-handshake messages
The original 1.1.1 design was to use SSL_CB_HANDSHAKE_START and
SSL_CB_HANDSHAKE_DONE to signal start/end of a post-handshake message
exchange in TLSv1.3. Unfortunately experience has shown that this confuses
some applications who mistake it for a TLSv1.2 renegotiation. This means
that KeyUpdate messages are not handled properly.
This commit removes the use of SSL_CB_HANDSHAKE_START and
SSL_CB_HANDSHAKE_DONE to signal the start/end of a post-handshake
message exchange. Individual post-handshake messages are still signalled in
the normal way.
This is a potentially breaking change if there are any applications already
written that expect to see these TLSv1.3 events. However, without it,
KeyUpdate is not currently usable for many applications.
Fixes #8069
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8096)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/statem/statem.c | 6 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 11 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 19 |
3 files changed, 12 insertions, 24 deletions
diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index ebe471b..24c7e94 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -342,8 +342,10 @@ static int state_machine(SSL *s, int server) } s->server = server; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); + if (cb != NULL) { + if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_IS_TLS13(s)) + cb(s, SSL_CB_HANDSHAKE_START, 1); + } /* * Fatal errors in this block don't send an alert because we have diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 2f78a3f..8a7ada8 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1030,6 +1030,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) { void (*cb) (const SSL *ssl, int type, int val) = NULL; + int cleanuphand = s->statem.cleanuphand; if (clearbufs) { if (!SSL_IS_DTLS(s)) { @@ -1056,7 +1057,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) * Only set if there was a Finished message and this isn't after a TLSv1.3 * post handshake exchange */ - if (s->statem.cleanuphand) { + if (cleanuphand) { /* skipped if we just sent a HelloRequest */ s->renegotiate = 0; s->new_session = 0; @@ -1116,8 +1117,12 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) /* The callback may expect us to not be in init at handshake done */ ossl_statem_set_in_init(s, 0); - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); + if (cb != NULL) { + if (cleanuphand + || !SSL_IS_TLS13(s) + || SSL_IS_FIRST_HANDSHAKE(s)) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } if (!stop) { /* If we've got more work to do we go back into init */ diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index f76568c..bf1819d 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -4040,7 +4040,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) uint64_t nonce; static const unsigned char nonce_label[] = "resumption"; const EVP_MD *md = ssl_handshake_md(s); - void (*cb) (const SSL *ssl, int type, int val) = NULL; int hashleni = EVP_MD_size(md); /* Ensure cast to size_t is safe */ @@ -4052,24 +4051,6 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } hashlen = (size_t)hashleni; - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - /* - * We don't start and stop the handshake in between each ticket when - * sending more than one - but it should appear that way to the info - * callback. - */ - if (s->sent_tickets != 0) { - ossl_statem_set_in_init(s, 0); - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - ossl_statem_set_in_init(s, 1); - } - cb(s, SSL_CB_HANDSHAKE_START, 1); - } /* * If we already sent one NewSessionTicket, or we resumed then * s->session may already be in a cache and so we must not modify it. |