diff options
author | jsing <> | 2015-09-12 20:56:14 +0000 |
---|---|---|
committer | jsing <> | 2015-09-12 20:56:14 +0000 |
commit | 5295709b8306b98ea97e2540c0e4dad875421ebe (patch) | |
tree | d0164220ce0df00349ec460a82ff171632156f4c /src/lib | |
parent | 1312e7b62867f57a9802f37d04aca245164178b3 (diff) | |
download | openbsd-5295709b8306b98ea97e2540c0e4dad875421ebe.tar.gz openbsd-5295709b8306b98ea97e2540c0e4dad875421ebe.tar.bz2 openbsd-5295709b8306b98ea97e2540c0e4dad875421ebe.zip |
Split ssl3_send_client_key_exchange() (387 lines of code) into five
functions. The original was written as a huge if/else if chain -
split out the handling for each key exchange type. This allows us to reduce
two levels of indentation, make the code far more readable and have single
return paths so that we can simplify clean up.
ok beck@
Diffstat (limited to 'src/lib')
-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 | ||