diff options
author | jsing <> | 2018-11-21 15:13:29 +0000 |
---|---|---|
committer | jsing <> | 2018-11-21 15:13:29 +0000 |
commit | ab91451e6ebf1260022c78c25a334e437c04d78e (patch) | |
tree | 7992535c747d2aff7dd9a131f8fc65ad2af3636d | |
parent | 1b50b4396296c64d8937c2ec1c7ed2eb5547cf91 (diff) | |
download | openbsd-ab91451e6ebf1260022c78c25a334e437c04d78e.tar.gz openbsd-ab91451e6ebf1260022c78c25a334e437c04d78e.tar.bz2 openbsd-ab91451e6ebf1260022c78c25a334e437c04d78e.zip |
Fix DTLS transcript handling for HelloVerifyRequest.
If DTLS sees a HelloVerifyRequest the transcript is reset - the previous
tls1_init_finished_mac() function could be called multiple times and would
discard any existing state. The replacement tls1_transcript_init() is more
strict and fails if a transcript already exists.
Provide an explicit tls1_transcript_reset() function and call it from the
appropriate places. This also lets us make DTLS less of a special snowflake
and call tls1_transcript_init() in the same place as used for TLS.
ok beck@ tb@
-rw-r--r-- | src/lib/libssl/ssl_clnt.c | 15 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/t1_hash.c | 19 |
4 files changed, 26 insertions, 18 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index 35df70f2f0..65277ef4ef 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_clnt.c,v 1.49 2018/11/19 15:07:29 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.50 2018/11/21 15:13:29 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -244,11 +244,9 @@ ssl3_connect(SSL *s) | |||
244 | 244 | ||
245 | /* don't push the buffering BIO quite yet */ | 245 | /* don't push the buffering BIO quite yet */ |
246 | 246 | ||
247 | if (!SSL_IS_DTLS(s)) { | 247 | if (!tls1_transcript_init(s)) { |
248 | if (!tls1_transcript_init(s)) { | 248 | ret = -1; |
249 | ret = -1; | 249 | goto end; |
250 | goto end; | ||
251 | } | ||
252 | } | 250 | } |
253 | 251 | ||
254 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | 252 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; |
@@ -270,10 +268,7 @@ ssl3_connect(SSL *s) | |||
270 | 268 | ||
271 | if (SSL_IS_DTLS(s)) { | 269 | if (SSL_IS_DTLS(s)) { |
272 | /* every DTLS ClientHello resets Finished MAC */ | 270 | /* every DTLS ClientHello resets Finished MAC */ |
273 | if (!tls1_transcript_init(s)) { | 271 | tls1_transcript_reset(s); |
274 | ret = -1; | ||
275 | goto end; | ||
276 | } | ||
277 | 272 | ||
278 | dtls1_start_timer(s); | 273 | dtls1_start_timer(s); |
279 | } | 274 | } |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 50806d1b18..94bb76eca3 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.224 2018/11/10 01:19:09 beck Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.225 2018/11/21 15:13:29 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1242,6 +1242,7 @@ void tls1_handshake_hash_free(SSL *s); | |||
1242 | 1242 | ||
1243 | int tls1_transcript_init(SSL *s); | 1243 | int tls1_transcript_init(SSL *s); |
1244 | void tls1_transcript_free(SSL *s); | 1244 | void tls1_transcript_free(SSL *s); |
1245 | void tls1_transcript_reset(SSL *s); | ||
1245 | int tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len); | 1246 | int tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len); |
1246 | int tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len); | 1247 | int tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len); |
1247 | void tls1_transcript_freeze(SSL *s); | 1248 | void tls1_transcript_freeze(SSL *s); |
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 27024be856..0667ac8da3 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.60 2018/11/11 21:54:47 beck Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.61 2018/11/21 15:13:29 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -368,10 +368,7 @@ ssl3_accept(SSL *s) | |||
368 | S3I(s)->hs.next_state = SSL3_ST_SR_CLNT_HELLO_A; | 368 | S3I(s)->hs.next_state = SSL3_ST_SR_CLNT_HELLO_A; |
369 | 369 | ||
370 | /* HelloVerifyRequest resets Finished MAC. */ | 370 | /* HelloVerifyRequest resets Finished MAC. */ |
371 | if (!tls1_transcript_init(s)) { | 371 | tls1_transcript_reset(s); |
372 | ret = -1; | ||
373 | goto end; | ||
374 | } | ||
375 | break; | 372 | break; |
376 | 373 | ||
377 | case SSL3_ST_SW_SRVR_HELLO_A: | 374 | case SSL3_ST_SW_SRVR_HELLO_A: |
diff --git a/src/lib/libssl/t1_hash.c b/src/lib/libssl/t1_hash.c index f514c5290e..50e0ad3ca0 100644 --- a/src/lib/libssl/t1_hash.c +++ b/src/lib/libssl/t1_hash.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_hash.c,v 1.4 2018/11/08 22:28:52 jsing Exp $ */ | 1 | /* $OpenBSD: t1_hash.c,v 1.5 2018/11/21 15:13:29 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -118,7 +118,7 @@ tls1_transcript_init(SSL *s) | |||
118 | if ((S3I(s)->handshake_transcript = BUF_MEM_new()) == NULL) | 118 | if ((S3I(s)->handshake_transcript = BUF_MEM_new()) == NULL) |
119 | return 0; | 119 | return 0; |
120 | 120 | ||
121 | s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT; | 121 | tls1_transcript_reset(s); |
122 | 122 | ||
123 | return 1; | 123 | return 1; |
124 | } | 124 | } |
@@ -130,6 +130,21 @@ tls1_transcript_free(SSL *s) | |||
130 | S3I(s)->handshake_transcript = NULL; | 130 | S3I(s)->handshake_transcript = NULL; |
131 | } | 131 | } |
132 | 132 | ||
133 | void | ||
134 | tls1_transcript_reset(SSL *s) | ||
135 | { | ||
136 | /* | ||
137 | * We should check the return value of BUF_MEM_grow_clean(), however | ||
138 | * due to yet another bad API design, when called with a length of zero | ||
139 | * it is impossible to tell if it succeeded (returning a length of zero) | ||
140 | * or if it failed (and returned zero)... our implementation never | ||
141 | * fails with a length of zero, so we trust all is okay... | ||
142 | */ | ||
143 | (void)BUF_MEM_grow_clean(S3I(s)->handshake_transcript, 0); | ||
144 | |||
145 | s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT; | ||
146 | } | ||
147 | |||
133 | int | 148 | int |
134 | tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len) | 149 | tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len) |
135 | { | 150 | { |