summaryrefslogtreecommitdiffstats
path: root/lib/libssl/ssl_lib.c
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2014-10-31 15:25:55 +0000
committerjsing <jsing@openbsd.org>2014-10-31 15:25:55 +0000
commit95986511df7e213592f431d31c873ef1468ac940 (patch)
treeb763b8049dfe7b6d29298e8e146a7f9a52697865 /lib/libssl/ssl_lib.c
parentEven in interrupt context curproc is not NULL. (diff)
downloadwireguard-openbsd-95986511df7e213592f431d31c873ef1468ac940.tar.xz
wireguard-openbsd-95986511df7e213592f431d31c873ef1468ac940.zip
Add support for automatic DH ephemeral keys.
This allows an SSL server to enable DHE ciphers with a single setting, which results in an DH key being generated based on the server key length. Partly based on OpenSSL.
Diffstat (limited to 'lib/libssl/ssl_lib.c')
-rw-r--r--lib/libssl/ssl_lib.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/libssl/ssl_lib.c b/lib/libssl/ssl_lib.c
index 579c005cc33..078a710c330 100644
--- a/lib/libssl/ssl_lib.c
+++ b/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_lib.c,v 1.88 2014/10/31 14:51:01 jsing Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.89 2014/10/31 15:25:55 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1942,7 +1942,8 @@ ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
if (c == NULL)
return;
- dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
+ dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL ||
+ c->dh_tmp_auto != 0);
have_ecdh_tmp = (c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL ||
c->ecdh_tmp_auto != 0);
@@ -2176,6 +2177,54 @@ ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, const EVP_MD **pmd)
return (c->pkeys[idx].privatekey);
}
+DH *
+ssl_get_auto_dh(SSL *s)
+{
+ CERT_PKEY *cpk;
+ int keylen;
+ DH *dhp;
+
+ if (s->cert->dh_tmp_auto == 2) {
+ keylen = 1024;
+ } else if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) {
+ keylen = 1024;
+ if (s->s3->tmp.new_cipher->strength_bits == 256)
+ keylen = 3072;
+ } else {
+ if ((cpk = ssl_get_server_send_pkey(s)) == NULL)
+ return (NULL);
+ if (cpk->privatekey == NULL || cpk->privatekey->pkey.dh == NULL)
+ return (NULL);
+ keylen = EVP_PKEY_bits(cpk->privatekey);
+ }
+
+ if ((dhp = DH_new()) == NULL)
+ return (NULL);
+
+ dhp->g = BN_new();
+ if (dhp->g != NULL)
+ BN_set_word(dhp->g, 2);
+
+ if (keylen >= 8192)
+ dhp->p = get_rfc3526_prime_8192(NULL);
+ else if (keylen >= 4096)
+ dhp->p = get_rfc3526_prime_4096(NULL);
+ else if (keylen >= 3072)
+ dhp->p = get_rfc3526_prime_3072(NULL);
+ else if (keylen >= 2048)
+ dhp->p = get_rfc3526_prime_2048(NULL);
+ else if (keylen >= 1536)
+ dhp->p = get_rfc3526_prime_1536(NULL);
+ else
+ dhp->p = get_rfc2409_prime_1024(NULL);
+
+ if (dhp->p == NULL || dhp->g == NULL) {
+ DH_free(dhp);
+ return (NULL);
+ }
+ return (dhp);
+}
+
void
ssl_update_cache(SSL *s, int mode)
{