diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/d1_pkt.c | 222 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_pkt.c | 263 |
2 files changed, 256 insertions, 229 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 6ed04395b9..f6f07052a1 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.119 2022/03/12 12:53:03 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.120 2022/03/14 16:49:35 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. |
| @@ -482,6 +482,123 @@ dtls1_get_record(SSL *s) | |||
| 482 | return (1); | 482 | return (1); |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | static int | ||
| 486 | dtls1_read_handshake_unexpected(SSL *s) | ||
| 487 | { | ||
| 488 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
| 489 | int i; | ||
| 490 | |||
| 491 | if (s->internal->in_handshake) { | ||
| 492 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 493 | return -1; | ||
| 494 | } | ||
| 495 | |||
| 496 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
| 497 | if (!s->server && rr->type == SSL3_RT_HANDSHAKE && | ||
| 498 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | ||
| 499 | rr->data[0] == SSL3_MT_HELLO_REQUEST && | ||
| 500 | s->session != NULL && s->session->cipher != NULL) { | ||
| 501 | struct hm_header_st msg_hdr; | ||
| 502 | CBS cbs; | ||
| 503 | |||
| 504 | CBS_init(&cbs, rr->data, rr->length); | ||
| 505 | if (!dtls1_get_message_header(&cbs, &msg_hdr)) | ||
| 506 | return -1; /* XXX - probably should drop/continue. */ | ||
| 507 | if (msg_hdr.msg_len != 0) { | ||
| 508 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | ||
| 509 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | ||
| 510 | return -1; | ||
| 511 | } | ||
| 512 | rr->length = 0; | ||
| 513 | |||
| 514 | /* no need to check sequence number on HELLO REQUEST messages */ | ||
| 515 | |||
| 516 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, rr->data, 4); | ||
| 517 | |||
| 518 | if (SSL_is_init_finished(s) && | ||
| 519 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
| 520 | !s->s3->renegotiate) { | ||
| 521 | s->d1->handshake_read_seq++; | ||
| 522 | s->internal->new_session = 1; | ||
| 523 | ssl3_renegotiate(s); | ||
| 524 | if (ssl3_renegotiate_check(s)) { | ||
| 525 | i = s->internal->handshake_func(s); | ||
| 526 | if (i < 0) | ||
| 527 | return (i); | ||
| 528 | if (i == 0) { | ||
| 529 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 530 | return (-1); | ||
| 531 | } | ||
| 532 | |||
| 533 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 534 | if (s->s3->rbuf.left == 0) { | ||
| 535 | ssl_force_want_read(s); | ||
| 536 | return (-1); | ||
| 537 | } | ||
| 538 | } | ||
| 539 | } | ||
| 540 | } | ||
| 541 | /* we either finished a handshake or ignored the request, | ||
| 542 | * now try again to obtain the (application) data we were asked for */ | ||
| 543 | rr->length = 0; | ||
| 544 | return 1; | ||
| 545 | } | ||
| 546 | |||
| 547 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | ||
| 548 | if (rr->type == SSL3_RT_HANDSHAKE && | ||
| 549 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | ||
| 550 | !s->internal->in_handshake) { | ||
| 551 | struct hm_header_st msg_hdr; | ||
| 552 | CBS cbs; | ||
| 553 | |||
| 554 | /* this may just be a stale retransmit */ | ||
| 555 | CBS_init(&cbs, rr->data, rr->length); | ||
| 556 | if (!dtls1_get_message_header(&cbs, &msg_hdr)) | ||
| 557 | return -1; /* XXX - this should probably drop/continue. */ | ||
| 558 | if (rr->epoch != tls12_record_layer_read_epoch(s->internal->rl)) { | ||
| 559 | rr->length = 0; | ||
| 560 | return 1; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* If we are server, we may have a repeated FINISHED of the | ||
| 564 | * client here, then retransmit our CCS and FINISHED. | ||
| 565 | */ | ||
| 566 | if (msg_hdr.type == SSL3_MT_FINISHED) { | ||
| 567 | if (dtls1_check_timeout_num(s) < 0) | ||
| 568 | return -1; | ||
| 569 | |||
| 570 | dtls1_retransmit_buffered_messages(s); | ||
| 571 | rr->length = 0; | ||
| 572 | return 1; | ||
| 573 | } | ||
| 574 | |||
| 575 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | ||
| 576 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { | ||
| 577 | s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | ||
| 578 | s->internal->renegotiate = 1; | ||
| 579 | s->internal->new_session = 1; | ||
| 580 | } | ||
| 581 | i = s->internal->handshake_func(s); | ||
| 582 | if (i < 0) | ||
| 583 | return (i); | ||
| 584 | if (i == 0) { | ||
| 585 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 586 | return (-1); | ||
| 587 | } | ||
| 588 | |||
| 589 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 590 | if (s->s3->rbuf.left == 0) { | ||
| 591 | ssl_force_want_read(s); | ||
| 592 | return (-1); | ||
| 593 | } | ||
| 594 | } | ||
| 595 | rr->length = 0; | ||
| 596 | return 1; | ||
| 597 | } | ||
| 598 | |||
| 599 | return 1; | ||
| 600 | } | ||
| 601 | |||
| 485 | /* Return up to 'len' payload bytes received in 'type' records. | 602 | /* Return up to 'len' payload bytes received in 'type' records. |
| 486 | * 'type' is one of the following: | 603 | * 'type' is one of the following: |
| 487 | * | 604 | * |
| @@ -684,57 +801,6 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
| 684 | } | 801 | } |
| 685 | } | 802 | } |
| 686 | 803 | ||
| 687 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
| 688 | if (!s->server && rr->type == SSL3_RT_HANDSHAKE && | ||
| 689 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | ||
| 690 | rr->data[0] == SSL3_MT_HELLO_REQUEST && | ||
| 691 | s->session != NULL && s->session->cipher != NULL) { | ||
| 692 | struct hm_header_st msg_hdr; | ||
| 693 | CBS cbs; | ||
| 694 | |||
| 695 | CBS_init(&cbs, rr->data, rr->length); | ||
| 696 | if (!dtls1_get_message_header(&cbs, &msg_hdr)) | ||
| 697 | return -1; | ||
| 698 | if (msg_hdr.msg_len != 0) { | ||
| 699 | al = SSL_AD_DECODE_ERROR; | ||
| 700 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | ||
| 701 | goto fatal_err; | ||
| 702 | } | ||
| 703 | rr->length = 0; | ||
| 704 | |||
| 705 | /* no need to check sequence number on HELLO REQUEST messages */ | ||
| 706 | |||
| 707 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, rr->data, 4); | ||
| 708 | |||
| 709 | if (SSL_is_init_finished(s) && | ||
| 710 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
| 711 | !s->s3->renegotiate) { | ||
| 712 | s->d1->handshake_read_seq++; | ||
| 713 | s->internal->new_session = 1; | ||
| 714 | ssl3_renegotiate(s); | ||
| 715 | if (ssl3_renegotiate_check(s)) { | ||
| 716 | i = s->internal->handshake_func(s); | ||
| 717 | if (i < 0) | ||
| 718 | return (i); | ||
| 719 | if (i == 0) { | ||
| 720 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 721 | return (-1); | ||
| 722 | } | ||
| 723 | |||
| 724 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 725 | if (s->s3->rbuf.left == 0) { | ||
| 726 | ssl_force_want_read(s); | ||
| 727 | return (-1); | ||
| 728 | } | ||
| 729 | } | ||
| 730 | } | ||
| 731 | } | ||
| 732 | /* we either finished a handshake or ignored the request, | ||
| 733 | * now try again to obtain the (application) data we were asked for */ | ||
| 734 | rr->length = 0; | ||
| 735 | goto start; | ||
| 736 | } | ||
| 737 | |||
| 738 | if (rr->type == SSL3_RT_ALERT) { | 804 | if (rr->type == SSL3_RT_ALERT) { |
| 739 | if ((ret = ssl3_read_alert(s)) <= 0) | 805 | if ((ret = ssl3_read_alert(s)) <= 0) |
| 740 | return ret; | 806 | return ret; |
| @@ -753,55 +819,9 @@ dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
| 753 | goto start; | 819 | goto start; |
| 754 | } | 820 | } |
| 755 | 821 | ||
| 756 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | 822 | if (rr->type == SSL3_RT_HANDSHAKE) { |
| 757 | if (rr->type == SSL3_RT_HANDSHAKE && | 823 | if ((ret = dtls1_read_handshake_unexpected(s)) <= 0) |
| 758 | rr->length >= DTLS1_HM_HEADER_LENGTH && rr->off == 0 && | 824 | return ret; |
| 759 | !s->internal->in_handshake) { | ||
| 760 | struct hm_header_st msg_hdr; | ||
| 761 | CBS cbs; | ||
| 762 | |||
| 763 | /* this may just be a stale retransmit */ | ||
| 764 | CBS_init(&cbs, rr->data, rr->length); | ||
| 765 | if (!dtls1_get_message_header(&cbs, &msg_hdr)) | ||
| 766 | return -1; | ||
| 767 | if (rr->epoch != tls12_record_layer_read_epoch(s->internal->rl)) { | ||
| 768 | rr->length = 0; | ||
| 769 | goto start; | ||
| 770 | } | ||
| 771 | |||
| 772 | /* If we are server, we may have a repeated FINISHED of the | ||
| 773 | * client here, then retransmit our CCS and FINISHED. | ||
| 774 | */ | ||
| 775 | if (msg_hdr.type == SSL3_MT_FINISHED) { | ||
| 776 | if (dtls1_check_timeout_num(s) < 0) | ||
| 777 | return -1; | ||
| 778 | |||
| 779 | dtls1_retransmit_buffered_messages(s); | ||
| 780 | rr->length = 0; | ||
| 781 | goto start; | ||
| 782 | } | ||
| 783 | |||
| 784 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | ||
| 785 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { | ||
| 786 | s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | ||
| 787 | s->internal->renegotiate = 1; | ||
| 788 | s->internal->new_session = 1; | ||
| 789 | } | ||
| 790 | i = s->internal->handshake_func(s); | ||
| 791 | if (i < 0) | ||
| 792 | return (i); | ||
| 793 | if (i == 0) { | ||
| 794 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 795 | return (-1); | ||
| 796 | } | ||
| 797 | |||
| 798 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 799 | if (s->s3->rbuf.left == 0) { | ||
| 800 | ssl_force_want_read(s); | ||
| 801 | return (-1); | ||
| 802 | } | ||
| 803 | } | ||
| 804 | rr->length = 0; | ||
| 805 | goto start; | 825 | goto start; |
| 806 | } | 826 | } |
| 807 | 827 | ||
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index 33bb4b659f..4dc7f3b610 100644 --- a/src/lib/libssl/ssl_pkt.c +++ b/src/lib/libssl/ssl_pkt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_pkt.c,v 1.55 2022/03/12 12:53:03 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.56 2022/03/14 16:49:35 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 | * |
| @@ -814,6 +814,134 @@ ssl3_read_change_cipher_spec(SSL *s) | |||
| 814 | return 1; | 814 | return 1; |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | static int | ||
| 818 | ssl3_read_handshake_unexpected(SSL *s) | ||
| 819 | { | ||
| 820 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
| 821 | int i; | ||
| 822 | |||
| 823 | /* | ||
| 824 | * We need four bytes of handshake data so we have a handshake message | ||
| 825 | * header - this may be in the same record or fragmented across multiple | ||
| 826 | * records. | ||
| 827 | */ | ||
| 828 | while (rr->length > 0 && | ||
| 829 | s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) { | ||
| 830 | s->s3->handshake_fragment[s->s3->handshake_fragment_len++] = | ||
| 831 | rr->data[rr->off++]; | ||
| 832 | rr->length--; | ||
| 833 | } | ||
| 834 | |||
| 835 | if (s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) | ||
| 836 | return 1; | ||
| 837 | |||
| 838 | if (s->internal->in_handshake) { | ||
| 839 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 840 | return -1; | ||
| 841 | } | ||
| 842 | |||
| 843 | /* | ||
| 844 | * This code currently deals with HelloRequest and ClientHello messages - | ||
| 845 | * anything else is pushed to the handshake_func. Almost all of this | ||
| 846 | * belongs in the client/server handshake code. | ||
| 847 | */ | ||
| 848 | |||
| 849 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
| 850 | if ((!s->server) && (s->s3->handshake_fragment_len >= 4) && | ||
| 851 | (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && | ||
| 852 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
| 853 | s->s3->handshake_fragment_len = 0; | ||
| 854 | |||
| 855 | if ((s->s3->handshake_fragment[1] != 0) || | ||
| 856 | (s->s3->handshake_fragment[2] != 0) || | ||
| 857 | (s->s3->handshake_fragment[3] != 0)) { | ||
| 858 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | ||
| 859 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | ||
| 860 | return -1; | ||
| 861 | } | ||
| 862 | |||
| 863 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, | ||
| 864 | s->s3->handshake_fragment, 4); | ||
| 865 | |||
| 866 | if (SSL_is_init_finished(s) && | ||
| 867 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
| 868 | !s->s3->renegotiate) { | ||
| 869 | ssl3_renegotiate(s); | ||
| 870 | if (ssl3_renegotiate_check(s)) { | ||
| 871 | i = s->internal->handshake_func(s); | ||
| 872 | if (i < 0) | ||
| 873 | return (i); | ||
| 874 | if (i == 0) { | ||
| 875 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 876 | return (-1); | ||
| 877 | } | ||
| 878 | |||
| 879 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 880 | if (s->s3->rbuf.left == 0) { | ||
| 881 | ssl_force_want_read(s); | ||
| 882 | return (-1); | ||
| 883 | } | ||
| 884 | } | ||
| 885 | } | ||
| 886 | } | ||
| 887 | /* we either finished a handshake or ignored the request, | ||
| 888 | * now try again to obtain the (application) data we were asked for */ | ||
| 889 | return 1; | ||
| 890 | } | ||
| 891 | |||
| 892 | /* Disallow client initiated renegotiation if configured. */ | ||
| 893 | if (s->server && SSL_is_init_finished(s) && | ||
| 894 | s->s3->handshake_fragment_len >= 4 && | ||
| 895 | s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO && | ||
| 896 | (s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION)) { | ||
| 897 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); | ||
| 898 | return -1; | ||
| 899 | } | ||
| 900 | |||
| 901 | /* If we are a server and get a client hello when renegotiation isn't | ||
| 902 | * allowed send back a no renegotiation alert and carry on. | ||
| 903 | * WARNING: experimental code, needs reviewing (steve) | ||
| 904 | */ | ||
| 905 | if (s->server && | ||
| 906 | SSL_is_init_finished(s) && | ||
| 907 | !s->s3->send_connection_binding && | ||
| 908 | (s->s3->handshake_fragment_len >= 4) && | ||
| 909 | (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && | ||
| 910 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
| 911 | /*s->s3->handshake_fragment_len = 0;*/ | ||
| 912 | rr->length = 0; | ||
| 913 | ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); | ||
| 914 | return 1; | ||
| 915 | } | ||
| 916 | |||
| 917 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | ||
| 918 | if ((s->s3->handshake_fragment_len >= 4) && !s->internal->in_handshake) { | ||
| 919 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | ||
| 920 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { | ||
| 921 | s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | ||
| 922 | s->internal->renegotiate = 1; | ||
| 923 | s->internal->new_session = 1; | ||
| 924 | } | ||
| 925 | i = s->internal->handshake_func(s); | ||
| 926 | if (i < 0) | ||
| 927 | return (i); | ||
| 928 | if (i == 0) { | ||
| 929 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 930 | return (-1); | ||
| 931 | } | ||
| 932 | |||
| 933 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 934 | if (s->s3->rbuf.left == 0) { | ||
| 935 | ssl_force_want_read(s); | ||
| 936 | return (-1); | ||
| 937 | } | ||
| 938 | } | ||
| 939 | return 1; | ||
| 940 | } | ||
| 941 | |||
| 942 | return 1; | ||
| 943 | } | ||
| 944 | |||
| 817 | /* Return up to 'len' payload bytes received in 'type' records. | 945 | /* Return up to 'len' payload bytes received in 'type' records. |
| 818 | * 'type' is one of the following: | 946 | * 'type' is one of the following: |
| 819 | * | 947 | * |
| @@ -950,7 +1078,6 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
| 950 | return (0); | 1078 | return (0); |
| 951 | } | 1079 | } |
| 952 | 1080 | ||
| 953 | |||
| 954 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ | 1081 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ |
| 955 | if (type == rr->type) { | 1082 | if (type == rr->type) { |
| 956 | /* make sure that we are not getting application data when we | 1083 | /* make sure that we are not getting application data when we |
| @@ -986,111 +1113,10 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
| 986 | return (n); | 1113 | return (n); |
| 987 | } | 1114 | } |
| 988 | 1115 | ||
| 989 | 1116 | /* | |
| 990 | /* If we get here, then type != rr->type; if we have a handshake | 1117 | * If we get here, then type != rr->type; if we have a handshake |
| 991 | * message, then it was unexpected (Hello Request or Client Hello). */ | 1118 | * message, then it was unexpected (Hello Request or Client Hello). |
| 992 | |||
| 993 | { | ||
| 994 | /* | ||
| 995 | * In case of record types for which we have 'fragment' | ||
| 996 | * storage, * fill that so that we can process the data | ||
| 997 | * at a fixed place. | ||
| 998 | */ | ||
| 999 | unsigned int dest_maxlen = 0; | ||
| 1000 | unsigned char *dest = NULL; | ||
| 1001 | unsigned int *dest_len = NULL; | ||
| 1002 | |||
| 1003 | if (rr->type == SSL3_RT_HANDSHAKE) { | ||
| 1004 | dest_maxlen = sizeof s->s3->handshake_fragment; | ||
| 1005 | dest = s->s3->handshake_fragment; | ||
| 1006 | dest_len = &s->s3->handshake_fragment_len; | ||
| 1007 | } | ||
| 1008 | if (dest_maxlen > 0) { | ||
| 1009 | /* available space in 'dest' */ | ||
| 1010 | n = dest_maxlen - *dest_len; | ||
| 1011 | if (rr->length < n) | ||
| 1012 | n = rr->length; /* available bytes */ | ||
| 1013 | |||
| 1014 | /* now move 'n' bytes: */ | ||
| 1015 | while (n-- > 0) { | ||
| 1016 | dest[(*dest_len)++] = rr->data[rr->off++]; | ||
| 1017 | rr->length--; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | if (*dest_len < dest_maxlen) | ||
| 1021 | goto start; /* fragment was too small */ | ||
| 1022 | } | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | /* s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; | ||
| 1026 | * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. | ||
| 1027 | * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ | ||
| 1028 | |||
| 1029 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
| 1030 | if ((!s->server) && (s->s3->handshake_fragment_len >= 4) && | ||
| 1031 | (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && | ||
| 1032 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
| 1033 | s->s3->handshake_fragment_len = 0; | ||
| 1034 | |||
| 1035 | if ((s->s3->handshake_fragment[1] != 0) || | ||
| 1036 | (s->s3->handshake_fragment[2] != 0) || | ||
| 1037 | (s->s3->handshake_fragment[3] != 0)) { | ||
| 1038 | al = SSL_AD_DECODE_ERROR; | ||
| 1039 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | ||
| 1040 | goto fatal_err; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, | ||
| 1044 | s->s3->handshake_fragment, 4); | ||
| 1045 | |||
| 1046 | if (SSL_is_init_finished(s) && | ||
| 1047 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
| 1048 | !s->s3->renegotiate) { | ||
| 1049 | ssl3_renegotiate(s); | ||
| 1050 | if (ssl3_renegotiate_check(s)) { | ||
| 1051 | i = s->internal->handshake_func(s); | ||
| 1052 | if (i < 0) | ||
| 1053 | return (i); | ||
| 1054 | if (i == 0) { | ||
| 1055 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 1056 | return (-1); | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 1060 | if (s->s3->rbuf.left == 0) { | ||
| 1061 | ssl_force_want_read(s); | ||
| 1062 | return (-1); | ||
| 1063 | } | ||
| 1064 | } | ||
| 1065 | } | ||
| 1066 | } | ||
| 1067 | /* we either finished a handshake or ignored the request, | ||
| 1068 | * now try again to obtain the (application) data we were asked for */ | ||
| 1069 | goto start; | ||
| 1070 | } | ||
| 1071 | /* Disallow client initiated renegotiation if configured. */ | ||
| 1072 | if (s->server && SSL_is_init_finished(s) && | ||
| 1073 | s->s3->handshake_fragment_len >= 4 && | ||
| 1074 | s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO && | ||
| 1075 | (s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION)) { | ||
| 1076 | al = SSL_AD_NO_RENEGOTIATION; | ||
| 1077 | goto fatal_err; | ||
| 1078 | } | ||
| 1079 | /* If we are a server and get a client hello when renegotiation isn't | ||
| 1080 | * allowed send back a no renegotiation alert and carry on. | ||
| 1081 | * WARNING: experimental code, needs reviewing (steve) | ||
| 1082 | */ | 1119 | */ |
| 1083 | if (s->server && | ||
| 1084 | SSL_is_init_finished(s) && | ||
| 1085 | !s->s3->send_connection_binding && | ||
| 1086 | (s->s3->handshake_fragment_len >= 4) && | ||
| 1087 | (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && | ||
| 1088 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
| 1089 | /*s->s3->handshake_fragment_len = 0;*/ | ||
| 1090 | rr->length = 0; | ||
| 1091 | ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); | ||
| 1092 | goto start; | ||
| 1093 | } | ||
| 1094 | 1120 | ||
| 1095 | if (rr->type == SSL3_RT_ALERT) { | 1121 | if (rr->type == SSL3_RT_ALERT) { |
| 1096 | if ((ret = ssl3_read_alert(s)) <= 0) | 1122 | if ((ret = ssl3_read_alert(s)) <= 0) |
| @@ -1111,28 +1137,9 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
| 1111 | goto start; | 1137 | goto start; |
| 1112 | } | 1138 | } |
| 1113 | 1139 | ||
| 1114 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | 1140 | if (rr->type == SSL3_RT_HANDSHAKE) { |
| 1115 | if ((s->s3->handshake_fragment_len >= 4) && !s->internal->in_handshake) { | 1141 | if ((ret = ssl3_read_handshake_unexpected(s)) <= 0) |
| 1116 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | 1142 | return ret; |
| 1117 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { | ||
| 1118 | s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | ||
| 1119 | s->internal->renegotiate = 1; | ||
| 1120 | s->internal->new_session = 1; | ||
| 1121 | } | ||
| 1122 | i = s->internal->handshake_func(s); | ||
| 1123 | if (i < 0) | ||
| 1124 | return (i); | ||
| 1125 | if (i == 0) { | ||
| 1126 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
| 1127 | return (-1); | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
| 1131 | if (s->s3->rbuf.left == 0) { | ||
| 1132 | ssl_force_want_read(s); | ||
| 1133 | return (-1); | ||
| 1134 | } | ||
| 1135 | } | ||
| 1136 | goto start; | 1143 | goto start; |
| 1137 | } | 1144 | } |
| 1138 | 1145 | ||
