diff options
author | jsing <> | 2018-05-19 14:23:16 +0000 |
---|---|---|
committer | jsing <> | 2018-05-19 14:23:16 +0000 |
commit | 107ce935c7a1e6afa35ba82da3c82fe8ca9c0b6e (patch) | |
tree | f8971840931233c39a3c3a443c92054ae1277514 | |
parent | d404c2a1e5706326d4083e7a61f5050dc8cee8f3 (diff) | |
download | openbsd-107ce935c7a1e6afa35ba82da3c82fe8ca9c0b6e.tar.gz openbsd-107ce935c7a1e6afa35ba82da3c82fe8ca9c0b6e.tar.bz2 openbsd-107ce935c7a1e6afa35ba82da3c82fe8ca9c0b6e.zip |
Clean out a pile of cruft from ssl3_get_client_kex_ecdhe_ecp().
For pure ECDHE we do not need to construct a new key using the one that
was set up during the other half of the key exchange. Also, since we do not
support any form of ECDH the n == 0 case is not valid (per RFC 4492 section
5.7), so we can ditch this entirely.
ok inoguchi@ tb@
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 131 |
1 files changed, 38 insertions, 93 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 94e263ad3c..b1861caa75 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.31 2018/05/19 14:17:55 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.32 2018/05/19 14:23:16 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 | * |
@@ -1889,120 +1889,69 @@ ssl3_get_client_kex_dhe(SSL *s, unsigned char *p, long n) | |||
1889 | static int | 1889 | static int |
1890 | ssl3_get_client_kex_ecdhe_ecp(SSL *s, unsigned char *p, long n) | 1890 | ssl3_get_client_kex_ecdhe_ecp(SSL *s, unsigned char *p, long n) |
1891 | { | 1891 | { |
1892 | EC_KEY *srvr_ecdh = NULL; | 1892 | EC_POINT *point = NULL; |
1893 | EVP_PKEY *clnt_pub_pkey = NULL; | 1893 | const EC_GROUP *group; |
1894 | EC_POINT *clnt_ecpoint = NULL; | ||
1895 | BN_CTX *bn_ctx = NULL; | 1894 | BN_CTX *bn_ctx = NULL; |
1896 | int i, al; | 1895 | EC_KEY *ecdh; |
1897 | |||
1898 | int ret = 1; | ||
1899 | int key_size; | 1896 | int key_size; |
1900 | const EC_KEY *tkey; | 1897 | int ret = 1; |
1901 | const EC_GROUP *group; | 1898 | int i; |
1902 | const BIGNUM *priv_key; | ||
1903 | |||
1904 | /* Initialize structures for server's ECDH key pair. */ | ||
1905 | if ((srvr_ecdh = EC_KEY_new()) == NULL) { | ||
1906 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1907 | goto err; | ||
1908 | } | ||
1909 | 1899 | ||
1910 | /* | 1900 | /* |
1911 | * Use the ephemeral values we saved when | 1901 | * Use the ephemeral values we saved when |
1912 | * generating the ServerKeyExchange message. | 1902 | * generating the ServerKeyExchange message. |
1913 | */ | 1903 | */ |
1914 | tkey = S3I(s)->tmp.ecdh; | 1904 | ecdh = S3I(s)->tmp.ecdh; |
1915 | 1905 | group = EC_KEY_get0_group(ecdh); | |
1916 | group = EC_KEY_get0_group(tkey); | ||
1917 | priv_key = EC_KEY_get0_private_key(tkey); | ||
1918 | 1906 | ||
1919 | if (!EC_KEY_set_group(srvr_ecdh, group) || | 1907 | /* Let's get client's public key */ |
1920 | !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { | 1908 | if ((point = EC_POINT_new(group)) == NULL) { |
1921 | SSLerror(s, ERR_R_EC_LIB); | 1909 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
1922 | goto err; | 1910 | goto err; |
1923 | } | 1911 | } |
1924 | 1912 | ||
1925 | /* Let's get client's public key */ | 1913 | /* |
1926 | if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { | 1914 | * Get client's public key from encoded point |
1915 | * in the ClientKeyExchange message. | ||
1916 | */ | ||
1917 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
1927 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 1918 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
1928 | goto err; | 1919 | goto err; |
1929 | } | 1920 | } |
1930 | 1921 | ||
1931 | if (n == 0L) { | 1922 | /* Get encoded point length */ |
1932 | /* Client Publickey was in Client Certificate */ | 1923 | if (n < 1) |
1933 | if (((clnt_pub_pkey = X509_get_pubkey( | 1924 | goto err; |
1934 | s->session->peer)) == NULL) || | 1925 | i = *p; |
1935 | (clnt_pub_pkey->type != EVP_PKEY_EC)) { | 1926 | p += 1; |
1936 | /* | 1927 | if (n != 1 + i) { |
1937 | * XXX: For now, we do not support client | 1928 | SSLerror(s, ERR_R_EC_LIB); |
1938 | * authentication using ECDH certificates | 1929 | goto err; |
1939 | * so this branch (n == 0L) of the code is | ||
1940 | * never executed. When that support is | ||
1941 | * added, we ought to ensure the key | ||
1942 | * received in the certificate is | ||
1943 | * authorized for key agreement. | ||
1944 | * ECDH_compute_key implicitly checks that | ||
1945 | * the two ECDH shares are for the same | ||
1946 | * group. | ||
1947 | */ | ||
1948 | al = SSL_AD_HANDSHAKE_FAILURE; | ||
1949 | SSLerror(s, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); | ||
1950 | goto f_err; | ||
1951 | } | ||
1952 | |||
1953 | if (EC_POINT_copy(clnt_ecpoint, | ||
1954 | EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) | ||
1955 | == 0) { | ||
1956 | SSLerror(s, ERR_R_EC_LIB); | ||
1957 | goto err; | ||
1958 | } | ||
1959 | ret = 2; /* Skip certificate verify processing */ | ||
1960 | } else { | ||
1961 | /* | ||
1962 | * Get client's public key from encoded point | ||
1963 | * in the ClientKeyExchange message. | ||
1964 | */ | ||
1965 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
1966 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
1967 | goto err; | ||
1968 | } | ||
1969 | |||
1970 | /* Get encoded point length */ | ||
1971 | i = *p; | ||
1972 | |||
1973 | p += 1; | ||
1974 | if (n != 1 + i) { | ||
1975 | SSLerror(s, ERR_R_EC_LIB); | ||
1976 | goto err; | ||
1977 | } | ||
1978 | if (EC_POINT_oct2point(group, | ||
1979 | clnt_ecpoint, p, i, bn_ctx) == 0) { | ||
1980 | SSLerror(s, ERR_R_EC_LIB); | ||
1981 | goto err; | ||
1982 | } | ||
1983 | /* | ||
1984 | * p is pointing to somewhere in the buffer | ||
1985 | * currently, so set it to the start. | ||
1986 | */ | ||
1987 | p = (unsigned char *)s->internal->init_buf->data; | ||
1988 | } | 1930 | } |
1931 | if (EC_POINT_oct2point(group, point, p, i, bn_ctx) == 0) { | ||
1932 | SSLerror(s, ERR_R_EC_LIB); | ||
1933 | goto err; | ||
1934 | } | ||
1935 | |||
1936 | /* | ||
1937 | * p is pointing to somewhere in the buffer | ||
1938 | * currently, so set it to the start. | ||
1939 | */ | ||
1940 | p = (unsigned char *)s->internal->init_buf->data; | ||
1989 | 1941 | ||
1990 | /* Compute the shared pre-master secret */ | 1942 | /* Compute the shared pre-master secret */ |
1991 | key_size = ECDH_size(srvr_ecdh); | 1943 | key_size = ECDH_size(ecdh); |
1992 | if (key_size <= 0) { | 1944 | if (key_size <= 0) { |
1993 | SSLerror(s, ERR_R_ECDH_LIB); | 1945 | SSLerror(s, ERR_R_ECDH_LIB); |
1994 | goto err; | 1946 | goto err; |
1995 | } | 1947 | } |
1996 | i = ECDH_compute_key(p, key_size, clnt_ecpoint, srvr_ecdh, | 1948 | i = ECDH_compute_key(p, key_size, point, ecdh, NULL); |
1997 | NULL); | ||
1998 | if (i <= 0) { | 1949 | if (i <= 0) { |
1999 | SSLerror(s, ERR_R_ECDH_LIB); | 1950 | SSLerror(s, ERR_R_ECDH_LIB); |
2000 | goto err; | 1951 | goto err; |
2001 | } | 1952 | } |
2002 | 1953 | ||
2003 | EVP_PKEY_free(clnt_pub_pkey); | 1954 | EC_POINT_free(point); |
2004 | EC_POINT_free(clnt_ecpoint); | ||
2005 | EC_KEY_free(srvr_ecdh); | ||
2006 | BN_CTX_free(bn_ctx); | 1955 | BN_CTX_free(bn_ctx); |
2007 | EC_KEY_free(S3I(s)->tmp.ecdh); | 1956 | EC_KEY_free(S3I(s)->tmp.ecdh); |
2008 | S3I(s)->tmp.ecdh = NULL; | 1957 | S3I(s)->tmp.ecdh = NULL; |
@@ -2015,12 +1964,8 @@ ssl3_get_client_kex_ecdhe_ecp(SSL *s, unsigned char *p, long n) | |||
2015 | explicit_bzero(p, i); | 1964 | explicit_bzero(p, i); |
2016 | return (ret); | 1965 | return (ret); |
2017 | 1966 | ||
2018 | f_err: | ||
2019 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | ||
2020 | err: | 1967 | err: |
2021 | EVP_PKEY_free(clnt_pub_pkey); | 1968 | EC_POINT_free(point); |
2022 | EC_POINT_free(clnt_ecpoint); | ||
2023 | EC_KEY_free(srvr_ecdh); | ||
2024 | BN_CTX_free(bn_ctx); | 1969 | BN_CTX_free(bn_ctx); |
2025 | return (-1); | 1970 | return (-1); |
2026 | } | 1971 | } |