]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added ssl_prefer_server_ciphers setting.
authorTimo Sirainen <tss@iki.fi>
Sat, 21 Sep 2013 23:20:09 +0000 (02:20 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 21 Sep 2013 23:20:09 +0000 (02:20 +0300)
doc/example-config/conf.d/10-ssl.conf
src/lib-master/master-service-ssl-settings.c
src/lib-master/master-service-ssl-settings.h
src/lib-master/master-service-ssl.c
src/lib-ssl-iostream/iostream-openssl-context.c
src/lib-ssl-iostream/iostream-openssl.c
src/lib-ssl-iostream/iostream-ssl.h
src/login-common/ssl-proxy-openssl.c

index 4b5b2b9e6701762f06fa3dc839a662e46fe15870..cab9423f6a1073b81a343efc6ed93bb606d3a040 100644 (file)
@@ -53,5 +53,8 @@ ssl_key = </etc/ssl/private/dovecot.pem
 # SSL ciphers to use
 #ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL
 
+# Prefer the server's order of ciphers over client's.
+#ssl_prefer_server_ciphers = no
+
 # SSL crypto device to use, for valid values run "openssl engine"
 #ssl_crypto_device =
index 852c418b0978451a4a54c9eb6538d5074476669b..adf1f330d7f53b7abaebf2142e4bdb2150e71336 100644 (file)
@@ -27,6 +27,7 @@ static const struct setting_define master_service_ssl_setting_defines[] = {
        DEF(SET_BOOL, ssl_verify_client_cert),
        DEF(SET_BOOL, ssl_require_crl),
        DEF(SET_BOOL, verbose_ssl),
+       DEF(SET_BOOL, ssl_prefer_server_ciphers),
 
        SETTING_DEFINE_LIST_END
 };
@@ -47,7 +48,8 @@ static const struct master_service_ssl_settings master_service_ssl_default_setti
        .ssl_crypto_device = "",
        .ssl_verify_client_cert = FALSE,
        .ssl_require_crl = TRUE,
-       .verbose_ssl = FALSE
+       .verbose_ssl = FALSE,
+       .ssl_prefer_server_ciphers = FALSE
 };
 
 const struct setting_parser_info master_service_ssl_setting_parser_info = {
index 9ce7b6ce0b8ecc8ee304a26254d01a9ce09bc49e..2569234dffcd5d69eeeb713cb56a8be08c0bc658 100644 (file)
@@ -16,6 +16,7 @@ struct master_service_ssl_settings {
        bool ssl_verify_client_cert;
        bool ssl_require_crl;
        bool verbose_ssl;
+       bool ssl_prefer_server_ciphers;
 };
 
 extern const struct setting_parser_info master_service_ssl_setting_parser_info;
index 77d59089109c3395947d67ee2d0de16a46f4ab22..1e1263a70127e5ca866dd861e31f4090217c342f 100644 (file)
@@ -119,6 +119,7 @@ void master_service_ssl_ctx_init(struct master_service *service)
 
        ssl_set.verbose = set->verbose_ssl;
        ssl_set.verify_remote_cert = set->ssl_verify_client_cert;
+       ssl_set.prefer_server_ciphers = set->ssl_prefer_server_ciphers;
 
        if (ssl_iostream_context_init_server(&ssl_set, &service->ssl_ctx,
                                             &error) < 0) {
index 2d2c7d8edcb029a4fad7554b20f0f19b70f63c1a..346a120ca72dc377d266a6702a59b1638cc7950e 100644 (file)
@@ -369,6 +369,10 @@ ssl_iostream_context_set(struct ssl_iostream_context *ctx,
                        set->cipher_list, openssl_iostream_error());
                return -1;
        }
+       if (set->prefer_server_ciphers) {
+               SSL_CTX_set_options(ctx->ssl_ctx,
+                                   SSL_OP_CIPHER_SERVER_PREFERENCE);
+       }
        if (ctx->set->protocols != NULL) {
                SSL_CTX_set_options(ctx->ssl_ctx,
                            openssl_get_protocol_options(ctx->set->protocols));
index 353c35d6daf84ee331b6861bd371ea5c22f586d4..0a1ea37cafbbe0f06f1e772c12492f0723cd3cb1 100644 (file)
@@ -154,6 +154,8 @@ openssl_iostream_set(struct ssl_iostream *ssl_io,
                        return -1;
                }
        }
+       if (set->prefer_server_ciphers)
+               SSL_set_options(ssl_io->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE);
        if (set->protocols != NULL) {
                SSL_clear_options(ssl_io->ssl, OPENSSL_ALL_PROTOCOL_OPTIONS);
                SSL_set_options(ssl_io->ssl,
index 8db6bb8f4d0aa503b981f1571977334cfaa3d904..2e2fc7e2a1966627ed3e25d72c1d626b8688101e 100644 (file)
@@ -17,6 +17,7 @@ struct ssl_iostream_settings {
        bool verbose, verbose_invalid_cert; /* stream-only */
        bool verify_remote_cert; /* neither/both */
        bool require_valid_cert; /* stream-only */
+       bool prefer_server_ciphers;
 };
 
 /* Returns 0 if ok, -1 and sets error_r if failed. The returned error string
index 508f171e4a6637fc62f68718e7421dd3b9024ab9..3f5a6c161c5095e88ece69274a91a30133c2b4f4 100644 (file)
@@ -99,6 +99,7 @@ struct ssl_server_context {
        const char *cipher_list;
        const char *protocols;
        bool verify_client_cert;
+       bool prefer_server_ciphers;
 };
 
 static int extdata_index;
@@ -634,6 +635,7 @@ ssl_server_context_get(const struct login_settings *login_set,
        lookup_ctx.verify_client_cert = set->ssl_verify_client_cert ||
                login_set->auth_ssl_require_client_cert ||
                login_set->auth_ssl_username_from_cert;
+       lookup_ctx.prefer_server_ciphers = set->ssl_prefer_server_ciphers;
 
        ctx = hash_table_lookup(ssl_servers, &lookup_ctx);
        if (ctx == NULL)
@@ -1271,6 +1273,7 @@ ssl_server_context_init(const struct login_settings *login_set,
        ctx->verify_client_cert = ssl_set->ssl_verify_client_cert ||
                login_set->auth_ssl_require_client_cert ||
                login_set->auth_ssl_username_from_cert;
+       ctx->prefer_server_ciphers = ssl_set->ssl_prefer_server_ciphers;
 
        ctx->ctx = ssl_ctx = SSL_CTX_new(SSLv23_server_method());
        if (ssl_ctx == NULL)
@@ -1281,6 +1284,8 @@ ssl_server_context_init(const struct login_settings *login_set,
                i_fatal("Can't set cipher list to '%s': %s",
                        ctx->cipher_list, ssl_last_error());
        }
+       if (ctx->prefer_server_ciphers)
+               SSL_CTX_set_options(ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
        SSL_CTX_set_options(ssl_ctx, openssl_get_protocol_options(ctx->protocols));
 
        if (ssl_proxy_ctx_use_certificate_chain(ctx->ctx, ctx->cert) != 1) {