Klaus Demo nginx / 99daa8e
merge r2995, r2996, r2997, r2998, r3003, r3141, r3210, r3211, r3232: various SSL fixes and features: *) $ssl_client_verify *) "ssl_verify_client ask" was changed to "ssl_verify_client optional" *) ssl_crl *) delete OpenSSL pre-0.9.7 compatibility: the sources were not actually compatible with OpenSSL 0.9.6 since ssl_session_cache introduction *) fix memory corruption in $ssl_client_cert *) issue SNI warning instead of failure: this is too common case *) use ngx_log_error(), since OpenSSL does not set an error on the failure *) add SNI support in -V output Igor Sysoev 12 years ago
7 changed file(s) with 124 addition(s) and 109 deletion(s). Raw diff Collapse all Expand all
238238 #ifdef NGX_COMPILER
239239 ngx_log_stderr(0, "built by " NGX_COMPILER);
240240 #endif
241 #if (NGX_SSL)
242 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
243 ngx_log_stderr(0, "TLS SNI support enabled");
244 #else
245 ngx_log_stderr(0, "TLS SNI support disabled");
246 #endif
247 #endif
241248 ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE);
242249 }
243250
9696 ngx_int_t
9797 ngx_ssl_init(ngx_log_t *log)
9898 {
99 #if OPENSSL_VERSION_NUMBER >= 0x00907000
10099 OPENSSL_config(NULL);
101 #endif
102100
103101 SSL_library_init();
104102 SSL_load_error_strings();
105103
106 #if (NGX_SSL_ENGINE)
107104 ENGINE_load_builtin_engines();
108 #endif
109105
110106 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
111107
168164 SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
169165 SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
170166
171 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
172167 SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
173 #endif
174168
175169 SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
176170
261255 ERR_clear_error();
262256
263257 SSL_CTX_set_client_CA_list(ssl->ctx, list);
258
259 return NGX_OK;
260 }
261
262
263 ngx_int_t
264 ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
265 {
266 X509_STORE *store;
267 X509_LOOKUP *lookup;
268
269 if (crl->len == 0) {
270 return NGX_OK;
271 }
272
273 if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
274 return NGX_ERROR;
275 }
276
277 store = SSL_CTX_get_cert_store(ssl->ctx);
278
279 if (store == NULL) {
280 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
281 "SSL_CTX_get_cert_store() failed");
282 return NGX_ERROR;
283 }
284
285 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
286
287 if (lookup == NULL) {
288 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
289 "X509_STORE_add_lookup() failed");
290 return NGX_ERROR;
291 }
292
293 if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
294 == 0)
295 {
296 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
297 "X509_LOOKUP_load_file(\"%s\") failed", crl->data);
298 return NGX_ERROR;
299 }
300
301 X509_STORE_set_flags(store,
302 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
264303
265304 return NGX_OK;
266305 }
12001239 if (err == NGX_ECONNRESET
12011240 || err == NGX_EPIPE
12021241 || err == NGX_ENOTCONN
1203 #if !(NGX_CRIT_ETIMEDOUT)
12041242 || err == NGX_ETIMEDOUT
1205 #endif
12061243 || err == NGX_ECONNREFUSED
12071244 || err == NGX_ENETDOWN
12081245 || err == NGX_ENETUNREACH
19732010
19742011 p = s->data;
19752012
1976 for (i = 0; i < len; i++) {
2013 for (i = 0; i < cert.len - 1; i++) {
19772014 *p++ = cert.data[i];
19782015 if (cert.data[i] == LF) {
19792016 *p++ = '\t';
21072144 }
21082145
21092146
2147 ngx_int_t
2148 ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
2149 {
2150 X509 *cert;
2151
2152 if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
2153 s->len = sizeof("FAILED") - 1;
2154 s->data = (u_char *) "FAILED";
2155
2156 return NGX_OK;
2157 }
2158
2159 cert = SSL_get_peer_certificate(c->ssl->connection);
2160
2161 if (cert) {
2162 s->len = sizeof("SUCCESS") - 1;
2163 s->data = (u_char *) "SUCCESS";
2164
2165 } else {
2166 s->len = sizeof("NONE") - 1;
2167 s->data = (u_char *) "NONE";
2168 }
2169
2170 X509_free(cert);
2171
2172 return NGX_OK;
2173 }
2174
2175
21102176 static void *
21112177 ngx_openssl_create_conf(ngx_cycle_t *cycle)
21122178 {
21302196 static char *
21312197 ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
21322198 {
2133 #if (NGX_SSL_ENGINE)
21342199 ngx_openssl_conf_t *oscf = conf;
21352200
21362201 ENGINE *engine;
21652230 ENGINE_free(engine);
21662231
21672232 return NGX_CONF_OK;
2168
2169 #else
2170
2171 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2172 "\"ssl_engine\" directive is available only in "
2173 "OpenSSL 0.9.7 and higher,");
2174
2175 return NGX_CONF_ERROR;
2176
2177 #endif
21782233 }
21792234
21802235
21812236 static void
21822237 ngx_openssl_exit(ngx_cycle_t *cycle)
21832238 {
2184 #if (NGX_SSL_ENGINE)
21852239 ENGINE_cleanup();
2186 #endif
2187 }
2240 }
1212
1313 #include <openssl/ssl.h>
1414 #include <openssl/err.h>
15
16 #if OPENSSL_VERSION_NUMBER >= 0x00907000
1715 #include <openssl/conf.h>
1816 #include <openssl/engine.h>
19 #define NGX_SSL_ENGINE 1
20 #endif
2117
2218 #define NGX_SSL_NAME "OpenSSL"
2319
9995 ngx_str_t *cert, ngx_str_t *key);
10096 ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
10197 ngx_str_t *cert, ngx_int_t depth);
98 ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
10299 ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
103100 ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
104101 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
130127 ngx_str_t *s);
131128 ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool,
132129 ngx_str_t *s);
130 ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool,
131 ngx_str_t *s);
133132
134133
135134 ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
2929 void *conf);
3030 static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
3131 void *conf);
32
33 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
34
35 static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
36 void *conf);
37
38 static char ngx_http_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
39
40 #endif
4132
4233
4334 static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
5142 static ngx_conf_enum_t ngx_http_ssl_verify[] = {
5243 { ngx_string("off"), 0 },
5344 { ngx_string("on"), 1 },
54 { ngx_string("ask"), 2 },
45 { ngx_string("optional"), 2 },
5546 { ngx_null_string, 0 }
5647 };
5748
123114
124115 { ngx_string("ssl_prefer_server_ciphers"),
125116 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
126 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
127117 ngx_conf_set_flag_slot,
128118 NGX_HTTP_SRV_CONF_OFFSET,
129119 offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
130120 NULL },
131 #else
132 ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 },
133 #endif
134121
135122 { ngx_string("ssl_session_cache"),
136123 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
144131 ngx_conf_set_sec_slot,
145132 NGX_HTTP_SRV_CONF_OFFSET,
146133 offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
134 NULL },
135
136 { ngx_string("ssl_crl"),
137 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
138 ngx_conf_set_str_slot,
139 NGX_HTTP_SRV_CONF_OFFSET,
140 offsetof(ngx_http_ssl_srv_conf_t, crl),
147141 NULL },
148142
149143 ngx_null_command
205199 { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
206200 (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
207201
202 { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
203 (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
204
208205 { ngx_null_string, NULL, NULL, 0, 0, 0 }
209206 };
210207
312309 * sscf->certificate_key = { 0, NULL };
313310 * sscf->dhparam = { 0, NULL };
314311 * sscf->client_certificate = { 0, NULL };
312 * sscf->crl = { 0, NULL };
315313 * sscf->ciphers.len = 0;
316314 * sscf->ciphers.data = NULL;
317315 * sscf->shm_zone = NULL;
358356
359357 ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
360358 "");
359 ngx_conf_merge_str_value(conf->crl, prev->crl, "");
361360
362361 ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
363362
406405 ngx_http_ssl_servername)
407406 == 0)
408407 {
409 ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
410 "SSL_CTX_set_tlsext_servername_callback() failed");
411 return NGX_CONF_ERROR;
408 ngx_log_error(NGX_LOG_WARN, cf->log, 0,
409 "nginx was built with SNI support, however, now it is linked "
410 "dynamically to an OpenSSL library which has no tlsext support, "
411 "therefore SNI is not available");
412412 }
413413
414414 #endif
452452 {
453453 return NGX_CONF_ERROR;
454454 }
455 }
456
457 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
455
456 if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
457 return NGX_CONF_ERROR;
458 }
459 }
458460
459461 if (conf->prefer_server_ciphers) {
460462 SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
461463 }
462
463 #endif
464464
465465 /* a temporary 512-bit RSA key is required for export versions of MSIE */
466466 if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
619619
620620 return NGX_CONF_ERROR;
621621 }
622
623
624 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
625
626 static char *
627 ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
628 {
629 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
630 "\"%V\" directive is available only in %s,",
631 &cmd->name, cmd->post);
632
633 return NGX_CONF_ERROR;
634 }
635
636 #endif
3232 ngx_str_t certificate_key;
3333 ngx_str_t dhparam;
3434 ngx_str_t client_certificate;
35 ngx_str_t crl;
3536
3637 ngx_str_t ciphers;
3738
15191519
15201520 sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
15211521
1522 if (sscf->verify == 1) {
1522 if (sscf->verify) {
15231523 rc = SSL_get_verify_result(c->ssl->connection);
15241524
15251525 if (rc != X509_V_OK) {
15341534 return;
15351535 }
15361536
1537 cert = SSL_get_peer_certificate(c->ssl->connection);
1538
1539 if (cert == NULL) {
1540 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1541 "client sent no required SSL certificate");
1542
1543 ngx_ssl_remove_cached_session(sscf->ssl.ctx,
1537 if (sscf->verify == 1) {
1538 cert = SSL_get_peer_certificate(c->ssl->connection);
1539
1540 if (cert == NULL) {
1541 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1542 "client sent no required SSL certificate");
1543
1544 ngx_ssl_remove_cached_session(sscf->ssl.ctx,
15441545 (SSL_get0_session(c->ssl->connection)));
15451546
1546 ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
1547 return;
1548 }
1549
1550 X509_free(cert);
1547 ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
1548 return;
1549 }
1550
1551 X509_free(cert);
1552 }
15511553 }
15521554 }
15531555
2121 static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
2222 void *conf);
2323
24 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
25
26 static char *ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
27 void *conf);
28
29 static char ngx_mail_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
30
31 #endif
32
3324
3425 static ngx_conf_enum_t ngx_http_starttls_state[] = {
3526 { ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
10192
10293 { ngx_string("ssl_prefer_server_ciphers"),
10394 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
104 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
10595 ngx_conf_set_flag_slot,
10696 NGX_MAIL_SRV_CONF_OFFSET,
10797 offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers),
10898 NULL },
109 #else
110 ngx_mail_ssl_nosupported, 0, 0, ngx_mail_ssl_openssl097 },
111 #endif
11299
113100 { ngx_string("ssl_session_cache"),
114101 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
296283 }
297284 }
298285
299 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
300
301286 if (conf->prefer_server_ciphers) {
302287 SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
303288 }
304
305 #endif
306289
307290 if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
308291 return NGX_CONF_ERROR;
491474
492475 return NGX_CONF_ERROR;
493476 }
494
495
496 #if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
497
498 static char *
499 ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
500 {
501 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
502 "\"%V\" directive is available only in %s,",
503 &cmd->name, cmd->post);
504
505 return NGX_CONF_ERROR;
506 }
507
508 #endif