diff options
Diffstat (limited to 'src/lib/libssl/ssl_srvr.c')
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 188 |
1 files changed, 168 insertions, 20 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index acdcb15398..821006af81 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.149 2022/08/17 07:39:19 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.150 2022/10/01 16:23:15 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 | * |
@@ -148,6 +148,7 @@ | |||
148 | * OTHERWISE. | 148 | * OTHERWISE. |
149 | */ | 149 | */ |
150 | 150 | ||
151 | #include <limits.h> | ||
151 | #include <stdio.h> | 152 | #include <stdio.h> |
152 | 153 | ||
153 | #include <openssl/bn.h> | 154 | #include <openssl/bn.h> |
@@ -171,6 +172,23 @@ | |||
171 | #include "ssl_sigalgs.h" | 172 | #include "ssl_sigalgs.h" |
172 | #include "ssl_tlsext.h" | 173 | #include "ssl_tlsext.h" |
173 | 174 | ||
175 | static int ssl3_get_client_hello(SSL *s); | ||
176 | static int ssl3_send_dtls_hello_verify_request(SSL *s); | ||
177 | static int ssl3_send_server_hello(SSL *s); | ||
178 | static int ssl3_send_hello_request(SSL *s); | ||
179 | static int ssl3_send_server_certificate(SSL *s); | ||
180 | static int ssl3_send_server_key_exchange(SSL *s); | ||
181 | static int ssl3_send_certificate_request(SSL *s); | ||
182 | static int ssl3_send_server_done(SSL *s); | ||
183 | static int ssl3_get_client_certificate(SSL *s); | ||
184 | static int ssl3_get_client_key_exchange(SSL *s); | ||
185 | static int ssl3_get_cert_verify(SSL *s); | ||
186 | static int ssl3_send_newsession_ticket(SSL *s); | ||
187 | static int ssl3_send_cert_status(SSL *s); | ||
188 | static int ssl3_send_server_change_cipher_spec(SSL *s); | ||
189 | static int ssl3_send_server_finished(SSL *s); | ||
190 | static int ssl3_get_client_finished(SSL *s); | ||
191 | |||
174 | int | 192 | int |
175 | ssl3_accept(SSL *s) | 193 | ssl3_accept(SSL *s) |
176 | { | 194 | { |
@@ -605,8 +623,7 @@ ssl3_accept(SSL *s) | |||
605 | s->d1->change_cipher_spec_ok = 1; | 623 | s->d1->change_cipher_spec_ok = 1; |
606 | else | 624 | else |
607 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | 625 | s->s3->flags |= SSL3_FLAGS_CCS_OK; |
608 | ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, | 626 | ret = ssl3_get_client_finished(s); |
609 | SSL3_ST_SR_FINISHED_B); | ||
610 | if (ret <= 0) | 627 | if (ret <= 0) |
611 | goto end; | 628 | goto end; |
612 | if (SSL_is_dtls(s)) | 629 | if (SSL_is_dtls(s)) |
@@ -640,8 +657,7 @@ ssl3_accept(SSL *s) | |||
640 | 657 | ||
641 | case SSL3_ST_SW_CHANGE_A: | 658 | case SSL3_ST_SW_CHANGE_A: |
642 | case SSL3_ST_SW_CHANGE_B: | 659 | case SSL3_ST_SW_CHANGE_B: |
643 | ret = ssl3_send_change_cipher_spec(s, | 660 | ret = ssl3_send_server_change_cipher_spec(s); |
644 | SSL3_ST_SW_CHANGE_A, SSL3_ST_SW_CHANGE_B); | ||
645 | if (ret <= 0) | 661 | if (ret <= 0) |
646 | goto end; | 662 | goto end; |
647 | s->s3->hs.state = SSL3_ST_SW_FINISHED_A; | 663 | s->s3->hs.state = SSL3_ST_SW_FINISHED_A; |
@@ -660,8 +676,7 @@ ssl3_accept(SSL *s) | |||
660 | 676 | ||
661 | case SSL3_ST_SW_FINISHED_A: | 677 | case SSL3_ST_SW_FINISHED_A: |
662 | case SSL3_ST_SW_FINISHED_B: | 678 | case SSL3_ST_SW_FINISHED_B: |
663 | ret = ssl3_send_finished(s, SSL3_ST_SW_FINISHED_A, | 679 | ret = ssl3_send_server_finished(s); |
664 | SSL3_ST_SW_FINISHED_B); | ||
665 | if (ret <= 0) | 680 | if (ret <= 0) |
666 | goto end; | 681 | goto end; |
667 | s->s3->hs.state = SSL3_ST_SW_FLUSH; | 682 | s->s3->hs.state = SSL3_ST_SW_FLUSH; |
@@ -748,7 +763,7 @@ ssl3_accept(SSL *s) | |||
748 | return (ret); | 763 | return (ret); |
749 | } | 764 | } |
750 | 765 | ||
751 | int | 766 | static int |
752 | ssl3_send_hello_request(SSL *s) | 767 | ssl3_send_hello_request(SSL *s) |
753 | { | 768 | { |
754 | CBB cbb, hello; | 769 | CBB cbb, hello; |
@@ -774,7 +789,7 @@ ssl3_send_hello_request(SSL *s) | |||
774 | return (-1); | 789 | return (-1); |
775 | } | 790 | } |
776 | 791 | ||
777 | int | 792 | static int |
778 | ssl3_get_client_hello(SSL *s) | 793 | ssl3_get_client_hello(SSL *s) |
779 | { | 794 | { |
780 | CBS cbs, client_random, session_id, cookie, cipher_suites; | 795 | CBS cbs, client_random, session_id, cookie, cipher_suites; |
@@ -1167,7 +1182,7 @@ ssl3_get_client_hello(SSL *s) | |||
1167 | return (ret); | 1182 | return (ret); |
1168 | } | 1183 | } |
1169 | 1184 | ||
1170 | int | 1185 | static int |
1171 | ssl3_send_dtls_hello_verify_request(SSL *s) | 1186 | ssl3_send_dtls_hello_verify_request(SSL *s) |
1172 | { | 1187 | { |
1173 | CBB cbb, verify, cookie; | 1188 | CBB cbb, verify, cookie; |
@@ -1211,7 +1226,7 @@ ssl3_send_dtls_hello_verify_request(SSL *s) | |||
1211 | return (-1); | 1226 | return (-1); |
1212 | } | 1227 | } |
1213 | 1228 | ||
1214 | int | 1229 | static int |
1215 | ssl3_send_server_hello(SSL *s) | 1230 | ssl3_send_server_hello(SSL *s) |
1216 | { | 1231 | { |
1217 | CBB cbb, server_hello, session_id; | 1232 | CBB cbb, server_hello, session_id; |
@@ -1290,7 +1305,7 @@ ssl3_send_server_hello(SSL *s) | |||
1290 | return (-1); | 1305 | return (-1); |
1291 | } | 1306 | } |
1292 | 1307 | ||
1293 | int | 1308 | static int |
1294 | ssl3_send_server_done(SSL *s) | 1309 | ssl3_send_server_done(SSL *s) |
1295 | { | 1310 | { |
1296 | CBB cbb, done; | 1311 | CBB cbb, done; |
@@ -1413,7 +1428,7 @@ ssl3_send_server_kex_ecdhe(SSL *s, CBB *cbb) | |||
1413 | return 0; | 1428 | return 0; |
1414 | } | 1429 | } |
1415 | 1430 | ||
1416 | int | 1431 | static int |
1417 | ssl3_send_server_key_exchange(SSL *s) | 1432 | ssl3_send_server_key_exchange(SSL *s) |
1418 | { | 1433 | { |
1419 | CBB cbb, cbb_params, cbb_signature, server_kex; | 1434 | CBB cbb, cbb_params, cbb_signature, server_kex; |
@@ -1552,7 +1567,7 @@ ssl3_send_server_key_exchange(SSL *s) | |||
1552 | return (-1); | 1567 | return (-1); |
1553 | } | 1568 | } |
1554 | 1569 | ||
1555 | int | 1570 | static int |
1556 | ssl3_send_certificate_request(SSL *s) | 1571 | ssl3_send_certificate_request(SSL *s) |
1557 | { | 1572 | { |
1558 | CBB cbb, cert_request, cert_types, sigalgs, cert_auth, dn; | 1573 | CBB cbb, cert_request, cert_types, sigalgs, cert_auth, dn; |
@@ -1868,7 +1883,7 @@ ssl3_get_client_kex_gost(SSL *s, CBS *cbs) | |||
1868 | return 0; | 1883 | return 0; |
1869 | } | 1884 | } |
1870 | 1885 | ||
1871 | int | 1886 | static int |
1872 | ssl3_get_client_key_exchange(SSL *s) | 1887 | ssl3_get_client_key_exchange(SSL *s) |
1873 | { | 1888 | { |
1874 | unsigned long alg_k; | 1889 | unsigned long alg_k; |
@@ -1919,7 +1934,7 @@ ssl3_get_client_key_exchange(SSL *s) | |||
1919 | return (-1); | 1934 | return (-1); |
1920 | } | 1935 | } |
1921 | 1936 | ||
1922 | int | 1937 | static int |
1923 | ssl3_get_cert_verify(SSL *s) | 1938 | ssl3_get_cert_verify(SSL *s) |
1924 | { | 1939 | { |
1925 | CBS cbs, signature; | 1940 | CBS cbs, signature; |
@@ -2153,7 +2168,7 @@ ssl3_get_cert_verify(SSL *s) | |||
2153 | return (ret); | 2168 | return (ret); |
2154 | } | 2169 | } |
2155 | 2170 | ||
2156 | int | 2171 | static int |
2157 | ssl3_get_client_certificate(SSL *s) | 2172 | ssl3_get_client_certificate(SSL *s) |
2158 | { | 2173 | { |
2159 | CBS cbs, cert_list, cert_data; | 2174 | CBS cbs, cert_list, cert_data; |
@@ -2271,7 +2286,7 @@ ssl3_get_client_certificate(SSL *s) | |||
2271 | return (ret); | 2286 | return (ret); |
2272 | } | 2287 | } |
2273 | 2288 | ||
2274 | int | 2289 | static int |
2275 | ssl3_send_server_certificate(SSL *s) | 2290 | ssl3_send_server_certificate(SSL *s) |
2276 | { | 2291 | { |
2277 | CBB cbb, server_cert; | 2292 | CBB cbb, server_cert; |
@@ -2310,7 +2325,7 @@ ssl3_send_server_certificate(SSL *s) | |||
2310 | } | 2325 | } |
2311 | 2326 | ||
2312 | /* send a new session ticket (not necessarily for a new session) */ | 2327 | /* send a new session ticket (not necessarily for a new session) */ |
2313 | int | 2328 | static int |
2314 | ssl3_send_newsession_ticket(SSL *s) | 2329 | ssl3_send_newsession_ticket(SSL *s) |
2315 | { | 2330 | { |
2316 | CBB cbb, session_ticket, ticket; | 2331 | CBB cbb, session_ticket, ticket; |
@@ -2443,7 +2458,7 @@ ssl3_send_newsession_ticket(SSL *s) | |||
2443 | return (-1); | 2458 | return (-1); |
2444 | } | 2459 | } |
2445 | 2460 | ||
2446 | int | 2461 | static int |
2447 | ssl3_send_cert_status(SSL *s) | 2462 | ssl3_send_cert_status(SSL *s) |
2448 | { | 2463 | { |
2449 | CBB cbb, certstatus, ocspresp; | 2464 | CBB cbb, certstatus, ocspresp; |
@@ -2475,3 +2490,136 @@ ssl3_send_cert_status(SSL *s) | |||
2475 | 2490 | ||
2476 | return (-1); | 2491 | return (-1); |
2477 | } | 2492 | } |
2493 | |||
2494 | static int | ||
2495 | ssl3_send_server_change_cipher_spec(SSL *s) | ||
2496 | { | ||
2497 | size_t outlen; | ||
2498 | CBB cbb; | ||
2499 | |||
2500 | memset(&cbb, 0, sizeof(cbb)); | ||
2501 | |||
2502 | if (s->s3->hs.state == SSL3_ST_SW_CHANGE_A) { | ||
2503 | if (!CBB_init_fixed(&cbb, s->internal->init_buf->data, | ||
2504 | s->internal->init_buf->length)) | ||
2505 | goto err; | ||
2506 | if (!CBB_add_u8(&cbb, SSL3_MT_CCS)) | ||
2507 | goto err; | ||
2508 | if (!CBB_finish(&cbb, NULL, &outlen)) | ||
2509 | goto err; | ||
2510 | |||
2511 | if (outlen > INT_MAX) | ||
2512 | goto err; | ||
2513 | |||
2514 | s->internal->init_num = (int)outlen; | ||
2515 | s->internal->init_off = 0; | ||
2516 | |||
2517 | if (SSL_is_dtls(s)) { | ||
2518 | s->d1->handshake_write_seq = | ||
2519 | s->d1->next_handshake_write_seq; | ||
2520 | dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, | ||
2521 | s->d1->handshake_write_seq, 0, 0); | ||
2522 | dtls1_buffer_message(s, 1); | ||
2523 | } | ||
2524 | |||
2525 | s->s3->hs.state = SSL3_ST_SW_CHANGE_B; | ||
2526 | } | ||
2527 | |||
2528 | /* SSL3_ST_SW_CHANGE_B */ | ||
2529 | return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); | ||
2530 | |||
2531 | err: | ||
2532 | CBB_cleanup(&cbb); | ||
2533 | |||
2534 | return -1; | ||
2535 | } | ||
2536 | |||
2537 | static int | ||
2538 | ssl3_get_client_finished(SSL *s) | ||
2539 | { | ||
2540 | int al, md_len, ret; | ||
2541 | CBS cbs; | ||
2542 | |||
2543 | /* should actually be 36+4 :-) */ | ||
2544 | if ((ret = ssl3_get_message(s, SSL3_ST_SR_FINISHED_A, | ||
2545 | SSL3_ST_SR_FINISHED_B, SSL3_MT_FINISHED, 64)) <= 0) | ||
2546 | return ret; | ||
2547 | |||
2548 | /* If this occurs, we have missed a message */ | ||
2549 | if (!s->s3->change_cipher_spec) { | ||
2550 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
2551 | SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS); | ||
2552 | goto fatal_err; | ||
2553 | } | ||
2554 | s->s3->change_cipher_spec = 0; | ||
2555 | |||
2556 | md_len = TLS1_FINISH_MAC_LENGTH; | ||
2557 | |||
2558 | if (s->internal->init_num < 0) { | ||
2559 | al = SSL_AD_DECODE_ERROR; | ||
2560 | SSLerror(s, SSL_R_BAD_DIGEST_LENGTH); | ||
2561 | goto fatal_err; | ||
2562 | } | ||
2563 | |||
2564 | CBS_init(&cbs, s->internal->init_msg, s->internal->init_num); | ||
2565 | |||
2566 | if (s->s3->hs.peer_finished_len != md_len || | ||
2567 | CBS_len(&cbs) != md_len) { | ||
2568 | al = SSL_AD_DECODE_ERROR; | ||
2569 | SSLerror(s, SSL_R_BAD_DIGEST_LENGTH); | ||
2570 | goto fatal_err; | ||
2571 | } | ||
2572 | |||
2573 | if (!CBS_mem_equal(&cbs, s->s3->hs.peer_finished, CBS_len(&cbs))) { | ||
2574 | al = SSL_AD_DECRYPT_ERROR; | ||
2575 | SSLerror(s, SSL_R_DIGEST_CHECK_FAILED); | ||
2576 | goto fatal_err; | ||
2577 | } | ||
2578 | |||
2579 | /* Copy finished so we can use it for renegotiation checks. */ | ||
2580 | OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE); | ||
2581 | memcpy(s->s3->previous_client_finished, | ||
2582 | s->s3->hs.peer_finished, md_len); | ||
2583 | s->s3->previous_client_finished_len = md_len; | ||
2584 | |||
2585 | return (1); | ||
2586 | fatal_err: | ||
2587 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | ||
2588 | return (0); | ||
2589 | } | ||
2590 | |||
2591 | static int | ||
2592 | ssl3_send_server_finished(SSL *s) | ||
2593 | { | ||
2594 | CBB cbb, finished; | ||
2595 | |||
2596 | memset(&cbb, 0, sizeof(cbb)); | ||
2597 | |||
2598 | if (s->s3->hs.state == SSL3_ST_SW_FINISHED_A) { | ||
2599 | if (!tls12_derive_finished(s)) | ||
2600 | goto err; | ||
2601 | |||
2602 | /* Copy finished so we can use it for renegotiation checks. */ | ||
2603 | memcpy(s->s3->previous_server_finished, | ||
2604 | s->s3->hs.finished, s->s3->hs.finished_len); | ||
2605 | s->s3->previous_server_finished_len = s->s3->hs.finished_len; | ||
2606 | |||
2607 | if (!ssl3_handshake_msg_start(s, &cbb, &finished, | ||
2608 | SSL3_MT_FINISHED)) | ||
2609 | goto err; | ||
2610 | if (!CBB_add_bytes(&finished, s->s3->hs.finished, | ||
2611 | s->s3->hs.finished_len)) | ||
2612 | goto err; | ||
2613 | if (!ssl3_handshake_msg_finish(s, &cbb)) | ||
2614 | goto err; | ||
2615 | |||
2616 | s->s3->hs.state = SSL3_ST_SW_FINISHED_B; | ||
2617 | } | ||
2618 | |||
2619 | return (ssl3_handshake_write(s)); | ||
2620 | |||
2621 | err: | ||
2622 | CBB_cleanup(&cbb); | ||
2623 | |||
2624 | return (-1); | ||
2625 | } | ||