xref: /nginx/src/http/modules/ngx_http_ssl_module.c (revision 7935:eb6c77e6d55d)
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  "auto"
19 
20 #define NGX_HTTP_ALPN_PROTO     "\x08http/1.1"
21 
22 
23 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
24 static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
25     const unsigned char **out, unsigned char *outlen,
26     const unsigned char *in, unsigned int inlen, void *arg);
27 #endif
28 
29 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
30     ngx_http_variable_value_t *v, uintptr_t data);
31 static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
32     ngx_http_variable_value_t *v, uintptr_t data);
33 
34 static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
35 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
36 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
37     void *parent, void *child);
38 
39 static ngx_int_t ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
40     ngx_http_ssl_srv_conf_t *conf);
41 
42 static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
43     void *conf);
44 static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
45     void *conf);
46 static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
47     void *conf);
48 static char *ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
49     void *conf);
50 
51 static char *ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post,
52     void *data);
53 
54 static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
55 
56 
57 static ngx_conf_bitmask_t  ngx_http_ssl_protocols[] = {
58     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
59     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
60     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
61     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
62     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
63     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
64     { ngx_null_string, 0 }
65 };
66 
67 
68 static ngx_conf_enum_t  ngx_http_ssl_verify[] = {
69     { ngx_string("off"), 0 },
70     { ngx_string("on"), 1 },
71     { ngx_string("optional"), 2 },
72     { ngx_string("optional_no_ca"), 3 },
73     { ngx_null_string, 0 }
74 };
75 
76 
77 static ngx_conf_enum_t  ngx_http_ssl_ocsp[] = {
78     { ngx_string("off"), 0 },
79     { ngx_string("on"), 1 },
80     { ngx_string("leaf"), 2 },
81     { ngx_null_string, 0 }
82 };
83 
84 
85 static ngx_conf_deprecated_t  ngx_http_ssl_deprecated = {
86     ngx_conf_deprecated, "ssl", "listen ... ssl"
87 };
88 
89 
90 static ngx_conf_post_t  ngx_http_ssl_conf_command_post =
91     { ngx_http_ssl_conf_command_check };
92 
93 
94 static ngx_command_t  ngx_http_ssl_commands[] = {
95 
96     { ngx_string("ssl"),
97       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
98       ngx_http_ssl_enable,
99       NGX_HTTP_SRV_CONF_OFFSET,
100       offsetof(ngx_http_ssl_srv_conf_t, enable),
101       &ngx_http_ssl_deprecated },
102 
103     { ngx_string("ssl_certificate"),
104       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
105       ngx_conf_set_str_array_slot,
106       NGX_HTTP_SRV_CONF_OFFSET,
107       offsetof(ngx_http_ssl_srv_conf_t, certificates),
108       NULL },
109 
110     { ngx_string("ssl_certificate_key"),
111       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
112       ngx_conf_set_str_array_slot,
113       NGX_HTTP_SRV_CONF_OFFSET,
114       offsetof(ngx_http_ssl_srv_conf_t, certificate_keys),
115       NULL },
116 
117     { ngx_string("ssl_password_file"),
118       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
119       ngx_http_ssl_password_file,
120       NGX_HTTP_SRV_CONF_OFFSET,
121       0,
122       NULL },
123 
124     { ngx_string("ssl_dhparam"),
125       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
126       ngx_conf_set_str_slot,
127       NGX_HTTP_SRV_CONF_OFFSET,
128       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
129       NULL },
130 
131     { ngx_string("ssl_ecdh_curve"),
132       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
133       ngx_conf_set_str_slot,
134       NGX_HTTP_SRV_CONF_OFFSET,
135       offsetof(ngx_http_ssl_srv_conf_t, ecdh_curve),
136       NULL },
137 
138     { ngx_string("ssl_protocols"),
139       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
140       ngx_conf_set_bitmask_slot,
141       NGX_HTTP_SRV_CONF_OFFSET,
142       offsetof(ngx_http_ssl_srv_conf_t, protocols),
143       &ngx_http_ssl_protocols },
144 
145     { ngx_string("ssl_ciphers"),
146       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
147       ngx_conf_set_str_slot,
148       NGX_HTTP_SRV_CONF_OFFSET,
149       offsetof(ngx_http_ssl_srv_conf_t, ciphers),
150       NULL },
151 
152     { ngx_string("ssl_buffer_size"),
153       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
154       ngx_conf_set_size_slot,
155       NGX_HTTP_SRV_CONF_OFFSET,
156       offsetof(ngx_http_ssl_srv_conf_t, buffer_size),
157       NULL },
158 
159     { ngx_string("ssl_verify_client"),
160       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
161       ngx_conf_set_enum_slot,
162       NGX_HTTP_SRV_CONF_OFFSET,
163       offsetof(ngx_http_ssl_srv_conf_t, verify),
164       &ngx_http_ssl_verify },
165 
166     { ngx_string("ssl_verify_depth"),
167       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
168       ngx_conf_set_num_slot,
169       NGX_HTTP_SRV_CONF_OFFSET,
170       offsetof(ngx_http_ssl_srv_conf_t, verify_depth),
171       NULL },
172 
173     { ngx_string("ssl_client_certificate"),
174       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
175       ngx_conf_set_str_slot,
176       NGX_HTTP_SRV_CONF_OFFSET,
177       offsetof(ngx_http_ssl_srv_conf_t, client_certificate),
178       NULL },
179 
180     { ngx_string("ssl_trusted_certificate"),
181       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
182       ngx_conf_set_str_slot,
183       NGX_HTTP_SRV_CONF_OFFSET,
184       offsetof(ngx_http_ssl_srv_conf_t, trusted_certificate),
185       NULL },
186 
187     { ngx_string("ssl_prefer_server_ciphers"),
188       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
189       ngx_conf_set_flag_slot,
190       NGX_HTTP_SRV_CONF_OFFSET,
191       offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
192       NULL },
193 
194     { ngx_string("ssl_session_cache"),
195       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
196       ngx_http_ssl_session_cache,
197       NGX_HTTP_SRV_CONF_OFFSET,
198       0,
199       NULL },
200 
201     { ngx_string("ssl_session_tickets"),
202       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
203       ngx_conf_set_flag_slot,
204       NGX_HTTP_SRV_CONF_OFFSET,
205       offsetof(ngx_http_ssl_srv_conf_t, session_tickets),
206       NULL },
207 
208     { ngx_string("ssl_session_ticket_key"),
209       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
210       ngx_conf_set_str_array_slot,
211       NGX_HTTP_SRV_CONF_OFFSET,
212       offsetof(ngx_http_ssl_srv_conf_t, session_ticket_keys),
213       NULL },
214 
215     { ngx_string("ssl_session_timeout"),
216       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
217       ngx_conf_set_sec_slot,
218       NGX_HTTP_SRV_CONF_OFFSET,
219       offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
220       NULL },
221 
222     { ngx_string("ssl_crl"),
223       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
224       ngx_conf_set_str_slot,
225       NGX_HTTP_SRV_CONF_OFFSET,
226       offsetof(ngx_http_ssl_srv_conf_t, crl),
227       NULL },
228 
229     { ngx_string("ssl_ocsp"),
230       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
231       ngx_conf_set_enum_slot,
232       NGX_HTTP_SRV_CONF_OFFSET,
233       offsetof(ngx_http_ssl_srv_conf_t, ocsp),
234       &ngx_http_ssl_ocsp },
235 
236     { ngx_string("ssl_ocsp_responder"),
237       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
238       ngx_conf_set_str_slot,
239       NGX_HTTP_SRV_CONF_OFFSET,
240       offsetof(ngx_http_ssl_srv_conf_t, ocsp_responder),
241       NULL },
242 
243     { ngx_string("ssl_ocsp_cache"),
244       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
245       ngx_http_ssl_ocsp_cache,
246       NGX_HTTP_SRV_CONF_OFFSET,
247       0,
248       NULL },
249 
250     { ngx_string("ssl_stapling"),
251       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
252       ngx_conf_set_flag_slot,
253       NGX_HTTP_SRV_CONF_OFFSET,
254       offsetof(ngx_http_ssl_srv_conf_t, stapling),
255       NULL },
256 
257     { ngx_string("ssl_stapling_file"),
258       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
259       ngx_conf_set_str_slot,
260       NGX_HTTP_SRV_CONF_OFFSET,
261       offsetof(ngx_http_ssl_srv_conf_t, stapling_file),
262       NULL },
263 
264     { ngx_string("ssl_stapling_responder"),
265       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
266       ngx_conf_set_str_slot,
267       NGX_HTTP_SRV_CONF_OFFSET,
268       offsetof(ngx_http_ssl_srv_conf_t, stapling_responder),
269       NULL },
270 
271     { ngx_string("ssl_stapling_verify"),
272       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
273       ngx_conf_set_flag_slot,
274       NGX_HTTP_SRV_CONF_OFFSET,
275       offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
276       NULL },
277 
278     { ngx_string("ssl_early_data"),
279       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
280       ngx_conf_set_flag_slot,
281       NGX_HTTP_SRV_CONF_OFFSET,
282       offsetof(ngx_http_ssl_srv_conf_t, early_data),
283       NULL },
284 
285     { ngx_string("ssl_conf_command"),
286       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
287       ngx_conf_set_keyval_slot,
288       NGX_HTTP_SRV_CONF_OFFSET,
289       offsetof(ngx_http_ssl_srv_conf_t, conf_commands),
290       &ngx_http_ssl_conf_command_post },
291 
292     { ngx_string("ssl_reject_handshake"),
293       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
294       ngx_conf_set_flag_slot,
295       NGX_HTTP_SRV_CONF_OFFSET,
296       offsetof(ngx_http_ssl_srv_conf_t, reject_handshake),
297       NULL },
298 
299       ngx_null_command
300 };
301 
302 
303 static ngx_http_module_t  ngx_http_ssl_module_ctx = {
304     ngx_http_ssl_add_variables,            /* preconfiguration */
305     ngx_http_ssl_init,                     /* postconfiguration */
306 
307     NULL,                                  /* create main configuration */
308     NULL,                                  /* init main configuration */
309 
310     ngx_http_ssl_create_srv_conf,          /* create server configuration */
311     ngx_http_ssl_merge_srv_conf,           /* merge server configuration */
312 
313     NULL,                                  /* create location configuration */
314     NULL                                   /* merge location configuration */
315 };
316 
317 
318 ngx_module_t  ngx_http_ssl_module = {
319     NGX_MODULE_V1,
320     &ngx_http_ssl_module_ctx,              /* module context */
321     ngx_http_ssl_commands,                 /* module directives */
322     NGX_HTTP_MODULE,                       /* module type */
323     NULL,                                  /* init master */
324     NULL,                                  /* init module */
325     NULL,                                  /* init process */
326     NULL,                                  /* init thread */
327     NULL,                                  /* exit thread */
328     NULL,                                  /* exit process */
329     NULL,                                  /* exit master */
330     NGX_MODULE_V1_PADDING
331 };
332 
333 
334 static ngx_http_variable_t  ngx_http_ssl_vars[] = {
335 
336     { ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
337       (uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
338 
339     { ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
340       (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
341 
342     { ngx_string("ssl_ciphers"), NULL, ngx_http_ssl_variable,
343       (uintptr_t) ngx_ssl_get_ciphers, NGX_HTTP_VAR_CHANGEABLE, 0 },
344 
345     { ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable,
346       (uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 },
347 
348     { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
349       (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
350 
351     { ngx_string("ssl_session_reused"), NULL, ngx_http_ssl_variable,
352       (uintptr_t) ngx_ssl_get_session_reused, NGX_HTTP_VAR_CHANGEABLE, 0 },
353 
354     { ngx_string("ssl_early_data"), NULL, ngx_http_ssl_variable,
355       (uintptr_t) ngx_ssl_get_early_data,
356       NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
357 
358     { ngx_string("ssl_server_name"), NULL, ngx_http_ssl_variable,
359       (uintptr_t) ngx_ssl_get_server_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
360 
361     { ngx_string("ssl_alpn_protocol"), NULL, ngx_http_ssl_variable,
362       (uintptr_t) ngx_ssl_get_alpn_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
363 
364     { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
365       (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
366 
367     { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable,
368       (uintptr_t) ngx_ssl_get_raw_certificate,
369       NGX_HTTP_VAR_CHANGEABLE, 0 },
370 
371     { ngx_string("ssl_client_escaped_cert"), NULL, ngx_http_ssl_variable,
372       (uintptr_t) ngx_ssl_get_escaped_certificate,
373       NGX_HTTP_VAR_CHANGEABLE, 0 },
374 
375     { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
376       (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
377 
378     { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
379       (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
380 
381     { ngx_string("ssl_client_s_dn_legacy"), NULL, ngx_http_ssl_variable,
382       (uintptr_t) ngx_ssl_get_subject_dn_legacy, NGX_HTTP_VAR_CHANGEABLE, 0 },
383 
384     { ngx_string("ssl_client_i_dn_legacy"), NULL, ngx_http_ssl_variable,
385       (uintptr_t) ngx_ssl_get_issuer_dn_legacy, NGX_HTTP_VAR_CHANGEABLE, 0 },
386 
387     { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
388       (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
389 
390     { ngx_string("ssl_client_fingerprint"), NULL, ngx_http_ssl_variable,
391       (uintptr_t) ngx_ssl_get_fingerprint, NGX_HTTP_VAR_CHANGEABLE, 0 },
392 
393     { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
394       (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
395 
396     { ngx_string("ssl_client_v_start"), NULL, ngx_http_ssl_variable,
397       (uintptr_t) ngx_ssl_get_client_v_start, NGX_HTTP_VAR_CHANGEABLE, 0 },
398 
399     { ngx_string("ssl_client_v_end"), NULL, ngx_http_ssl_variable,
400       (uintptr_t) ngx_ssl_get_client_v_end, NGX_HTTP_VAR_CHANGEABLE, 0 },
401 
402     { ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
403       (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
404 
405       ngx_http_null_variable
406 };
407 
408 
409 static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
410 
411 
412 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
413 
414 static int
415 ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
416     unsigned char *outlen, const unsigned char *in, unsigned int inlen,
417     void *arg)
418 {
419     unsigned int            srvlen;
420     unsigned char          *srv;
421 #if (NGX_DEBUG)
422     unsigned int            i;
423 #endif
424 #if (NGX_HTTP_V2)
425     ngx_http_connection_t  *hc;
426 #endif
427 #if (NGX_HTTP_V2 || NGX_DEBUG)
428     ngx_connection_t       *c;
429 
430     c = ngx_ssl_get_connection(ssl_conn);
431 #endif
432 
433 #if (NGX_DEBUG)
434     for (i = 0; i < inlen; i += in[i] + 1) {
435         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
436                        "SSL ALPN supported by client: %*s",
437                        (size_t) in[i], &in[i + 1]);
438     }
439 #endif
440 
441 #if (NGX_HTTP_V2)
442     hc = c->data;
443 
444     if (hc->addr_conf->http2) {
445         srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTO;
446         srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTO) - 1;
447 
448     } else
449 #endif
450     {
451         srv = (unsigned char *) NGX_HTTP_ALPN_PROTO;
452         srvlen = sizeof(NGX_HTTP_ALPN_PROTO) - 1;
453     }
454 
455     if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
456                               in, inlen)
457         != OPENSSL_NPN_NEGOTIATED)
458     {
459         return SSL_TLSEXT_ERR_NOACK;
460     }
461 
462     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
463                    "SSL ALPN selected: %*s", (size_t) *outlen, *out);
464 
465     return SSL_TLSEXT_ERR_OK;
466 }
467 
468 #endif
469 
470 
471 static ngx_int_t
472 ngx_http_ssl_static_variable(ngx_http_request_t *r,
473     ngx_http_variable_value_t *v, uintptr_t data)
474 {
475     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
476 
477     size_t     len;
478     ngx_str_t  s;
479 
480     if (r->connection->ssl) {
481 
482         (void) handler(r->connection, NULL, &s);
483 
484         v->data = s.data;
485 
486         for (len = 0; v->data[len]; len++) { /* void */ }
487 
488         v->len = len;
489         v->valid = 1;
490         v->no_cacheable = 0;
491         v->not_found = 0;
492 
493         return NGX_OK;
494     }
495 
496     v->not_found = 1;
497 
498     return NGX_OK;
499 }
500 
501 
502 static ngx_int_t
503 ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
504     uintptr_t data)
505 {
506     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
507 
508     ngx_str_t  s;
509 
510     if (r->connection->ssl) {
511 
512         if (handler(r->connection, r->pool, &s) != NGX_OK) {
513             return NGX_ERROR;
514         }
515 
516         v->len = s.len;
517         v->data = s.data;
518 
519         if (v->len) {
520             v->valid = 1;
521             v->no_cacheable = 0;
522             v->not_found = 0;
523 
524             return NGX_OK;
525         }
526     }
527 
528     v->not_found = 1;
529 
530     return NGX_OK;
531 }
532 
533 
534 static ngx_int_t
535 ngx_http_ssl_add_variables(ngx_conf_t *cf)
536 {
537     ngx_http_variable_t  *var, *v;
538 
539     for (v = ngx_http_ssl_vars; v->name.len; v++) {
540         var = ngx_http_add_variable(cf, &v->name, v->flags);
541         if (var == NULL) {
542             return NGX_ERROR;
543         }
544 
545         var->get_handler = v->get_handler;
546         var->data = v->data;
547     }
548 
549     return NGX_OK;
550 }
551 
552 
553 static void *
554 ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
555 {
556     ngx_http_ssl_srv_conf_t  *sscf;
557 
558     sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
559     if (sscf == NULL) {
560         return NULL;
561     }
562 
563     /*
564      * set by ngx_pcalloc():
565      *
566      *     sscf->protocols = 0;
567      *     sscf->certificate_values = NULL;
568      *     sscf->dhparam = { 0, NULL };
569      *     sscf->ecdh_curve = { 0, NULL };
570      *     sscf->client_certificate = { 0, NULL };
571      *     sscf->trusted_certificate = { 0, NULL };
572      *     sscf->crl = { 0, NULL };
573      *     sscf->ciphers = { 0, NULL };
574      *     sscf->shm_zone = NULL;
575      *     sscf->ocsp_responder = { 0, NULL };
576      *     sscf->stapling_file = { 0, NULL };
577      *     sscf->stapling_responder = { 0, NULL };
578      */
579 
580     sscf->enable = NGX_CONF_UNSET;
581     sscf->prefer_server_ciphers = NGX_CONF_UNSET;
582     sscf->early_data = NGX_CONF_UNSET;
583     sscf->reject_handshake = NGX_CONF_UNSET;
584     sscf->buffer_size = NGX_CONF_UNSET_SIZE;
585     sscf->verify = NGX_CONF_UNSET_UINT;
586     sscf->verify_depth = NGX_CONF_UNSET_UINT;
587     sscf->certificates = NGX_CONF_UNSET_PTR;
588     sscf->certificate_keys = NGX_CONF_UNSET_PTR;
589     sscf->passwords = NGX_CONF_UNSET_PTR;
590     sscf->conf_commands = NGX_CONF_UNSET_PTR;
591     sscf->builtin_session_cache = NGX_CONF_UNSET;
592     sscf->session_timeout = NGX_CONF_UNSET;
593     sscf->session_tickets = NGX_CONF_UNSET;
594     sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
595     sscf->ocsp = NGX_CONF_UNSET_UINT;
596     sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
597     sscf->stapling = NGX_CONF_UNSET;
598     sscf->stapling_verify = NGX_CONF_UNSET;
599 
600     return sscf;
601 }
602 
603 
604 static char *
605 ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
606 {
607     ngx_http_ssl_srv_conf_t *prev = parent;
608     ngx_http_ssl_srv_conf_t *conf = child;
609 
610     ngx_pool_cleanup_t  *cln;
611 
612     if (conf->enable == NGX_CONF_UNSET) {
613         if (prev->enable == NGX_CONF_UNSET) {
614             conf->enable = 0;
615 
616         } else {
617             conf->enable = prev->enable;
618             conf->file = prev->file;
619             conf->line = prev->line;
620         }
621     }
622 
623     ngx_conf_merge_value(conf->session_timeout,
624                          prev->session_timeout, 300);
625 
626     ngx_conf_merge_value(conf->prefer_server_ciphers,
627                          prev->prefer_server_ciphers, 0);
628 
629     ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
630     ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
631 
632     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
633                          (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
634                           |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
635 
636     ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
637                          NGX_SSL_BUFSIZE);
638 
639     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
640     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
641 
642     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
643     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
644                          NULL);
645 
646     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
647 
648     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
649 
650     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
651                          "");
652     ngx_conf_merge_str_value(conf->trusted_certificate,
653                          prev->trusted_certificate, "");
654     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
655 
656     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
657                          NGX_DEFAULT_ECDH_CURVE);
658 
659     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
660 
661     ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
662 
663     ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
664     ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
665     ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
666                          prev->ocsp_cache_zone, NULL);
667 
668     ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
669     ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
670     ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
671     ngx_conf_merge_str_value(conf->stapling_responder,
672                          prev->stapling_responder, "");
673 
674     conf->ssl.log = cf->log;
675 
676     if (conf->enable) {
677 
678         if (conf->certificates) {
679             if (conf->certificate_keys == NULL) {
680                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
681                               "no \"ssl_certificate_key\" is defined for "
682                               "the \"ssl\" directive in %s:%ui",
683                               conf->file, conf->line);
684                 return NGX_CONF_ERROR;
685             }
686 
687             if (conf->certificate_keys->nelts < conf->certificates->nelts) {
688                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
689                               "no \"ssl_certificate_key\" is defined "
690                               "for certificate \"%V\" and "
691                               "the \"ssl\" directive in %s:%ui",
692                               ((ngx_str_t *) conf->certificates->elts)
693                               + conf->certificates->nelts - 1,
694                               conf->file, conf->line);
695                 return NGX_CONF_ERROR;
696             }
697 
698         } else if (!conf->reject_handshake) {
699             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
700                           "no \"ssl_certificate\" is defined for "
701                           "the \"ssl\" directive in %s:%ui",
702                           conf->file, conf->line);
703             return NGX_CONF_ERROR;
704         }
705 
706     } else if (conf->certificates) {
707 
708         if (conf->certificate_keys == NULL
709             || conf->certificate_keys->nelts < conf->certificates->nelts)
710         {
711             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
712                           "no \"ssl_certificate_key\" is defined "
713                           "for certificate \"%V\"",
714                           ((ngx_str_t *) conf->certificates->elts)
715                           + conf->certificates->nelts - 1);
716             return NGX_CONF_ERROR;
717         }
718 
719     } else if (!conf->reject_handshake) {
720         return NGX_CONF_OK;
721     }
722 
723     if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
724         return NGX_CONF_ERROR;
725     }
726 
727     cln = ngx_pool_cleanup_add(cf->pool, 0);
728     if (cln == NULL) {
729         ngx_ssl_cleanup_ctx(&conf->ssl);
730         return NGX_CONF_ERROR;
731     }
732 
733     cln->handler = ngx_ssl_cleanup_ctx;
734     cln->data = &conf->ssl;
735 
736 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
737 
738     if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
739                                                ngx_http_ssl_servername)
740         == 0)
741     {
742         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
743             "nginx was built with SNI support, however, now it is linked "
744             "dynamically to an OpenSSL library which has no tlsext support, "
745             "therefore SNI is not available");
746     }
747 
748 #endif
749 
750 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
751     SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
752 #endif
753 
754     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
755                         conf->prefer_server_ciphers)
756         != NGX_OK)
757     {
758         return NGX_CONF_ERROR;
759     }
760 
761     if (ngx_http_ssl_compile_certificates(cf, conf) != NGX_OK) {
762         return NGX_CONF_ERROR;
763     }
764 
765     if (conf->certificate_values) {
766 
767 #ifdef SSL_R_CERT_CB_ERROR
768 
769         /* install callback to lookup certificates */
770 
771         SSL_CTX_set_cert_cb(conf->ssl.ctx, ngx_http_ssl_certificate, conf);
772 
773 #else
774         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
775                       "variables in "
776                       "\"ssl_certificate\" and \"ssl_certificate_key\" "
777                       "directives are not supported on this platform");
778         return NGX_CONF_ERROR;
779 #endif
780 
781     } else if (conf->certificates) {
782 
783         /* configure certificates */
784 
785         if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
786                                  conf->certificate_keys, conf->passwords)
787             != NGX_OK)
788         {
789             return NGX_CONF_ERROR;
790         }
791     }
792 
793     conf->ssl.buffer_size = conf->buffer_size;
794 
795     if (conf->verify) {
796 
797         if (conf->client_certificate.len == 0 && conf->verify != 3) {
798             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
799                           "no ssl_client_certificate for ssl_verify_client");
800             return NGX_CONF_ERROR;
801         }
802 
803         if (ngx_ssl_client_certificate(cf, &conf->ssl,
804                                        &conf->client_certificate,
805                                        conf->verify_depth)
806             != NGX_OK)
807         {
808             return NGX_CONF_ERROR;
809         }
810     }
811 
812     if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
813                                     &conf->trusted_certificate,
814                                     conf->verify_depth)
815         != NGX_OK)
816     {
817         return NGX_CONF_ERROR;
818     }
819 
820     if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
821         return NGX_CONF_ERROR;
822     }
823 
824     if (conf->ocsp) {
825 
826         if (conf->verify == 3) {
827             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
828                           "\"ssl_ocsp\" is incompatible with "
829                           "\"ssl_verify_client optional_no_ca\"");
830             return NGX_CONF_ERROR;
831         }
832 
833         if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
834                          conf->ocsp_cache_zone)
835             != NGX_OK)
836         {
837             return NGX_CONF_ERROR;
838         }
839     }
840 
841     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
842         return NGX_CONF_ERROR;
843     }
844 
845     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
846         return NGX_CONF_ERROR;
847     }
848 
849     ngx_conf_merge_value(conf->builtin_session_cache,
850                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
851 
852     if (conf->shm_zone == NULL) {
853         conf->shm_zone = prev->shm_zone;
854     }
855 
856     if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
857                               conf->certificates, conf->builtin_session_cache,
858                               conf->shm_zone, conf->session_timeout)
859         != NGX_OK)
860     {
861         return NGX_CONF_ERROR;
862     }
863 
864     ngx_conf_merge_value(conf->session_tickets, prev->session_tickets, 1);
865 
866 #ifdef SSL_OP_NO_TICKET
867     if (!conf->session_tickets) {
868         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
869     }
870 #endif
871 
872     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
873                          prev->session_ticket_keys, NULL);
874 
875     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
876         != NGX_OK)
877     {
878         return NGX_CONF_ERROR;
879     }
880 
881     if (conf->stapling) {
882 
883         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
884                              &conf->stapling_responder, conf->stapling_verify)
885             != NGX_OK)
886         {
887             return NGX_CONF_ERROR;
888         }
889 
890     }
891 
892     if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
893         return NGX_CONF_ERROR;
894     }
895 
896     if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
897         return NGX_CONF_ERROR;
898     }
899 
900     return NGX_CONF_OK;
901 }
902 
903 
904 static ngx_int_t
905 ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
906     ngx_http_ssl_srv_conf_t *conf)
907 {
908     ngx_str_t                         *cert, *key;
909     ngx_uint_t                         i, nelts;
910     ngx_http_complex_value_t          *cv;
911     ngx_http_compile_complex_value_t   ccv;
912 
913     if (conf->certificates == NULL) {
914         return NGX_OK;
915     }
916 
917     cert = conf->certificates->elts;
918     key = conf->certificate_keys->elts;
919     nelts = conf->certificates->nelts;
920 
921     for (i = 0; i < nelts; i++) {
922 
923         if (ngx_http_script_variables_count(&cert[i])) {
924             goto found;
925         }
926 
927         if (ngx_http_script_variables_count(&key[i])) {
928             goto found;
929         }
930     }
931 
932     return NGX_OK;
933 
934 found:
935 
936     conf->certificate_values = ngx_array_create(cf->pool, nelts,
937                                              sizeof(ngx_http_complex_value_t));
938     if (conf->certificate_values == NULL) {
939         return NGX_ERROR;
940     }
941 
942     conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
943                                              sizeof(ngx_http_complex_value_t));
944     if (conf->certificate_key_values == NULL) {
945         return NGX_ERROR;
946     }
947 
948     for (i = 0; i < nelts; i++) {
949 
950         cv = ngx_array_push(conf->certificate_values);
951         if (cv == NULL) {
952             return NGX_ERROR;
953         }
954 
955         ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
956 
957         ccv.cf = cf;
958         ccv.value = &cert[i];
959         ccv.complex_value = cv;
960         ccv.zero = 1;
961 
962         if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
963             return NGX_ERROR;
964         }
965 
966         cv = ngx_array_push(conf->certificate_key_values);
967         if (cv == NULL) {
968             return NGX_ERROR;
969         }
970 
971         ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
972 
973         ccv.cf = cf;
974         ccv.value = &key[i];
975         ccv.complex_value = cv;
976         ccv.zero = 1;
977 
978         if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
979             return NGX_ERROR;
980         }
981     }
982 
983     conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
984     if (conf->passwords == NULL) {
985         return NGX_ERROR;
986     }
987 
988     return NGX_OK;
989 }
990 
991 
992 static char *
993 ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
994 {
995     ngx_http_ssl_srv_conf_t *sscf = conf;
996 
997     char  *rv;
998 
999     rv = ngx_conf_set_flag_slot(cf, cmd, conf);
1000 
1001     if (rv != NGX_CONF_OK) {
1002         return rv;
1003     }
1004 
1005     sscf->file = cf->conf_file->file.name.data;
1006     sscf->line = cf->conf_file->line;
1007 
1008     return NGX_CONF_OK;
1009 }
1010 
1011 
1012 static char *
1013 ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1014 {
1015     ngx_http_ssl_srv_conf_t *sscf = conf;
1016 
1017     ngx_str_t  *value;
1018 
1019     if (sscf->passwords != NGX_CONF_UNSET_PTR) {
1020         return "is duplicate";
1021     }
1022 
1023     value = cf->args->elts;
1024 
1025     sscf->passwords = ngx_ssl_read_password_file(cf, &value[1]);
1026 
1027     if (sscf->passwords == NULL) {
1028         return NGX_CONF_ERROR;
1029     }
1030 
1031     return NGX_CONF_OK;
1032 }
1033 
1034 
1035 static char *
1036 ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1037 {
1038     ngx_http_ssl_srv_conf_t *sscf = conf;
1039 
1040     size_t       len;
1041     ngx_str_t   *value, name, size;
1042     ngx_int_t    n;
1043     ngx_uint_t   i, j;
1044 
1045     value = cf->args->elts;
1046 
1047     for (i = 1; i < cf->args->nelts; i++) {
1048 
1049         if (ngx_strcmp(value[i].data, "off") == 0) {
1050             sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
1051             continue;
1052         }
1053 
1054         if (ngx_strcmp(value[i].data, "none") == 0) {
1055             sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
1056             continue;
1057         }
1058 
1059         if (ngx_strcmp(value[i].data, "builtin") == 0) {
1060             sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
1061             continue;
1062         }
1063 
1064         if (value[i].len > sizeof("builtin:") - 1
1065             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
1066                == 0)
1067         {
1068             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
1069                          value[i].len - (sizeof("builtin:") - 1));
1070 
1071             if (n == NGX_ERROR) {
1072                 goto invalid;
1073             }
1074 
1075             sscf->builtin_session_cache = n;
1076 
1077             continue;
1078         }
1079 
1080         if (value[i].len > sizeof("shared:") - 1
1081             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
1082                == 0)
1083         {
1084             len = 0;
1085 
1086             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
1087                 if (value[i].data[j] == ':') {
1088                     break;
1089                 }
1090 
1091                 len++;
1092             }
1093 
1094             if (len == 0) {
1095                 goto invalid;
1096             }
1097 
1098             name.len = len;
1099             name.data = value[i].data + sizeof("shared:") - 1;
1100 
1101             size.len = value[i].len - j - 1;
1102             size.data = name.data + len + 1;
1103 
1104             n = ngx_parse_size(&size);
1105 
1106             if (n == NGX_ERROR) {
1107                 goto invalid;
1108             }
1109 
1110             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
1111                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1112                                    "session cache \"%V\" is too small",
1113                                    &value[i]);
1114 
1115                 return NGX_CONF_ERROR;
1116             }
1117 
1118             sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
1119                                                    &ngx_http_ssl_module);
1120             if (sscf->shm_zone == NULL) {
1121                 return NGX_CONF_ERROR;
1122             }
1123 
1124             sscf->shm_zone->init = ngx_ssl_session_cache_init;
1125 
1126             continue;
1127         }
1128 
1129         goto invalid;
1130     }
1131 
1132     if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
1133         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
1134     }
1135 
1136     return NGX_CONF_OK;
1137 
1138 invalid:
1139 
1140     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1141                        "invalid session cache \"%V\"", &value[i]);
1142 
1143     return NGX_CONF_ERROR;
1144 }
1145 
1146 
1147 static char *
1148 ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1149 {
1150     ngx_http_ssl_srv_conf_t *sscf = conf;
1151 
1152     size_t       len;
1153     ngx_int_t    n;
1154     ngx_str_t   *value, name, size;
1155     ngx_uint_t   j;
1156 
1157     if (sscf->ocsp_cache_zone != NGX_CONF_UNSET_PTR) {
1158         return "is duplicate";
1159     }
1160 
1161     value = cf->args->elts;
1162 
1163     if (ngx_strcmp(value[1].data, "off") == 0) {
1164         sscf->ocsp_cache_zone = NULL;
1165         return NGX_CONF_OK;
1166     }
1167 
1168     if (value[1].len <= sizeof("shared:") - 1
1169         || ngx_strncmp(value[1].data, "shared:", sizeof("shared:") - 1) != 0)
1170     {
1171         goto invalid;
1172     }
1173 
1174     len = 0;
1175 
1176     for (j = sizeof("shared:") - 1; j < value[1].len; j++) {
1177         if (value[1].data[j] == ':') {
1178             break;
1179         }
1180 
1181         len++;
1182     }
1183 
1184     if (len == 0) {
1185         goto invalid;
1186     }
1187 
1188     name.len = len;
1189     name.data = value[1].data + sizeof("shared:") - 1;
1190 
1191     size.len = value[1].len - j - 1;
1192     size.data = name.data + len + 1;
1193 
1194     n = ngx_parse_size(&size);
1195 
1196     if (n == NGX_ERROR) {
1197         goto invalid;
1198     }
1199 
1200     if (n < (ngx_int_t) (8 * ngx_pagesize)) {
1201         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1202                            "OCSP cache \"%V\" is too small", &value[1]);
1203 
1204         return NGX_CONF_ERROR;
1205     }
1206 
1207     sscf->ocsp_cache_zone = ngx_shared_memory_add(cf, &name, n,
1208                                                   &ngx_http_ssl_module_ctx);
1209     if (sscf->ocsp_cache_zone == NULL) {
1210         return NGX_CONF_ERROR;
1211     }
1212 
1213     sscf->ocsp_cache_zone->init = ngx_ssl_ocsp_cache_init;
1214 
1215     return NGX_CONF_OK;
1216 
1217 invalid:
1218 
1219     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1220                        "invalid OCSP cache \"%V\"", &value[1]);
1221 
1222     return NGX_CONF_ERROR;
1223 }
1224 
1225 
1226 static char *
1227 ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
1228 {
1229 #ifndef SSL_CONF_FLAG_FILE
1230     return "is not supported on this platform";
1231 #else
1232     return NGX_CONF_OK;
1233 #endif
1234 }
1235 
1236 
1237 static ngx_int_t
1238 ngx_http_ssl_init(ngx_conf_t *cf)
1239 {
1240     ngx_uint_t                   a, p, s;
1241     ngx_http_conf_addr_t        *addr;
1242     ngx_http_conf_port_t        *port;
1243     ngx_http_ssl_srv_conf_t     *sscf;
1244     ngx_http_core_loc_conf_t    *clcf;
1245     ngx_http_core_srv_conf_t   **cscfp, *cscf;
1246     ngx_http_core_main_conf_t   *cmcf;
1247 
1248     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
1249     cscfp = cmcf->servers.elts;
1250 
1251     for (s = 0; s < cmcf->servers.nelts; s++) {
1252 
1253         sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
1254 
1255         if (sscf->ssl.ctx == NULL) {
1256             continue;
1257         }
1258 
1259         clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
1260 
1261         if (sscf->stapling) {
1262             if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
1263                                           clcf->resolver_timeout)
1264                 != NGX_OK)
1265             {
1266                 return NGX_ERROR;
1267             }
1268         }
1269 
1270         if (sscf->ocsp) {
1271             if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl, clcf->resolver,
1272                                       clcf->resolver_timeout)
1273                 != NGX_OK)
1274             {
1275                 return NGX_ERROR;
1276             }
1277         }
1278     }
1279 
1280     if (cmcf->ports == NULL) {
1281         return NGX_OK;
1282     }
1283 
1284     port = cmcf->ports->elts;
1285     for (p = 0; p < cmcf->ports->nelts; p++) {
1286 
1287         addr = port[p].addrs.elts;
1288         for (a = 0; a < port[p].addrs.nelts; a++) {
1289 
1290             if (!addr[a].opt.ssl) {
1291                 continue;
1292             }
1293 
1294             cscf = addr[a].default_server;
1295             sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
1296 
1297             if (sscf->certificates) {
1298                 continue;
1299             }
1300 
1301             if (!sscf->reject_handshake) {
1302                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1303                               "no \"ssl_certificate\" is defined for "
1304                               "the \"listen ... ssl\" directive in %s:%ui",
1305                               cscf->file_name, cscf->line);
1306                 return NGX_ERROR;
1307             }
1308 
1309             /*
1310              * if no certificates are defined in the default server,
1311              * check all non-default server blocks
1312              */
1313 
1314             cscfp = addr[a].servers.elts;
1315             for (s = 0; s < addr[a].servers.nelts; s++) {
1316 
1317                 cscf = cscfp[s];
1318                 sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
1319 
1320                 if (sscf->certificates || sscf->reject_handshake) {
1321                     continue;
1322                 }
1323 
1324                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1325                               "no \"ssl_certificate\" is defined for "
1326                               "the \"listen ... ssl\" directive in %s:%ui",
1327                               cscf->file_name, cscf->line);
1328                 return NGX_ERROR;
1329             }
1330         }
1331     }
1332 
1333     return NGX_OK;
1334 }
1335