diff options
| author | jsing <> | 2015-09-12 12:26:56 +0000 | 
|---|---|---|
| committer | jsing <> | 2015-09-12 12:26:56 +0000 | 
| commit | baa36ea9c417204b2eaca259cd3522318c5df609 (patch) | |
| tree | 05be485f80e47ce5ad3d28aa6890706bc38ef1fc /src/lib/libssl/d1_clnt.c | |
| parent | 8e82261904f03adc0b4911e602bd90997a4d0289 (diff) | |
| download | openbsd-baa36ea9c417204b2eaca259cd3522318c5df609.tar.gz openbsd-baa36ea9c417204b2eaca259cd3522318c5df609.tar.bz2 openbsd-baa36ea9c417204b2eaca259cd3522318c5df609.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@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/d1_clnt.c | 271 | 
1 files changed, 4 insertions, 267 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; | 
