Skip to content
This repository was archived by the owner on Apr 23, 2024. It is now read-only.

Commit 3f3d429

Browse files
committed
SSL: ssl_conf_command directive.
With the ssl_conf_command directive it is now possible to set arbitrary OpenSSL configuration parameters as long as nginx is compiled with OpenSSL 1.0.2 or later. Full list of available configuration commands can be found in the SSL_CONF_cmd manual page (https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html). In particular, this allows configuring PrioritizeChaCha option (ticket #1445): ssl_conf_command Options PrioritizeChaCha; It can be also used to configure TLSv1.3 ciphers in OpenSSL, which fails to configure them via the SSL_CTX_set_cipher_list() interface (ticket #1529): ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256; Configuration commands are applied after nginx own configuration for SSL, so they can be used to override anything set by nginx. Note though that configuring OpenSSL directly with ssl_conf_command might result in a behaviour nginx does not expect, and should be done with care.
1 parent 23a5335 commit 3f3d429

File tree

8 files changed

+176
-0
lines changed

8 files changed

+176
-0
lines changed

src/event/ngx_event_openssl.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,78 @@ ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
14701470
}
14711471

14721472

1473+
ngx_int_t
1474+
ngx_ssl_conf_commands(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *commands)
1475+
{
1476+
if (commands == NULL) {
1477+
return NGX_OK;
1478+
}
1479+
1480+
#ifdef SSL_CONF_FLAG_FILE
1481+
{
1482+
int type;
1483+
u_char *key, *value;
1484+
ngx_uint_t i;
1485+
ngx_keyval_t *cmd;
1486+
SSL_CONF_CTX *cctx;
1487+
1488+
cctx = SSL_CONF_CTX_new();
1489+
if (cctx == NULL) {
1490+
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1491+
"SSL_CONF_CTX_new() failed");
1492+
return NGX_ERROR;
1493+
}
1494+
1495+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
1496+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
1497+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
1498+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
1499+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS);
1500+
1501+
SSL_CONF_CTX_set_ssl_ctx(cctx, ssl->ctx);
1502+
1503+
cmd = commands->elts;
1504+
for (i = 0; i < commands->nelts; i++) {
1505+
1506+
key = cmd[i].key.data;
1507+
type = SSL_CONF_cmd_value_type(cctx, (char *) key);
1508+
1509+
if (type == SSL_CONF_TYPE_FILE || type == SSL_CONF_TYPE_DIR) {
1510+
if (ngx_conf_full_name(cf->cycle, &cmd[i].value, 1) != NGX_OK) {
1511+
SSL_CONF_CTX_free(cctx);
1512+
return NGX_ERROR;
1513+
}
1514+
}
1515+
1516+
value = cmd[i].value.data;
1517+
1518+
if (SSL_CONF_cmd(cctx, (char *) key, (char *) value) <= 0) {
1519+
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1520+
"SSL_CONF_cmd(\"%s\", \"%s\") failed", key, value);
1521+
SSL_CONF_CTX_free(cctx);
1522+
return NGX_ERROR;
1523+
}
1524+
}
1525+
1526+
if (SSL_CONF_CTX_finish(cctx) != 1) {
1527+
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1528+
"SSL_CONF_finish() failed");
1529+
SSL_CONF_CTX_free(cctx);
1530+
return NGX_ERROR;
1531+
}
1532+
1533+
SSL_CONF_CTX_free(cctx);
1534+
1535+
return NGX_OK;
1536+
}
1537+
#else
1538+
ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,
1539+
"SSL_CONF_cmd() is not available on this platform");
1540+
return NGX_ERROR;
1541+
#endif
1542+
}
1543+
1544+
14731545
ngx_int_t
14741546
ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
14751547
{

src/event/ngx_event_openssl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
203203
ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
204204
ngx_int_t ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl,
205205
ngx_uint_t enable);
206+
ngx_int_t ngx_ssl_conf_commands(ngx_conf_t *cf, ngx_ssl_t *ssl,
207+
ngx_array_t *commands);
208+
206209
ngx_int_t ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl,
207210
ngx_uint_t enable);
208211
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
@@ -211,6 +214,7 @@ ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
211214
ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl,
212215
ngx_array_t *paths);
213216
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
217+
214218
ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
215219
ngx_uint_t flags);
216220

src/http/modules/ngx_http_ssl_module.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
5353
static char *ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
5454
void *conf);
5555

56+
static char *ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post,
57+
void *data);
58+
5659
static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
5760

5861

@@ -89,6 +92,10 @@ static ngx_conf_deprecated_t ngx_http_ssl_deprecated = {
8992
};
9093

9194

95+
static ngx_conf_post_t ngx_http_ssl_conf_command_post =
96+
{ ngx_http_ssl_conf_command_check };
97+
98+
9299
static ngx_command_t ngx_http_ssl_commands[] = {
93100

94101
{ ngx_string("ssl"),
@@ -280,6 +287,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
280287
offsetof(ngx_http_ssl_srv_conf_t, early_data),
281288
NULL },
282289

290+
{ ngx_string("ssl_conf_command"),
291+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
292+
ngx_conf_set_keyval_slot,
293+
NGX_HTTP_SRV_CONF_OFFSET,
294+
offsetof(ngx_http_ssl_srv_conf_t, conf_commands),
295+
&ngx_http_ssl_conf_command_post },
296+
283297
ngx_null_command
284298
};
285299

@@ -606,6 +620,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
606620
sscf->certificates = NGX_CONF_UNSET_PTR;
607621
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
608622
sscf->passwords = NGX_CONF_UNSET_PTR;
623+
sscf->conf_commands = NGX_CONF_UNSET_PTR;
609624
sscf->builtin_session_cache = NGX_CONF_UNSET;
610625
sscf->session_timeout = NGX_CONF_UNSET;
611626
sscf->session_tickets = NGX_CONF_UNSET;
@@ -675,6 +690,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
675690

676691
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
677692

693+
ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
694+
678695
ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
679696
ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
680697
ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
@@ -913,6 +930,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
913930
return NGX_CONF_ERROR;
914931
}
915932

933+
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
934+
return NGX_CONF_ERROR;
935+
}
936+
916937
return NGX_CONF_OK;
917938
}
918939

@@ -1235,6 +1256,17 @@ ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
12351256
}
12361257

12371258

1259+
static char *
1260+
ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
1261+
{
1262+
#ifndef SSL_CONF_FLAG_FILE
1263+
return "is not supported on this platform";
1264+
#endif
1265+
1266+
return NGX_CONF_OK;
1267+
}
1268+
1269+
12381270
static ngx_int_t
12391271
ngx_http_ssl_init(ngx_conf_t *cf)
12401272
{

src/http/modules/ngx_http_ssl_module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef struct {
4848
ngx_str_t ciphers;
4949

5050
ngx_array_t *passwords;
51+
ngx_array_t *conf_commands;
5152

5253
ngx_shm_zone_t *shm_zone;
5354

src/mail/ngx_mail_ssl_module.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ static char *ngx_mail_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
2626
static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
2727
void *conf);
2828

29+
static char *ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post,
30+
void *data);
31+
2932

3033
static ngx_conf_enum_t ngx_mail_starttls_state[] = {
3134
{ ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
@@ -61,6 +64,10 @@ static ngx_conf_deprecated_t ngx_mail_ssl_deprecated = {
6164
};
6265

6366

67+
static ngx_conf_post_t ngx_mail_ssl_conf_command_post =
68+
{ ngx_mail_ssl_conf_command_check };
69+
70+
6471
static ngx_command_t ngx_mail_ssl_commands[] = {
6572

6673
{ ngx_string("ssl"),
@@ -196,6 +203,13 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
196203
offsetof(ngx_mail_ssl_conf_t, crl),
197204
NULL },
198205

206+
{ ngx_string("ssl_conf_command"),
207+
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE2,
208+
ngx_conf_set_keyval_slot,
209+
NGX_MAIL_SRV_CONF_OFFSET,
210+
offsetof(ngx_mail_ssl_conf_t, conf_commands),
211+
&ngx_mail_ssl_conf_command_post },
212+
199213
ngx_null_command
200214
};
201215

@@ -259,6 +273,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
259273
scf->certificates = NGX_CONF_UNSET_PTR;
260274
scf->certificate_keys = NGX_CONF_UNSET_PTR;
261275
scf->passwords = NGX_CONF_UNSET_PTR;
276+
scf->conf_commands = NGX_CONF_UNSET_PTR;
262277
scf->prefer_server_ciphers = NGX_CONF_UNSET;
263278
scf->verify = NGX_CONF_UNSET_UINT;
264279
scf->verify_depth = NGX_CONF_UNSET_UINT;
@@ -316,6 +331,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
316331

317332
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
318333

334+
ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
335+
319336

320337
conf->ssl.log = cf->log;
321338

@@ -461,6 +478,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
461478
return NGX_CONF_ERROR;
462479
}
463480

481+
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
482+
return NGX_CONF_ERROR;
483+
}
484+
464485
return NGX_CONF_OK;
465486
}
466487

@@ -654,3 +675,14 @@ ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
654675

655676
return NGX_CONF_ERROR;
656677
}
678+
679+
680+
static char *
681+
ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
682+
{
683+
#ifndef SSL_CONF_FLAG_FILE
684+
return "is not supported on this platform";
685+
#endif
686+
687+
return NGX_CONF_OK;
688+
}

src/mail/ngx_mail_ssl_module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef struct {
4848
ngx_str_t ciphers;
4949

5050
ngx_array_t *passwords;
51+
ngx_array_t *conf_commands;
5152

5253
ngx_shm_zone_t *shm_zone;
5354

src/stream/ngx_stream_ssl_module.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
4545
void *conf);
4646
static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
4747
void *conf);
48+
49+
static char *ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post,
50+
void *data);
51+
4852
static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf);
4953

5054

@@ -68,6 +72,10 @@ static ngx_conf_enum_t ngx_stream_ssl_verify[] = {
6872
};
6973

7074

75+
static ngx_conf_post_t ngx_stream_ssl_conf_command_post =
76+
{ ngx_stream_ssl_conf_command_check };
77+
78+
7179
static ngx_command_t ngx_stream_ssl_commands[] = {
7280

7381
{ ngx_string("ssl_handshake_timeout"),
@@ -196,6 +204,13 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
196204
offsetof(ngx_stream_ssl_conf_t, crl),
197205
NULL },
198206

207+
{ ngx_string("ssl_conf_command"),
208+
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
209+
ngx_conf_set_keyval_slot,
210+
NGX_STREAM_SRV_CONF_OFFSET,
211+
offsetof(ngx_stream_ssl_conf_t, conf_commands),
212+
&ngx_stream_ssl_conf_command_post },
213+
199214
ngx_null_command
200215
};
201216

@@ -595,6 +610,7 @@ ngx_stream_ssl_create_conf(ngx_conf_t *cf)
595610
scf->certificates = NGX_CONF_UNSET_PTR;
596611
scf->certificate_keys = NGX_CONF_UNSET_PTR;
597612
scf->passwords = NGX_CONF_UNSET_PTR;
613+
scf->conf_commands = NGX_CONF_UNSET_PTR;
598614
scf->prefer_server_ciphers = NGX_CONF_UNSET;
599615
scf->verify = NGX_CONF_UNSET_UINT;
600616
scf->verify_depth = NGX_CONF_UNSET_UINT;
@@ -650,6 +666,8 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
650666

651667
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
652668

669+
ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
670+
653671

654672
conf->ssl.log = cf->log;
655673

@@ -811,6 +829,10 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
811829
return NGX_CONF_ERROR;
812830
}
813831

832+
if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
833+
return NGX_CONF_ERROR;
834+
}
835+
814836
return NGX_CONF_OK;
815837
}
816838

@@ -1034,6 +1056,17 @@ ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
10341056
}
10351057

10361058

1059+
static char *
1060+
ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
1061+
{
1062+
#ifndef SSL_CONF_FLAG_FILE
1063+
return "is not supported on this platform";
1064+
#endif
1065+
1066+
return NGX_CONF_OK;
1067+
}
1068+
1069+
10371070
static ngx_int_t
10381071
ngx_stream_ssl_init(ngx_conf_t *cf)
10391072
{

src/stream/ngx_stream_ssl_module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ typedef struct {
4646
ngx_str_t ciphers;
4747

4848
ngx_array_t *passwords;
49+
ngx_array_t *conf_commands;
4950

5051
ngx_shm_zone_t *shm_zone;
5152

0 commit comments

Comments
 (0)