summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2021-12-04 14:03:22 +0000
committerjsing <>2021-12-04 14:03:22 +0000
commit553bc9b478f48580c6c51ddaa65c906cac0ee4e7 (patch)
treeeaa42a538f5b252c276e4477b5f4bd6b0fd7a981
parent7747938abe289fe6b8f9dd672e16cfcfcbdf8c95 (diff)
downloadopenbsd-553bc9b478f48580c6c51ddaa65c906cac0ee4e7.tar.gz
openbsd-553bc9b478f48580c6c51ddaa65c906cac0ee4e7.tar.bz2
openbsd-553bc9b478f48580c6c51ddaa65c906cac0ee4e7.zip
Clean up and refactor server side DHE key exchange.
Provide ssl_kex_generate_dhe_params_auto() which handles DHE key generation based on parameters determined by the specified key bits. Convert the existing DHE auto parameter selection code into a function that just tells us how many key bits to use. Untangle and rework the server side DHE key exchange to use the ssl_kex_* functions. ok inoguchi@ tb@
-rw-r--r--src/lib/libssl/ssl_kex.c48
-rw-r--r--src/lib/libssl/ssl_lib.c50
-rw-r--r--src/lib/libssl/ssl_locl.h5
-rw-r--r--src/lib/libssl/ssl_srvr.c133
4 files changed, 116 insertions, 120 deletions
diff --git a/src/lib/libssl/ssl_kex.c b/src/lib/libssl/ssl_kex.c
index 639981bec9..78b528b168 100644
--- a/src/lib/libssl/ssl_kex.c
+++ b/src/lib/libssl/ssl_kex.c
@@ -1,6 +1,6 @@
1/* $OpenBSD: ssl_kex.c,v 1.7 2021/12/04 13:50:35 jsing Exp $ */ 1/* $OpenBSD: ssl_kex.c,v 1.8 2021/12/04 14:03:22 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2020, 2021 Joel Sing <jsing@openbsd.org>
4 * 4 *
5 * Permission to use, copy, modify, and distribute this software for any 5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,7 @@
17 17
18#include <stdlib.h> 18#include <stdlib.h>
19 19
20#include <openssl/bn.h>
20#include <openssl/dh.h> 21#include <openssl/dh.h>
21#include <openssl/ec.h> 22#include <openssl/ec.h>
22#include <openssl/ecdh.h> 23#include <openssl/ecdh.h>
@@ -40,7 +41,50 @@ ssl_kex_generate_dhe(DH *dh, DH *dh_params)
40 41
41 if (!DH_set0_pqg(dh, p, NULL, g)) 42 if (!DH_set0_pqg(dh, p, NULL, g))
42 goto err; 43 goto err;
44 p = NULL;
45 g = NULL;
46
47 if (!DH_generate_key(dh))
48 goto err;
49
50 ret = 1;
51
52 err:
53 BN_free(p);
54 BN_free(g);
55
56 return ret;
57}
43 58
59int
60ssl_kex_generate_dhe_params_auto(DH *dh, size_t key_bits)
61{
62 BIGNUM *p = NULL, *g = NULL;
63 int ret = 0;
64
65 if (key_bits >= 8192)
66 p = get_rfc3526_prime_8192(NULL);
67 else if (key_bits >= 4096)
68 p = get_rfc3526_prime_4096(NULL);
69 else if (key_bits >= 3072)
70 p = get_rfc3526_prime_3072(NULL);
71 else if (key_bits >= 2048)
72 p = get_rfc3526_prime_2048(NULL);
73 else if (key_bits >= 1536)
74 p = get_rfc3526_prime_1536(NULL);
75 else
76 p = get_rfc2409_prime_1024(NULL);
77
78 if (p == NULL)
79 goto err;
80
81 if ((g = BN_new()) == NULL)
82 goto err;
83 if (!BN_set_word(g, 2))
84 goto err;
85
86 if (!DH_set0_pqg(dh, p, NULL, g))
87 goto err;
44 p = NULL; 88 p = NULL;
45 g = NULL; 89 g = NULL;
46 90
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index 662013378e..a0d3d05775 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_lib.c,v 1.279 2021/11/14 22:31:29 tb Exp $ */ 1/* $OpenBSD: ssl_lib.c,v 1.280 2021/12/04 14:03:22 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 *
@@ -147,7 +147,6 @@
147#include <limits.h> 147#include <limits.h>
148#include <stdio.h> 148#include <stdio.h>
149 149
150#include <openssl/bn.h>
151#include <openssl/dh.h> 150#include <openssl/dh.h>
152#include <openssl/lhash.h> 151#include <openssl/lhash.h>
153#include <openssl/objects.h> 152#include <openssl/objects.h>
@@ -2319,54 +2318,29 @@ ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd,
2319 return (pkey); 2318 return (pkey);
2320} 2319}
2321 2320
2322DH * 2321size_t
2323ssl_get_auto_dh(SSL *s) 2322ssl_dhe_params_auto_key_bits(SSL *s)
2324{ 2323{
2325 CERT_PKEY *cpk; 2324 CERT_PKEY *cpk;
2326 int keylen; 2325 int key_bits;
2327 DH *dhp;
2328 2326
2329 if (s->cert->dh_tmp_auto == 2) { 2327 if (s->cert->dh_tmp_auto == 2) {
2330 keylen = 1024; 2328 key_bits = 1024;
2331 } else if (S3I(s)->hs.cipher->algorithm_auth & SSL_aNULL) { 2329 } else if (S3I(s)->hs.cipher->algorithm_auth & SSL_aNULL) {
2332 keylen = 1024; 2330 key_bits = 1024;
2333 if (S3I(s)->hs.cipher->strength_bits == 256) 2331 if (S3I(s)->hs.cipher->strength_bits == 256)
2334 keylen = 3072; 2332 key_bits = 3072;
2335 } else { 2333 } else {
2336 if ((cpk = ssl_get_server_send_pkey(s)) == NULL) 2334 if ((cpk = ssl_get_server_send_pkey(s)) == NULL)
2337 return (NULL); 2335 return 0;
2338 if (cpk->privatekey == NULL || 2336 if (cpk->privatekey == NULL ||
2339 EVP_PKEY_get0_RSA(cpk->privatekey) == NULL) 2337 EVP_PKEY_get0_RSA(cpk->privatekey) == NULL)
2340 return (NULL); 2338 return 0;
2341 if ((keylen = EVP_PKEY_bits(cpk->privatekey)) <= 0) 2339 if ((key_bits = EVP_PKEY_bits(cpk->privatekey)) <= 0)
2342 return (NULL); 2340 return 0;
2343 } 2341 }
2344 2342
2345 if ((dhp = DH_new()) == NULL) 2343 return key_bits;
2346 return (NULL);
2347
2348 dhp->g = BN_new();
2349 if (dhp->g != NULL)
2350 BN_set_word(dhp->g, 2);
2351
2352 if (keylen >= 8192)
2353 dhp->p = get_rfc3526_prime_8192(NULL);
2354 else if (keylen >= 4096)
2355 dhp->p = get_rfc3526_prime_4096(NULL);
2356 else if (keylen >= 3072)
2357 dhp->p = get_rfc3526_prime_3072(NULL);
2358 else if (keylen >= 2048)
2359 dhp->p = get_rfc3526_prime_2048(NULL);
2360 else if (keylen >= 1536)
2361 dhp->p = get_rfc3526_prime_1536(NULL);
2362 else
2363 dhp->p = get_rfc2409_prime_1024(NULL);
2364
2365 if (dhp->p == NULL || dhp->g == NULL) {
2366 DH_free(dhp);
2367 return (NULL);
2368 }
2369 return (dhp);
2370} 2344}
2371 2345
2372static int 2346static int
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 0051989ea0..d53c9ec273 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.371 2021/12/04 13:50:35 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.372 2021/12/04 14:03:22 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 *
@@ -1343,7 +1343,7 @@ int ssl_undefined_const_function(const SSL *s);
1343CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); 1343CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
1344EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd, 1344EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd,
1345 const struct ssl_sigalg **sap); 1345 const struct ssl_sigalg **sap);
1346DH *ssl_get_auto_dh(SSL *s); 1346size_t ssl_dhe_params_auto_key_bits(SSL *s);
1347int ssl_cert_type(X509 *x, EVP_PKEY *pkey); 1347int ssl_cert_type(X509 *x, EVP_PKEY *pkey);
1348void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); 1348void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
1349STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); 1349STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
@@ -1448,6 +1448,7 @@ int ssl3_get_client_key_exchange(SSL *s);
1448int ssl3_get_cert_verify(SSL *s); 1448int ssl3_get_cert_verify(SSL *s);
1449 1449
1450int ssl_kex_generate_dhe(DH *dh, DH *dh_params); 1450int ssl_kex_generate_dhe(DH *dh, DH *dh_params);
1451int ssl_kex_generate_dhe_params_auto(DH *dh, size_t key_len);
1451int ssl_kex_params_dhe(DH *dh, CBB *cbb); 1452int ssl_kex_params_dhe(DH *dh, CBB *cbb);
1452int ssl_kex_public_dhe(DH *dh, CBB *cbb); 1453int ssl_kex_public_dhe(DH *dh, CBB *cbb);
1453int ssl_kex_peer_params_dhe(DH *dh, CBS *cbs, int *invalid_params); 1454int ssl_kex_peer_params_dhe(DH *dh, CBS *cbs, int *invalid_params);
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index 0c217d6d3e..e9ea6b141c 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.126 2021/11/29 16:03:56 jsing Exp $ */ 1/* $OpenBSD: ssl_srvr.c,v 1.127 2021/12/04 14:03:22 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 *
@@ -1309,43 +1309,38 @@ ssl3_send_server_done(SSL *s)
1309static int 1309static int
1310ssl3_send_server_kex_dhe(SSL *s, CBB *cbb) 1310ssl3_send_server_kex_dhe(SSL *s, CBB *cbb)
1311{ 1311{
1312 DH *dh = NULL, *dhp; 1312 DH *dh = NULL;
1313 int al; 1313 int al;
1314 1314
1315 if ((dh = DH_new()) == NULL)
1316 goto err;
1317
1315 if (s->cert->dh_tmp_auto != 0) { 1318 if (s->cert->dh_tmp_auto != 0) {
1316 if ((dhp = ssl_get_auto_dh(s)) == NULL) { 1319 size_t key_bits;
1320
1321 if ((key_bits = ssl_dhe_params_auto_key_bits(s)) == 0) {
1317 al = SSL_AD_INTERNAL_ERROR; 1322 al = SSL_AD_INTERNAL_ERROR;
1318 SSLerror(s, ERR_R_INTERNAL_ERROR); 1323 SSLerror(s, ERR_R_INTERNAL_ERROR);
1319 goto fatal_err; 1324 goto fatal_err;
1320 } 1325 }
1321 } else
1322 dhp = s->cert->dh_tmp;
1323 1326
1324 if (dhp == NULL && s->cert->dh_tmp_cb != NULL) 1327 if (!ssl_kex_generate_dhe_params_auto(dh, key_bits))
1325 dhp = s->cert->dh_tmp_cb(s, 0, 1328 goto err;
1326 SSL_C_PKEYLENGTH(S3I(s)->hs.cipher)); 1329 } else {
1330 DH *dh_params = s->cert->dh_tmp;
1327 1331
1328 if (dhp == NULL) { 1332 if (dh_params == NULL && s->cert->dh_tmp_cb != NULL)
1329 al = SSL_AD_HANDSHAKE_FAILURE; 1333 dh_params = s->cert->dh_tmp_cb(s, 0,
1330 SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); 1334 SSL_C_PKEYLENGTH(S3I(s)->hs.cipher));
1331 goto fatal_err;
1332 }
1333 1335
1334 if (S3I(s)->tmp.dh != NULL) { 1336 if (dh_params == NULL) {
1335 SSLerror(s, ERR_R_INTERNAL_ERROR); 1337 al = SSL_AD_HANDSHAKE_FAILURE;
1336 goto err; 1338 SSLerror(s, SSL_R_MISSING_TMP_DH_KEY);
1337 } 1339 goto fatal_err;
1340 }
1338 1341
1339 if (s->cert->dh_tmp_auto != 0) { 1342 if (!ssl_kex_generate_dhe(dh, dh_params))
1340 dh = dhp; 1343 goto err;
1341 } else if ((dh = DHparams_dup(dhp)) == NULL) {
1342 SSLerror(s, ERR_R_DH_LIB);
1343 goto err;
1344 }
1345 S3I(s)->tmp.dh = dh;
1346 if (!DH_generate_key(dh)) {
1347 SSLerror(s, ERR_R_DH_LIB);
1348 goto err;
1349 } 1344 }
1350 1345
1351 if (!ssl_kex_params_dhe(dh, cbb)) 1346 if (!ssl_kex_params_dhe(dh, cbb))
@@ -1353,12 +1348,20 @@ ssl3_send_server_kex_dhe(SSL *s, CBB *cbb)
1353 if (!ssl_kex_public_dhe(dh, cbb)) 1348 if (!ssl_kex_public_dhe(dh, cbb))
1354 goto err; 1349 goto err;
1355 1350
1356 return (1); 1351 if (S3I(s)->tmp.dh != NULL) {
1352 SSLerror(s, ERR_R_INTERNAL_ERROR);
1353 goto err;
1354 }
1355 S3I(s)->tmp.dh = dh;
1356
1357 return 1;
1357 1358
1358 fatal_err: 1359 fatal_err:
1359 ssl3_send_alert(s, SSL3_AL_FATAL, al); 1360 ssl3_send_alert(s, SSL3_AL_FATAL, al);
1360 err: 1361 err:
1361 return (-1); 1362 DH_free(dh);
1363
1364 return -1;
1362} 1365}
1363 1366
1364static int 1367static int
@@ -1787,53 +1790,35 @@ ssl3_get_client_kex_rsa(SSL *s, CBS *cbs)
1787static int 1790static int
1788ssl3_get_client_kex_dhe(SSL *s, CBS *cbs) 1791ssl3_get_client_kex_dhe(SSL *s, CBS *cbs)
1789{ 1792{
1790 int key_size = 0; 1793 DH *dh_clnt = NULL;
1791 int key_is_invalid, key_len, al; 1794 DH *dh_srvr;
1792 unsigned char *key = NULL; 1795 int invalid_key;
1793 BIGNUM *bn = NULL; 1796 uint8_t *key = NULL;
1794 CBS dh_Yc; 1797 size_t key_len = 0;
1795 DH *dh; 1798 int ret = -1;
1796
1797 if (!CBS_get_u16_length_prefixed(cbs, &dh_Yc))
1798 goto decode_err;
1799 if (CBS_len(cbs) != 0)
1800 goto decode_err;
1801 1799
1802 if (S3I(s)->tmp.dh == NULL) { 1800 if ((dh_srvr = S3I(s)->tmp.dh) == NULL) {
1803 al = SSL_AD_HANDSHAKE_FAILURE; 1801 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1804 SSLerror(s, SSL_R_MISSING_TMP_DH_KEY); 1802 SSLerror(s, SSL_R_MISSING_TMP_DH_KEY);
1805 goto fatal_err; 1803 goto err;
1806 } 1804 }
1807 dh = S3I(s)->tmp.dh;
1808 1805
1809 if ((bn = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL)) == NULL) { 1806 if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL)
1810 SSLerror(s, SSL_R_BN_LIB);
1811 goto err; 1807 goto err;
1812 }
1813 1808
1814 if ((key_size = DH_size(dh)) <= 0) { 1809 if (!ssl_kex_peer_public_dhe(dh_clnt, cbs, &invalid_key)) {
1815 SSLerror(s, ERR_R_DH_LIB); 1810 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
1811 SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
1816 goto err; 1812 goto err;
1817 } 1813 }
1818 if ((key = malloc(key_size)) == NULL) { 1814 if (invalid_key) {
1819 SSLerror(s, ERR_R_MALLOC_FAILURE); 1815 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
1816 SSLerror(s, SSL_R_BAD_DH_PUB_KEY_LENGTH);
1820 goto err; 1817 goto err;
1821 } 1818 }
1822 if (!DH_check_pub_key(dh, bn, &key_is_invalid)) { 1819
1823 al = SSL_AD_INTERNAL_ERROR; 1820 if (!ssl_kex_derive_dhe(dh_srvr, dh_clnt, &key, &key_len))
1824 SSLerror(s, ERR_R_DH_LIB); 1821 goto err;
1825 goto fatal_err;
1826 }
1827 if (key_is_invalid) {
1828 al = SSL_AD_ILLEGAL_PARAMETER;
1829 SSLerror(s, ERR_R_DH_LIB);
1830 goto fatal_err;
1831 }
1832 if ((key_len = DH_compute_key(key, bn, dh)) <= 0) {
1833 al = SSL_AD_INTERNAL_ERROR;
1834 SSLerror(s, ERR_R_DH_LIB);
1835 goto fatal_err;
1836 }
1837 1822
1838 if (!tls12_derive_master_secret(s, key, key_len)) 1823 if (!tls12_derive_master_secret(s, key, key_len))
1839 goto err; 1824 goto err;
@@ -1841,21 +1826,13 @@ ssl3_get_client_kex_dhe(SSL *s, CBS *cbs)
1841 DH_free(S3I(s)->tmp.dh); 1826 DH_free(S3I(s)->tmp.dh);
1842 S3I(s)->tmp.dh = NULL; 1827 S3I(s)->tmp.dh = NULL;
1843 1828
1844 freezero(key, key_size); 1829 ret = 1;
1845 BN_clear_free(bn);
1846
1847 return (1);
1848 1830
1849 decode_err:
1850 al = SSL_AD_DECODE_ERROR;
1851 SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
1852 fatal_err:
1853 ssl3_send_alert(s, SSL3_AL_FATAL, al);
1854 err: 1831 err:
1855 freezero(key, key_size); 1832 freezero(key, key_len);
1856 BN_clear_free(bn); 1833 DH_free(dh_clnt);
1857 1834
1858 return (-1); 1835 return ret;
1859} 1836}
1860 1837
1861static int 1838static int