summaryrefslogtreecommitdiff
path: root/lib/libssl
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2014-10-31 15:25:56 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2014-10-31 15:25:56 +0000
commitfe1eba9445f8fedd2d25e74ba038bb5e0364e177 (patch)
treed63e137f54ffeeb89af1b0d46ec9ee1d8613a01b /lib/libssl
parent81f39d02909b034dd9b0c05881ec45d8573ff2fb (diff)
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')
-rw-r--r--lib/libssl/src/ssl/s3_lib.c30
-rw-r--r--lib/libssl/src/ssl/s3_srvr.c21
-rw-r--r--lib/libssl/src/ssl/ssl.h8
-rw-r--r--lib/libssl/src/ssl/ssl_cert.c3
-rw-r--r--lib/libssl/src/ssl/ssl_lib.c53
-rw-r--r--lib/libssl/src/ssl/ssl_locl.h4
6 files changed, 97 insertions, 22 deletions
diff --git a/lib/libssl/src/ssl/s3_lib.c b/lib/libssl/src/ssl/s3_lib.c
index 08c51111298..21f1367442b 100644
--- a/lib/libssl/src/ssl/s3_lib.c
+++ b/lib/libssl/src/ssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.83 2014/10/31 14:51:01 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.84 2014/10/31 15:25:55 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1994,13 +1994,15 @@ ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
ret = 1;
}
break;
+
case SSL_CTRL_SET_TMP_DH_CB:
- {
- SSLerr(SSL_F_SSL3_CTRL,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return (ret);
- }
- break;
+ SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return (ret);
+
+ case SSL_CTRL_SET_DH_AUTO:
+ s->cert->dh_tmp_auto = larg;
+ return 1;
+
case SSL_CTRL_SET_TMP_ECDH:
{
EC_KEY *ecdh = NULL;
@@ -2183,13 +2185,15 @@ ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
return 1;
}
/*break; */
+
case SSL_CTRL_SET_TMP_DH_CB:
- {
- SSLerr(SSL_F_SSL3_CTX_CTRL,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return (0);
- }
- break;
+ SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return (0);
+
+ case SSL_CTRL_SET_DH_AUTO:
+ ctx->cert->dh_tmp_auto = larg;
+ return (1);
+
case SSL_CTRL_SET_TMP_ECDH:
{
EC_KEY *ecdh = NULL;
diff --git a/lib/libssl/src/ssl/s3_srvr.c b/lib/libssl/src/ssl/s3_srvr.c
index 1b97895f76f..3a311fbfb6b 100644
--- a/lib/libssl/src/ssl/s3_srvr.c
+++ b/lib/libssl/src/ssl/s3_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_srvr.c,v 1.88 2014/10/31 14:51:01 jsing Exp $ */
+/* $OpenBSD: s3_srvr.c,v 1.89 2014/10/31 15:25:55 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1360,10 +1360,21 @@ ssl3_send_server_key_exchange(SSL *s)
r[0] = r[1] = r[2] = r[3] = NULL;
n = 0;
if (type & SSL_kDHE) {
- dhp = cert->dh_tmp;
- if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
+ if (s->cert->dh_tmp_auto != 0) {
+ if ((dhp = ssl_get_auto_dh(s)) == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(
+ SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ } else
+ dhp = cert->dh_tmp;
+
+ if (dhp == NULL && s->cert->dh_tmp_cb != NULL)
dhp = s->cert->dh_tmp_cb(s, 0,
SSL_C_PKEYLENGTH(s->s3->tmp.new_cipher));
+
if (dhp == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
@@ -1377,7 +1388,9 @@ ssl3_send_server_key_exchange(SSL *s)
goto err;
}
- if ((dh = DHparams_dup(dhp)) == NULL) {
+ if (s->cert->dh_tmp_auto != 0) {
+ dh = dhp;
+ } else if ((dh = DHparams_dup(dhp)) == NULL) {
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
ERR_R_DH_LIB);
goto err;
diff --git a/lib/libssl/src/ssl/ssl.h b/lib/libssl/src/ssl/ssl.h
index 2b1ceaf2c70..350d6fb4d1e 100644
--- a/lib/libssl/src/ssl/ssl.h
+++ b/lib/libssl/src/ssl/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.68 2014/10/15 13:57:21 jsing Exp $ */
+/* $OpenBSD: ssl.h,v 1.69 2014/10/31 15:25:55 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1429,6 +1429,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_ECDH_AUTO 94
+#define SSL_CTRL_SET_DH_AUTO 118
+
#define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
#define DTLSv1_handle_timeout(ssl) \
@@ -1453,6 +1455,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+#define SSL_CTX_set_dh_auto(ctx, onoff) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL)
#define SSL_CTX_set_ecdh_auto(ctx, onoff) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
@@ -1464,6 +1468,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
#define SSL_set_tmp_ecdh(ssl,ecdh) \
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+#define SSL_set_dh_auto(s, onoff) \
+ SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL)
#define SSL_set_ecdh_auto(s, onoff) \
SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL)
diff --git a/lib/libssl/src/ssl/ssl_cert.c b/lib/libssl/src/ssl/ssl_cert.c
index beea31c64bd..8adb9aa0326 100644
--- a/lib/libssl/src/ssl/ssl_cert.c
+++ b/lib/libssl/src/ssl/ssl_cert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_cert.c,v 1.43 2014/10/31 14:51:01 jsing Exp $ */
+/* $OpenBSD: ssl_cert.c,v 1.44 2014/10/31 15:25:55 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -229,6 +229,7 @@ ssl_cert_dup(CERT *cert)
}
}
ret->dh_tmp_cb = cert->dh_tmp_cb;
+ ret->dh_tmp_auto = cert->dh_tmp_auto;
if (cert->ecdh_tmp) {
ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
diff --git a/lib/libssl/src/ssl/ssl_lib.c b/lib/libssl/src/ssl/ssl_lib.c
index 579c005cc33..078a710c330 100644
--- a/lib/libssl/src/ssl/ssl_lib.c
+++ b/lib/libssl/src/ssl/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)
{
diff --git a/lib/libssl/src/ssl/ssl_locl.h b/lib/libssl/src/ssl/ssl_locl.h
index 955c169244e..e7bcb890e4e 100644
--- a/lib/libssl/src/ssl/ssl_locl.h
+++ b/lib/libssl/src/ssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.72 2014/10/31 14:51:01 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.73 2014/10/31 15:25:55 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -442,6 +442,7 @@ typedef struct cert_st {
DH *dh_tmp;
DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize);
+ int dh_tmp_auto;
EC_KEY *ecdh_tmp;
EC_KEY *(*ecdh_tmp_cb)(SSL *ssl, int is_export, int keysize);
@@ -588,6 +589,7 @@ int ssl_undefined_const_function(const SSL *s);
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
X509 *ssl_get_server_send_cert(const SSL *);
EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd);
+DH *ssl_get_auto_dh(SSL *s);
int ssl_cert_type(X509 *x, EVP_PKEY *pkey);
void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);