diff options
| author | jsing <> | 2020-01-30 16:25:09 +0000 |
|---|---|---|
| committer | jsing <> | 2020-01-30 16:25:09 +0000 |
| commit | c435cca7eec0ec8c6d2f34f5511be91edae36307 (patch) | |
| tree | c2c8df4a9c431efa5cc0db8ff09bf1be05c80c4e /src/lib/libssl/ssl_clnt.c | |
| parent | aa6adbc5818a984bc67f244d0b3f6dcd36e2905e (diff) | |
| download | openbsd-c435cca7eec0ec8c6d2f34f5511be91edae36307.tar.gz openbsd-c435cca7eec0ec8c6d2f34f5511be91edae36307.tar.bz2 openbsd-c435cca7eec0ec8c6d2f34f5511be91edae36307.zip | |
Factor out/rewrite the ECDHE EC point key exchange code.
This reduces replication between the existing TLS client/server and allows
the code to soon be reused for TLSv1.3.
With feedback from inoguchi@ and tb@
ok inoguchi@ tb@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/ssl_clnt.c | 109 |
1 files changed, 15 insertions, 94 deletions
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c index 22e02735c8..dfb1d7ddb6 100644 --- a/src/lib/libssl/ssl_clnt.c +++ b/src/lib/libssl/ssl_clnt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_clnt.c,v 1.62 2020/01/23 10:48:37 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_clnt.c,v 1.63 2020/01/30 16:25:09 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 | * |
| @@ -1263,56 +1263,27 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, CBS *cbs) | |||
| 1263 | static int | 1263 | static int |
| 1264 | ssl3_get_server_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, int nid, CBS *public) | 1264 | ssl3_get_server_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, int nid, CBS *public) |
| 1265 | { | 1265 | { |
| 1266 | const EC_GROUP *group; | ||
| 1267 | EC_GROUP *ngroup = NULL; | ||
| 1268 | EC_POINT *point = NULL; | ||
| 1269 | BN_CTX *bn_ctx = NULL; | ||
| 1270 | EC_KEY *ecdh = NULL; | 1266 | EC_KEY *ecdh = NULL; |
| 1271 | int ret = -1; | 1267 | int ret = -1; |
| 1272 | 1268 | ||
| 1273 | /* | 1269 | /* Extract the server's ephemeral ECDH public key. */ |
| 1274 | * Extract the server's ephemeral ECDH public key. | ||
| 1275 | */ | ||
| 1276 | |||
| 1277 | if ((ecdh = EC_KEY_new()) == NULL) { | 1270 | if ((ecdh = EC_KEY_new()) == NULL) { |
| 1278 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 1271 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
| 1279 | goto err; | 1272 | goto err; |
| 1280 | } | 1273 | } |
| 1281 | 1274 | if (!ssl_kex_peer_public_ecdhe_ecp(ecdh, nid, public)) { | |
| 1282 | if ((ngroup = EC_GROUP_new_by_curve_name(nid)) == NULL) { | ||
| 1283 | SSLerror(s, ERR_R_EC_LIB); | ||
| 1284 | goto err; | ||
| 1285 | } | ||
| 1286 | if (EC_KEY_set_group(ecdh, ngroup) == 0) { | ||
| 1287 | SSLerror(s, ERR_R_EC_LIB); | ||
| 1288 | goto err; | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | group = EC_KEY_get0_group(ecdh); | ||
| 1292 | |||
| 1293 | if ((point = EC_POINT_new(group)) == NULL || | ||
| 1294 | (bn_ctx = BN_CTX_new()) == NULL) { | ||
| 1295 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
| 1296 | goto err; | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | if (EC_POINT_oct2point(group, point, CBS_data(public), | ||
| 1300 | CBS_len(public), bn_ctx) == 0) { | ||
| 1301 | SSLerror(s, SSL_R_BAD_ECPOINT); | 1275 | SSLerror(s, SSL_R_BAD_ECPOINT); |
| 1302 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | 1276 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); |
| 1303 | goto err; | 1277 | goto err; |
| 1304 | } | 1278 | } |
| 1305 | 1279 | ||
| 1306 | EC_KEY_set_public_key(ecdh, point); | 1280 | sc->peer_nid = nid; |
| 1307 | sc->peer_ecdh_tmp = ecdh; | 1281 | sc->peer_ecdh_tmp = ecdh; |
| 1308 | ecdh = NULL; | 1282 | ecdh = NULL; |
| 1309 | 1283 | ||
| 1310 | ret = 1; | 1284 | ret = 1; |
| 1311 | 1285 | ||
| 1312 | err: | 1286 | err: |
| 1313 | BN_CTX_free(bn_ctx); | ||
| 1314 | EC_GROUP_free(ngroup); | ||
| 1315 | EC_POINT_free(point); | ||
| 1316 | EC_KEY_free(ecdh); | 1287 | EC_KEY_free(ecdh); |
| 1317 | 1288 | ||
| 1318 | return (ret); | 1289 | return (ret); |
| @@ -2049,87 +2020,37 @@ err: | |||
| 2049 | static int | 2020 | static int |
| 2050 | ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb) | 2021 | ssl3_send_client_kex_ecdhe_ecp(SSL *s, SESS_CERT *sc, CBB *cbb) |
| 2051 | { | 2022 | { |
| 2052 | const EC_GROUP *group = NULL; | ||
| 2053 | const EC_POINT *point = NULL; | ||
| 2054 | EC_KEY *ecdh = NULL; | 2023 | EC_KEY *ecdh = NULL; |
| 2055 | BN_CTX *bn_ctx = NULL; | 2024 | uint8_t *key = NULL; |
| 2056 | unsigned char *key = NULL; | 2025 | size_t key_len = 0; |
| 2057 | unsigned char *data; | ||
| 2058 | size_t encoded_len; | ||
| 2059 | int key_size = 0, key_len; | ||
| 2060 | int ret = -1; | 2026 | int ret = -1; |
| 2061 | CBB ecpoint; | 2027 | CBB ecpoint; |
| 2062 | 2028 | ||
| 2063 | if ((group = EC_KEY_get0_group(sc->peer_ecdh_tmp)) == NULL || | ||
| 2064 | (point = EC_KEY_get0_public_key(sc->peer_ecdh_tmp)) == NULL) { | ||
| 2065 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 2066 | goto err; | ||
| 2067 | } | ||
| 2068 | |||
| 2069 | if ((ecdh = EC_KEY_new()) == NULL) { | 2029 | if ((ecdh = EC_KEY_new()) == NULL) { |
| 2070 | SSLerror(s, ERR_R_MALLOC_FAILURE); | 2030 | SSLerror(s, ERR_R_MALLOC_FAILURE); |
| 2071 | goto err; | 2031 | goto err; |
| 2072 | } | 2032 | } |
| 2073 | 2033 | ||
| 2074 | if (!EC_KEY_set_group(ecdh, group)) { | 2034 | if (!ssl_kex_generate_ecdhe_ecp(ecdh, sc->peer_nid)) |
| 2075 | SSLerror(s, ERR_R_EC_LIB); | ||
| 2076 | goto err; | 2035 | goto err; |
| 2077 | } | ||
| 2078 | 2036 | ||
| 2079 | /* Generate a new ECDH key pair. */ | 2037 | /* Encode our public key. */ |
| 2080 | if (!EC_KEY_generate_key(ecdh)) { | ||
| 2081 | SSLerror(s, ERR_R_ECDH_LIB); | ||
| 2082 | goto err; | ||
| 2083 | } | ||
| 2084 | if ((key_size = ECDH_size(ecdh)) <= 0) { | ||
| 2085 | SSLerror(s, ERR_R_ECDH_LIB); | ||
| 2086 | goto err; | ||
| 2087 | } | ||
| 2088 | if ((key = malloc(key_size)) == NULL) { | ||
| 2089 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
| 2090 | goto err; | ||
| 2091 | } | ||
| 2092 | key_len = ECDH_compute_key(key, key_size, point, ecdh, NULL); | ||
| 2093 | if (key_len <= 0) { | ||
| 2094 | SSLerror(s, ERR_R_ECDH_LIB); | ||
| 2095 | goto err; | ||
| 2096 | } | ||
| 2097 | |||
| 2098 | /* Generate master key from the result. */ | ||
| 2099 | s->session->master_key_length = | ||
| 2100 | tls1_generate_master_secret(s, | ||
| 2101 | s->session->master_key, key, key_len); | ||
| 2102 | |||
| 2103 | encoded_len = EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), | ||
| 2104 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); | ||
| 2105 | if (encoded_len == 0) { | ||
| 2106 | SSLerror(s, ERR_R_ECDH_LIB); | ||
| 2107 | goto err; | ||
| 2108 | } | ||
| 2109 | |||
| 2110 | if ((bn_ctx = BN_CTX_new()) == NULL) { | ||
| 2111 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
| 2112 | goto err; | ||
| 2113 | } | ||
| 2114 | |||
| 2115 | /* Encode the public key. */ | ||
| 2116 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) | 2038 | if (!CBB_add_u8_length_prefixed(cbb, &ecpoint)) |
| 2117 | goto err; | 2039 | goto err; |
| 2118 | if (!CBB_add_space(&ecpoint, &data, encoded_len)) | 2040 | if (!ssl_kex_public_ecdhe_ecp(ecdh, &ecpoint)) |
| 2119 | goto err; | ||
| 2120 | if (EC_POINT_point2oct(group, EC_KEY_get0_public_key(ecdh), | ||
| 2121 | POINT_CONVERSION_UNCOMPRESSED, data, encoded_len, | ||
| 2122 | bn_ctx) == 0) | ||
| 2123 | goto err; | 2041 | goto err; |
| 2124 | if (!CBB_flush(cbb)) | 2042 | if (!CBB_flush(cbb)) |
| 2125 | goto err; | 2043 | goto err; |
| 2126 | 2044 | ||
| 2045 | if (!ssl_kex_derive_ecdhe_ecp(ecdh, sc->peer_ecdh_tmp, &key, &key_len)) | ||
| 2046 | goto err; | ||
| 2047 | s->session->master_key_length = tls1_generate_master_secret(s, | ||
| 2048 | s->session->master_key, key, key_len); | ||
| 2049 | |||
| 2127 | ret = 1; | 2050 | ret = 1; |
| 2128 | 2051 | ||
| 2129 | err: | 2052 | err: |
| 2130 | freezero(key, key_size); | 2053 | freezero(key, key_len); |
| 2131 | |||
| 2132 | BN_CTX_free(bn_ctx); | ||
| 2133 | EC_KEY_free(ecdh); | 2054 | EC_KEY_free(ecdh); |
| 2134 | 2055 | ||
| 2135 | return (ret); | 2056 | return (ret); |
