From 61969c3073f147352a3b99297208e3690080a4d6 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Thu, 3 Mar 2016 12:40:38 +0200 Subject: [PATCH] lib-ssl-iostream: Read dh parameters from PEM string --- .../iostream-openssl-context.c | 54 +++++++++++++++++++ src/lib-ssl-iostream/iostream-ssl.h | 1 + 2 files changed, 55 insertions(+) diff --git a/src/lib-ssl-iostream/iostream-openssl-context.c b/src/lib-ssl-iostream/iostream-openssl-context.c index b1cf1af9b2..c0680c40a2 100644 --- a/src/lib-ssl-iostream/iostream-openssl-context.c +++ b/src/lib-ssl-iostream/iostream-openssl-context.c @@ -98,6 +98,35 @@ int openssl_iostream_load_key(const struct ssl_iostream_settings *set, return pkey == NULL ? -1 : 0; } +static +int openssl_iostream_load_dh(const struct ssl_iostream_settings *set, + DH **dh_r, const char **error_r) +{ + DH *dh; + BIO *bio; + char *dhvalue; + + dhvalue = t_strdup_noconst(set->dh); + bio = BIO_new_mem_buf(dhvalue, strlen(dhvalue)); + + if (bio == NULL) { + *error_r = t_strdup_printf("BIO_new_mem_buf() failed: %s", + openssl_iostream_error()); + return -1; + } + + dh = NULL; + dh = PEM_read_bio_DHparams(bio, &dh, NULL, NULL); + + if (dh == NULL) { + *error_r = t_strdup_printf("Couldn't parse DH parameters: %s", + openssl_iostream_error()); + } + BIO_free(bio); + *dh_r = dh; + return dh == NULL ? -1 : 0; +} + static int ssl_iostream_ctx_use_key(struct ssl_iostream_context *ctx, const struct ssl_iostream_settings *set, @@ -118,6 +147,26 @@ ssl_iostream_ctx_use_key(struct ssl_iostream_context *ctx, return ret; } +static int +ssl_iostream_ctx_use_dh(struct ssl_iostream_context *ctx, + const struct ssl_iostream_settings *set, + const char **error_r) +{ + DH *dh; + int ret = 0; + + if (openssl_iostream_load_dh(set, &dh, error_r) < 0) + return -1; + if (!SSL_CTX_set_tmp_dh(ctx->ssl_ctx, dh)) { + *error_r = t_strdup_printf( + "Can't load DH parameters: %s", + openssl_iostream_key_load_error()); + ret = -1; + } + DH_free(dh); + return ret; +} + static int ssl_ctx_use_certificate_chain(SSL_CTX *ctx, const char *cert) { /* mostly just copy&pasted from SSL_CTX_use_certificate_chain_file() */ @@ -317,6 +366,11 @@ ssl_iostream_context_set(struct ssl_iostream_context *ctx, return -1; } + if (set->dh != NULL) { + if (ssl_iostream_ctx_use_dh(ctx, set, error_r) < 0) + return -1; + } + /* set trusted CA certs */ if (set->verify_remote_cert) { if (ssl_iostream_context_load_ca(ctx, set, error_r) < 0) diff --git a/src/lib-ssl-iostream/iostream-ssl.h b/src/lib-ssl-iostream/iostream-ssl.h index 9aab8889f4..d4ca6cba2b 100644 --- a/src/lib-ssl-iostream/iostream-ssl.h +++ b/src/lib-ssl-iostream/iostream-ssl.h @@ -11,6 +11,7 @@ struct ssl_iostream_settings { const char *cert; const char *key; const char *key_password; + const char *dh; const char *cert_username_field; const char *crypto_device; /* context-only */