diff options
author | jsing <> | 2022-11-11 17:15:27 +0000 |
---|---|---|
committer | jsing <> | 2022-11-11 17:15:27 +0000 |
commit | 167103faa44f8407455f11f6599e9919e2b22653 (patch) | |
tree | a8f8e94c51cf1dc74d90e267faf0ad4720537e35 /src/lib/libssl/d1_pkt.c | |
parent | f8749b129444d560b9e645a68ec7b045800243ed (diff) | |
download | openbsd-167103faa44f8407455f11f6599e9919e2b22653.tar.gz openbsd-167103faa44f8407455f11f6599e9919e2b22653.tar.bz2 openbsd-167103faa44f8407455f11f6599e9919e2b22653.zip |
Convert the legacy TLS stack to tls_content.
This converts the legacy TLS stack to tls_content - records are now
opened into a tls_content structure, rather than being written back into
the same buffer that the sealed record was read into.
This will allow for further clean up of the legacy record layer.
ok tb@
Diffstat (limited to 'src/lib/libssl/d1_pkt.c')
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 190 |
1 files changed, 123 insertions, 67 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 1431434ba8..35d5d8ec6d 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_pkt.c,v 1.124 2022/10/02 16:36:41 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.125 2022/11/11 17:15:26 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -115,6 +115,7 @@ | |||
115 | 115 | ||
116 | #include <endian.h> | 116 | #include <endian.h> |
117 | #include <errno.h> | 117 | #include <errno.h> |
118 | #include <limits.h> | ||
118 | #include <stdio.h> | 119 | #include <stdio.h> |
119 | 120 | ||
120 | #include <openssl/buffer.h> | 121 | #include <openssl/buffer.h> |
@@ -124,6 +125,7 @@ | |||
124 | #include "dtls_locl.h" | 125 | #include "dtls_locl.h" |
125 | #include "pqueue.h" | 126 | #include "pqueue.h" |
126 | #include "ssl_locl.h" | 127 | #include "ssl_locl.h" |
128 | #include "tls_content.h" | ||
127 | 129 | ||
128 | /* mod 128 saturating subtract of two 64-bit values in big-endian order */ | 130 | /* mod 128 saturating subtract of two 64-bit values in big-endian order */ |
129 | static int | 131 | static int |
@@ -247,6 +249,44 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) | |||
247 | return (-1); | 249 | return (-1); |
248 | } | 250 | } |
249 | 251 | ||
252 | static int | ||
253 | dtls1_buffer_rcontent(SSL *s, rcontent_pqueue *queue, unsigned char *priority) | ||
254 | { | ||
255 | DTLS1_RCONTENT_DATA_INTERNAL *rdata; | ||
256 | pitem *item; | ||
257 | |||
258 | /* Limit the size of the queue to prevent DOS attacks */ | ||
259 | if (pqueue_size(queue->q) >= 100) | ||
260 | return 0; | ||
261 | |||
262 | rdata = malloc(sizeof(DTLS1_RCONTENT_DATA_INTERNAL)); | ||
263 | item = pitem_new(priority, rdata); | ||
264 | if (rdata == NULL || item == NULL) | ||
265 | goto init_err; | ||
266 | |||
267 | rdata->rcontent = s->s3->rcontent; | ||
268 | s->s3->rcontent = NULL; | ||
269 | |||
270 | item->data = rdata; | ||
271 | |||
272 | /* insert should not fail, since duplicates are dropped */ | ||
273 | if (pqueue_insert(queue->q, item) == NULL) | ||
274 | goto err; | ||
275 | |||
276 | if ((s->s3->rcontent = tls_content_new()) == NULL) | ||
277 | goto err; | ||
278 | |||
279 | return (1); | ||
280 | |||
281 | err: | ||
282 | tls_content_free(rdata->rcontent); | ||
283 | |||
284 | init_err: | ||
285 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
286 | free(rdata); | ||
287 | pitem_free(item); | ||
288 | return (-1); | ||
289 | } | ||
250 | 290 | ||
251 | static int | 291 | static int |
252 | dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) | 292 | dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) |
@@ -267,6 +307,29 @@ dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) | |||
267 | } | 307 | } |
268 | 308 | ||
269 | static int | 309 | static int |
310 | dtls1_retrieve_buffered_rcontent(SSL *s, rcontent_pqueue *queue) | ||
311 | { | ||
312 | DTLS1_RCONTENT_DATA_INTERNAL *rdata; | ||
313 | pitem *item; | ||
314 | |||
315 | item = pqueue_pop(queue->q); | ||
316 | if (item) { | ||
317 | rdata = item->data; | ||
318 | |||
319 | tls_content_free(s->s3->rcontent); | ||
320 | s->s3->rcontent = rdata->rcontent; | ||
321 | s->s3->rrec.epoch = tls_content_epoch(s->s3->rcontent); | ||
322 | |||
323 | free(item->data); | ||
324 | pitem_free(item); | ||
325 | |||
326 | return (1); | ||
327 | } | ||
328 | |||
329 | return (0); | ||
330 | } | ||
331 | |||
332 | static int | ||
270 | dtls1_process_buffered_record(SSL *s) | 333 | dtls1_process_buffered_record(SSL *s) |
271 | { | 334 | { |
272 | /* Check if epoch is current. */ | 335 | /* Check if epoch is current. */ |
@@ -295,13 +358,11 @@ dtls1_process_record(SSL *s) | |||
295 | { | 358 | { |
296 | SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec); | 359 | SSL3_RECORD_INTERNAL *rr = &(s->s3->rrec); |
297 | uint8_t alert_desc; | 360 | uint8_t alert_desc; |
298 | uint8_t *out; | ||
299 | size_t out_len; | ||
300 | 361 | ||
301 | tls12_record_layer_set_version(s->rl, s->version); | 362 | tls12_record_layer_set_version(s->rl, s->version); |
302 | 363 | ||
303 | if (!tls12_record_layer_open_record(s->rl, s->packet, | 364 | if (!tls12_record_layer_open_record(s->rl, s->packet, s->packet_length, |
304 | s->packet_length, &out, &out_len)) { | 365 | s->s3->rcontent)) { |
305 | tls12_record_layer_alert(s->rl, &alert_desc); | 366 | tls12_record_layer_alert(s->rl, &alert_desc); |
306 | 367 | ||
307 | if (alert_desc == 0) | 368 | if (alert_desc == 0) |
@@ -311,10 +372,8 @@ dtls1_process_record(SSL *s) | |||
311 | * DTLS should silently discard invalid records, including those | 372 | * DTLS should silently discard invalid records, including those |
312 | * with a bad MAC, as per RFC 6347 section 4.1.2.1. | 373 | * with a bad MAC, as per RFC 6347 section 4.1.2.1. |
313 | */ | 374 | */ |
314 | if (alert_desc == SSL_AD_BAD_RECORD_MAC) { | 375 | if (alert_desc == SSL_AD_BAD_RECORD_MAC) |
315 | out_len = 0; | ||
316 | goto done; | 376 | goto done; |
317 | } | ||
318 | 377 | ||
319 | if (alert_desc == SSL_AD_RECORD_OVERFLOW) | 378 | if (alert_desc == SSL_AD_RECORD_OVERFLOW) |
320 | SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | 379 | SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); |
@@ -322,11 +381,10 @@ dtls1_process_record(SSL *s) | |||
322 | goto fatal_err; | 381 | goto fatal_err; |
323 | } | 382 | } |
324 | 383 | ||
325 | done: | 384 | /* XXX move to record layer. */ |
326 | rr->data = out; | 385 | tls_content_set_epoch(s->s3->rcontent, rr->epoch); |
327 | rr->length = out_len; | ||
328 | rr->off = 0; | ||
329 | 386 | ||
387 | done: | ||
330 | s->packet_length = 0; | 388 | s->packet_length = 0; |
331 | 389 | ||
332 | return (1); | 390 | return (1); |
@@ -485,7 +543,6 @@ dtls1_get_record(SSL *s) | |||
485 | static int | 543 | static int |
486 | dtls1_read_handshake_unexpected(SSL *s) | 544 | dtls1_read_handshake_unexpected(SSL *s) |
487 | { | 545 | { |
488 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
489 | struct hm_header_st hs_msg_hdr; | 546 | struct hm_header_st hs_msg_hdr; |
490 | CBS cbs; | 547 | CBS cbs; |
491 | int ret; | 548 | int ret; |
@@ -495,19 +552,16 @@ dtls1_read_handshake_unexpected(SSL *s) | |||
495 | return -1; | 552 | return -1; |
496 | } | 553 | } |
497 | 554 | ||
498 | if (rr->off != 0) { | ||
499 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
500 | return -1; | ||
501 | } | ||
502 | |||
503 | /* Parse handshake message header. */ | 555 | /* Parse handshake message header. */ |
504 | CBS_init(&cbs, rr->data, rr->length); | 556 | CBS_dup(&cbs, tls_content_cbs(s->s3->rcontent)); |
505 | if (!dtls1_get_message_header(&cbs, &hs_msg_hdr)) | 557 | if (!dtls1_get_message_header(&cbs, &hs_msg_hdr)) |
506 | return -1; /* XXX - probably should drop/continue. */ | 558 | return -1; /* XXX - probably should drop/continue. */ |
507 | 559 | ||
508 | /* This may just be a stale retransmit. */ | 560 | /* This may just be a stale retransmit. */ |
509 | if (rr->epoch != tls12_record_layer_read_epoch(s->rl)) { | 561 | if (tls_content_epoch(s->s3->rcontent) != |
510 | rr->length = 0; | 562 | tls12_record_layer_read_epoch(s->rl)) { |
563 | tls_content_clear(s->s3->rcontent); | ||
564 | s->s3->rrec.length = 0; | ||
511 | return 1; | 565 | return 1; |
512 | } | 566 | } |
513 | 567 | ||
@@ -532,10 +586,11 @@ dtls1_read_handshake_unexpected(SSL *s) | |||
532 | return -1; | 586 | return -1; |
533 | } | 587 | } |
534 | 588 | ||
535 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, rr->data, | 589 | ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, |
536 | DTLS1_HM_HEADER_LENGTH); | 590 | tls_content_cbs(s->s3->rcontent)); |
537 | 591 | ||
538 | rr->length = 0; | 592 | tls_content_clear(s->s3->rcontent); |
593 | s->s3->rrec.length = 0; | ||
539 | 594 | ||
540 | /* | 595 | /* |
541 | * It should be impossible to hit this, but keep the safety | 596 | * It should be impossible to hit this, but keep the safety |
@@ -624,7 +679,8 @@ dtls1_read_handshake_unexpected(SSL *s) | |||
624 | 679 | ||
625 | dtls1_retransmit_buffered_messages(s); | 680 | dtls1_retransmit_buffered_messages(s); |
626 | 681 | ||
627 | rr->length = 0; | 682 | tls_content_clear(s->s3->rcontent); |
683 | s->s3->rrec.length = 0; | ||
628 | 684 | ||
629 | return 1; | 685 | return 1; |
630 | 686 | ||
@@ -685,9 +741,8 @@ dtls1_read_handshake_unexpected(SSL *s) | |||
685 | int | 741 | int |
686 | dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | 742 | dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) |
687 | { | 743 | { |
688 | SSL3_RECORD_INTERNAL *rr; | ||
689 | int rrcount = 0; | 744 | int rrcount = 0; |
690 | unsigned int n; | 745 | ssize_t ssret; |
691 | int ret; | 746 | int ret; |
692 | 747 | ||
693 | if (s->s3->rbuf.buf == NULL) { | 748 | if (s->s3->rbuf.buf == NULL) { |
@@ -695,6 +750,11 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
695 | return -1; | 750 | return -1; |
696 | } | 751 | } |
697 | 752 | ||
753 | if (s->s3->rcontent == NULL) { | ||
754 | if ((s->s3->rcontent = tls_content_new()) == NULL) | ||
755 | return -1; | ||
756 | } | ||
757 | |||
698 | if (len < 0) { | 758 | if (len < 0) { |
699 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 759 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
700 | return -1; | 760 | return -1; |
@@ -735,19 +795,18 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
735 | 795 | ||
736 | s->rwstate = SSL_NOTHING; | 796 | s->rwstate = SSL_NOTHING; |
737 | 797 | ||
738 | rr = &s->s3->rrec; | ||
739 | |||
740 | /* | 798 | /* |
741 | * We are not handshaking and have no data yet, so process data buffered | 799 | * We are not handshaking and have no data yet, so process data buffered |
742 | * during the last handshake in advance, if any. | 800 | * during the last handshake in advance, if any. |
743 | */ | 801 | */ |
744 | if (s->s3->hs.state == SSL_ST_OK && rr->length == 0) | 802 | if (s->s3->hs.state == SSL_ST_OK && |
745 | dtls1_retrieve_buffered_record(s, &s->d1->buffered_app_data); | 803 | tls_content_remaining(s->s3->rcontent) == 0) |
804 | dtls1_retrieve_buffered_rcontent(s, &s->d1->buffered_app_data); | ||
746 | 805 | ||
747 | if (dtls1_handle_timeout(s) > 0) | 806 | if (dtls1_handle_timeout(s) > 0) |
748 | goto start; | 807 | goto start; |
749 | 808 | ||
750 | if (rr->length == 0 || s->rstate == SSL_ST_READ_BODY) { | 809 | if (tls_content_remaining(s->s3->rcontent) == 0) { |
751 | if ((ret = dtls1_get_record(s)) <= 0) { | 810 | if ((ret = dtls1_get_record(s)) <= 0) { |
752 | /* Anything other than a timeout is an error. */ | 811 | /* Anything other than a timeout is an error. */ |
753 | if ((ret = dtls1_read_failed(s, ret)) <= 0) | 812 | if ((ret = dtls1_read_failed(s, ret)) <= 0) |
@@ -756,26 +815,30 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
756 | } | 815 | } |
757 | } | 816 | } |
758 | 817 | ||
759 | if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { | 818 | if (s->d1->listen && |
760 | rr->length = 0; | 819 | tls_content_type(s->s3->rcontent) != SSL3_RT_HANDSHAKE) { |
820 | tls_content_clear(s->s3->rcontent); | ||
821 | s->s3->rrec.length = 0; | ||
761 | goto start; | 822 | goto start; |
762 | } | 823 | } |
763 | 824 | ||
764 | /* We now have a packet which can be read and processed. */ | 825 | /* We now have a packet which can be read and processed. */ |
765 | 826 | ||
766 | if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE) { | 827 | if (s->s3->change_cipher_spec && |
828 | tls_content_type(s->s3->rcontent) != SSL3_RT_HANDSHAKE) { | ||
767 | /* | 829 | /* |
768 | * We now have application data between CCS and Finished. | 830 | * We now have application data between CCS and Finished. |
769 | * Most likely the packets were reordered on their way, so | 831 | * Most likely the packets were reordered on their way, so |
770 | * buffer the application data for later processing rather | 832 | * buffer the application data for later processing rather |
771 | * than dropping the connection. | 833 | * than dropping the connection. |
772 | */ | 834 | */ |
773 | if (dtls1_buffer_record(s, &s->d1->buffered_app_data, | 835 | if (dtls1_buffer_rcontent(s, &s->d1->buffered_app_data, |
774 | rr->seq_num) < 0) { | 836 | s->s3->rrec.seq_num) < 0) { |
775 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 837 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
776 | return (-1); | 838 | return (-1); |
777 | } | 839 | } |
778 | rr->length = 0; | 840 | tls_content_clear(s->s3->rcontent); |
841 | s->s3->rrec.length = 0; | ||
779 | goto start; | 842 | goto start; |
780 | } | 843 | } |
781 | 844 | ||
@@ -785,12 +848,13 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
785 | */ | 848 | */ |
786 | if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { | 849 | if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { |
787 | s->rwstate = SSL_NOTHING; | 850 | s->rwstate = SSL_NOTHING; |
788 | rr->length = 0; | 851 | tls_content_clear(s->s3->rcontent); |
852 | s->s3->rrec.length = 0; | ||
789 | return 0; | 853 | return 0; |
790 | } | 854 | } |
791 | 855 | ||
792 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ | 856 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ |
793 | if (type == rr->type) { | 857 | if (tls_content_type(s->s3->rcontent) == type) { |
794 | /* | 858 | /* |
795 | * Make sure that we are not getting application data when we | 859 | * Make sure that we are not getting application data when we |
796 | * are doing a handshake for the first time. | 860 | * are doing a handshake for the first time. |
@@ -806,31 +870,23 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
806 | if (len <= 0) | 870 | if (len <= 0) |
807 | return len; | 871 | return len; |
808 | 872 | ||
809 | if ((unsigned int)len > rr->length) | 873 | if (peek) { |
810 | n = rr->length; | 874 | ssret = tls_content_peek(s->s3->rcontent, buf, len); |
811 | else | 875 | } else { |
812 | n = (unsigned int)len; | 876 | ssret = tls_content_read(s->s3->rcontent, buf, len); |
813 | |||
814 | memcpy(buf, &rr->data[rr->off], n); | ||
815 | if (!peek) { | ||
816 | memset(&rr->data[rr->off], 0, n); | ||
817 | rr->length -= n; | ||
818 | rr->off += n; | ||
819 | if (rr->length == 0) { | ||
820 | s->rstate = SSL_ST_READ_HEADER; | ||
821 | rr->off = 0; | ||
822 | } | ||
823 | } | 877 | } |
878 | if (ssret < INT_MIN || ssret > INT_MAX) | ||
879 | return -1; | ||
880 | if (ssret < 0) | ||
881 | return (int)ssret; | ||
824 | 882 | ||
825 | return n; | 883 | if (tls_content_remaining(s->s3->rcontent) == 0) |
826 | } | 884 | s->rstate = SSL_ST_READ_HEADER; |
827 | 885 | ||
828 | /* | 886 | return (int)ssret; |
829 | * If we get here, then type != rr->type; if we have a handshake | 887 | } |
830 | * message, then it was unexpected (Hello Request or Client Hello). | ||
831 | */ | ||
832 | 888 | ||
833 | if (rr->type == SSL3_RT_ALERT) { | 889 | if (tls_content_type(s->s3->rcontent) == SSL3_RT_ALERT) { |
834 | if ((ret = ssl3_read_alert(s)) <= 0) | 890 | if ((ret = ssl3_read_alert(s)) <= 0) |
835 | return ret; | 891 | return ret; |
836 | goto start; | 892 | goto start; |
@@ -838,11 +894,12 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
838 | 894 | ||
839 | if (s->shutdown & SSL_SENT_SHUTDOWN) { | 895 | if (s->shutdown & SSL_SENT_SHUTDOWN) { |
840 | s->rwstate = SSL_NOTHING; | 896 | s->rwstate = SSL_NOTHING; |
841 | rr->length = 0; | 897 | tls_content_clear(s->s3->rcontent); |
898 | s->s3->rrec.length = 0; | ||
842 | return (0); | 899 | return (0); |
843 | } | 900 | } |
844 | 901 | ||
845 | if (rr->type == SSL3_RT_APPLICATION_DATA) { | 902 | if (tls_content_type(s->s3->rcontent) == SSL3_RT_APPLICATION_DATA) { |
846 | /* | 903 | /* |
847 | * At this point, we were expecting handshake data, but have | 904 | * At this point, we were expecting handshake data, but have |
848 | * application data. If the library was running inside | 905 | * application data. If the library was running inside |
@@ -868,13 +925,13 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
868 | } | 925 | } |
869 | } | 926 | } |
870 | 927 | ||
871 | if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { | 928 | if (tls_content_type(s->s3->rcontent) == SSL3_RT_CHANGE_CIPHER_SPEC) { |
872 | if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) | 929 | if ((ret = ssl3_read_change_cipher_spec(s)) <= 0) |
873 | return ret; | 930 | return ret; |
874 | goto start; | 931 | goto start; |
875 | } | 932 | } |
876 | 933 | ||
877 | if (rr->type == SSL3_RT_HANDSHAKE) { | 934 | if (tls_content_type(s->s3->rcontent) == SSL3_RT_HANDSHAKE) { |
878 | if ((ret = dtls1_read_handshake_unexpected(s)) <= 0) | 935 | if ((ret = dtls1_read_handshake_unexpected(s)) <= 0) |
879 | return ret; | 936 | return ret; |
880 | goto start; | 937 | goto start; |
@@ -891,8 +948,7 @@ dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) | |||
891 | { | 948 | { |
892 | int i; | 949 | int i; |
893 | 950 | ||
894 | if (SSL_in_init(s) && !s->in_handshake) | 951 | if (SSL_in_init(s) && !s->in_handshake) { |
895 | { | ||
896 | i = s->handshake_func(s); | 952 | i = s->handshake_func(s); |
897 | if (i < 0) | 953 | if (i < 0) |
898 | return (i); | 954 | return (i); |