diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/d1_srvr.c | 329 |
1 files changed, 2 insertions, 327 deletions
diff --git a/src/lib/libssl/d1_srvr.c b/src/lib/libssl/d1_srvr.c index 6e1c6d2ef9..768c39eb25 100644 --- a/src/lib/libssl/d1_srvr.c +++ b/src/lib/libssl/d1_srvr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: d1_srvr.c,v 1.61 2015/09/12 13:35:34 jsing Exp $ */ | 1 | /* $OpenBSD: d1_srvr.c,v 1.62 2015/09/12 14:28:23 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. |
| @@ -387,7 +387,7 @@ dtls1_accept(SSL *s) | |||
| 387 | /* Only send if using a DH key exchange. */ | 387 | /* Only send if using a DH key exchange. */ |
| 388 | if (alg_k & (SSL_kDHE|SSL_kECDHE)) { | 388 | if (alg_k & (SSL_kDHE|SSL_kECDHE)) { |
| 389 | dtls1_start_timer(s); | 389 | dtls1_start_timer(s); |
| 390 | ret = dtls1_send_server_key_exchange(s); | 390 | ret = ssl3_send_server_key_exchange(s); |
| 391 | if (ret <= 0) | 391 | if (ret <= 0) |
| 392 | goto end; | 392 | goto end; |
| 393 | } else | 393 | } else |
| @@ -700,331 +700,6 @@ dtls1_send_hello_verify_request(SSL *s) | |||
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | int | 702 | int |
| 703 | dtls1_send_server_key_exchange(SSL *s) | ||
| 704 | { | ||
| 705 | unsigned char *q; | ||
| 706 | int j, num; | ||
| 707 | unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; | ||
| 708 | unsigned int u; | ||
| 709 | DH *dh = NULL, *dhp; | ||
| 710 | EC_KEY *ecdh = NULL, *ecdhp; | ||
| 711 | unsigned char *encodedPoint = NULL; | ||
| 712 | int encodedlen = 0; | ||
| 713 | int curve_id = 0; | ||
| 714 | BN_CTX *bn_ctx = NULL; | ||
| 715 | |||
| 716 | EVP_PKEY *pkey; | ||
| 717 | unsigned char *p, *d; | ||
| 718 | int al, i; | ||
| 719 | unsigned long type; | ||
| 720 | int n; | ||
| 721 | CERT *cert; | ||
| 722 | BIGNUM *r[4]; | ||
| 723 | int nr[4], kn; | ||
| 724 | BUF_MEM *buf; | ||
| 725 | EVP_MD_CTX md_ctx; | ||
| 726 | |||
| 727 | EVP_MD_CTX_init(&md_ctx); | ||
| 728 | if (s->state == SSL3_ST_SW_KEY_EXCH_A) { | ||
| 729 | type = s->s3->tmp.new_cipher->algorithm_mkey; | ||
| 730 | cert = s->cert; | ||
| 731 | |||
| 732 | buf = s->init_buf; | ||
| 733 | |||
| 734 | r[0] = r[1] = r[2] = r[3] = NULL; | ||
| 735 | n = 0; | ||
| 736 | |||
| 737 | if (type & SSL_kDHE) { | ||
| 738 | dhp = cert->dh_tmp; | ||
| 739 | if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) | ||
| 740 | dhp = s->cert->dh_tmp_cb(s, 0, | ||
| 741 | SSL_C_PKEYLENGTH(s->s3->tmp.new_cipher)); | ||
| 742 | if (dhp == NULL) { | ||
| 743 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
| 744 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, SSL_R_MISSING_TMP_DH_KEY); | ||
| 745 | goto f_err; | ||
| 746 | } | ||
| 747 | |||
| 748 | if (s->s3->tmp.dh != NULL) { | ||
| 749 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); | ||
| 750 | goto err; | ||
| 751 | } | ||
| 752 | |||
| 753 | if ((dh = DHparams_dup(dhp)) == NULL) { | ||
| 754 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); | ||
| 755 | goto err; | ||
| 756 | } | ||
| 757 | |||
| 758 | s->s3->tmp.dh = dh; | ||
| 759 | if ((dhp->pub_key == NULL || dhp->priv_key == NULL || | ||
| 760 | (s->options & SSL_OP_SINGLE_DH_USE))) { | ||
| 761 | if (!DH_generate_key(dh)) { | ||
| 762 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, | ||
| 763 | ERR_R_DH_LIB); | ||
| 764 | goto err; | ||
| 765 | } | ||
| 766 | } else { | ||
| 767 | dh->pub_key = BN_dup(dhp->pub_key); | ||
| 768 | dh->priv_key = BN_dup(dhp->priv_key); | ||
| 769 | if ((dh->pub_key == NULL) || | ||
| 770 | (dh->priv_key == NULL)) { | ||
| 771 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); | ||
| 772 | goto err; | ||
| 773 | } | ||
| 774 | } | ||
| 775 | r[0] = dh->p; | ||
| 776 | r[1] = dh->g; | ||
| 777 | r[2] = dh->pub_key; | ||
| 778 | } else if (type & SSL_kECDHE) { | ||
| 779 | const EC_GROUP *group; | ||
| 780 | |||
| 781 | ecdhp = cert->ecdh_tmp; | ||
| 782 | if (ecdhp == NULL && s->cert->ecdh_tmp_cb != NULL) | ||
| 783 | ecdhp = s->cert->ecdh_tmp_cb(s, 0, | ||
| 784 | SSL_C_PKEYLENGTH(s->s3->tmp.new_cipher)); | ||
| 785 | if (ecdhp == NULL) { | ||
| 786 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
| 787 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, SSL_R_MISSING_TMP_ECDH_KEY); | ||
| 788 | goto f_err; | ||
| 789 | } | ||
| 790 | |||
| 791 | if (s->s3->tmp.ecdh != NULL) { | ||
| 792 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); | ||
| 793 | goto err; | ||
| 794 | } | ||
| 795 | |||
| 796 | /* Duplicate the ECDH structure. */ | ||
| 797 | if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { | ||
| 798 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
| 799 | goto err; | ||
| 800 | } | ||
| 801 | s->s3->tmp.ecdh = ecdh; | ||
| 802 | |||
| 803 | if ((EC_KEY_get0_public_key(ecdh) == NULL) || | ||
| 804 | (EC_KEY_get0_private_key(ecdh) == NULL) || | ||
| 805 | (s->options & SSL_OP_SINGLE_ECDH_USE)) { | ||
| 806 | if (!EC_KEY_generate_key(ecdh)) { | ||
| 807 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
| 808 | goto err; | ||
| 809 | } | ||
| 810 | } | ||
| 811 | |||
| 812 | if (((group = EC_KEY_get0_group(ecdh)) == NULL) || | ||
| 813 | (EC_KEY_get0_public_key(ecdh) == NULL) || | ||
| 814 | (EC_KEY_get0_private_key(ecdh) == NULL)) { | ||
| 815 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
| 816 | goto err; | ||
| 817 | } | ||
| 818 | |||
| 819 | /* XXX: For now, we only support ephemeral ECDH | ||
| 820 | * keys over named (not generic) curves. For | ||
| 821 | * supported named curves, curve_id is non-zero. | ||
| 822 | */ | ||
| 823 | if ((curve_id = tls1_ec_nid2curve_id( | ||
| 824 | EC_GROUP_get_curve_name(group))) == 0) { | ||
| 825 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); | ||
| 826 | goto err; | ||
| 827 | } | ||
| 828 | |||
| 829 | /* Encode the public key. | ||
| 830 | * First check the size of encoding and | ||
| 831 | * allocate memory accordingly. | ||
| 832 | */ | ||
| 833 | encodedlen = EC_POINT_point2oct(group, | ||
| 834 | EC_KEY_get0_public_key(ecdh), | ||
| 835 | POINT_CONVERSION_UNCOMPRESSED, | ||
| 836 | NULL, 0, NULL); | ||
| 837 | |||
| 838 | encodedPoint = malloc(encodedlen); | ||
| 839 | |||
| 840 | bn_ctx = BN_CTX_new(); | ||
| 841 | if ((encodedPoint == NULL) || (bn_ctx == NULL)) { | ||
| 842 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); | ||
| 843 | goto err; | ||
| 844 | } | ||
| 845 | |||
| 846 | |||
| 847 | encodedlen = EC_POINT_point2oct(group, | ||
| 848 | EC_KEY_get0_public_key(ecdh), | ||
| 849 | POINT_CONVERSION_UNCOMPRESSED, | ||
| 850 | encodedPoint, encodedlen, bn_ctx); | ||
| 851 | |||
| 852 | if (encodedlen == 0) { | ||
| 853 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
| 854 | goto err; | ||
| 855 | } | ||
| 856 | |||
| 857 | BN_CTX_free(bn_ctx); | ||
| 858 | bn_ctx = NULL; | ||
| 859 | |||
| 860 | /* XXX: For now, we only support named (not | ||
| 861 | * generic) curves in ECDH ephemeral key exchanges. | ||
| 862 | * In this situation, we need four additional bytes | ||
| 863 | * to encode the entire ServerECDHParams | ||
| 864 | * structure. | ||
| 865 | */ | ||
| 866 | n = 4 + encodedlen; | ||
| 867 | |||
| 868 | /* We'll generate the serverKeyExchange message | ||
| 869 | * explicitly so we can set these to NULLs | ||
| 870 | */ | ||
| 871 | r[0] = NULL; | ||
| 872 | r[1] = NULL; | ||
| 873 | r[2] = NULL; | ||
| 874 | r[3] = NULL; | ||
| 875 | } else { | ||
| 876 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
| 877 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, | ||
| 878 | SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); | ||
| 879 | goto f_err; | ||
| 880 | } | ||
| 881 | for (i = 0; r[i] != NULL; i++) { | ||
| 882 | nr[i] = BN_num_bytes(r[i]); | ||
| 883 | n += 2 + nr[i]; | ||
| 884 | } | ||
| 885 | |||
| 886 | if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) { | ||
| 887 | if ((pkey = ssl_get_sign_pkey(s, | ||
| 888 | s->s3->tmp.new_cipher, NULL)) == NULL) { | ||
| 889 | al = SSL_AD_DECODE_ERROR; | ||
| 890 | goto f_err; | ||
| 891 | } | ||
| 892 | kn = EVP_PKEY_size(pkey); | ||
| 893 | } else { | ||
| 894 | pkey = NULL; | ||
| 895 | kn = 0; | ||
| 896 | } | ||
| 897 | |||
| 898 | if (!BUF_MEM_grow_clean(buf, n + DTLS1_HM_HEADER_LENGTH + kn)) { | ||
| 899 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF); | ||
| 900 | goto err; | ||
| 901 | } | ||
| 902 | d = (unsigned char *)s->init_buf->data; | ||
| 903 | p = &(d[DTLS1_HM_HEADER_LENGTH]); | ||
| 904 | |||
| 905 | for (i = 0; r[i] != NULL; i++) { | ||
| 906 | s2n(nr[i], p); | ||
| 907 | BN_bn2bin(r[i], p); | ||
| 908 | p += nr[i]; | ||
| 909 | } | ||
| 910 | |||
| 911 | if (type & SSL_kECDHE) { | ||
| 912 | /* XXX: For now, we only support named (not generic) curves. | ||
| 913 | * In this situation, the serverKeyExchange message has: | ||
| 914 | * [1 byte CurveType], [2 byte CurveName] | ||
| 915 | * [1 byte length of encoded point], followed by | ||
| 916 | * the actual encoded point itself | ||
| 917 | */ | ||
| 918 | *p = NAMED_CURVE_TYPE; | ||
| 919 | p += 1; | ||
| 920 | *p = 0; | ||
| 921 | p += 1; | ||
| 922 | *p = curve_id; | ||
| 923 | p += 1; | ||
| 924 | *p = encodedlen; | ||
| 925 | p += 1; | ||
| 926 | memcpy((unsigned char*)p, | ||
| 927 | (unsigned char *)encodedPoint, encodedlen); | ||
| 928 | free(encodedPoint); | ||
| 929 | encodedPoint = NULL; | ||
| 930 | p += encodedlen; | ||
| 931 | } | ||
| 932 | |||
| 933 | |||
| 934 | /* not anonymous */ | ||
| 935 | if (pkey != NULL) { | ||
| 936 | /* n is the length of the params, they start at | ||
| 937 | * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space | ||
| 938 | * at the end. */ | ||
| 939 | if (pkey->type == EVP_PKEY_RSA) { | ||
| 940 | q = md_buf; | ||
| 941 | j = 0; | ||
| 942 | for (num = 2; num > 0; num--) { | ||
| 943 | if (!EVP_DigestInit_ex(&md_ctx, (num == 2) | ||
| 944 | ? s->ctx->md5 : s->ctx->sha1, NULL)) | ||
| 945 | goto err; | ||
| 946 | EVP_DigestUpdate(&md_ctx, | ||
| 947 | &(s->s3->client_random[0]), | ||
| 948 | SSL3_RANDOM_SIZE); | ||
| 949 | EVP_DigestUpdate(&md_ctx, | ||
| 950 | &(s->s3->server_random[0]), | ||
| 951 | SSL3_RANDOM_SIZE); | ||
| 952 | EVP_DigestUpdate(&md_ctx, | ||
| 953 | &(d[DTLS1_HM_HEADER_LENGTH]), n); | ||
| 954 | EVP_DigestFinal_ex(&md_ctx, q, | ||
| 955 | (unsigned int *)&i); | ||
| 956 | q += i; | ||
| 957 | j += i; | ||
| 958 | } | ||
| 959 | if (RSA_sign(NID_md5_sha1, md_buf, j, &(p[2]), | ||
| 960 | &u, pkey->pkey.rsa) <= 0) { | ||
| 961 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); | ||
| 962 | goto err; | ||
| 963 | } | ||
| 964 | s2n(u, p); | ||
| 965 | n += u + 2; | ||
| 966 | } else | ||
| 967 | if (pkey->type == EVP_PKEY_DSA) { | ||
| 968 | /* lets do DSS */ | ||
| 969 | EVP_SignInit_ex(&md_ctx, EVP_dss1(), NULL); | ||
| 970 | EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE); | ||
| 971 | EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE); | ||
| 972 | EVP_SignUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), n); | ||
| 973 | if (!EVP_SignFinal(&md_ctx, &(p[2]), | ||
| 974 | (unsigned int *)&i, pkey)) { | ||
| 975 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_DSA); | ||
| 976 | goto err; | ||
| 977 | } | ||
| 978 | s2n(i, p); | ||
| 979 | n += i + 2; | ||
| 980 | } else | ||
| 981 | if (pkey->type == EVP_PKEY_EC) { | ||
| 982 | /* let's do ECDSA */ | ||
| 983 | EVP_SignInit_ex(&md_ctx, EVP_ecdsa(), NULL); | ||
| 984 | EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE); | ||
| 985 | EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE); | ||
| 986 | EVP_SignUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), n); | ||
| 987 | if (!EVP_SignFinal(&md_ctx, &(p[2]), | ||
| 988 | (unsigned int *)&i, pkey)) { | ||
| 989 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_ECDSA); | ||
| 990 | goto err; | ||
| 991 | } | ||
| 992 | s2n(i, p); | ||
| 993 | n += i + 2; | ||
| 994 | } else | ||
| 995 | { | ||
| 996 | /* Is this error check actually needed? */ | ||
| 997 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
| 998 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, SSL_R_UNKNOWN_PKEY_TYPE); | ||
| 999 | goto f_err; | ||
| 1000 | } | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | d = dtls1_set_message_header(s, d, | ||
| 1004 | SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n); | ||
| 1005 | |||
| 1006 | /* we should now have things packed up, so lets send | ||
| 1007 | * it off */ | ||
| 1008 | s->init_num = n + DTLS1_HM_HEADER_LENGTH; | ||
| 1009 | s->init_off = 0; | ||
| 1010 | |||
| 1011 | /* buffer the message to handle re-xmits */ | ||
| 1012 | dtls1_buffer_message(s, 0); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | s->state = SSL3_ST_SW_KEY_EXCH_B; | ||
| 1016 | EVP_MD_CTX_cleanup(&md_ctx); | ||
| 1017 | return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); | ||
| 1018 | f_err: | ||
| 1019 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | ||
| 1020 | err: | ||
| 1021 | free(encodedPoint); | ||
| 1022 | BN_CTX_free(bn_ctx); | ||
| 1023 | EVP_MD_CTX_cleanup(&md_ctx); | ||
| 1024 | return (-1); | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | int | ||
| 1028 | dtls1_send_certificate_request(SSL *s) | 703 | dtls1_send_certificate_request(SSL *s) |
| 1029 | { | 704 | { |
| 1030 | unsigned char *p, *d; | 705 | unsigned char *p, *d; |
