diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2014-10-31 15:25:56 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2014-10-31 15:25:56 +0000 |
commit | fe1eba9445f8fedd2d25e74ba038bb5e0364e177 (patch) | |
tree | d63e137f54ffeeb89af1b0d46ec9ee1d8613a01b /lib/libssl | |
parent | 81f39d02909b034dd9b0c05881ec45d8573ff2fb (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.c | 30 | ||||
-rw-r--r-- | lib/libssl/src/ssl/s3_srvr.c | 21 | ||||
-rw-r--r-- | lib/libssl/src/ssl/ssl.h | 8 | ||||
-rw-r--r-- | lib/libssl/src/ssl/ssl_cert.c | 3 | ||||
-rw-r--r-- | lib/libssl/src/ssl/ssl_lib.c | 53 | ||||
-rw-r--r-- | lib/libssl/src/ssl/ssl_locl.h | 4 |
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); |