1
/* Copyright (c) 2009-2012 Dovecot authors, see the included COPYING file */
4
#include "safe-memset.h"
5
#include "iostream-openssl.h"
7
#include <openssl/crypto.h>
8
#include <openssl/x509.h>
9
#include <openssl/engine.h>
10
#include <openssl/pem.h>
11
#include <openssl/ssl.h>
12
#include <openssl/err.h>
13
#include <openssl/rand.h>
15
struct ssl_iostream_password_context {
17
const char *key_source;
20
static bool ssl_global_initialized = FALSE;
21
static ENGINE *ssl_iostream_engine;
22
int dovecot_ssl_extdata_index;
24
static void ssl_iostream_init_global(const struct ssl_iostream_settings *set);
26
const char *ssl_iostream_error(void)
30
size_t err_size = 256;
32
err = ERR_get_error();
35
return strerror(errno);
36
return "Unknown error";
38
if (ERR_GET_REASON(err) == ERR_R_MALLOC_FAILURE)
39
i_fatal_status(FATAL_OUTOFMEM, "OpenSSL malloc() failed");
41
buf = t_malloc(err_size);
42
buf[err_size-1] = '\0';
43
ERR_error_string_n(err, buf, err_size-1);
47
const char *ssl_iostream_key_load_error(void)
49
unsigned long err = ERR_peek_error();
51
if (ERR_GET_LIB(err) == ERR_LIB_X509 &&
52
ERR_GET_REASON(err) == X509_R_KEY_VALUES_MISMATCH)
53
return "Key is for a different cert than ssl_cert";
55
return ssl_iostream_error();
58
static RSA *ssl_gen_rsa_key(SSL *ssl ATTR_UNUSED,
59
int is_export ATTR_UNUSED, int keylength)
61
return RSA_generate_key(keylength, RSA_F4, NULL, NULL);
64
static DH *ssl_tmp_dh_callback(SSL *ssl ATTR_UNUSED,
65
int is_export, int keylength)
67
struct ssl_iostream *ssl_io;
69
ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
70
/* Well, I'm not exactly sure why the logic in here is this.
71
It's the same as in Postfix, so it can't be too wrong. */
72
if (is_export && keylength == 512 && ssl_io->ctx->dh_512 != NULL)
73
return ssl_io->ctx->dh_512;
75
return ssl_io->ctx->dh_1024;
79
pem_password_callback(char *buf, int size, int rwflag ATTR_UNUSED,
82
struct ssl_iostream_password_context *ctx = userdata;
84
if (ctx->password == NULL) {
85
i_error("%s: SSL private key file is password protected, "
86
"but password isn't given", ctx->key_source);
90
if (i_strocpy(buf, userdata, size) < 0) {
91
i_error("%s: SSL private key password is too long",
98
int ssl_iostream_load_key(const struct ssl_iostream_settings *set,
99
const char *key_source, EVP_PKEY **pkey_r)
101
struct ssl_iostream_password_context ctx;
106
key = t_strdup_noconst(set->key);
107
bio = BIO_new_mem_buf(key, strlen(key));
109
i_error("BIO_new_mem_buf() failed: %s", ssl_iostream_error());
110
safe_memset(key, 0, strlen(key));
114
ctx.password = set->key_password;
115
ctx.key_source = key_source;
117
pkey = PEM_read_bio_PrivateKey(bio, NULL, pem_password_callback, &ctx);
119
i_error("%s: Couldn't parse private SSL key: %s",
120
key_source, ssl_iostream_error());
124
safe_memset(key, 0, strlen(key));
126
return pkey == NULL ? -1 : 0;
130
ssl_iostream_ctx_use_key(struct ssl_iostream_context *ctx,
131
const struct ssl_iostream_settings *set)
136
if (ssl_iostream_load_key(set, ctx->source, &pkey) < 0)
138
if (!SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey)) {
139
i_error("%s: Can't load SSL private key: %s",
140
ctx->source, ssl_iostream_key_load_error());
147
static bool is_pem_key(const char *cert)
149
return strstr(cert, "PRIVATE KEY---") != NULL;
152
const char *ssl_iostream_get_use_certificate_error(const char *cert)
156
err = ERR_peek_error();
157
if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
158
ERR_GET_REASON(err) != PEM_R_NO_START_LINE)
159
return ssl_iostream_error();
160
else if (is_pem_key(cert)) {
161
return "The file contains a private key "
162
"(you've mixed ssl_cert and ssl_key settings)";
164
return "There is no certificate.";
168
static int ssl_ctx_use_certificate_chain(SSL_CTX *ctx, const char *cert)
170
/* mostly just copy&pasted from SSL_CTX_use_certificate_chain_file() */
175
in = BIO_new_mem_buf(t_strdup_noconst(cert), strlen(cert));
177
i_fatal("BIO_new_mem_buf() failed");
179
x = PEM_read_bio_X509(in, NULL, NULL, NULL);
183
ret = SSL_CTX_use_certificate(ctx, x);
184
if (ERR_peek_error() != 0)
188
/* If we could set up our certificate, now proceed to
189
* the CA certificates.
195
while ((ca = PEM_read_bio_X509(in,NULL,NULL,NULL)) != NULL) {
196
r = SSL_CTX_add_extra_chain_cert(ctx, ca);
203
/* When the while loop ends, it's usually just EOF. */
204
err = ERR_peek_last_error();
205
if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
208
ret = 0; /* some real error */
212
if (x != NULL) X509_free(x);
217
static int load_ca(X509_STORE *store, const char *ca,
218
STACK_OF(X509_NAME) **xnames_r)
220
/* mostly just copy&pasted from X509_load_cert_crl_file() */
221
STACK_OF(X509_INFO) *inf;
222
STACK_OF(X509_NAME) *xnames;
228
bio = BIO_new_mem_buf(t_strdup_noconst(ca), strlen(ca));
230
i_fatal("BIO_new_mem_buf() failed");
231
inf = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
237
xnames = sk_X509_NAME_new_null();
239
i_fatal("sk_X509_NAME_new_null() failed");
240
for(i = 0; i < sk_X509_INFO_num(inf); i++) {
241
itmp = sk_X509_INFO_value(inf, i);
243
X509_STORE_add_cert(store, itmp->x509);
244
xname = X509_get_subject_name(itmp->x509);
246
xname = X509_NAME_dup(xname);
248
sk_X509_NAME_push(xnames, xname);
251
X509_STORE_add_crl(store, itmp->crl);
253
sk_X509_INFO_pop_free(inf, X509_INFO_free);
259
ssl_iostream_ctx_verify_remote_cert(struct ssl_iostream_context *ctx,
260
STACK_OF(X509_NAME) *ca_names)
262
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
265
store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
266
X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK |
267
X509_V_FLAG_CRL_CHECK_ALL);
270
SSL_CTX_set_client_CA_list(ctx->ssl_ctx, ca_names);
274
static struct ssl_iostream_settings *
275
ssl_iostream_settings_dup(pool_t pool,
276
const struct ssl_iostream_settings *old_set)
278
struct ssl_iostream_settings *new_set;
280
new_set = p_new(pool, struct ssl_iostream_settings, 1);
281
new_set->cipher_list = p_strdup(pool, old_set->cipher_list);
282
new_set->cert = p_strdup(pool, old_set->cert);
283
new_set->key = p_strdup(pool, old_set->key);
284
new_set->key_password = p_strdup(pool, old_set->key_password);
286
new_set->verbose = old_set->verbose;
291
ssl_iostream_context_set(struct ssl_iostream_context *ctx,
292
const struct ssl_iostream_settings *set)
295
STACK_OF(X509_NAME) *xnames = NULL;
297
ctx->set = ssl_iostream_settings_dup(ctx->pool, set);
298
if (set->cipher_list != NULL &&
299
!SSL_CTX_set_cipher_list(ctx->ssl_ctx, set->cipher_list)) {
300
i_error("%s: Can't set cipher list to '%s': %s",
301
ctx->source, set->cipher_list,
302
ssl_iostream_error());
306
if (set->cert != NULL &&
307
ssl_ctx_use_certificate_chain(ctx->ssl_ctx, set->cert) < 0) {
308
i_error("%s: Can't load SSL certificate: %s", ctx->source,
309
ssl_iostream_get_use_certificate_error(set->cert));
311
if (set->key != NULL) {
312
if (ssl_iostream_ctx_use_key(ctx, set) < 0)
316
/* set trusted CA certs */
317
if (!set->verify_remote_cert) {
319
} else if (set->ca != NULL) {
320
store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
321
if (load_ca(store, set->ca, &xnames) < 0) {
322
i_error("%s: Couldn't parse ssl_ca: %s", ctx->source,
323
ssl_iostream_error());
326
if (ssl_iostream_ctx_verify_remote_cert(ctx, xnames) < 0)
328
} else if (set->ca_dir != NULL) {
329
if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, NULL,
331
i_error("%s: Can't load CA certs from directory %s: %s",
332
ctx->source, set->ca_dir, ssl_iostream_error());
336
i_error("%s: Can't verify remote certs without CA",
341
if (set->cert_username_field != NULL) {
342
ctx->username_nid = OBJ_txt2nid(set->cert_username_field);
343
if (ctx->username_nid == NID_undef) {
344
i_error("%s: Invalid cert_username_field: %s",
345
ctx->source, set->cert_username_field);
352
ssl_iostream_context_init_common(struct ssl_iostream_context *ctx,
354
const struct ssl_iostream_settings *set)
356
ctx->pool = pool_alloconly_create("ssl iostream context", 4096);
357
ctx->source = p_strdup(ctx->pool, source);
359
/* enable all SSL workarounds, except empty fragments as it
360
makes SSL more vulnerable against attacks */
361
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 |
362
(SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS));
363
if (SSL_CTX_need_tmp_RSA(ctx->ssl_ctx))
364
SSL_CTX_set_tmp_rsa_callback(ctx->ssl_ctx, ssl_gen_rsa_key);
365
SSL_CTX_set_tmp_dh_callback(ctx->ssl_ctx, ssl_tmp_dh_callback);
367
return ssl_iostream_context_set(ctx, set);
370
int ssl_iostream_context_init_client(const char *source,
371
const struct ssl_iostream_settings *set,
372
struct ssl_iostream_context **ctx_r)
374
struct ssl_iostream_context *ctx;
377
ssl_iostream_init_global(set);
378
if ((ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
379
i_error("SSL_CTX_new() failed: %s", ssl_iostream_error());
383
ctx = i_new(struct ssl_iostream_context, 1);
384
ctx->ssl_ctx = ssl_ctx;
385
ctx->client_ctx = TRUE;
386
if (ssl_iostream_context_init_common(ctx, source, set) < 0) {
387
ssl_iostream_context_deinit(&ctx);
394
int ssl_iostream_context_init_server(const char *source,
395
const struct ssl_iostream_settings *set,
396
struct ssl_iostream_context **ctx_r)
398
struct ssl_iostream_context *ctx;
401
ssl_iostream_init_global(set);
402
if ((ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
403
i_error("SSL_CTX_new() failed: %s", ssl_iostream_error());
407
ctx = i_new(struct ssl_iostream_context, 1);
408
ctx->ssl_ctx = ssl_ctx;
409
if (ssl_iostream_context_init_common(ctx, source, set) < 0) {
410
ssl_iostream_context_deinit(&ctx);
417
void ssl_iostream_context_deinit(struct ssl_iostream_context **_ctx)
419
struct ssl_iostream_context *ctx = *_ctx;
422
SSL_CTX_free(ctx->ssl_ctx);
423
ssl_iostream_context_free_params(ctx);
424
pool_unref(&ctx->pool);
428
static void ssl_iostream_deinit_global(void)
430
if (ssl_iostream_engine != NULL)
431
ENGINE_finish(ssl_iostream_engine);
437
static void ssl_iostream_init_global(const struct ssl_iostream_settings *set)
439
static char dovecot[] = "dovecot";
442
if (ssl_global_initialized)
445
atexit(ssl_iostream_deinit_global);
446
ssl_global_initialized = TRUE;
448
SSL_load_error_strings();
449
OpenSSL_add_all_algorithms();
451
dovecot_ssl_extdata_index =
452
SSL_get_ex_new_index(0, dovecot, NULL, NULL, NULL);
454
/* PRNG initialization might want to use /dev/urandom, make sure it
455
does it before chrooting. We might not have enough entropy at
456
the first try, so this function may fail. It's still been
457
initialized though. */
458
(void)RAND_bytes(&buf, 1);
460
if (set->crypto_device != NULL && *set->crypto_device != '\0') {
461
ENGINE_load_builtin_engines();
462
ssl_iostream_engine = ENGINE_by_id(set->crypto_device);
463
if (ssl_iostream_engine == NULL) {
464
i_error("Unknown ssl_crypto_device: %s",
467
ENGINE_init(ssl_iostream_engine);
468
ENGINE_set_default_RSA(ssl_iostream_engine);
469
ENGINE_set_default_DSA(ssl_iostream_engine);
470
ENGINE_set_default_ciphers(ssl_iostream_engine);