Annotation of embedaddon/nginx/src/http/modules/ngx_http_ssl_module.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (C) Igor Sysoev
4: * Copyright (C) Nginx, Inc.
5: */
6:
7:
8: #include <ngx_config.h>
9: #include <ngx_core.h>
10: #include <ngx_http.h>
11:
12:
13: typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
14: ngx_pool_t *pool, ngx_str_t *s);
15:
16:
17: #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
18: #define NGX_DEFAULT_ECDH_CURVE "prime256v1"
19:
20:
21: #ifdef TLSEXT_TYPE_next_proto_neg
22: static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
23: const unsigned char **out, unsigned int *outlen, void *arg);
24: #endif
25:
26: static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
27: ngx_http_variable_value_t *v, uintptr_t data);
28: static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
29: ngx_http_variable_value_t *v, uintptr_t data);
30:
31: static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
32: static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
33: static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
34: void *parent, void *child);
35:
36: static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
37: void *conf);
38: static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
39: void *conf);
40:
41: static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
42:
43:
44: static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
45: { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
46: { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
47: { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
48: { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
49: { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
50: { ngx_null_string, 0 }
51: };
52:
53:
54: static ngx_conf_enum_t ngx_http_ssl_verify[] = {
55: { ngx_string("off"), 0 },
56: { ngx_string("on"), 1 },
57: { ngx_string("optional"), 2 },
58: { ngx_string("optional_no_ca"), 3 },
59: { ngx_null_string, 0 }
60: };
61:
62:
63: static ngx_command_t ngx_http_ssl_commands[] = {
64:
65: { ngx_string("ssl"),
66: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
67: ngx_http_ssl_enable,
68: NGX_HTTP_SRV_CONF_OFFSET,
69: offsetof(ngx_http_ssl_srv_conf_t, enable),
70: NULL },
71:
72: { ngx_string("ssl_certificate"),
73: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
74: ngx_conf_set_str_slot,
75: NGX_HTTP_SRV_CONF_OFFSET,
76: offsetof(ngx_http_ssl_srv_conf_t, certificate),
77: NULL },
78:
79: { ngx_string("ssl_certificate_key"),
80: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
81: ngx_conf_set_str_slot,
82: NGX_HTTP_SRV_CONF_OFFSET,
83: offsetof(ngx_http_ssl_srv_conf_t, certificate_key),
84: NULL },
85:
86: { ngx_string("ssl_dhparam"),
87: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
88: ngx_conf_set_str_slot,
89: NGX_HTTP_SRV_CONF_OFFSET,
90: offsetof(ngx_http_ssl_srv_conf_t, dhparam),
91: NULL },
92:
93: { ngx_string("ssl_ecdh_curve"),
94: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
95: ngx_conf_set_str_slot,
96: NGX_HTTP_SRV_CONF_OFFSET,
97: offsetof(ngx_http_ssl_srv_conf_t, ecdh_curve),
98: NULL },
99:
100: { ngx_string("ssl_protocols"),
101: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
102: ngx_conf_set_bitmask_slot,
103: NGX_HTTP_SRV_CONF_OFFSET,
104: offsetof(ngx_http_ssl_srv_conf_t, protocols),
105: &ngx_http_ssl_protocols },
106:
107: { ngx_string("ssl_ciphers"),
108: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
109: ngx_conf_set_str_slot,
110: NGX_HTTP_SRV_CONF_OFFSET,
111: offsetof(ngx_http_ssl_srv_conf_t, ciphers),
112: NULL },
113:
114: { ngx_string("ssl_verify_client"),
115: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
116: ngx_conf_set_enum_slot,
117: NGX_HTTP_SRV_CONF_OFFSET,
118: offsetof(ngx_http_ssl_srv_conf_t, verify),
119: &ngx_http_ssl_verify },
120:
121: { ngx_string("ssl_verify_depth"),
122: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
123: ngx_conf_set_num_slot,
124: NGX_HTTP_SRV_CONF_OFFSET,
125: offsetof(ngx_http_ssl_srv_conf_t, verify_depth),
126: NULL },
127:
128: { ngx_string("ssl_client_certificate"),
129: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
130: ngx_conf_set_str_slot,
131: NGX_HTTP_SRV_CONF_OFFSET,
132: offsetof(ngx_http_ssl_srv_conf_t, client_certificate),
133: NULL },
134:
135: { ngx_string("ssl_trusted_certificate"),
136: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
137: ngx_conf_set_str_slot,
138: NGX_HTTP_SRV_CONF_OFFSET,
139: offsetof(ngx_http_ssl_srv_conf_t, trusted_certificate),
140: NULL },
141:
142: { ngx_string("ssl_prefer_server_ciphers"),
143: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
144: ngx_conf_set_flag_slot,
145: NGX_HTTP_SRV_CONF_OFFSET,
146: offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
147: NULL },
148:
149: { ngx_string("ssl_session_cache"),
150: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
151: ngx_http_ssl_session_cache,
152: NGX_HTTP_SRV_CONF_OFFSET,
153: 0,
154: NULL },
155:
156: { ngx_string("ssl_session_timeout"),
157: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
158: ngx_conf_set_sec_slot,
159: NGX_HTTP_SRV_CONF_OFFSET,
160: offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
161: NULL },
162:
163: { ngx_string("ssl_crl"),
164: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
165: ngx_conf_set_str_slot,
166: NGX_HTTP_SRV_CONF_OFFSET,
167: offsetof(ngx_http_ssl_srv_conf_t, crl),
168: NULL },
169:
170: { ngx_string("ssl_stapling"),
171: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
172: ngx_conf_set_flag_slot,
173: NGX_HTTP_SRV_CONF_OFFSET,
174: offsetof(ngx_http_ssl_srv_conf_t, stapling),
175: NULL },
176:
177: { ngx_string("ssl_stapling_file"),
178: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
179: ngx_conf_set_str_slot,
180: NGX_HTTP_SRV_CONF_OFFSET,
181: offsetof(ngx_http_ssl_srv_conf_t, stapling_file),
182: NULL },
183:
184: { ngx_string("ssl_stapling_responder"),
185: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
186: ngx_conf_set_str_slot,
187: NGX_HTTP_SRV_CONF_OFFSET,
188: offsetof(ngx_http_ssl_srv_conf_t, stapling_responder),
189: NULL },
190:
191: { ngx_string("ssl_stapling_verify"),
192: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
193: ngx_conf_set_flag_slot,
194: NGX_HTTP_SRV_CONF_OFFSET,
195: offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
196: NULL },
197:
198: ngx_null_command
199: };
200:
201:
202: static ngx_http_module_t ngx_http_ssl_module_ctx = {
203: ngx_http_ssl_add_variables, /* preconfiguration */
204: ngx_http_ssl_init, /* postconfiguration */
205:
206: NULL, /* create main configuration */
207: NULL, /* init main configuration */
208:
209: ngx_http_ssl_create_srv_conf, /* create server configuration */
210: ngx_http_ssl_merge_srv_conf, /* merge server configuration */
211:
212: NULL, /* create location configuration */
213: NULL /* merge location configuration */
214: };
215:
216:
217: ngx_module_t ngx_http_ssl_module = {
218: NGX_MODULE_V1,
219: &ngx_http_ssl_module_ctx, /* module context */
220: ngx_http_ssl_commands, /* module directives */
221: NGX_HTTP_MODULE, /* module type */
222: NULL, /* init master */
223: NULL, /* init module */
224: NULL, /* init process */
225: NULL, /* init thread */
226: NULL, /* exit thread */
227: NULL, /* exit process */
228: NULL, /* exit master */
229: NGX_MODULE_V1_PADDING
230: };
231:
232:
233: static ngx_http_variable_t ngx_http_ssl_vars[] = {
234:
235: { ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
236: (uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
237:
238: { ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
239: (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
240:
241: { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
242: (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
243:
244: { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
245: (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
246:
247: { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable,
248: (uintptr_t) ngx_ssl_get_raw_certificate,
249: NGX_HTTP_VAR_CHANGEABLE, 0 },
250:
251: { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
252: (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
253:
254: { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
255: (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
256:
257: { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
258: (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
259:
260: { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
261: (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
262:
263: { ngx_null_string, NULL, NULL, 0, 0, 0 }
264: };
265:
266:
267: static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
268:
269:
270: #ifdef TLSEXT_TYPE_next_proto_neg
271:
272: #define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1"
273:
274: static int
275: ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
276: const unsigned char **out, unsigned int *outlen, void *arg)
277: {
278: #if (NGX_HTTP_SPDY || NGX_DEBUG)
279: ngx_connection_t *c;
280:
281: c = ngx_ssl_get_connection(ssl_conn);
282: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised");
283: #endif
284:
285: #if (NGX_HTTP_SPDY)
286: {
287: ngx_http_connection_t *hc;
288:
289: hc = c->data;
290:
291: if (hc->addr_conf->spdy) {
292: *out = (unsigned char *) NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
293: *outlen = sizeof(NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
294:
295: return SSL_TLSEXT_ERR_OK;
296: }
297: }
298: #endif
299:
300: *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
301: *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
302:
303: return SSL_TLSEXT_ERR_OK;
304: }
305:
306: #endif
307:
308:
309: static ngx_int_t
310: ngx_http_ssl_static_variable(ngx_http_request_t *r,
311: ngx_http_variable_value_t *v, uintptr_t data)
312: {
313: ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
314:
315: size_t len;
316: ngx_str_t s;
317:
318: if (r->connection->ssl) {
319:
320: (void) handler(r->connection, NULL, &s);
321:
322: v->data = s.data;
323:
324: for (len = 0; v->data[len]; len++) { /* void */ }
325:
326: v->len = len;
327: v->valid = 1;
328: v->no_cacheable = 0;
329: v->not_found = 0;
330:
331: return NGX_OK;
332: }
333:
334: v->not_found = 1;
335:
336: return NGX_OK;
337: }
338:
339:
340: static ngx_int_t
341: ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
342: uintptr_t data)
343: {
344: ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
345:
346: ngx_str_t s;
347:
348: if (r->connection->ssl) {
349:
350: if (handler(r->connection, r->pool, &s) != NGX_OK) {
351: return NGX_ERROR;
352: }
353:
354: v->len = s.len;
355: v->data = s.data;
356:
357: if (v->len) {
358: v->valid = 1;
359: v->no_cacheable = 0;
360: v->not_found = 0;
361:
362: return NGX_OK;
363: }
364: }
365:
366: v->not_found = 1;
367:
368: return NGX_OK;
369: }
370:
371:
372: static ngx_int_t
373: ngx_http_ssl_add_variables(ngx_conf_t *cf)
374: {
375: ngx_http_variable_t *var, *v;
376:
377: for (v = ngx_http_ssl_vars; v->name.len; v++) {
378: var = ngx_http_add_variable(cf, &v->name, v->flags);
379: if (var == NULL) {
380: return NGX_ERROR;
381: }
382:
383: var->get_handler = v->get_handler;
384: var->data = v->data;
385: }
386:
387: return NGX_OK;
388: }
389:
390:
391: static void *
392: ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
393: {
394: ngx_http_ssl_srv_conf_t *sscf;
395:
396: sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
397: if (sscf == NULL) {
398: return NULL;
399: }
400:
401: /*
402: * set by ngx_pcalloc():
403: *
404: * sscf->protocols = 0;
405: * sscf->certificate = { 0, NULL };
406: * sscf->certificate_key = { 0, NULL };
407: * sscf->dhparam = { 0, NULL };
408: * sscf->ecdh_curve = { 0, NULL };
409: * sscf->client_certificate = { 0, NULL };
410: * sscf->trusted_certificate = { 0, NULL };
411: * sscf->crl = { 0, NULL };
412: * sscf->ciphers = { 0, NULL };
413: * sscf->shm_zone = NULL;
414: * sscf->stapling_file = { 0, NULL };
415: * sscf->stapling_responder = { 0, NULL };
416: */
417:
418: sscf->enable = NGX_CONF_UNSET;
419: sscf->prefer_server_ciphers = NGX_CONF_UNSET;
420: sscf->verify = NGX_CONF_UNSET_UINT;
421: sscf->verify_depth = NGX_CONF_UNSET_UINT;
422: sscf->builtin_session_cache = NGX_CONF_UNSET;
423: sscf->session_timeout = NGX_CONF_UNSET;
424: sscf->stapling = NGX_CONF_UNSET;
425: sscf->stapling_verify = NGX_CONF_UNSET;
426:
427: return sscf;
428: }
429:
430:
431: static char *
432: ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
433: {
434: ngx_http_ssl_srv_conf_t *prev = parent;
435: ngx_http_ssl_srv_conf_t *conf = child;
436:
437: ngx_pool_cleanup_t *cln;
438:
439: if (conf->enable == NGX_CONF_UNSET) {
440: if (prev->enable == NGX_CONF_UNSET) {
441: conf->enable = 0;
442:
443: } else {
444: conf->enable = prev->enable;
445: conf->file = prev->file;
446: conf->line = prev->line;
447: }
448: }
449:
450: ngx_conf_merge_value(conf->session_timeout,
451: prev->session_timeout, 300);
452:
453: ngx_conf_merge_value(conf->prefer_server_ciphers,
454: prev->prefer_server_ciphers, 0);
455:
456: ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
457: (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1
458: |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
459:
460: ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
461: ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
462:
463: ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
464: ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
465:
466: ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
467:
468: ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
469: "");
470: ngx_conf_merge_str_value(conf->trusted_certificate,
471: prev->trusted_certificate, "");
472: ngx_conf_merge_str_value(conf->crl, prev->crl, "");
473:
474: ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
475: NGX_DEFAULT_ECDH_CURVE);
476:
477: ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
478:
479: ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
480: ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
481: ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
482: ngx_conf_merge_str_value(conf->stapling_responder,
483: prev->stapling_responder, "");
484:
485: conf->ssl.log = cf->log;
486:
487: if (conf->enable) {
488:
489: if (conf->certificate.len == 0) {
490: ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
491: "no \"ssl_certificate\" is defined for "
492: "the \"ssl\" directive in %s:%ui",
493: conf->file, conf->line);
494: return NGX_CONF_ERROR;
495: }
496:
497: if (conf->certificate_key.len == 0) {
498: ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
499: "no \"ssl_certificate_key\" is defined for "
500: "the \"ssl\" directive in %s:%ui",
501: conf->file, conf->line);
502: return NGX_CONF_ERROR;
503: }
504:
505: } else {
506:
507: if (conf->certificate.len == 0) {
508: return NGX_CONF_OK;
509: }
510:
511: if (conf->certificate_key.len == 0) {
512: ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
513: "no \"ssl_certificate_key\" is defined "
514: "for certificate \"%V\"", &conf->certificate);
515: return NGX_CONF_ERROR;
516: }
517: }
518:
519: if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
520: return NGX_CONF_ERROR;
521: }
522:
523: #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
524:
525: if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
526: ngx_http_ssl_servername)
527: == 0)
528: {
529: ngx_log_error(NGX_LOG_WARN, cf->log, 0,
530: "nginx was built with SNI support, however, now it is linked "
531: "dynamically to an OpenSSL library which has no tlsext support, "
532: "therefore SNI is not available");
533: }
534:
535: #endif
536:
537: #ifdef TLSEXT_TYPE_next_proto_neg
538: SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
539: ngx_http_ssl_npn_advertised, NULL);
540: #endif
541:
542: cln = ngx_pool_cleanup_add(cf->pool, 0);
543: if (cln == NULL) {
544: return NGX_CONF_ERROR;
545: }
546:
547: cln->handler = ngx_ssl_cleanup_ctx;
548: cln->data = &conf->ssl;
549:
550: if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
551: &conf->certificate_key)
552: != NGX_OK)
553: {
554: return NGX_CONF_ERROR;
555: }
556:
557: if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
558: (const char *) conf->ciphers.data)
559: == 0)
560: {
561: ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
562: "SSL_CTX_set_cipher_list(\"%V\") failed",
563: &conf->ciphers);
564: }
565:
566: if (conf->verify) {
567:
568: if (conf->client_certificate.len == 0 && conf->verify != 3) {
569: ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
570: "no ssl_client_certificate for ssl_client_verify");
571: return NGX_CONF_ERROR;
572: }
573:
574: if (ngx_ssl_client_certificate(cf, &conf->ssl,
575: &conf->client_certificate,
576: conf->verify_depth)
577: != NGX_OK)
578: {
579: return NGX_CONF_ERROR;
580: }
581: }
582:
583: if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
584: &conf->trusted_certificate,
585: conf->verify_depth)
586: != NGX_OK)
587: {
588: return NGX_CONF_ERROR;
589: }
590:
591: if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
592: return NGX_CONF_ERROR;
593: }
594:
595: if (conf->prefer_server_ciphers) {
596: SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
597: }
598:
599: /* a temporary 512-bit RSA key is required for export versions of MSIE */
600: SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
601:
602: if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
603: return NGX_CONF_ERROR;
604: }
605:
606: if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
607: return NGX_CONF_ERROR;
608: }
609:
610: ngx_conf_merge_value(conf->builtin_session_cache,
611: prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
612:
613: if (conf->shm_zone == NULL) {
614: conf->shm_zone = prev->shm_zone;
615: }
616:
617: if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
618: conf->builtin_session_cache,
619: conf->shm_zone, conf->session_timeout)
620: != NGX_OK)
621: {
622: return NGX_CONF_ERROR;
623: }
624:
625: if (conf->stapling) {
626:
627: if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
628: &conf->stapling_responder, conf->stapling_verify)
629: != NGX_OK)
630: {
631: return NGX_CONF_ERROR;
632: }
633:
634: }
635:
636: return NGX_CONF_OK;
637: }
638:
639:
640: static char *
641: ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
642: {
643: ngx_http_ssl_srv_conf_t *sscf = conf;
644:
645: char *rv;
646:
647: rv = ngx_conf_set_flag_slot(cf, cmd, conf);
648:
649: if (rv != NGX_CONF_OK) {
650: return rv;
651: }
652:
653: sscf->file = cf->conf_file->file.name.data;
654: sscf->line = cf->conf_file->line;
655:
656: return NGX_CONF_OK;
657: }
658:
659:
660: static char *
661: ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
662: {
663: ngx_http_ssl_srv_conf_t *sscf = conf;
664:
665: size_t len;
666: ngx_str_t *value, name, size;
667: ngx_int_t n;
668: ngx_uint_t i, j;
669:
670: value = cf->args->elts;
671:
672: for (i = 1; i < cf->args->nelts; i++) {
673:
674: if (ngx_strcmp(value[i].data, "off") == 0) {
675: sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
676: continue;
677: }
678:
679: if (ngx_strcmp(value[i].data, "none") == 0) {
680: sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
681: continue;
682: }
683:
684: if (ngx_strcmp(value[i].data, "builtin") == 0) {
685: sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
686: continue;
687: }
688:
689: if (value[i].len > sizeof("builtin:") - 1
690: && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
691: == 0)
692: {
693: n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
694: value[i].len - (sizeof("builtin:") - 1));
695:
696: if (n == NGX_ERROR) {
697: goto invalid;
698: }
699:
700: sscf->builtin_session_cache = n;
701:
702: continue;
703: }
704:
705: if (value[i].len > sizeof("shared:") - 1
706: && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
707: == 0)
708: {
709: len = 0;
710:
711: for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
712: if (value[i].data[j] == ':') {
713: break;
714: }
715:
716: len++;
717: }
718:
719: if (len == 0) {
720: goto invalid;
721: }
722:
723: name.len = len;
724: name.data = value[i].data + sizeof("shared:") - 1;
725:
726: size.len = value[i].len - j - 1;
727: size.data = name.data + len + 1;
728:
729: n = ngx_parse_size(&size);
730:
731: if (n == NGX_ERROR) {
732: goto invalid;
733: }
734:
735: if (n < (ngx_int_t) (8 * ngx_pagesize)) {
736: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
737: "session cache \"%V\" is too small",
738: &value[i]);
739:
740: return NGX_CONF_ERROR;
741: }
742:
743: sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
744: &ngx_http_ssl_module);
745: if (sscf->shm_zone == NULL) {
746: return NGX_CONF_ERROR;
747: }
748:
749: sscf->shm_zone->init = ngx_ssl_session_cache_init;
750:
751: continue;
752: }
753:
754: goto invalid;
755: }
756:
757: if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
758: sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
759: }
760:
761: return NGX_CONF_OK;
762:
763: invalid:
764:
765: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
766: "invalid session cache \"%V\"", &value[i]);
767:
768: return NGX_CONF_ERROR;
769: }
770:
771:
772: static ngx_int_t
773: ngx_http_ssl_init(ngx_conf_t *cf)
774: {
775: ngx_uint_t s;
776: ngx_http_ssl_srv_conf_t *sscf;
777: ngx_http_core_loc_conf_t *clcf;
778: ngx_http_core_srv_conf_t **cscfp;
779: ngx_http_core_main_conf_t *cmcf;
780:
781: cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
782: cscfp = cmcf->servers.elts;
783:
784: for (s = 0; s < cmcf->servers.nelts; s++) {
785:
786: sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
787:
788: if (sscf->ssl.ctx == NULL || !sscf->stapling) {
789: continue;
790: }
791:
792: clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
793:
794: if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
795: clcf->resolver_timeout)
796: != NGX_OK)
797: {
798: return NGX_ERROR;
799: }
800: }
801:
802: return NGX_OK;
803: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>