Skip to content

Commit

Permalink
ssl-proxy: Use ssl_dh setting from config
Browse files Browse the repository at this point in the history
  • Loading branch information
cmouse authored and GitLab committed Aug 11, 2016
1 parent 878734e commit bb5eac8
Showing 1 changed file with 35 additions and 111 deletions.
146 changes: 35 additions & 111 deletions src/login-common/ssl-proxy-openssl.c
Expand Up @@ -33,11 +33,6 @@
# define HAVE_ECDH
#endif

/* Check every 30 minutes if parameters file has been updated */
#define SSL_PARAMFILE_CHECK_INTERVAL (60*30)

#define SSL_PARAMETERS_PATH "ssl-params"

#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME /* FIXME: this may be unnecessary.. */
# undef HAVE_SSL_GET_SERVERNAME
#endif
Expand Down Expand Up @@ -84,11 +79,7 @@ struct ssl_proxy {
};

struct ssl_parameters {
const char *path;
time_t last_refresh;
int fd;

DH *dh_512, *dh_default;
DH *dh_default;
};

struct ssl_server_context {
Expand All @@ -98,6 +89,7 @@ struct ssl_server_context {
const char *cert;
const char *key;
const char *ca;
const char *dh;
const char *cipher_list;
const char *protocols;
bool verify_client_cert;
Expand Down Expand Up @@ -172,103 +164,14 @@ static int ssl_server_context_cmp(const struct ssl_server_context *ctx1,
return ctx1->verify_client_cert == ctx2->verify_client_cert ? 0 : 1;
}

static void ssl_params_corrupted(const char *reason)
{
i_fatal("Corrupted SSL ssl-parameters.dat in state_dir: %s", reason);
}

static void read_next(struct ssl_parameters *params, void *data, size_t size)
{
int ret;

if ((ret = read_full(params->fd, data, size)) < 0)
i_fatal("read(%s) failed: %m", params->path);
if (ret == 0)
ssl_params_corrupted("Truncated file");
}

static bool read_dh_parameters_next(struct ssl_parameters *params)
{
unsigned char *buf;
const unsigned char *cbuf;
unsigned int len;
int bits;

/* read bit size. 0 ends the DH parameters list. */
read_next(params, &bits, sizeof(bits));

if (bits == 0)
return FALSE;

/* read data size. */
read_next(params, &len, sizeof(len));
if (len > 1024*100) /* should be enough? */
ssl_params_corrupted("File too large");

buf = i_malloc(len);
read_next(params, buf, len);

cbuf = buf;
switch (bits) {
case 512:
if (params->dh_512 != NULL)
ssl_params_corrupted("Duplicate 512bit parameters");
params->dh_512 = d2i_DHparams(NULL, &cbuf, len);
break;
default:
if (params->dh_default != NULL)
ssl_params_corrupted("Duplicate default parameters");
params->dh_default = d2i_DHparams(NULL, &cbuf, len);
break;
}

i_free(buf);
return TRUE;
}

static void ssl_free_parameters(struct ssl_parameters *params)
{
if (params->dh_512 != NULL) {
DH_free(params->dh_512);
params->dh_512 = NULL;
}
if (params->dh_default != NULL) {
DH_free(params->dh_default);
params->dh_default = NULL;
}
}

static void ssl_refresh_parameters(struct ssl_parameters *params)
{
char c;
int ret;

if (params->last_refresh > ioloop_time - SSL_PARAMFILE_CHECK_INTERVAL)
return;
params->last_refresh = ioloop_time;

params->fd = net_connect_unix(params->path);
if (params->fd == -1) {
i_error("connect(%s) failed: %m", params->path);
return;
}
net_set_nonblock(params->fd, FALSE);

ssl_free_parameters(params);
while (read_dh_parameters_next(params)) ;

if ((ret = read_full(params->fd, &c, 1)) < 0)
i_fatal("read(%s) failed: %m", params->path);
else if (ret != 0) {
/* more data than expected */
ssl_params_corrupted("More data than expected");
}

if (close(params->fd) < 0)
i_error("close(%s) failed: %m", params->path);
params->fd = -1;
}

static void ssl_set_io(struct ssl_proxy *proxy, enum ssl_io_action action)
{
switch (action) {
Expand Down Expand Up @@ -556,7 +459,7 @@ ssl_proxy_alloc_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip,
return -1;
}

ssl_refresh_parameters(&ssl_params);


ssl = SSL_new(ssl_ctx);
if (ssl == NULL) {
Expand Down Expand Up @@ -829,15 +732,6 @@ static RSA *ssl_gen_rsa_key(SSL *ssl ATTR_UNUSED,
return RSA_generate_key(keylength, RSA_F4, NULL, NULL);
}

static DH *ssl_tmp_dh_callback(SSL *ssl ATTR_UNUSED,
int is_export, int keylength)
{
if (is_export != 0 && keylength == 512 && ssl_params.dh_512 != NULL)
return ssl_params.dh_512;

return ssl_params.dh_default;
}

static void ssl_info_callback(const SSL *ssl, int where, int ret)
{
struct ssl_proxy *proxy;
Expand Down Expand Up @@ -1025,7 +919,6 @@ ssl_proxy_ctx_set_crypto_params(SSL_CTX *ssl_ctx,
#endif
if (SSL_CTX_need_tmp_RSA(ssl_ctx) != 0)
SSL_CTX_set_tmp_rsa_callback(ssl_ctx, ssl_gen_rsa_key);
SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_tmp_dh_callback);
#ifdef HAVE_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
Expand Down Expand Up @@ -1101,6 +994,24 @@ ssl_proxy_load_key(const char *key, const char *password)
return pkey;
}

static DH *
ssl_proxy_load_dh(const char *dhparam)
{
DH *dh;
BIO *bio;

bio = BIO_new_mem_buf(t_strdup_noconst(dhparam), strlen(dhparam));
if (bio == NULL)
i_fatal("BIO_new_mem_buf() failed");
dh = NULL;
dh = PEM_read_bio_DHparams(bio, &dh, NULL, NULL);
if (dh == NULL)
i_fatal("Couldn't parse DH parameters: %s",
openssl_iostream_key_load_error());
BIO_free(bio);
return dh;
}

static void
ssl_proxy_ctx_use_key(SSL_CTX *ctx,
const struct master_service_ssl_settings *set)
Expand All @@ -1116,6 +1027,18 @@ ssl_proxy_ctx_use_key(SSL_CTX *ctx,
EVP_PKEY_free(pkey);
}

static void
ssl_proxy_ctx_use_dh(SSL_CTX *ctx,
const struct master_service_ssl_settings *set)
{
DH *dh;

dh = ssl_proxy_load_dh(set->ssl_dh);
if (SSL_CTX_set_tmp_dh(ctx, dh) != 1)
i_fatal("Can't load DH parameters: %s", openssl_iostream_key_load_error());
DH_free(dh);
}

#if defined(HAVE_ECDH) && !defined(SSL_CTRL_SET_ECDH_AUTO)
static int
ssl_proxy_ctx_get_pkey_ec_curve_name(const struct master_service_ssl_settings *set)
Expand Down Expand Up @@ -1237,6 +1160,7 @@ ssl_server_context_init(const struct login_settings *login_set,
ctx->cert = p_strdup(pool, ssl_set->ssl_cert);
ctx->key = p_strdup(pool, ssl_set->ssl_key);
ctx->ca = p_strdup(pool, ssl_set->ssl_ca);
ctx->dh = p_strdup(pool, ssl_set->ssl_dh);
ctx->cipher_list = p_strdup(pool, ssl_set->ssl_cipher_list);
ctx->protocols = p_strdup(pool, ssl_set->ssl_protocols);
ctx->verify_client_cert = ssl_set->ssl_verify_client_cert ||
Expand Down Expand Up @@ -1273,6 +1197,7 @@ ssl_server_context_init(const struct login_settings *login_set,
#endif

ssl_proxy_ctx_use_key(ctx->ctx, ssl_set);
ssl_proxy_ctx_use_dh(ctx->ctx, ssl_set);

if (ctx->verify_client_cert)
ssl_proxy_ctx_verify_client(ctx->ctx, xnames);
Expand Down Expand Up @@ -1374,7 +1299,6 @@ void ssl_proxy_init(void)
(void)RAND_bytes(&buf, 1);

memset(&ssl_params, 0, sizeof(ssl_params));
ssl_params.path = SSL_PARAMETERS_PATH;

ssl_proxy_count = 0;
ssl_proxies = NULL;
Expand Down

0 comments on commit bb5eac8

Please sign in to comment.