dovecot-2.2: lib-ssl-iostream: Added support for ECDH/ECDHE ciph...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jul 10 08:58:48 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/dc99912e5047
changeset: 16590:dc99912e5047
user: Timo Sirainen <tss at iki.fi>
date: Wed Jul 10 08:58:36 2013 +0300
description:
lib-ssl-iostream: Added support for ECDH/ECDHE cipher suites
Based on the login-common patch by David Hicks.
diffstat:
src/lib-ssl-iostream/iostream-openssl-context.c | 83 ++++++++++++++++++++++++-
1 files changed, 80 insertions(+), 3 deletions(-)
diffs (100 lines):
diff -r ac0dd2fbdbf0 -r dc99912e5047 src/lib-ssl-iostream/iostream-openssl-context.c
--- a/src/lib-ssl-iostream/iostream-openssl-context.c Wed Jul 10 08:47:49 2013 +0300
+++ b/src/lib-ssl-iostream/iostream-openssl-context.c Wed Jul 10 08:58:36 2013 +0300
@@ -406,6 +406,84 @@
return 0;
}
+#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10002000L
+static int
+ssl_proxy_ctx_get_pkey_ec_curve_name(const struct ssl_iostream_settings *set,
+ int *nid_r, const char **error_r)
+{
+ int nid = 0;
+ EVP_PKEY *pkey;
+ const char *password;
+ EC_KEY *eckey;
+ const EC_GROUP *ecgrp;
+
+ password = set->key_password[0] != '\0' ? set->key_password : NULL;
+ if (openssl_iostream_load_key(set, &pkey, error_r) < 0)
+ return -1;
+
+ if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL &&
+ (ecgrp = EC_KEY_get0_group(eckey)) != NULL)
+ nid = EC_GROUP_get_curve_name(ecgrp);
+ EVP_PKEY_free(pkey);
+
+ *nid_r = nid;
+ return 0;
+}
+#endif
+
+static int
+ssl_proxy_ctx_set_crypto_params(SSL_CTX *ssl_ctx,
+ const struct ssl_iostream_settings *set,
+ const char **error_r)
+{
+#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10002000L
+ EC_KEY *ecdh;
+ int nid;
+ const char *curve_name;
+#endif
+ if (SSL_CTX_need_tmp_RSA(ssl_ctx))
+ SSL_CTX_set_tmp_rsa_callback(ssl_ctx, ssl_gen_rsa_key);
+ SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_tmp_dh_callback);
+#if !defined(OPENSSL_NO_ECDH)
+ /* In the non-recommended situation where ECDH cipher suites are being
+ used instead of ECDHE, do not reuse the same ECDH key pair for
+ different sessions. This option improves forward secrecy. */
+ SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
+#endif
+#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10002000L
+ /* OpenSSL >= 1.0.2 automatically handles ECDH temporary key parameter
+ selection. */
+ SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
+#elif !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L
+ /* For OpenSSL < 1.0.2, ECDH temporary key parameter selection must be
+ performed manually. Attempt to select the same curve as that used
+ in the server's private EC key file. Otherwise fall back to the
+ NIST P-384 (secp384r1) curve to be compliant with RFC 6460 when
+ AES-256 TLS cipher suites are in use. This fall back option does
+ however make Dovecot non-compliant with RFC 6460 which requires
+ curve NIST P-256 (prime256v1) be used when AES-128 TLS cipher
+ suites are in use. At least the non-compliance is in the form of
+ providing too much security rather than too little. */
+ if (ssl_proxy_ctx_get_pkey_ec_curve_name(set, &nid, error_r) < 0)
+ return -1;
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ if (ecdh == NULL) {
+ /* Fall back option */
+ nid = NID_secp384r1;
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ }
+ if ((curve_name = OBJ_nid2sn(nid)) != NULL && set->verbose) {
+ i_debug("SSL: elliptic curve %s will be used for ECDH and"
+ " ECDHE key exchanges", curve_name);
+ }
+ if (ecdh != NULL) {
+ SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
+ EC_KEY_free(ecdh);
+ }
+#endif
+ return 0;
+}
+
static int
ssl_iostream_context_init_common(struct ssl_iostream_context *ctx,
const struct ssl_iostream_settings *set,
@@ -417,9 +495,8 @@
makes SSL more vulnerable against attacks */
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 |
(SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
- if (SSL_CTX_need_tmp_RSA(ctx->ssl_ctx))
- SSL_CTX_set_tmp_rsa_callback(ctx->ssl_ctx, ssl_gen_rsa_key);
- SSL_CTX_set_tmp_dh_callback(ctx->ssl_ctx, ssl_tmp_dh_callback);
+ if (ssl_proxy_ctx_set_crypto_params(ctx->ssl_ctx, set, error_r) < 0)
+ return -1;
return ssl_iostream_context_set(ctx, set, error_r);
}
More information about the dovecot-cvs
mailing list