summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_both.c
diff options
context:
space:
mode:
authorjsing <>2021-04-25 13:15:23 +0000
committerjsing <>2021-04-25 13:15:23 +0000
commitebe128ca73ce7d178a186b93684c8bf8577f3b80 (patch)
tree0d77df32f82a4eb3addc8531055c43c868f52f5e /src/lib/libssl/ssl_both.c
parent6b7899114d6b9acd6fbc1fc2f5129bf1ca98ac1c (diff)
downloadopenbsd-ebe128ca73ce7d178a186b93684c8bf8577f3b80.tar.gz
openbsd-ebe128ca73ce7d178a186b93684c8bf8577f3b80.tar.bz2
openbsd-ebe128ca73ce7d178a186b93684c8bf8577f3b80.zip
Clean up derivation of finished/peer finished.
Make this process more readable by having specific client/server functions, calling the correct one based on s->server. This allows to remove various SSL_ST_ACCEPT/SSL_ST_CONNECT checks, along with duplicate code. ok inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_both.c')
-rw-r--r--src/lib/libssl/ssl_both.c77
1 files changed, 25 insertions, 52 deletions
diff --git a/src/lib/libssl/ssl_both.c b/src/lib/libssl/ssl_both.c
index ad9b0ee257..fe04f809b0 100644
--- a/src/lib/libssl/ssl_both.c
+++ b/src/lib/libssl/ssl_both.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_both.c,v 1.28 2021/04/19 16:51:56 jsing Exp $ */ 1/* $OpenBSD: ssl_both.c,v 1.29 2021/04/25 13:15:22 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 *
@@ -164,42 +164,39 @@ ssl3_do_write(SSL *s, int type)
164} 164}
165 165
166int 166int
167ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) 167ssl3_send_finished(SSL *s, int state_a, int state_b)
168{ 168{
169 CBB cbb, finished; 169 CBB cbb, finished;
170 int md_len;
171 170
172 memset(&cbb, 0, sizeof(cbb)); 171 memset(&cbb, 0, sizeof(cbb));
173 172
174 if (S3I(s)->hs.state == a) { 173 if (S3I(s)->hs.state == state_a) {
175 md_len = TLS1_FINISH_MAC_LENGTH; 174 if (!tls12_derive_finished(s))
176 OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE); 175 goto err;
177
178 if (tls1_final_finish_mac(s, sender, slen,
179 S3I(s)->hs.finished) != md_len)
180 return (0);
181 S3I(s)->hs.finished_len = md_len;
182 176
183 /* Copy finished so we can use it for renegotiation checks. */ 177 /* Copy finished so we can use it for renegotiation checks. */
184 if (!s->server) { 178 if (!s->server) {
185 memcpy(S3I(s)->previous_client_finished, 179 memcpy(S3I(s)->previous_client_finished,
186 S3I(s)->hs.finished, md_len); 180 S3I(s)->hs.finished, S3I(s)->hs.finished_len);
187 S3I(s)->previous_client_finished_len = md_len; 181 S3I(s)->previous_client_finished_len =
182 S3I(s)->hs.finished_len;
188 } else { 183 } else {
189 memcpy(S3I(s)->previous_server_finished, 184 memcpy(S3I(s)->previous_server_finished,
190 S3I(s)->hs.finished, md_len); 185 S3I(s)->hs.finished, S3I(s)->hs.finished_len);
191 S3I(s)->previous_server_finished_len = md_len; 186 S3I(s)->previous_server_finished_len =
187 S3I(s)->hs.finished_len;
192 } 188 }
193 189
194 if (!ssl3_handshake_msg_start(s, &cbb, &finished, 190 if (!ssl3_handshake_msg_start(s, &cbb, &finished,
195 SSL3_MT_FINISHED)) 191 SSL3_MT_FINISHED))
196 goto err; 192 goto err;
197 if (!CBB_add_bytes(&finished, S3I(s)->hs.finished, md_len)) 193 if (!CBB_add_bytes(&finished, S3I(s)->hs.finished,
194 S3I(s)->hs.finished_len))
198 goto err; 195 goto err;
199 if (!ssl3_handshake_msg_finish(s, &cbb)) 196 if (!ssl3_handshake_msg_finish(s, &cbb))
200 goto err; 197 goto err;
201 198
202 S3I(s)->hs.state = b; 199 S3I(s)->hs.state = state_b;
203 } 200 }
204 201
205 return (ssl3_handshake_write(s)); 202 return (ssl3_handshake_write(s));
@@ -210,36 +207,6 @@ ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
210 return (-1); 207 return (-1);
211} 208}
212 209
213/*
214 * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
215 * so far.
216 */
217static void
218ssl3_take_mac(SSL *s)
219{
220 const char *sender;
221 int slen;
222
223 /*
224 * If no new cipher setup return immediately: other functions will
225 * set the appropriate error.
226 */
227 if (S3I(s)->hs.cipher == NULL)
228 return;
229
230 if (S3I(s)->hs.state & SSL_ST_CONNECT) {
231 sender = TLS_MD_SERVER_FINISH_CONST;
232 slen = TLS_MD_SERVER_FINISH_CONST_SIZE;
233 } else {
234 sender = TLS_MD_CLIENT_FINISH_CONST;
235 slen = TLS_MD_CLIENT_FINISH_CONST_SIZE;
236 }
237
238 S3I(s)->hs.peer_finished_len =
239 tls1_final_finish_mac(s, sender, slen,
240 S3I(s)->hs.peer_finished);
241}
242
243int 210int
244ssl3_get_finished(SSL *s, int a, int b) 211ssl3_get_finished(SSL *s, int a, int b)
245{ 212{
@@ -544,10 +511,16 @@ ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
544 n -= i; 511 n -= i;
545 } 512 }
546 513
547 /* If receiving Finished, record MAC of prior handshake messages for 514 /*
548 * Finished verification. */ 515 * If receiving Finished, record MAC of prior handshake messages for
549 if (*s->internal->init_buf->data == SSL3_MT_FINISHED) 516 * Finished verification.
550 ssl3_take_mac(s); 517 */
518 if (*s->internal->init_buf->data == SSL3_MT_FINISHED) {
519 if (S3I(s)->hs.cipher != NULL) {
520 if (!tls12_derive_peer_finished(s))
521 goto err;
522 }
523 }
551 524
552 /* Feed this message into MAC computation. */ 525 /* Feed this message into MAC computation. */
553 if (s->internal->mac_packet) { 526 if (s->internal->mac_packet) {
@@ -566,7 +539,7 @@ ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
566 539
567 fatal_err: 540 fatal_err:
568 ssl3_send_alert(s, SSL3_AL_FATAL, al); 541 ssl3_send_alert(s, SSL3_AL_FATAL, al);
569err: 542 err:
570 *ok = 0; 543 *ok = 0;
571 return (-1); 544 return (-1);
572} 545}