diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/s3_clnt.c | 678 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_clnt.c | 678 |
2 files changed, 702 insertions, 654 deletions
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c index 343b0a8cfe..c2f5ea4e07 100644 --- a/src/lib/libssl/s3_clnt.c +++ b/src/lib/libssl/s3_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_clnt.c,v 1.132 2015/09/12 20:23:56 jsing Exp $ */ | 1 | /* $OpenBSD: s3_clnt.c,v 1.133 2015/09/12 20:56:14 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 | * |
@@ -1853,372 +1853,400 @@ ssl3_get_server_done(SSL *s) | |||
1853 | return (ret); | 1853 | return (ret); |
1854 | } | 1854 | } |
1855 | 1855 | ||
1856 | int | 1856 | static int |
1857 | ssl3_send_client_key_exchange(SSL *s) | 1857 | ssl3_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, unsigned char *p, int *outlen) |
1858 | { | 1858 | { |
1859 | unsigned char *p, *q; | 1859 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; |
1860 | int n; | 1860 | EVP_PKEY *pkey = NULL; |
1861 | unsigned long alg_k; | 1861 | unsigned char *q; |
1862 | EVP_PKEY *pkey = NULL; | 1862 | int ret = -1; |
1863 | EC_KEY *clnt_ecdh = NULL; | 1863 | int n; |
1864 | const EC_POINT *srvr_ecpoint = NULL; | 1864 | |
1865 | EVP_PKEY *srvr_pub_pkey = NULL; | 1865 | pkey = X509_get_pubkey(sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); |
1866 | unsigned char *encodedPoint = NULL; | 1866 | if (pkey == NULL || pkey->type != EVP_PKEY_RSA || |
1867 | int encoded_pt_len = 0; | 1867 | pkey->pkey.rsa == NULL) { |
1868 | BN_CTX *bn_ctx = NULL; | 1868 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
1869 | ERR_R_INTERNAL_ERROR); | ||
1870 | goto err; | ||
1871 | } | ||
1869 | 1872 | ||
1870 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) { | 1873 | tmp_buf[0] = s->client_version >> 8; |
1871 | p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); | 1874 | tmp_buf[1] = s->client_version & 0xff; |
1875 | arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); | ||
1872 | 1876 | ||
1873 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; | 1877 | s->session->master_key_length = sizeof(tmp_buf); |
1874 | 1878 | ||
1875 | if (s->session->sess_cert == NULL) { | 1879 | q = p; |
1876 | ssl3_send_alert(s, SSL3_AL_FATAL, | 1880 | p += 2; |
1877 | SSL_AD_UNEXPECTED_MESSAGE); | ||
1878 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1879 | ERR_R_INTERNAL_ERROR); | ||
1880 | goto err; | ||
1881 | } | ||
1882 | 1881 | ||
1883 | if (alg_k & SSL_kRSA) { | 1882 | n = RSA_public_encrypt(sizeof(tmp_buf), tmp_buf, p, pkey->pkey.rsa, |
1884 | RSA *rsa; | 1883 | RSA_PKCS1_PADDING); |
1885 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | 1884 | if (n <= 0) { |
1885 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1886 | SSL_R_BAD_RSA_ENCRYPT); | ||
1887 | goto err; | ||
1888 | } | ||
1886 | 1889 | ||
1887 | pkey = X509_get_pubkey( | 1890 | s2n(n, q); |
1888 | s->session->sess_cert->peer_pkeys[ | 1891 | n += 2; |
1889 | SSL_PKEY_RSA_ENC].x509); | ||
1890 | if ((pkey == NULL) || | ||
1891 | (pkey->type != EVP_PKEY_RSA) || | ||
1892 | (pkey->pkey.rsa == NULL)) { | ||
1893 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1894 | ERR_R_INTERNAL_ERROR); | ||
1895 | EVP_PKEY_free(pkey); | ||
1896 | goto err; | ||
1897 | } | ||
1898 | rsa = pkey->pkey.rsa; | ||
1899 | EVP_PKEY_free(pkey); | ||
1900 | 1892 | ||
1901 | tmp_buf[0] = s->client_version >> 8; | 1893 | s->session->master_key_length = |
1902 | tmp_buf[1] = s->client_version & 0xff; | 1894 | s->method->ssl3_enc->generate_master_secret(s, |
1903 | arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); | 1895 | s->session->master_key, tmp_buf, sizeof(tmp_buf)); |
1904 | 1896 | ||
1905 | s->session->master_key_length = sizeof tmp_buf; | 1897 | *outlen = n; |
1898 | ret = 1; | ||
1906 | 1899 | ||
1907 | q = p; | 1900 | err: |
1908 | /* Fix buf for TLS and beyond */ | 1901 | explicit_bzero(tmp_buf, sizeof(tmp_buf)); |
1909 | p += 2; | 1902 | EVP_PKEY_free(pkey); |
1910 | 1903 | ||
1911 | n = RSA_public_encrypt(sizeof tmp_buf, | 1904 | return (ret); |
1912 | tmp_buf, p, rsa, RSA_PKCS1_PADDING); | 1905 | } |
1913 | if (n <= 0) { | ||
1914 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1915 | SSL_R_BAD_RSA_ENCRYPT); | ||
1916 | goto err; | ||
1917 | } | ||
1918 | 1906 | ||
1919 | /* Fix buf for TLS and beyond */ | 1907 | static int |
1920 | s2n(n, q); | 1908 | ssl3_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, unsigned char *p, int *outlen) |
1921 | n += 2; | 1909 | { |
1910 | DH *dh_srvr = NULL, *dh_clnt = NULL; | ||
1911 | int ret = -1; | ||
1912 | int n; | ||
1913 | |||
1914 | /* Ensure that we have an ephemeral key for DHE. */ | ||
1915 | if (sess_cert->peer_dh_tmp == NULL) { | ||
1916 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); | ||
1917 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1918 | SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
1919 | goto err; | ||
1920 | } | ||
1921 | dh_srvr = sess_cert->peer_dh_tmp; | ||
1922 | 1922 | ||
1923 | s->session->master_key_length = | 1923 | /* Generate a new random key. */ |
1924 | s->method->ssl3_enc->generate_master_secret( | 1924 | if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { |
1925 | s, s->session->master_key, tmp_buf, sizeof tmp_buf); | 1925 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); |
1926 | explicit_bzero(tmp_buf, sizeof tmp_buf); | 1926 | goto err; |
1927 | } else if (alg_k & SSL_kDHE) { | 1927 | } |
1928 | DH *dh_srvr, *dh_clnt; | 1928 | if (!DH_generate_key(dh_clnt)) { |
1929 | 1929 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); | |
1930 | /* Ensure that we have an ephemeral key for DHE. */ | 1930 | goto err; |
1931 | if (s->session->sess_cert->peer_dh_tmp == NULL) { | 1931 | } |
1932 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
1933 | SSL_AD_HANDSHAKE_FAILURE); | ||
1934 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1935 | SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
1936 | goto err; | ||
1937 | } | ||
1938 | dh_srvr = s->session->sess_cert->peer_dh_tmp; | ||
1939 | 1932 | ||
1940 | /* Generate a new random key. */ | 1933 | /* |
1941 | if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { | 1934 | * Use the 'p' output buffer for the DH key, but make sure to clear |
1942 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1935 | * it out afterwards. |
1943 | ERR_R_DH_LIB); | 1936 | */ |
1944 | goto err; | 1937 | n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); |
1945 | } | 1938 | if (n <= 0) { |
1946 | if (!DH_generate_key(dh_clnt)) { | 1939 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); |
1947 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1940 | goto err; |
1948 | ERR_R_DH_LIB); | 1941 | } |
1949 | DH_free(dh_clnt); | ||
1950 | goto err; | ||
1951 | } | ||
1952 | 1942 | ||
1953 | /* | 1943 | /* Generate master key from the result. */ |
1954 | * Use the 'p' output buffer for the DH key, but | 1944 | s->session->master_key_length = |
1955 | * make sure to clear it out afterwards. | 1945 | s->method->ssl3_enc->generate_master_secret(s, |
1956 | */ | 1946 | s->session->master_key, p, n); |
1957 | n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); | ||
1958 | if (n <= 0) { | ||
1959 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1960 | ERR_R_DH_LIB); | ||
1961 | DH_free(dh_clnt); | ||
1962 | goto err; | ||
1963 | } | ||
1964 | 1947 | ||
1965 | /* Generate master key from the result. */ | 1948 | /* Clean up. */ |
1966 | s->session->master_key_length = | 1949 | explicit_bzero(p, n); |
1967 | s->method->ssl3_enc->generate_master_secret(s, | ||
1968 | s->session->master_key, p, n); | ||
1969 | 1950 | ||
1970 | /* Clean up. */ | 1951 | /* Send off the data. */ |
1971 | explicit_bzero(p, n); | 1952 | n = BN_num_bytes(dh_clnt->pub_key); |
1953 | s2n(n, p); | ||
1954 | BN_bn2bin(dh_clnt->pub_key, p); | ||
1955 | n += 2; | ||
1972 | 1956 | ||
1973 | /* Send off the data. */ | 1957 | *outlen = n; |
1974 | n = BN_num_bytes(dh_clnt->pub_key); | 1958 | ret = 1; |
1975 | s2n(n, p); | ||
1976 | BN_bn2bin(dh_clnt->pub_key, p); | ||
1977 | n += 2; | ||
1978 | 1959 | ||
1979 | DH_free(dh_clnt); | 1960 | err: |
1961 | DH_free(dh_clnt); | ||
1980 | 1962 | ||
1981 | /* perhaps clean things up a bit EAY EAY EAY EAY*/ | 1963 | return (ret); |
1982 | } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { | 1964 | } |
1983 | const EC_GROUP *srvr_group = NULL; | ||
1984 | EC_KEY *tkey; | ||
1985 | int field_size = 0; | ||
1986 | |||
1987 | /* Ensure that we have an ephemeral key for ECDHE. */ | ||
1988 | if ((alg_k & SSL_kECDHE) && | ||
1989 | s->session->sess_cert->peer_ecdh_tmp == NULL) { | ||
1990 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
1991 | SSL_AD_HANDSHAKE_FAILURE); | ||
1992 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1993 | ERR_R_INTERNAL_ERROR); | ||
1994 | goto err; | ||
1995 | } | ||
1996 | tkey = s->session->sess_cert->peer_ecdh_tmp; | ||
1997 | |||
1998 | if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { | ||
1999 | /* Get the Server Public Key from Cert */ | ||
2000 | srvr_pub_pkey = X509_get_pubkey(s->session-> \ | ||
2001 | sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); | ||
2002 | if (srvr_pub_pkey != NULL && | ||
2003 | srvr_pub_pkey->type == EVP_PKEY_EC) | ||
2004 | tkey = srvr_pub_pkey->pkey.ec; | ||
2005 | } | ||
2006 | 1965 | ||
2007 | if (tkey == NULL) { | 1966 | static int |
2008 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1967 | ssl3_client_kex_ecdh(SSL *s, SESS_CERT *sess_cert, unsigned char *p, |
2009 | ERR_R_INTERNAL_ERROR); | 1968 | int *outlen) |
2010 | goto err; | 1969 | { |
2011 | } | 1970 | EC_KEY *clnt_ecdh = NULL; |
1971 | const EC_GROUP *srvr_group = NULL; | ||
1972 | const EC_POINT *srvr_ecpoint = NULL; | ||
1973 | EVP_PKEY *srvr_pub_pkey = NULL; | ||
1974 | BN_CTX *bn_ctx = NULL; | ||
1975 | unsigned char *encodedPoint = NULL; | ||
1976 | unsigned long alg_k; | ||
1977 | int encoded_pt_len = 0; | ||
1978 | int field_size = 0; | ||
1979 | EC_KEY *tkey; | ||
1980 | int ret = -1; | ||
1981 | int n; | ||
2012 | 1982 | ||
2013 | srvr_group = EC_KEY_get0_group(tkey); | 1983 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; |
2014 | srvr_ecpoint = EC_KEY_get0_public_key(tkey); | ||
2015 | 1984 | ||
2016 | if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { | 1985 | /* Ensure that we have an ephemeral key for ECDHE. */ |
2017 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1986 | if ((alg_k & SSL_kECDHE) && sess_cert->peer_ecdh_tmp == NULL) { |
2018 | ERR_R_INTERNAL_ERROR); | 1987 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); |
2019 | goto err; | 1988 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2020 | } | 1989 | ERR_R_INTERNAL_ERROR); |
1990 | goto err; | ||
1991 | } | ||
1992 | tkey = sess_cert->peer_ecdh_tmp; | ||
1993 | |||
1994 | if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { | ||
1995 | /* Get the Server Public Key from certificate. */ | ||
1996 | srvr_pub_pkey = X509_get_pubkey( | ||
1997 | sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); | ||
1998 | if (srvr_pub_pkey != NULL && srvr_pub_pkey->type == EVP_PKEY_EC) | ||
1999 | tkey = srvr_pub_pkey->pkey.ec; | ||
2000 | } | ||
2021 | 2001 | ||
2022 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { | 2002 | if (tkey == NULL) { |
2023 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2003 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2024 | ERR_R_MALLOC_FAILURE); | 2004 | ERR_R_INTERNAL_ERROR); |
2025 | goto err; | 2005 | goto err; |
2026 | } | 2006 | } |
2027 | 2007 | ||
2028 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { | 2008 | srvr_group = EC_KEY_get0_group(tkey); |
2029 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2009 | srvr_ecpoint = EC_KEY_get0_public_key(tkey); |
2030 | ERR_R_EC_LIB); | ||
2031 | goto err; | ||
2032 | } | ||
2033 | 2010 | ||
2034 | /* Generate a new ECDH key pair */ | 2011 | if (srvr_group == NULL || srvr_ecpoint == NULL) { |
2035 | if (!(EC_KEY_generate_key(clnt_ecdh))) { | 2012 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2036 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2013 | ERR_R_INTERNAL_ERROR); |
2037 | ERR_R_ECDH_LIB); | 2014 | goto err; |
2038 | goto err; | 2015 | } |
2039 | } | ||
2040 | 2016 | ||
2041 | /* | 2017 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { |
2042 | * Use the 'p' output buffer for the ECDH key, but | 2018 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2043 | * make sure to clear it out afterwards. | 2019 | ERR_R_MALLOC_FAILURE); |
2044 | */ | 2020 | goto err; |
2045 | field_size = EC_GROUP_get_degree(srvr_group); | 2021 | } |
2046 | if (field_size <= 0) { | ||
2047 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2048 | ERR_R_ECDH_LIB); | ||
2049 | goto err; | ||
2050 | } | ||
2051 | n = ECDH_compute_key(p, (field_size + 7) / 8, | ||
2052 | srvr_ecpoint, clnt_ecdh, NULL); | ||
2053 | if (n <= 0) { | ||
2054 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2055 | ERR_R_ECDH_LIB); | ||
2056 | goto err; | ||
2057 | } | ||
2058 | 2022 | ||
2059 | /* generate master key from the result */ | 2023 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { |
2060 | s->session->master_key_length = | 2024 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); |
2061 | s->method->ssl3_enc->generate_master_secret(s, | 2025 | goto err; |
2062 | s->session->master_key, p, n); | 2026 | } |
2063 | 2027 | ||
2064 | /* Clean up. */ | 2028 | /* Generate a new ECDH key pair */ |
2065 | explicit_bzero(p, n); | 2029 | if (!(EC_KEY_generate_key(clnt_ecdh))) { |
2030 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
2031 | goto err; | ||
2032 | } | ||
2066 | 2033 | ||
2067 | /* | 2034 | /* |
2068 | * First check the size of encoding and | 2035 | * Use the 'p' output buffer for the ECDH key, but make sure to clear |
2069 | * allocate memory accordingly. | 2036 | * it out afterwards. |
2070 | */ | 2037 | */ |
2071 | encoded_pt_len = EC_POINT_point2oct(srvr_group, | 2038 | field_size = EC_GROUP_get_degree(srvr_group); |
2072 | EC_KEY_get0_public_key(clnt_ecdh), | 2039 | if (field_size <= 0) { |
2073 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | 2040 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); |
2041 | goto err; | ||
2042 | } | ||
2043 | n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, clnt_ecdh, | ||
2044 | NULL); | ||
2045 | if (n <= 0) { | ||
2046 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
2047 | goto err; | ||
2048 | } | ||
2074 | 2049 | ||
2075 | encodedPoint = malloc(encoded_pt_len); | 2050 | /* Generate master key from the result. */ |
2051 | s->session->master_key_length = | ||
2052 | s->method->ssl3_enc->generate_master_secret(s, | ||
2053 | s->session->master_key, p, n); | ||
2076 | 2054 | ||
2077 | bn_ctx = BN_CTX_new(); | 2055 | /* Clean up. */ |
2078 | if ((encodedPoint == NULL) || (bn_ctx == NULL)) { | 2056 | explicit_bzero(p, n); |
2079 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2080 | ERR_R_MALLOC_FAILURE); | ||
2081 | goto err; | ||
2082 | } | ||
2083 | 2057 | ||
2084 | /* Encode the public key */ | 2058 | /* |
2085 | n = EC_POINT_point2oct(srvr_group, | 2059 | * First check the size of encoding and allocate memory accordingly. |
2086 | EC_KEY_get0_public_key(clnt_ecdh), | 2060 | */ |
2087 | POINT_CONVERSION_UNCOMPRESSED, encodedPoint, | 2061 | encoded_pt_len = EC_POINT_point2oct(srvr_group, |
2088 | encoded_pt_len, bn_ctx); | 2062 | EC_KEY_get0_public_key(clnt_ecdh), |
2089 | 2063 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | |
2090 | *p = n; /* length of encoded point */ | 2064 | |
2091 | /* Encoded point will be copied here */ | 2065 | bn_ctx = BN_CTX_new(); |
2092 | p += 1; | 2066 | encodedPoint = malloc(encoded_pt_len); |
2093 | 2067 | if (encodedPoint == NULL || bn_ctx == NULL) { | |
2094 | /* copy the point */ | 2068 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2095 | memcpy((unsigned char *)p, encodedPoint, n); | 2069 | ERR_R_MALLOC_FAILURE); |
2096 | /* increment n to account for length field */ | 2070 | goto err; |
2097 | n += 1; | 2071 | } |
2098 | |||
2099 | /* Free allocated memory */ | ||
2100 | BN_CTX_free(bn_ctx); | ||
2101 | free(encodedPoint); | ||
2102 | EC_KEY_free(clnt_ecdh); | ||
2103 | EVP_PKEY_free(srvr_pub_pkey); | ||
2104 | } else if (alg_k & SSL_kGOST) { | ||
2105 | /* GOST key exchange message creation */ | ||
2106 | EVP_PKEY_CTX *pkey_ctx; | ||
2107 | X509 *peer_cert; | ||
2108 | |||
2109 | size_t msglen; | ||
2110 | unsigned int md_len; | ||
2111 | unsigned char premaster_secret[32], shared_ukm[32], | ||
2112 | tmp[256]; | ||
2113 | EVP_MD_CTX *ukm_hash; | ||
2114 | EVP_PKEY *pub_key; | ||
2115 | int nid; | ||
2116 | 2072 | ||
2117 | /* Get server sertificate PKEY and create ctx from it */ | 2073 | /* Encode the public key */ |
2118 | peer_cert = s->session->sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509; | 2074 | n = EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh), |
2119 | if (!peer_cert) { | 2075 | POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encoded_pt_len, |
2120 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2076 | bn_ctx); |
2121 | SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); | ||
2122 | goto err; | ||
2123 | } | ||
2124 | 2077 | ||
2125 | pub_key = X509_get_pubkey(peer_cert); | 2078 | *p = n; /* length of encoded point */ |
2126 | pkey_ctx = EVP_PKEY_CTX_new(pub_key, NULL); | 2079 | /* Encoded point will be copied here */ |
2080 | p += 1; | ||
2127 | 2081 | ||
2128 | /* | 2082 | /* copy the point */ |
2129 | * If we have send a certificate, and certificate key | 2083 | memcpy((unsigned char *)p, encodedPoint, n); |
2130 | * parameters match those of server certificate, use | 2084 | /* increment n to account for length field */ |
2131 | * certificate key for key exchange. | 2085 | n += 1; |
2132 | * Otherwise, generate ephemeral key pair. | ||
2133 | */ | ||
2134 | EVP_PKEY_encrypt_init(pkey_ctx); | ||
2135 | 2086 | ||
2136 | /* Generate session key. */ | 2087 | *outlen = n; |
2137 | arc4random_buf(premaster_secret, 32); | 2088 | ret = 1; |
2138 | 2089 | ||
2139 | /* | 2090 | err: |
2140 | * If we have client certificate, use its secret as | 2091 | /* Free allocated memory */ |
2141 | * peer key. | 2092 | BN_CTX_free(bn_ctx); |
2142 | */ | 2093 | free(encodedPoint); |
2143 | if (s->s3->tmp.cert_req && s->cert->key->privatekey) { | 2094 | EC_KEY_free(clnt_ecdh); |
2144 | if (EVP_PKEY_derive_set_peer(pkey_ctx, | 2095 | EVP_PKEY_free(srvr_pub_pkey); |
2145 | s->cert->key->privatekey) <=0) { | 2096 | |
2146 | /* | 2097 | return (ret); |
2147 | * If there was an error - just ignore | 2098 | } |
2148 | * it. Ephemeral key would be used. | 2099 | |
2149 | */ | 2100 | static int |
2150 | ERR_clear_error(); | 2101 | ssl3_client_kex_gost(SSL *s, SESS_CERT *sess_cert, unsigned char *p, |
2151 | } | 2102 | int *outlen) |
2152 | } | 2103 | { |
2104 | unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; | ||
2105 | EVP_PKEY *pub_key = NULL; | ||
2106 | EVP_PKEY_CTX *pkey_ctx; | ||
2107 | X509 *peer_cert; | ||
2108 | size_t msglen; | ||
2109 | unsigned int md_len; | ||
2110 | EVP_MD_CTX *ukm_hash; | ||
2111 | int ret = -1; | ||
2112 | int nid; | ||
2113 | int n; | ||
2114 | |||
2115 | /* Get server sertificate PKEY and create ctx from it */ | ||
2116 | peer_cert = sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509; | ||
2117 | if (peer_cert == NULL) { | ||
2118 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2119 | SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); | ||
2120 | goto err; | ||
2121 | } | ||
2122 | |||
2123 | pub_key = X509_get_pubkey(peer_cert); | ||
2124 | pkey_ctx = EVP_PKEY_CTX_new(pub_key, NULL); | ||
2125 | |||
2126 | /* | ||
2127 | * If we have send a certificate, and certificate key parameters match | ||
2128 | * those of server certificate, use certificate key for key exchange. | ||
2129 | * Otherwise, generate ephemeral key pair. | ||
2130 | */ | ||
2131 | EVP_PKEY_encrypt_init(pkey_ctx); | ||
2132 | |||
2133 | /* Generate session key. */ | ||
2134 | arc4random_buf(premaster_secret, 32); | ||
2153 | 2135 | ||
2136 | /* | ||
2137 | * If we have client certificate, use its secret as peer key. | ||
2138 | */ | ||
2139 | if (s->s3->tmp.cert_req && s->cert->key->privatekey) { | ||
2140 | if (EVP_PKEY_derive_set_peer(pkey_ctx, | ||
2141 | s->cert->key->privatekey) <=0) { | ||
2154 | /* | 2142 | /* |
2155 | * Compute shared IV and store it in algorithm-specific | 2143 | * If there was an error - just ignore it. |
2156 | * context data. | 2144 | * Ephemeral key would be used. |
2157 | */ | 2145 | */ |
2158 | ukm_hash = EVP_MD_CTX_create(); | 2146 | ERR_clear_error(); |
2159 | if (ukm_hash == NULL) { | 2147 | } |
2160 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2148 | } |
2161 | ERR_R_MALLOC_FAILURE); | ||
2162 | explicit_bzero(premaster_secret, | ||
2163 | sizeof(premaster_secret)); | ||
2164 | goto err; | ||
2165 | } | ||
2166 | 2149 | ||
2167 | if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94) | 2150 | /* |
2168 | nid = NID_id_GostR3411_94; | 2151 | * Compute shared IV and store it in algorithm-specific context data. |
2169 | else | 2152 | */ |
2170 | nid = NID_id_tc26_gost3411_2012_256; | 2153 | ukm_hash = EVP_MD_CTX_create(); |
2171 | if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid))) | 2154 | if (ukm_hash == NULL) { |
2155 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2156 | ERR_R_MALLOC_FAILURE); | ||
2157 | goto err; | ||
2158 | } | ||
2159 | |||
2160 | if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94) | ||
2161 | nid = NID_id_GostR3411_94; | ||
2162 | else | ||
2163 | nid = NID_id_tc26_gost3411_2012_256; | ||
2164 | if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid))) | ||
2165 | goto err; | ||
2166 | EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE); | ||
2167 | EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE); | ||
2168 | EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len); | ||
2169 | EVP_MD_CTX_destroy(ukm_hash); | ||
2170 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, | ||
2171 | EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { | ||
2172 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); | ||
2173 | goto err; | ||
2174 | } | ||
2175 | |||
2176 | /* | ||
2177 | * Make GOST keytransport blob message, encapsulate it into sequence. | ||
2178 | */ | ||
2179 | *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; | ||
2180 | msglen = 255; | ||
2181 | if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, | ||
2182 | 32) < 0) { | ||
2183 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); | ||
2184 | goto err; | ||
2185 | } | ||
2186 | if (msglen >= 0x80) { | ||
2187 | *(p++) = 0x81; | ||
2188 | *(p++) = msglen & 0xff; | ||
2189 | n = msglen + 3; | ||
2190 | } else { | ||
2191 | *(p++) = msglen & 0xff; | ||
2192 | n = msglen + 2; | ||
2193 | } | ||
2194 | memcpy(p, tmp, msglen); | ||
2195 | |||
2196 | /* Check if pubkey from client certificate was used. */ | ||
2197 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, | ||
2198 | NULL) > 0) { | ||
2199 | /* Set flag "skip certificate verify". */ | ||
2200 | s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; | ||
2201 | } | ||
2202 | EVP_PKEY_CTX_free(pkey_ctx); | ||
2203 | s->session->master_key_length = | ||
2204 | s->method->ssl3_enc->generate_master_secret(s, | ||
2205 | s->session->master_key, premaster_secret, 32); | ||
2206 | |||
2207 | *outlen = n; | ||
2208 | ret = 1; | ||
2209 | |||
2210 | err: | ||
2211 | explicit_bzero(premaster_secret, sizeof(premaster_secret)); | ||
2212 | EVP_PKEY_free(pub_key); | ||
2213 | |||
2214 | return (ret); | ||
2215 | } | ||
2216 | |||
2217 | int | ||
2218 | ssl3_send_client_key_exchange(SSL *s) | ||
2219 | { | ||
2220 | SESS_CERT *sess_cert; | ||
2221 | unsigned long alg_k; | ||
2222 | unsigned char *p; | ||
2223 | int n; | ||
2224 | |||
2225 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) { | ||
2226 | p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); | ||
2227 | |||
2228 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; | ||
2229 | |||
2230 | if ((sess_cert = s->session->sess_cert) == NULL) { | ||
2231 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
2232 | SSL_AD_UNEXPECTED_MESSAGE); | ||
2233 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2234 | ERR_R_INTERNAL_ERROR); | ||
2235 | goto err; | ||
2236 | } | ||
2237 | |||
2238 | if (alg_k & SSL_kRSA) { | ||
2239 | if (ssl3_client_kex_rsa(s, sess_cert, p, &n) != 1) | ||
2172 | goto err; | 2240 | goto err; |
2173 | EVP_DigestUpdate(ukm_hash, | 2241 | } else if (alg_k & SSL_kDHE) { |
2174 | s->s3->client_random, SSL3_RANDOM_SIZE); | 2242 | if (ssl3_client_kex_dhe(s, sess_cert, p, &n) != 1) |
2175 | EVP_DigestUpdate(ukm_hash, | ||
2176 | s->s3->server_random, SSL3_RANDOM_SIZE); | ||
2177 | EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len); | ||
2178 | EVP_MD_CTX_destroy(ukm_hash); | ||
2179 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, | ||
2180 | EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { | ||
2181 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2182 | SSL_R_LIBRARY_BUG); | ||
2183 | explicit_bzero(premaster_secret, | ||
2184 | sizeof(premaster_secret)); | ||
2185 | goto err; | 2243 | goto err; |
2186 | } | 2244 | } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { |
2187 | 2245 | if (ssl3_client_kex_ecdh(s, sess_cert, p, &n) != 1) | |
2188 | /* | 2246 | goto err; |
2189 | * Make GOST keytransport blob message, encapsulate it | 2247 | } else if (alg_k & SSL_kGOST) { |
2190 | * into sequence. | 2248 | if (ssl3_client_kex_gost(s, sess_cert, p, &n) != 1) |
2191 | */ | ||
2192 | *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; | ||
2193 | msglen = 255; | ||
2194 | if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, | ||
2195 | premaster_secret, 32) < 0) { | ||
2196 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2197 | SSL_R_LIBRARY_BUG); | ||
2198 | goto err; | 2249 | goto err; |
2199 | } | ||
2200 | if (msglen >= 0x80) { | ||
2201 | *(p++) = 0x81; | ||
2202 | *(p++) = msglen & 0xff; | ||
2203 | n = msglen + 3; | ||
2204 | } else { | ||
2205 | *(p++) = msglen & 0xff; | ||
2206 | n = msglen + 2; | ||
2207 | } | ||
2208 | memcpy(p, tmp, msglen); | ||
2209 | /* Check if pubkey from client certificate was used. */ | ||
2210 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, | ||
2211 | EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) { | ||
2212 | /* Set flag "skip certificate verify". */ | ||
2213 | s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; | ||
2214 | } | ||
2215 | EVP_PKEY_CTX_free(pkey_ctx); | ||
2216 | s->session->master_key_length = | ||
2217 | s->method->ssl3_enc->generate_master_secret(s, | ||
2218 | s->session->master_key, premaster_secret, 32); | ||
2219 | EVP_PKEY_free(pub_key); | ||
2220 | explicit_bzero(premaster_secret, | ||
2221 | sizeof(premaster_secret)); | ||
2222 | } else { | 2250 | } else { |
2223 | ssl3_send_alert(s, SSL3_AL_FATAL, | 2251 | ssl3_send_alert(s, SSL3_AL_FATAL, |
2224 | SSL_AD_HANDSHAKE_FAILURE); | 2252 | SSL_AD_HANDSHAKE_FAILURE); |
@@ -2236,10 +2264,6 @@ ssl3_send_client_key_exchange(SSL *s) | |||
2236 | return (ssl3_handshake_write(s)); | 2264 | return (ssl3_handshake_write(s)); |
2237 | 2265 | ||
2238 | err: | 2266 | err: |
2239 | BN_CTX_free(bn_ctx); | ||
2240 | free(encodedPoint); | ||
2241 | EC_KEY_free(clnt_ecdh); | ||
2242 | EVP_PKEY_free(srvr_pub_pkey); | ||
2243 | return (-1); | 2267 | return (-1); |
2244 | } | 2268 | } |
2245 | 2269 | ||
diff --git a/src/lib/libssl/src/ssl/s3_clnt.c b/src/lib/libssl/src/ssl/s3_clnt.c index 343b0a8cfe..c2f5ea4e07 100644 --- a/src/lib/libssl/src/ssl/s3_clnt.c +++ b/src/lib/libssl/src/ssl/s3_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: s3_clnt.c,v 1.132 2015/09/12 20:23:56 jsing Exp $ */ | 1 | /* $OpenBSD: s3_clnt.c,v 1.133 2015/09/12 20:56:14 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 | * |
@@ -1853,372 +1853,400 @@ ssl3_get_server_done(SSL *s) | |||
1853 | return (ret); | 1853 | return (ret); |
1854 | } | 1854 | } |
1855 | 1855 | ||
1856 | int | 1856 | static int |
1857 | ssl3_send_client_key_exchange(SSL *s) | 1857 | ssl3_client_kex_rsa(SSL *s, SESS_CERT *sess_cert, unsigned char *p, int *outlen) |
1858 | { | 1858 | { |
1859 | unsigned char *p, *q; | 1859 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; |
1860 | int n; | 1860 | EVP_PKEY *pkey = NULL; |
1861 | unsigned long alg_k; | 1861 | unsigned char *q; |
1862 | EVP_PKEY *pkey = NULL; | 1862 | int ret = -1; |
1863 | EC_KEY *clnt_ecdh = NULL; | 1863 | int n; |
1864 | const EC_POINT *srvr_ecpoint = NULL; | 1864 | |
1865 | EVP_PKEY *srvr_pub_pkey = NULL; | 1865 | pkey = X509_get_pubkey(sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); |
1866 | unsigned char *encodedPoint = NULL; | 1866 | if (pkey == NULL || pkey->type != EVP_PKEY_RSA || |
1867 | int encoded_pt_len = 0; | 1867 | pkey->pkey.rsa == NULL) { |
1868 | BN_CTX *bn_ctx = NULL; | 1868 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
1869 | ERR_R_INTERNAL_ERROR); | ||
1870 | goto err; | ||
1871 | } | ||
1869 | 1872 | ||
1870 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) { | 1873 | tmp_buf[0] = s->client_version >> 8; |
1871 | p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); | 1874 | tmp_buf[1] = s->client_version & 0xff; |
1875 | arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); | ||
1872 | 1876 | ||
1873 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; | 1877 | s->session->master_key_length = sizeof(tmp_buf); |
1874 | 1878 | ||
1875 | if (s->session->sess_cert == NULL) { | 1879 | q = p; |
1876 | ssl3_send_alert(s, SSL3_AL_FATAL, | 1880 | p += 2; |
1877 | SSL_AD_UNEXPECTED_MESSAGE); | ||
1878 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1879 | ERR_R_INTERNAL_ERROR); | ||
1880 | goto err; | ||
1881 | } | ||
1882 | 1881 | ||
1883 | if (alg_k & SSL_kRSA) { | 1882 | n = RSA_public_encrypt(sizeof(tmp_buf), tmp_buf, p, pkey->pkey.rsa, |
1884 | RSA *rsa; | 1883 | RSA_PKCS1_PADDING); |
1885 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | 1884 | if (n <= 0) { |
1885 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1886 | SSL_R_BAD_RSA_ENCRYPT); | ||
1887 | goto err; | ||
1888 | } | ||
1886 | 1889 | ||
1887 | pkey = X509_get_pubkey( | 1890 | s2n(n, q); |
1888 | s->session->sess_cert->peer_pkeys[ | 1891 | n += 2; |
1889 | SSL_PKEY_RSA_ENC].x509); | ||
1890 | if ((pkey == NULL) || | ||
1891 | (pkey->type != EVP_PKEY_RSA) || | ||
1892 | (pkey->pkey.rsa == NULL)) { | ||
1893 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1894 | ERR_R_INTERNAL_ERROR); | ||
1895 | EVP_PKEY_free(pkey); | ||
1896 | goto err; | ||
1897 | } | ||
1898 | rsa = pkey->pkey.rsa; | ||
1899 | EVP_PKEY_free(pkey); | ||
1900 | 1892 | ||
1901 | tmp_buf[0] = s->client_version >> 8; | 1893 | s->session->master_key_length = |
1902 | tmp_buf[1] = s->client_version & 0xff; | 1894 | s->method->ssl3_enc->generate_master_secret(s, |
1903 | arc4random_buf(&tmp_buf[2], sizeof(tmp_buf) - 2); | 1895 | s->session->master_key, tmp_buf, sizeof(tmp_buf)); |
1904 | 1896 | ||
1905 | s->session->master_key_length = sizeof tmp_buf; | 1897 | *outlen = n; |
1898 | ret = 1; | ||
1906 | 1899 | ||
1907 | q = p; | 1900 | err: |
1908 | /* Fix buf for TLS and beyond */ | 1901 | explicit_bzero(tmp_buf, sizeof(tmp_buf)); |
1909 | p += 2; | 1902 | EVP_PKEY_free(pkey); |
1910 | 1903 | ||
1911 | n = RSA_public_encrypt(sizeof tmp_buf, | 1904 | return (ret); |
1912 | tmp_buf, p, rsa, RSA_PKCS1_PADDING); | 1905 | } |
1913 | if (n <= 0) { | ||
1914 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1915 | SSL_R_BAD_RSA_ENCRYPT); | ||
1916 | goto err; | ||
1917 | } | ||
1918 | 1906 | ||
1919 | /* Fix buf for TLS and beyond */ | 1907 | static int |
1920 | s2n(n, q); | 1908 | ssl3_client_kex_dhe(SSL *s, SESS_CERT *sess_cert, unsigned char *p, int *outlen) |
1921 | n += 2; | 1909 | { |
1910 | DH *dh_srvr = NULL, *dh_clnt = NULL; | ||
1911 | int ret = -1; | ||
1912 | int n; | ||
1913 | |||
1914 | /* Ensure that we have an ephemeral key for DHE. */ | ||
1915 | if (sess_cert->peer_dh_tmp == NULL) { | ||
1916 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); | ||
1917 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1918 | SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
1919 | goto err; | ||
1920 | } | ||
1921 | dh_srvr = sess_cert->peer_dh_tmp; | ||
1922 | 1922 | ||
1923 | s->session->master_key_length = | 1923 | /* Generate a new random key. */ |
1924 | s->method->ssl3_enc->generate_master_secret( | 1924 | if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { |
1925 | s, s->session->master_key, tmp_buf, sizeof tmp_buf); | 1925 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); |
1926 | explicit_bzero(tmp_buf, sizeof tmp_buf); | 1926 | goto err; |
1927 | } else if (alg_k & SSL_kDHE) { | 1927 | } |
1928 | DH *dh_srvr, *dh_clnt; | 1928 | if (!DH_generate_key(dh_clnt)) { |
1929 | 1929 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); | |
1930 | /* Ensure that we have an ephemeral key for DHE. */ | 1930 | goto err; |
1931 | if (s->session->sess_cert->peer_dh_tmp == NULL) { | 1931 | } |
1932 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
1933 | SSL_AD_HANDSHAKE_FAILURE); | ||
1934 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1935 | SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
1936 | goto err; | ||
1937 | } | ||
1938 | dh_srvr = s->session->sess_cert->peer_dh_tmp; | ||
1939 | 1932 | ||
1940 | /* Generate a new random key. */ | 1933 | /* |
1941 | if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { | 1934 | * Use the 'p' output buffer for the DH key, but make sure to clear |
1942 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1935 | * it out afterwards. |
1943 | ERR_R_DH_LIB); | 1936 | */ |
1944 | goto err; | 1937 | n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); |
1945 | } | 1938 | if (n <= 0) { |
1946 | if (!DH_generate_key(dh_clnt)) { | 1939 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); |
1947 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1940 | goto err; |
1948 | ERR_R_DH_LIB); | 1941 | } |
1949 | DH_free(dh_clnt); | ||
1950 | goto err; | ||
1951 | } | ||
1952 | 1942 | ||
1953 | /* | 1943 | /* Generate master key from the result. */ |
1954 | * Use the 'p' output buffer for the DH key, but | 1944 | s->session->master_key_length = |
1955 | * make sure to clear it out afterwards. | 1945 | s->method->ssl3_enc->generate_master_secret(s, |
1956 | */ | 1946 | s->session->master_key, p, n); |
1957 | n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); | ||
1958 | if (n <= 0) { | ||
1959 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1960 | ERR_R_DH_LIB); | ||
1961 | DH_free(dh_clnt); | ||
1962 | goto err; | ||
1963 | } | ||
1964 | 1947 | ||
1965 | /* Generate master key from the result. */ | 1948 | /* Clean up. */ |
1966 | s->session->master_key_length = | 1949 | explicit_bzero(p, n); |
1967 | s->method->ssl3_enc->generate_master_secret(s, | ||
1968 | s->session->master_key, p, n); | ||
1969 | 1950 | ||
1970 | /* Clean up. */ | 1951 | /* Send off the data. */ |
1971 | explicit_bzero(p, n); | 1952 | n = BN_num_bytes(dh_clnt->pub_key); |
1953 | s2n(n, p); | ||
1954 | BN_bn2bin(dh_clnt->pub_key, p); | ||
1955 | n += 2; | ||
1972 | 1956 | ||
1973 | /* Send off the data. */ | 1957 | *outlen = n; |
1974 | n = BN_num_bytes(dh_clnt->pub_key); | 1958 | ret = 1; |
1975 | s2n(n, p); | ||
1976 | BN_bn2bin(dh_clnt->pub_key, p); | ||
1977 | n += 2; | ||
1978 | 1959 | ||
1979 | DH_free(dh_clnt); | 1960 | err: |
1961 | DH_free(dh_clnt); | ||
1980 | 1962 | ||
1981 | /* perhaps clean things up a bit EAY EAY EAY EAY*/ | 1963 | return (ret); |
1982 | } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { | 1964 | } |
1983 | const EC_GROUP *srvr_group = NULL; | ||
1984 | EC_KEY *tkey; | ||
1985 | int field_size = 0; | ||
1986 | |||
1987 | /* Ensure that we have an ephemeral key for ECDHE. */ | ||
1988 | if ((alg_k & SSL_kECDHE) && | ||
1989 | s->session->sess_cert->peer_ecdh_tmp == NULL) { | ||
1990 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
1991 | SSL_AD_HANDSHAKE_FAILURE); | ||
1992 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
1993 | ERR_R_INTERNAL_ERROR); | ||
1994 | goto err; | ||
1995 | } | ||
1996 | tkey = s->session->sess_cert->peer_ecdh_tmp; | ||
1997 | |||
1998 | if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { | ||
1999 | /* Get the Server Public Key from Cert */ | ||
2000 | srvr_pub_pkey = X509_get_pubkey(s->session-> \ | ||
2001 | sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); | ||
2002 | if (srvr_pub_pkey != NULL && | ||
2003 | srvr_pub_pkey->type == EVP_PKEY_EC) | ||
2004 | tkey = srvr_pub_pkey->pkey.ec; | ||
2005 | } | ||
2006 | 1965 | ||
2007 | if (tkey == NULL) { | 1966 | static int |
2008 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1967 | ssl3_client_kex_ecdh(SSL *s, SESS_CERT *sess_cert, unsigned char *p, |
2009 | ERR_R_INTERNAL_ERROR); | 1968 | int *outlen) |
2010 | goto err; | 1969 | { |
2011 | } | 1970 | EC_KEY *clnt_ecdh = NULL; |
1971 | const EC_GROUP *srvr_group = NULL; | ||
1972 | const EC_POINT *srvr_ecpoint = NULL; | ||
1973 | EVP_PKEY *srvr_pub_pkey = NULL; | ||
1974 | BN_CTX *bn_ctx = NULL; | ||
1975 | unsigned char *encodedPoint = NULL; | ||
1976 | unsigned long alg_k; | ||
1977 | int encoded_pt_len = 0; | ||
1978 | int field_size = 0; | ||
1979 | EC_KEY *tkey; | ||
1980 | int ret = -1; | ||
1981 | int n; | ||
2012 | 1982 | ||
2013 | srvr_group = EC_KEY_get0_group(tkey); | 1983 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; |
2014 | srvr_ecpoint = EC_KEY_get0_public_key(tkey); | ||
2015 | 1984 | ||
2016 | if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { | 1985 | /* Ensure that we have an ephemeral key for ECDHE. */ |
2017 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 1986 | if ((alg_k & SSL_kECDHE) && sess_cert->peer_ecdh_tmp == NULL) { |
2018 | ERR_R_INTERNAL_ERROR); | 1987 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); |
2019 | goto err; | 1988 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2020 | } | 1989 | ERR_R_INTERNAL_ERROR); |
1990 | goto err; | ||
1991 | } | ||
1992 | tkey = sess_cert->peer_ecdh_tmp; | ||
1993 | |||
1994 | if (alg_k & (SSL_kECDHr|SSL_kECDHe)) { | ||
1995 | /* Get the Server Public Key from certificate. */ | ||
1996 | srvr_pub_pkey = X509_get_pubkey( | ||
1997 | sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); | ||
1998 | if (srvr_pub_pkey != NULL && srvr_pub_pkey->type == EVP_PKEY_EC) | ||
1999 | tkey = srvr_pub_pkey->pkey.ec; | ||
2000 | } | ||
2021 | 2001 | ||
2022 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { | 2002 | if (tkey == NULL) { |
2023 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2003 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2024 | ERR_R_MALLOC_FAILURE); | 2004 | ERR_R_INTERNAL_ERROR); |
2025 | goto err; | 2005 | goto err; |
2026 | } | 2006 | } |
2027 | 2007 | ||
2028 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { | 2008 | srvr_group = EC_KEY_get0_group(tkey); |
2029 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2009 | srvr_ecpoint = EC_KEY_get0_public_key(tkey); |
2030 | ERR_R_EC_LIB); | ||
2031 | goto err; | ||
2032 | } | ||
2033 | 2010 | ||
2034 | /* Generate a new ECDH key pair */ | 2011 | if (srvr_group == NULL || srvr_ecpoint == NULL) { |
2035 | if (!(EC_KEY_generate_key(clnt_ecdh))) { | 2012 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2036 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2013 | ERR_R_INTERNAL_ERROR); |
2037 | ERR_R_ECDH_LIB); | 2014 | goto err; |
2038 | goto err; | 2015 | } |
2039 | } | ||
2040 | 2016 | ||
2041 | /* | 2017 | if ((clnt_ecdh = EC_KEY_new()) == NULL) { |
2042 | * Use the 'p' output buffer for the ECDH key, but | 2018 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2043 | * make sure to clear it out afterwards. | 2019 | ERR_R_MALLOC_FAILURE); |
2044 | */ | 2020 | goto err; |
2045 | field_size = EC_GROUP_get_degree(srvr_group); | 2021 | } |
2046 | if (field_size <= 0) { | ||
2047 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2048 | ERR_R_ECDH_LIB); | ||
2049 | goto err; | ||
2050 | } | ||
2051 | n = ECDH_compute_key(p, (field_size + 7) / 8, | ||
2052 | srvr_ecpoint, clnt_ecdh, NULL); | ||
2053 | if (n <= 0) { | ||
2054 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2055 | ERR_R_ECDH_LIB); | ||
2056 | goto err; | ||
2057 | } | ||
2058 | 2022 | ||
2059 | /* generate master key from the result */ | 2023 | if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { |
2060 | s->session->master_key_length = | 2024 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); |
2061 | s->method->ssl3_enc->generate_master_secret(s, | 2025 | goto err; |
2062 | s->session->master_key, p, n); | 2026 | } |
2063 | 2027 | ||
2064 | /* Clean up. */ | 2028 | /* Generate a new ECDH key pair */ |
2065 | explicit_bzero(p, n); | 2029 | if (!(EC_KEY_generate_key(clnt_ecdh))) { |
2030 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
2031 | goto err; | ||
2032 | } | ||
2066 | 2033 | ||
2067 | /* | 2034 | /* |
2068 | * First check the size of encoding and | 2035 | * Use the 'p' output buffer for the ECDH key, but make sure to clear |
2069 | * allocate memory accordingly. | 2036 | * it out afterwards. |
2070 | */ | 2037 | */ |
2071 | encoded_pt_len = EC_POINT_point2oct(srvr_group, | 2038 | field_size = EC_GROUP_get_degree(srvr_group); |
2072 | EC_KEY_get0_public_key(clnt_ecdh), | 2039 | if (field_size <= 0) { |
2073 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | 2040 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); |
2041 | goto err; | ||
2042 | } | ||
2043 | n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, clnt_ecdh, | ||
2044 | NULL); | ||
2045 | if (n <= 0) { | ||
2046 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); | ||
2047 | goto err; | ||
2048 | } | ||
2074 | 2049 | ||
2075 | encodedPoint = malloc(encoded_pt_len); | 2050 | /* Generate master key from the result. */ |
2051 | s->session->master_key_length = | ||
2052 | s->method->ssl3_enc->generate_master_secret(s, | ||
2053 | s->session->master_key, p, n); | ||
2076 | 2054 | ||
2077 | bn_ctx = BN_CTX_new(); | 2055 | /* Clean up. */ |
2078 | if ((encodedPoint == NULL) || (bn_ctx == NULL)) { | 2056 | explicit_bzero(p, n); |
2079 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2080 | ERR_R_MALLOC_FAILURE); | ||
2081 | goto err; | ||
2082 | } | ||
2083 | 2057 | ||
2084 | /* Encode the public key */ | 2058 | /* |
2085 | n = EC_POINT_point2oct(srvr_group, | 2059 | * First check the size of encoding and allocate memory accordingly. |
2086 | EC_KEY_get0_public_key(clnt_ecdh), | 2060 | */ |
2087 | POINT_CONVERSION_UNCOMPRESSED, encodedPoint, | 2061 | encoded_pt_len = EC_POINT_point2oct(srvr_group, |
2088 | encoded_pt_len, bn_ctx); | 2062 | EC_KEY_get0_public_key(clnt_ecdh), |
2089 | 2063 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | |
2090 | *p = n; /* length of encoded point */ | 2064 | |
2091 | /* Encoded point will be copied here */ | 2065 | bn_ctx = BN_CTX_new(); |
2092 | p += 1; | 2066 | encodedPoint = malloc(encoded_pt_len); |
2093 | 2067 | if (encodedPoint == NULL || bn_ctx == NULL) { | |
2094 | /* copy the point */ | 2068 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, |
2095 | memcpy((unsigned char *)p, encodedPoint, n); | 2069 | ERR_R_MALLOC_FAILURE); |
2096 | /* increment n to account for length field */ | 2070 | goto err; |
2097 | n += 1; | 2071 | } |
2098 | |||
2099 | /* Free allocated memory */ | ||
2100 | BN_CTX_free(bn_ctx); | ||
2101 | free(encodedPoint); | ||
2102 | EC_KEY_free(clnt_ecdh); | ||
2103 | EVP_PKEY_free(srvr_pub_pkey); | ||
2104 | } else if (alg_k & SSL_kGOST) { | ||
2105 | /* GOST key exchange message creation */ | ||
2106 | EVP_PKEY_CTX *pkey_ctx; | ||
2107 | X509 *peer_cert; | ||
2108 | |||
2109 | size_t msglen; | ||
2110 | unsigned int md_len; | ||
2111 | unsigned char premaster_secret[32], shared_ukm[32], | ||
2112 | tmp[256]; | ||
2113 | EVP_MD_CTX *ukm_hash; | ||
2114 | EVP_PKEY *pub_key; | ||
2115 | int nid; | ||
2116 | 2072 | ||
2117 | /* Get server sertificate PKEY and create ctx from it */ | 2073 | /* Encode the public key */ |
2118 | peer_cert = s->session->sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509; | 2074 | n = EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh), |
2119 | if (!peer_cert) { | 2075 | POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encoded_pt_len, |
2120 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2076 | bn_ctx); |
2121 | SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); | ||
2122 | goto err; | ||
2123 | } | ||
2124 | 2077 | ||
2125 | pub_key = X509_get_pubkey(peer_cert); | 2078 | *p = n; /* length of encoded point */ |
2126 | pkey_ctx = EVP_PKEY_CTX_new(pub_key, NULL); | 2079 | /* Encoded point will be copied here */ |
2080 | p += 1; | ||
2127 | 2081 | ||
2128 | /* | 2082 | /* copy the point */ |
2129 | * If we have send a certificate, and certificate key | 2083 | memcpy((unsigned char *)p, encodedPoint, n); |
2130 | * parameters match those of server certificate, use | 2084 | /* increment n to account for length field */ |
2131 | * certificate key for key exchange. | 2085 | n += 1; |
2132 | * Otherwise, generate ephemeral key pair. | ||
2133 | */ | ||
2134 | EVP_PKEY_encrypt_init(pkey_ctx); | ||
2135 | 2086 | ||
2136 | /* Generate session key. */ | 2087 | *outlen = n; |
2137 | arc4random_buf(premaster_secret, 32); | 2088 | ret = 1; |
2138 | 2089 | ||
2139 | /* | 2090 | err: |
2140 | * If we have client certificate, use its secret as | 2091 | /* Free allocated memory */ |
2141 | * peer key. | 2092 | BN_CTX_free(bn_ctx); |
2142 | */ | 2093 | free(encodedPoint); |
2143 | if (s->s3->tmp.cert_req && s->cert->key->privatekey) { | 2094 | EC_KEY_free(clnt_ecdh); |
2144 | if (EVP_PKEY_derive_set_peer(pkey_ctx, | 2095 | EVP_PKEY_free(srvr_pub_pkey); |
2145 | s->cert->key->privatekey) <=0) { | 2096 | |
2146 | /* | 2097 | return (ret); |
2147 | * If there was an error - just ignore | 2098 | } |
2148 | * it. Ephemeral key would be used. | 2099 | |
2149 | */ | 2100 | static int |
2150 | ERR_clear_error(); | 2101 | ssl3_client_kex_gost(SSL *s, SESS_CERT *sess_cert, unsigned char *p, |
2151 | } | 2102 | int *outlen) |
2152 | } | 2103 | { |
2104 | unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; | ||
2105 | EVP_PKEY *pub_key = NULL; | ||
2106 | EVP_PKEY_CTX *pkey_ctx; | ||
2107 | X509 *peer_cert; | ||
2108 | size_t msglen; | ||
2109 | unsigned int md_len; | ||
2110 | EVP_MD_CTX *ukm_hash; | ||
2111 | int ret = -1; | ||
2112 | int nid; | ||
2113 | int n; | ||
2114 | |||
2115 | /* Get server sertificate PKEY and create ctx from it */ | ||
2116 | peer_cert = sess_cert->peer_pkeys[SSL_PKEY_GOST01].x509; | ||
2117 | if (peer_cert == NULL) { | ||
2118 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2119 | SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); | ||
2120 | goto err; | ||
2121 | } | ||
2122 | |||
2123 | pub_key = X509_get_pubkey(peer_cert); | ||
2124 | pkey_ctx = EVP_PKEY_CTX_new(pub_key, NULL); | ||
2125 | |||
2126 | /* | ||
2127 | * If we have send a certificate, and certificate key parameters match | ||
2128 | * those of server certificate, use certificate key for key exchange. | ||
2129 | * Otherwise, generate ephemeral key pair. | ||
2130 | */ | ||
2131 | EVP_PKEY_encrypt_init(pkey_ctx); | ||
2132 | |||
2133 | /* Generate session key. */ | ||
2134 | arc4random_buf(premaster_secret, 32); | ||
2153 | 2135 | ||
2136 | /* | ||
2137 | * If we have client certificate, use its secret as peer key. | ||
2138 | */ | ||
2139 | if (s->s3->tmp.cert_req && s->cert->key->privatekey) { | ||
2140 | if (EVP_PKEY_derive_set_peer(pkey_ctx, | ||
2141 | s->cert->key->privatekey) <=0) { | ||
2154 | /* | 2142 | /* |
2155 | * Compute shared IV and store it in algorithm-specific | 2143 | * If there was an error - just ignore it. |
2156 | * context data. | 2144 | * Ephemeral key would be used. |
2157 | */ | 2145 | */ |
2158 | ukm_hash = EVP_MD_CTX_create(); | 2146 | ERR_clear_error(); |
2159 | if (ukm_hash == NULL) { | 2147 | } |
2160 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | 2148 | } |
2161 | ERR_R_MALLOC_FAILURE); | ||
2162 | explicit_bzero(premaster_secret, | ||
2163 | sizeof(premaster_secret)); | ||
2164 | goto err; | ||
2165 | } | ||
2166 | 2149 | ||
2167 | if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94) | 2150 | /* |
2168 | nid = NID_id_GostR3411_94; | 2151 | * Compute shared IV and store it in algorithm-specific context data. |
2169 | else | 2152 | */ |
2170 | nid = NID_id_tc26_gost3411_2012_256; | 2153 | ukm_hash = EVP_MD_CTX_create(); |
2171 | if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid))) | 2154 | if (ukm_hash == NULL) { |
2155 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2156 | ERR_R_MALLOC_FAILURE); | ||
2157 | goto err; | ||
2158 | } | ||
2159 | |||
2160 | if (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_GOST94) | ||
2161 | nid = NID_id_GostR3411_94; | ||
2162 | else | ||
2163 | nid = NID_id_tc26_gost3411_2012_256; | ||
2164 | if (!EVP_DigestInit(ukm_hash, EVP_get_digestbynid(nid))) | ||
2165 | goto err; | ||
2166 | EVP_DigestUpdate(ukm_hash, s->s3->client_random, SSL3_RANDOM_SIZE); | ||
2167 | EVP_DigestUpdate(ukm_hash, s->s3->server_random, SSL3_RANDOM_SIZE); | ||
2168 | EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len); | ||
2169 | EVP_MD_CTX_destroy(ukm_hash); | ||
2170 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, | ||
2171 | EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { | ||
2172 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); | ||
2173 | goto err; | ||
2174 | } | ||
2175 | |||
2176 | /* | ||
2177 | * Make GOST keytransport blob message, encapsulate it into sequence. | ||
2178 | */ | ||
2179 | *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; | ||
2180 | msglen = 255; | ||
2181 | if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, | ||
2182 | 32) < 0) { | ||
2183 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, SSL_R_LIBRARY_BUG); | ||
2184 | goto err; | ||
2185 | } | ||
2186 | if (msglen >= 0x80) { | ||
2187 | *(p++) = 0x81; | ||
2188 | *(p++) = msglen & 0xff; | ||
2189 | n = msglen + 3; | ||
2190 | } else { | ||
2191 | *(p++) = msglen & 0xff; | ||
2192 | n = msglen + 2; | ||
2193 | } | ||
2194 | memcpy(p, tmp, msglen); | ||
2195 | |||
2196 | /* Check if pubkey from client certificate was used. */ | ||
2197 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, | ||
2198 | NULL) > 0) { | ||
2199 | /* Set flag "skip certificate verify". */ | ||
2200 | s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; | ||
2201 | } | ||
2202 | EVP_PKEY_CTX_free(pkey_ctx); | ||
2203 | s->session->master_key_length = | ||
2204 | s->method->ssl3_enc->generate_master_secret(s, | ||
2205 | s->session->master_key, premaster_secret, 32); | ||
2206 | |||
2207 | *outlen = n; | ||
2208 | ret = 1; | ||
2209 | |||
2210 | err: | ||
2211 | explicit_bzero(premaster_secret, sizeof(premaster_secret)); | ||
2212 | EVP_PKEY_free(pub_key); | ||
2213 | |||
2214 | return (ret); | ||
2215 | } | ||
2216 | |||
2217 | int | ||
2218 | ssl3_send_client_key_exchange(SSL *s) | ||
2219 | { | ||
2220 | SESS_CERT *sess_cert; | ||
2221 | unsigned long alg_k; | ||
2222 | unsigned char *p; | ||
2223 | int n; | ||
2224 | |||
2225 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) { | ||
2226 | p = ssl3_handshake_msg_start(s, SSL3_MT_CLIENT_KEY_EXCHANGE); | ||
2227 | |||
2228 | alg_k = s->s3->tmp.new_cipher->algorithm_mkey; | ||
2229 | |||
2230 | if ((sess_cert = s->session->sess_cert) == NULL) { | ||
2231 | ssl3_send_alert(s, SSL3_AL_FATAL, | ||
2232 | SSL_AD_UNEXPECTED_MESSAGE); | ||
2233 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2234 | ERR_R_INTERNAL_ERROR); | ||
2235 | goto err; | ||
2236 | } | ||
2237 | |||
2238 | if (alg_k & SSL_kRSA) { | ||
2239 | if (ssl3_client_kex_rsa(s, sess_cert, p, &n) != 1) | ||
2172 | goto err; | 2240 | goto err; |
2173 | EVP_DigestUpdate(ukm_hash, | 2241 | } else if (alg_k & SSL_kDHE) { |
2174 | s->s3->client_random, SSL3_RANDOM_SIZE); | 2242 | if (ssl3_client_kex_dhe(s, sess_cert, p, &n) != 1) |
2175 | EVP_DigestUpdate(ukm_hash, | ||
2176 | s->s3->server_random, SSL3_RANDOM_SIZE); | ||
2177 | EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len); | ||
2178 | EVP_MD_CTX_destroy(ukm_hash); | ||
2179 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, | ||
2180 | EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { | ||
2181 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2182 | SSL_R_LIBRARY_BUG); | ||
2183 | explicit_bzero(premaster_secret, | ||
2184 | sizeof(premaster_secret)); | ||
2185 | goto err; | 2243 | goto err; |
2186 | } | 2244 | } else if (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) { |
2187 | 2245 | if (ssl3_client_kex_ecdh(s, sess_cert, p, &n) != 1) | |
2188 | /* | 2246 | goto err; |
2189 | * Make GOST keytransport blob message, encapsulate it | 2247 | } else if (alg_k & SSL_kGOST) { |
2190 | * into sequence. | 2248 | if (ssl3_client_kex_gost(s, sess_cert, p, &n) != 1) |
2191 | */ | ||
2192 | *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; | ||
2193 | msglen = 255; | ||
2194 | if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, | ||
2195 | premaster_secret, 32) < 0) { | ||
2196 | SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, | ||
2197 | SSL_R_LIBRARY_BUG); | ||
2198 | goto err; | 2249 | goto err; |
2199 | } | ||
2200 | if (msglen >= 0x80) { | ||
2201 | *(p++) = 0x81; | ||
2202 | *(p++) = msglen & 0xff; | ||
2203 | n = msglen + 3; | ||
2204 | } else { | ||
2205 | *(p++) = msglen & 0xff; | ||
2206 | n = msglen + 2; | ||
2207 | } | ||
2208 | memcpy(p, tmp, msglen); | ||
2209 | /* Check if pubkey from client certificate was used. */ | ||
2210 | if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, | ||
2211 | EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) { | ||
2212 | /* Set flag "skip certificate verify". */ | ||
2213 | s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; | ||
2214 | } | ||
2215 | EVP_PKEY_CTX_free(pkey_ctx); | ||
2216 | s->session->master_key_length = | ||
2217 | s->method->ssl3_enc->generate_master_secret(s, | ||
2218 | s->session->master_key, premaster_secret, 32); | ||
2219 | EVP_PKEY_free(pub_key); | ||
2220 | explicit_bzero(premaster_secret, | ||
2221 | sizeof(premaster_secret)); | ||
2222 | } else { | 2250 | } else { |
2223 | ssl3_send_alert(s, SSL3_AL_FATAL, | 2251 | ssl3_send_alert(s, SSL3_AL_FATAL, |
2224 | SSL_AD_HANDSHAKE_FAILURE); | 2252 | SSL_AD_HANDSHAKE_FAILURE); |
@@ -2236,10 +2264,6 @@ ssl3_send_client_key_exchange(SSL *s) | |||
2236 | return (ssl3_handshake_write(s)); | 2264 | return (ssl3_handshake_write(s)); |
2237 | 2265 | ||
2238 | err: | 2266 | err: |
2239 | BN_CTX_free(bn_ctx); | ||
2240 | free(encodedPoint); | ||
2241 | EC_KEY_free(clnt_ecdh); | ||
2242 | EVP_PKEY_free(srvr_pub_pkey); | ||
2243 | return (-1); | 2267 | return (-1); |
2244 | } | 2268 | } |
2245 | 2269 | ||