diff options
author | jsing <> | 2015-09-12 12:26:56 +0000 |
---|---|---|
committer | jsing <> | 2015-09-12 12:26:56 +0000 |
commit | 5c03218e21b8acfe31f7e9937f652f76eeb6fd87 (patch) | |
tree | 05be485f80e47ce5ad3d28aa6890706bc38ef1fc | |
parent | 92f4e2ce0c9ddc92f921c99c2ca499dd86451dd4 (diff) | |
download | openbsd-5c03218e21b8acfe31f7e9937f652f76eeb6fd87.tar.gz openbsd-5c03218e21b8acfe31f7e9937f652f76eeb6fd87.tar.bz2 openbsd-5c03218e21b8acfe31f7e9937f652f76eeb6fd87.zip |
Uncopy and unpaste dtls1_send_client_key_exchange() - the
ssl3_send_client_key_exchange() is effectively identical, in fact it has
a number of bug fixes and improvements that never got merged into the
DTLS copy of the code. Flenses another 264 lines of code.
ok beck@
-rw-r--r-- | src/lib/libssl/d1_clnt.c | 271 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/d1_clnt.c | 271 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 3 |
4 files changed, 10 insertions, 538 deletions
diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c index f45ef939ed..7dd6126c97 100644 --- a/src/lib/libssl/d1_clnt.c +++ b/src/lib/libssl/d1_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_clnt.c,v 1.52 2015/09/11 18:08:21 jsing Exp $ */ | 1 | /* $OpenBSD: d1_clnt.c,v 1.53 2015/09/12 12:26:56 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. |
@@ -376,8 +376,7 @@ dtls1_connect(SSL *s) | |||
376 | else | 376 | else |
377 | s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; | 377 | s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; |
378 | s->init_num = 0; | 378 | s->init_num = 0; |
379 | 379 | s->state = s->s3->tmp.next_state; | |
380 | s->state = s->s3->tmp.next_state; | ||
381 | break; | 380 | break; |
382 | 381 | ||
383 | case SSL3_ST_CW_CERT_A: | 382 | case SSL3_ST_CW_CERT_A: |
@@ -395,11 +394,10 @@ dtls1_connect(SSL *s) | |||
395 | case SSL3_ST_CW_KEY_EXCH_A: | 394 | case SSL3_ST_CW_KEY_EXCH_A: |
396 | case SSL3_ST_CW_KEY_EXCH_B: | 395 | case SSL3_ST_CW_KEY_EXCH_B: |
397 | dtls1_start_timer(s); | 396 | dtls1_start_timer(s); |
398 | ret = dtls1_send_client_key_exchange(s); | 397 | ret = ssl3_send_client_key_exchange(s); |
399 | if (ret <= 0) | 398 | if (ret <= 0) |
400 | goto end; | 399 | goto end; |
401 | 400 | ||
402 | |||
403 | /* EAY EAY EAY need to check for DH fix cert | 401 | /* EAY EAY EAY need to check for DH fix cert |
404 | * sent back */ | 402 | * sent back */ |
405 | /* For TLS, cert_req is set to 2, so a cert chain | 403 | /* For TLS, cert_req is set to 2, so a cert chain |
@@ -407,7 +405,7 @@ dtls1_connect(SSL *s) | |||
407 | if (s->s3->tmp.cert_req == 1) { | 405 | if (s->s3->tmp.cert_req == 1) { |
408 | s->state = SSL3_ST_CW_CERT_VRFY_A; | 406 | s->state = SSL3_ST_CW_CERT_VRFY_A; |
409 | } else { | 407 | } else { |
410 | s->state = SSL3_ST_CW_CHANGE_A; | 408 | s->state = SSL3_ST_CW_CHANGE_A; |
411 | s->s3->change_cipher_spec = 0; | 409 | s->s3->change_cipher_spec = 0; |
412 | } | 410 | } |
413 | 411 | ||
@@ -661,267 +659,6 @@ f_err: | |||
661 | } | 659 | } |
662 | 660 | ||
663 | int | 661 | int |
664 | dtls1_send_client_key_exchange(SSL *s) | ||
665 | { | ||
666 | unsigned char *p, *q; | ||
667 | int n; | ||
668 | unsigned long alg_k; | ||
669 | EVP_PKEY *pkey = NULL; | ||
670 | EC_KEY *clnt_ecdh = NULL; | ||
671 | const EC_POINT *srvr_ecpoint = NULL; | ||
672 | EVP_PKEY *srvr_pub_pkey = NULL; | ||
673 | unsigned char *encodedPoint = NULL; | ||
674 | int encoded_pt_len = 0; | ||
675 | BN_CTX * bn_ctx = NULL; | ||
676 | |||
677 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) { | ||
678 | p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); | ||
679 | |||
680 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; | ||
681 | |||
682 | if (s->session->sess_cert == NULL) { | ||
683 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
684 | SSL_AD_HANDSHAKE_FAILURE); | ||
685 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
686 | ERR_R_INTERNAL_ERROR); | ||
687 | goto err; | ||
688 | } | ||
689 | |||
690 | if (alg_k & SSL_kRSA) { | ||
691 | RSA *rsa; | ||
692 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | ||
693 | |||
694 | pkey = X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); | ||
695 | if ((pkey == NULL) || | ||
696 | (pkey->type != EVP_PKEY_RSA) || | ||
697 | (pkey->pkey.rsa == NULL)) { | ||
698 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
699 | ERR_R_INTERNAL_ERROR); | ||
700 | goto err; | ||
701 | } | ||
702 | rsa = pkey->pkey.rsa; | ||
703 | EVP_PKEY_free(pkey); | ||
704 | |||
705 | tmp_buf[0] = s->client_version >> 8; | ||
706 | tmp_buf[1] = s->client_version&0xff; | ||
707 | arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); | ||
708 | |||
709 | s->session->master_key_length = sizeof tmp_buf; | ||
710 | |||
711 | q = p; | ||
712 | /* Fix buf for TLS and [incidentally] DTLS */ | ||
713 | if (s->version > SSL3_VERSION) | ||
714 | p += 2; | ||
715 | n = RSA_public_encrypt(sizeof tmp_buf, | ||
716 | tmp_buf, p, rsa, RSA_PKCS1_PADDING); | ||
717 | if (n <= 0) { | ||
718 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
719 | SSL_R_BAD_RSA_ENCRYPT); | ||
720 | goto err; | ||
721 | } | ||
722 | |||
723 | /* Fix buf for TLS and [incidentally] DTLS */ | ||
724 | if (s->version > SSL3_VERSION) { | ||
725 | s2n(n, q); | ||
726 | n += 2; | ||
727 | } | ||
728 | |||
729 | s->session->master_key_length = | ||
730 | s->method->ssl3_enc->generate_master_secret(s, | ||
731 | s->session->master_key, | ||
732 | tmp_buf, sizeof tmp_buf); | ||
733 | explicit_bzero(tmp_buf, sizeof tmp_buf); | ||
734 | } else if (alg_k & SSL_kDHE) { | ||
735 | DH *dh_srvr, *dh_clnt; | ||
736 | |||
737 | if (s->session->sess_cert->peer_dh_tmp != NULL) | ||
738 | dh_srvr = s->session->sess_cert->peer_dh_tmp; | ||
739 | else { | ||
740 | /* we get them from the cert */ | ||
741 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
742 | SSL_AD_HANDSHAKE_FAILURE); | ||
743 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
744 | SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
745 | goto err; | ||
746 | } | ||
747 | |||
748 | /* generate a new random key */ | ||
749 | if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { | ||
750 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
751 | ERR_R_DH_LIB); | ||
752 | goto err; | ||
753 | } | ||
754 | if (!DH_generate_key(dh_clnt)) { | ||
755 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
756 | ERR_R_DH_LIB); | ||
757 | goto err; | ||
758 | } | ||
759 | |||
760 | /* use the 'p' output buffer for the DH key, but | ||
761 | * make sure to clear it out afterwards */ | ||
762 | |||
763 | n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); | ||
764 | |||
765 | if (n <= 0) { | ||
766 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
767 | ERR_R_DH_LIB); | ||
768 | goto err; | ||
769 | } | ||
770 | |||
771 | /* generate master key from the result */ | ||
772 | s->session->master_key_length = | ||
773 | s->method->ssl3_enc->generate_master_secret( | ||
774 | s, s->session->master_key, p, n); | ||
775 | /* clean up */ | ||
776 | memset(p, 0, n); | ||
777 | |||
778 | /* send off the data */ | ||
779 | n = BN_num_bytes(dh_clnt->pub_key); | ||
780 | s2n(n, p); | ||
781 | BN_bn2bin(dh_clnt->pub_key, p); | ||
782 | n += 2; | ||
783 | |||
784 | DH_free(dh_clnt); | ||
785 | |||
786 | /* perhaps clean things up a bit EAY EAY EAY EAY*/ | ||
787 | } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { | ||
788 | const EC_GROUP *srvr_group = NULL; | ||
789 | EC_KEY *tkey; | ||
790 | int field_size = 0; | ||
791 | |||
792 | if (s->session->sess_cert->peer_ecdh_tmp != NULL) { | ||
793 | tkey = s->session->sess_cert->peer_ecdh_tmp; | ||
794 | } else { | ||
795 | /* Get the Server Public Key from Cert */ | ||
796 | srvr_pub_pkey = X509_get_pubkey(s->session-> \ | ||
797 | sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); | ||
798 | if ((srvr_pub_pkey == NULL) || | ||
799 | (srvr_pub_pkey->type != EVP_PKEY_EC) || | ||
800 | (srvr_pub_pkey->pkey.ec == NULL)) { | ||
801 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
802 | ERR_R_INTERNAL_ERROR); | ||
803 | goto err; | ||
804 | } | ||
805 | |||
806 | tkey = srvr_pub_pkey->pkey.ec; | ||
807 | } | ||
808 | |||
809 | srvr_group = EC_KEY_get0_group(tkey); | ||
810 | srvr_ecpoint = EC_KEY_get0_public_key(tkey); | ||
811 | |||
812 | if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { | ||
813 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
814 | ERR_R_INTERNAL_ERROR); | ||
815 | goto err; | ||
816 | } | ||
817 | |||
818 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { | ||
819 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
820 | ERR_R_MALLOC_FAILURE); | ||
821 | goto err; | ||
822 | } | ||
823 | |||
824 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { | ||
825 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
826 | ERR_R_EC_LIB); | ||
827 | goto err; | ||
828 | } | ||
829 | |||
830 | /* Generate a new ECDH key pair */ | ||
831 | if (!(EC_KEY_generate_key(clnt_ecdh))) { | ||
832 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
833 | ERR_R_ECDH_LIB); | ||
834 | goto err; | ||
835 | } | ||
836 | |||
837 | /* use the 'p' output buffer for the ECDH key, but | ||
838 | * make sure to clear it out afterwards | ||
839 | */ | ||
840 | |||
841 | field_size = EC_GROUP_get_degree(srvr_group); | ||
842 | if (field_size <= 0) { | ||
843 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
844 | ERR_R_ECDH_LIB); | ||
845 | goto err; | ||
846 | } | ||
847 | n = ECDH_compute_key(p, (field_size + 7)/8, srvr_ecpoint, clnt_ecdh, NULL); | ||
848 | if (n <= 0) { | ||
849 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
850 | ERR_R_ECDH_LIB); | ||
851 | goto err; | ||
852 | } | ||
853 | |||
854 | /* generate master key from the result */ | ||
855 | s->session->master_key_length = | ||
856 | s->method->ssl3_enc->generate_master_secret( | ||
857 | s, s->session->master_key, p, n); | ||
858 | memset(p, 0, n); /* clean up */ | ||
859 | |||
860 | /* First check the size of encoding and | ||
861 | * allocate memory accordingly. | ||
862 | */ | ||
863 | encoded_pt_len = EC_POINT_point2oct(srvr_group, | ||
864 | EC_KEY_get0_public_key(clnt_ecdh), | ||
865 | POINT_CONVERSION_UNCOMPRESSED, | ||
866 | NULL, 0, NULL); | ||
867 | |||
868 | encodedPoint = malloc(encoded_pt_len); | ||
869 | |||
870 | bn_ctx = BN_CTX_new(); | ||
871 | if ((encodedPoint == NULL) || | ||
872 | (bn_ctx == NULL)) { | ||
873 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
874 | ERR_R_MALLOC_FAILURE); | ||
875 | goto err; | ||
876 | } | ||
877 | |||
878 | /* Encode the public key */ | ||
879 | n = EC_POINT_point2oct(srvr_group, | ||
880 | EC_KEY_get0_public_key(clnt_ecdh), | ||
881 | POINT_CONVERSION_UNCOMPRESSED, | ||
882 | encodedPoint, encoded_pt_len, bn_ctx); | ||
883 | |||
884 | *p = n; /* length of encoded point */ | ||
885 | /* Encoded point will be copied here */ | ||
886 | p += 1; | ||
887 | |||
888 | /* copy the point */ | ||
889 | memcpy((unsigned char *)p, encodedPoint, n); | ||
890 | /* increment n to account for length field */ | ||
891 | n += 1; | ||
892 | |||
893 | /* Free allocated memory */ | ||
894 | BN_CTX_free(bn_ctx); | ||
895 | free(encodedPoint); | ||
896 | EC_KEY_free(clnt_ecdh); | ||
897 | EVP_PKEY_free(srvr_pub_pkey); | ||
898 | } | ||
899 | |||
900 | else { | ||
901 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
902 | SSL_AD_HANDSHAKE_FAILURE); | ||
903 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
904 | ERR_R_INTERNAL_ERROR); | ||
905 | goto err; | ||
906 | } | ||
907 | |||
908 | ssl3_handshake_msg_finish(s, n); | ||
909 | |||
910 | s->state = SSL3_ST_CW_KEY_EXCH_B; | ||
911 | } | ||
912 | |||
913 | /* SSL3_ST_CW_KEY_EXCH_B */ | ||
914 | return (ssl3_handshake_write(s)); | ||
915 | |||
916 | err: | ||
917 | BN_CTX_free(bn_ctx); | ||
918 | free(encodedPoint); | ||
919 | EC_KEY_free(clnt_ecdh); | ||
920 | EVP_PKEY_free(srvr_pub_pkey); | ||
921 | return (-1); | ||
922 | } | ||
923 | |||
924 | int | ||
925 | dtls1_send_client_verify(SSL *s) | 662 | dtls1_send_client_verify(SSL *s) |
926 | { | 663 | { |
927 | unsigned char *p; | 664 | unsigned char *p; |
diff --git a/src/lib/libssl/src/ssl/d1_clnt.c b/src/lib/libssl/src/ssl/d1_clnt.c index f45ef939ed..7dd6126c97 100644 --- a/src/lib/libssl/src/ssl/d1_clnt.c +++ b/src/lib/libssl/src/ssl/d1_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_clnt.c,v 1.52 2015/09/11 18:08:21 jsing Exp $ */ | 1 | /* $OpenBSD: d1_clnt.c,v 1.53 2015/09/12 12:26:56 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. |
@@ -376,8 +376,7 @@ dtls1_connect(SSL *s) | |||
376 | else | 376 | else |
377 | s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; | 377 | s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; |
378 | s->init_num = 0; | 378 | s->init_num = 0; |
379 | 379 | s->state = s->s3->tmp.next_state; | |
380 | s->state = s->s3->tmp.next_state; | ||
381 | break; | 380 | break; |
382 | 381 | ||
383 | case SSL3_ST_CW_CERT_A: | 382 | case SSL3_ST_CW_CERT_A: |
@@ -395,11 +394,10 @@ dtls1_connect(SSL *s) | |||
395 | case SSL3_ST_CW_KEY_EXCH_A: | 394 | case SSL3_ST_CW_KEY_EXCH_A: |
396 | case SSL3_ST_CW_KEY_EXCH_B: | 395 | case SSL3_ST_CW_KEY_EXCH_B: |
397 | dtls1_start_timer(s); | 396 | dtls1_start_timer(s); |
398 | ret = dtls1_send_client_key_exchange(s); | 397 | ret = ssl3_send_client_key_exchange(s); |
399 | if (ret <= 0) | 398 | if (ret <= 0) |
400 | goto end; | 399 | goto end; |
401 | 400 | ||
402 | |||
403 | /* EAY EAY EAY need to check for DH fix cert | 401 | /* EAY EAY EAY need to check for DH fix cert |
404 | * sent back */ | 402 | * sent back */ |
405 | /* For TLS, cert_req is set to 2, so a cert chain | 403 | /* For TLS, cert_req is set to 2, so a cert chain |
@@ -407,7 +405,7 @@ dtls1_connect(SSL *s) | |||
407 | if (s->s3->tmp.cert_req == 1) { | 405 | if (s->s3->tmp.cert_req == 1) { |
408 | s->state = SSL3_ST_CW_CERT_VRFY_A; | 406 | s->state = SSL3_ST_CW_CERT_VRFY_A; |
409 | } else { | 407 | } else { |
410 | s->state = SSL3_ST_CW_CHANGE_A; | 408 | s->state = SSL3_ST_CW_CHANGE_A; |
411 | s->s3->change_cipher_spec = 0; | 409 | s->s3->change_cipher_spec = 0; |
412 | } | 410 | } |
413 | 411 | ||
@@ -661,267 +659,6 @@ f_err: | |||
661 | } | 659 | } |
662 | 660 | ||
663 | int | 661 | int |
664 | dtls1_send_client_key_exchange(SSL *s) | ||
665 | { | ||
666 | unsigned char *p, *q; | ||
667 | int n; | ||
668 | unsigned long alg_k; | ||
669 | EVP_PKEY *pkey = NULL; | ||
670 | EC_KEY *clnt_ecdh = NULL; | ||
671 | const EC_POINT *srvr_ecpoint = NULL; | ||
672 | EVP_PKEY *srvr_pub_pkey = NULL; | ||
673 | unsigned char *encodedPoint = NULL; | ||
674 | int encoded_pt_len = 0; | ||
675 | BN_CTX * bn_ctx = NULL; | ||
676 | |||
677 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) { | ||
678 | p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); | ||
679 | |||
680 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; | ||
681 | |||
682 | if (s->session->sess_cert == NULL) { | ||
683 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
684 | SSL_AD_HANDSHAKE_FAILURE); | ||
685 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
686 | ERR_R_INTERNAL_ERROR); | ||
687 | goto err; | ||
688 | } | ||
689 | |||
690 | if (alg_k & SSL_kRSA) { | ||
691 | RSA *rsa; | ||
692 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | ||
693 | |||
694 | pkey = X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); | ||
695 | if ((pkey == NULL) || | ||
696 | (pkey->type != EVP_PKEY_RSA) || | ||
697 | (pkey->pkey.rsa == NULL)) { | ||
698 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
699 | ERR_R_INTERNAL_ERROR); | ||
700 | goto err; | ||
701 | } | ||
702 | rsa = pkey->pkey.rsa; | ||
703 | EVP_PKEY_free(pkey); | ||
704 | |||
705 | tmp_buf[0] = s->client_version >> 8; | ||
706 | tmp_buf[1] = s->client_version&0xff; | ||
707 | arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); | ||
708 | |||
709 | s->session->master_key_length = sizeof tmp_buf; | ||
710 | |||
711 | q = p; | ||
712 | /* Fix buf for TLS and [incidentally] DTLS */ | ||
713 | if (s->version > SSL3_VERSION) | ||
714 | p += 2; | ||
715 | n = RSA_public_encrypt(sizeof tmp_buf, | ||
716 | tmp_buf, p, rsa, RSA_PKCS1_PADDING); | ||
717 | if (n <= 0) { | ||
718 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
719 | SSL_R_BAD_RSA_ENCRYPT); | ||
720 | goto err; | ||
721 | } | ||
722 | |||
723 | /* Fix buf for TLS and [incidentally] DTLS */ | ||
724 | if (s->version > SSL3_VERSION) { | ||
725 | s2n(n, q); | ||
726 | n += 2; | ||
727 | } | ||
728 | |||
729 | s->session->master_key_length = | ||
730 | s->method->ssl3_enc->generate_master_secret(s, | ||
731 | s->session->master_key, | ||
732 | tmp_buf, sizeof tmp_buf); | ||
733 | explicit_bzero(tmp_buf, sizeof tmp_buf); | ||
734 | } else if (alg_k & SSL_kDHE) { | ||
735 | DH *dh_srvr, *dh_clnt; | ||
736 | |||
737 | if (s->session->sess_cert->peer_dh_tmp != NULL) | ||
738 | dh_srvr = s->session->sess_cert->peer_dh_tmp; | ||
739 | else { | ||
740 | /* we get them from the cert */ | ||
741 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
742 | SSL_AD_HANDSHAKE_FAILURE); | ||
743 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
744 | SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
745 | goto err; | ||
746 | } | ||
747 | |||
748 | /* generate a new random key */ | ||
749 | if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { | ||
750 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
751 | ERR_R_DH_LIB); | ||
752 | goto err; | ||
753 | } | ||
754 | if (!DH_generate_key(dh_clnt)) { | ||
755 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
756 | ERR_R_DH_LIB); | ||
757 | goto err; | ||
758 | } | ||
759 | |||
760 | /* use the 'p' output buffer for the DH key, but | ||
761 | * make sure to clear it out afterwards */ | ||
762 | |||
763 | n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); | ||
764 | |||
765 | if (n <= 0) { | ||
766 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
767 | ERR_R_DH_LIB); | ||
768 | goto err; | ||
769 | } | ||
770 | |||
771 | /* generate master key from the result */ | ||
772 | s->session->master_key_length = | ||
773 | s->method->ssl3_enc->generate_master_secret( | ||
774 | s, s->session->master_key, p, n); | ||
775 | /* clean up */ | ||
776 | memset(p, 0, n); | ||
777 | |||
778 | /* send off the data */ | ||
779 | n = BN_num_bytes(dh_clnt->pub_key); | ||
780 | s2n(n, p); | ||
781 | BN_bn2bin(dh_clnt->pub_key, p); | ||
782 | n += 2; | ||
783 | |||
784 | DH_free(dh_clnt); | ||
785 | |||
786 | /* perhaps clean things up a bit EAY EAY EAY EAY*/ | ||
787 | } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { | ||
788 | const EC_GROUP *srvr_group = NULL; | ||
789 | EC_KEY *tkey; | ||
790 | int field_size = 0; | ||
791 | |||
792 | if (s->session->sess_cert->peer_ecdh_tmp != NULL) { | ||
793 | tkey = s->session->sess_cert->peer_ecdh_tmp; | ||
794 | } else { | ||
795 | /* Get the Server Public Key from Cert */ | ||
796 | srvr_pub_pkey = X509_get_pubkey(s->session-> \ | ||
797 | sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); | ||
798 | if ((srvr_pub_pkey == NULL) || | ||
799 | (srvr_pub_pkey->type != EVP_PKEY_EC) || | ||
800 | (srvr_pub_pkey->pkey.ec == NULL)) { | ||
801 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
802 | ERR_R_INTERNAL_ERROR); | ||
803 | goto err; | ||
804 | } | ||
805 | |||
806 | tkey = srvr_pub_pkey->pkey.ec; | ||
807 | } | ||
808 | |||
809 | srvr_group = EC_KEY_get0_group(tkey); | ||
810 | srvr_ecpoint = EC_KEY_get0_public_key(tkey); | ||
811 | |||
812 | if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { | ||
813 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
814 | ERR_R_INTERNAL_ERROR); | ||
815 | goto err; | ||
816 | } | ||
817 | |||
818 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { | ||
819 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
820 | ERR_R_MALLOC_FAILURE); | ||
821 | goto err; | ||
822 | } | ||
823 | |||
824 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { | ||
825 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
826 | ERR_R_EC_LIB); | ||
827 | goto err; | ||
828 | } | ||
829 | |||
830 | /* Generate a new ECDH key pair */ | ||
831 | if (!(EC_KEY_generate_key(clnt_ecdh))) { | ||
832 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
833 | ERR_R_ECDH_LIB); | ||
834 | goto err; | ||
835 | } | ||
836 | |||
837 | /* use the 'p' output buffer for the ECDH key, but | ||
838 | * make sure to clear it out afterwards | ||
839 | */ | ||
840 | |||
841 | field_size = EC_GROUP_get_degree(srvr_group); | ||
842 | if (field_size <= 0) { | ||
843 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
844 | ERR_R_ECDH_LIB); | ||
845 | goto err; | ||
846 | } | ||
847 | n = ECDH_compute_key(p, (field_size + 7)/8, srvr_ecpoint, clnt_ecdh, NULL); | ||
848 | if (n <= 0) { | ||
849 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
850 | ERR_R_ECDH_LIB); | ||
851 | goto err; | ||
852 | } | ||
853 | |||
854 | /* generate master key from the result */ | ||
855 | s->session->master_key_length = | ||
856 | s->method->ssl3_enc->generate_master_secret( | ||
857 | s, s->session->master_key, p, n); | ||
858 | memset(p, 0, n); /* clean up */ | ||
859 | |||
860 | /* First check the size of encoding and | ||
861 | * allocate memory accordingly. | ||
862 | */ | ||
863 | encoded_pt_len = EC_POINT_point2oct(srvr_group, | ||
864 | EC_KEY_get0_public_key(clnt_ecdh), | ||
865 | POINT_CONVERSION_UNCOMPRESSED, | ||
866 | NULL, 0, NULL); | ||
867 | |||
868 | encodedPoint = malloc(encoded_pt_len); | ||
869 | |||
870 | bn_ctx = BN_CTX_new(); | ||
871 | if ((encodedPoint == NULL) || | ||
872 | (bn_ctx == NULL)) { | ||
873 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
874 | ERR_R_MALLOC_FAILURE); | ||
875 | goto err; | ||
876 | } | ||
877 | |||
878 | /* Encode the public key */ | ||
879 | n = EC_POINT_point2oct(srvr_group, | ||
880 | EC_KEY_get0_public_key(clnt_ecdh), | ||
881 | POINT_CONVERSION_UNCOMPRESSED, | ||
882 | encodedPoint, encoded_pt_len, bn_ctx); | ||
883 | |||
884 | *p = n; /* length of encoded point */ | ||
885 | /* Encoded point will be copied here */ | ||
886 | p += 1; | ||
887 | |||
888 | /* copy the point */ | ||
889 | memcpy((unsigned char *)p, encodedPoint, n); | ||
890 | /* increment n to account for length field */ | ||
891 | n += 1; | ||
892 | |||
893 | /* Free allocated memory */ | ||
894 | BN_CTX_free(bn_ctx); | ||
895 | free(encodedPoint); | ||
896 | EC_KEY_free(clnt_ecdh); | ||
897 | EVP_PKEY_free(srvr_pub_pkey); | ||
898 | } | ||
899 | |||
900 | else { | ||
901 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
902 | SSL_AD_HANDSHAKE_FAILURE); | ||
903 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
904 | ERR_R_INTERNAL_ERROR); | ||
905 | goto err; | ||
906 | } | ||
907 | |||
908 | ssl3_handshake_msg_finish(s, n); | ||
909 | |||
910 | s->state = SSL3_ST_CW_KEY_EXCH_B; | ||
911 | } | ||
912 | |||
913 | /* SSL3_ST_CW_KEY_EXCH_B */ | ||
914 | return (ssl3_handshake_write(s)); | ||
915 | |||
916 | err: | ||
917 | BN_CTX_free(bn_ctx); | ||
918 | free(encodedPoint); | ||
919 | EC_KEY_free(clnt_ecdh); | ||
920 | EVP_PKEY_free(srvr_pub_pkey); | ||
921 | return (-1); | ||
922 | } | ||
923 | |||
924 | int | ||
925 | dtls1_send_client_verify(SSL *s) | 662 | dtls1_send_client_verify(SSL *s) |
926 | { | 663 | { |
927 | unsigned char *p; | 664 | unsigned char *p; |
diff --git a/src/lib/libssl/src/ssl/ssl_locl.h b/src/lib/libssl/src/ssl/ssl_locl.h index f9be29b241..92842346a2 100644 --- a/src/lib/libssl/src/ssl/ssl_locl.h +++ b/src/lib/libssl/src/ssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.119 2015/09/11 18:08:21 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.120 2015/09/12 12:26:56 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 | * |
@@ -711,7 +711,6 @@ int ssl3_check_finished(SSL *s); | |||
711 | int ssl3_send_next_proto(SSL *s); | 711 | int ssl3_send_next_proto(SSL *s); |
712 | 712 | ||
713 | int dtls1_send_client_certificate(SSL *s); | 713 | int dtls1_send_client_certificate(SSL *s); |
714 | int dtls1_send_client_key_exchange(SSL *s); | ||
715 | int dtls1_send_client_verify(SSL *s); | 714 | int dtls1_send_client_verify(SSL *s); |
716 | 715 | ||
717 | /* some server-only functions */ | 716 | /* some server-only functions */ |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index f9be29b241..92842346a2 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.119 2015/09/11 18:08:21 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.120 2015/09/12 12:26:56 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 | * |
@@ -711,7 +711,6 @@ int ssl3_check_finished(SSL *s); | |||
711 | int ssl3_send_next_proto(SSL *s); | 711 | int ssl3_send_next_proto(SSL *s); |
712 | 712 | ||
713 | int dtls1_send_client_certificate(SSL *s); | 713 | int dtls1_send_client_certificate(SSL *s); |
714 | int dtls1_send_client_key_exchange(SSL *s); | ||
715 | int dtls1_send_client_verify(SSL *s); | 714 | int dtls1_send_client_verify(SSL *s); |
716 | 715 | ||
717 | /* some server-only functions */ | 716 | /* some server-only functions */ |