xref: /nginx/src/http/modules/ngx_http_ssl_module.c (revision 7937:db6b630e6086)
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_PROTOS    "\x08http/1.1\x08http/1.0\x08http/0.9"
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_PROTOS;
446         srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1;
447     } else
448 #endif
449     {
450         srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
451         srvlen = sizeof(NGX_HTTP_ALPN_PROTOS) - 1;
452     }
453 
454     if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
455                               in, inlen)
456         != OPENSSL_NPN_NEGOTIATED)
457     {
458         return SSL_TLSEXT_ERR_ALERT_FATAL;
459     }
460 
461     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
462                    "SSL ALPN selected: %*s", (size_t) *outlen, *out);
463 
464     return SSL_TLSEXT_ERR_OK;
465 }
466 
467 #endif
468 
469 
470 static ngx_int_t
471 ngx_http_ssl_static_variable(ngx_http_request_t *r,
472     ngx_http_variable_value_t *v, uintptr_t data)
473 {
474     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
475 
476     size_t     len;
477     ngx_str_t  s;
478 
479     if (r->connection->ssl) {
480 
481         (void) handler(r->connection, NULL, &s);
482 
483         v->data = s.data;
484 
485         for (len = 0; v->data[len]; len++) { /* void */ }
486 
487         v->len = len;
488         v->valid = 1;
489         v->no_cacheable = 0;
490         v->not_found = 0;
491 
492         return NGX_OK;
493     }
494 
495     v->not_found = 1;
496 
497     return NGX_OK;
498 }
499 
500 
501 static ngx_int_t
502 ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
503     uintptr_t data)
504 {
505     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
506 
507     ngx_str_t  s;
508 
509     if (r->connection->ssl) {
510 
511         if (handler(r->connection, r->pool, &s) != NGX_OK) {
512             return NGX_ERROR;
513         }
514 
515         v->len = s.len;
516         v->data = s.data;
517 
518         if (v->len) {
519             v->valid = 1;
520             v->no_cacheable = 0;
521             v->not_found = 0;
522 
523             return NGX_OK;
524         }
525     }
526 
527     v->not_found = 1;
528 
529     return NGX_OK;
530 }
531 
532 
533 static ngx_int_t
534 ngx_http_ssl_add_variables(ngx_conf_t *cf)
535 {
536     ngx_http_variable_t  *var, *v;
537 
538     for (v = ngx_http_ssl_vars; v->name.len; v++) {
539         var = ngx_http_add_variable(cf, &v->name, v->flags);
540         if (var == NULL) {
541             return NGX_ERROR;
542         }
543 
544         var->get_handler = v->get_handler;
545         var->data = v->data;
546     }
547 
548     return NGX_OK;
549 }
550 
551 
552 static void *
553 ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
554 {
555     ngx_http_ssl_srv_conf_t  *sscf;
556 
557     sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
558     if (sscf == NULL) {
559         return NULL;
560     }
561 
562     /*
563      * set by ngx_pcalloc():
564      *
565      *     sscf->protocols = 0;
566      *     sscf->certificate_values = NULL;
567      *     sscf->dhparam = { 0, NULL };
568      *     sscf->ecdh_curve = { 0, NULL };
569      *     sscf->client_certificate = { 0, NULL };
570      *     sscf->trusted_certificate = { 0, NULL };
571      *     sscf->crl = { 0, NULL };
572      *     sscf->ciphers = { 0, NULL };
573      *     sscf->shm_zone = NULL;
574      *     sscf->ocsp_responder = { 0, NULL };
575      *     sscf->stapling_file = { 0, NULL };
576      *     sscf->stapling_responder = { 0, NULL };
577      */
578 
579     sscf->enable = NGX_CONF_UNSET;
580     sscf->prefer_server_ciphers = NGX_CONF_UNSET;
581     sscf->early_data = NGX_CONF_UNSET;
582     sscf->reject_handshake = NGX_CONF_UNSET;
583     sscf->buffer_size = NGX_CONF_UNSET_SIZE;
584     sscf->verify = NGX_CONF_UNSET_UINT;
585     sscf->verify_depth = NGX_CONF_UNSET_UINT;
586     sscf->certificates = NGX_CONF_UNSET_PTR;
587     sscf->certificate_keys = NGX_CONF_UNSET_PTR;
588     sscf->passwords = NGX_CONF_UNSET_PTR;
589     sscf->conf_commands = NGX_CONF_UNSET_PTR;
590     sscf->builtin_session_cache = NGX_CONF_UNSET;
591     sscf->session_timeout = NGX_CONF_UNSET;
592     sscf->session_tickets = NGX_CONF_UNSET;
593     sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
594     sscf->ocsp = NGX_CONF_UNSET_UINT;
595     sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
596     sscf->stapling = NGX_CONF_UNSET;
597     sscf->stapling_verify = NGX_CONF_UNSET;
598 
599     return sscf;
600 }
601 
602 
603 static char *
604 ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
605 {
606     ngx_http_ssl_srv_conf_t *prev = parent;
607     ngx_http_ssl_srv_conf_t *conf = child;
608 
609     ngx_pool_cleanup_t  *cln;
610 
611     if (conf->enable == NGX_CONF_UNSET) {
612         if (prev->enable == NGX_CONF_UNSET) {
613             conf->enable = 0;
614 
615         } else {
616             conf->enable = prev->enable;
617             conf->file = prev->file;
618             conf->line = prev->line;
619         }
620     }
621 
622     ngx_conf_merge_value(conf->session_timeout,
623                          prev->session_timeout, 300);
624 
625     ngx_conf_merge_value(conf->prefer_server_ciphers,
626                          prev->prefer_server_ciphers, 0);
627 
628     ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
629     ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
630 
631     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
632                          (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
633                           |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
634 
635     ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
636                          NGX_SSL_BUFSIZE);
637 
638     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
639     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
640 
641     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
642     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
643                          NULL);
644 
645     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
646 
647     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
648 
649     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
650                          "");
651     ngx_conf_merge_str_value(conf->trusted_certificate,
652                          prev->trusted_certificate, "");
653     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
654 
655     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
656                          NGX_DEFAULT_ECDH_CURVE);
657 
658     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
659 
660     ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);
661 
662     ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
663     ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
664     ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
665                          prev->ocsp_cache_zone, NULL);
666 
667     ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
668     ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
669     ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
670     ngx_conf_merge_str_value(conf->stapling_responder,
671                          prev->stapling_responder, "");
672 
673     conf->ssl.log = cf->log;
674 
675     if (conf->enable) {
676 
677         if (conf->certificates) {
678             if (conf->certificate_keys == NULL) {
679                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
680                               "no \"ssl_certificate_key\" is defined for "
681                               "the \"ssl\" directive in %s:%ui",
682                               conf->file, conf->line);
683                 return NGX_CONF_ERROR;
684             }
685 
686             if (conf->certificate_keys->nelts < conf->certificates->nelts) {
687                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
688                               "no \"ssl_certificate_key\" is defined "
689                               "for certificate \"%V\" and "
690                               "the \"ssl\" directive in %s:%ui",
691                               ((ngx_str_t *) conf->certificates->elts)
692                               + conf->certificates->nelts - 1,
693                               conf->file, conf->line);
694                 return NGX_CONF_ERROR;
695             }
696 
697         } else if (!conf->reject_handshake) {
698             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
699                           "no \"ssl_certificate\" is defined for "
700                           "the \"ssl\" directive in %s:%ui",
701                           conf->file, conf->line);
702             return NGX_CONF_ERROR;
703         }
704 
705     } else if (conf->certificates) {
706 
707         if (conf->certificate_keys == NULL
708             || conf->certificate_keys->nelts < conf->certificates->nelts)
709         {
710             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
711                           "no \"ssl_certificate_key\" is defined "
712                           "for certificate \"%V\"",
713                           ((ngx_str_t *) conf->certificates->elts)
714                           + conf->certificates->nelts - 1);
715             return NGX_CONF_ERROR;
716         }
717 
718     } else if (!conf->reject_handshake) {
719         return NGX_CONF_OK;
720     }
721 
722     if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
723         return NGX_CONF_ERROR;
724     }
725 
726     cln = ngx_pool_cleanup_add(cf->pool, 0);
727     if (cln == NULL) {
728         ngx_ssl_cleanup_ctx(&conf->ssl);
729         return NGX_CONF_ERROR;
730     }
731 
732     cln->handler = ngx_ssl_cleanup_ctx;
733     cln->data = &conf->ssl;
734 
735 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
736 
737     if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
738                                                ngx_http_ssl_servername)
739         == 0)
740     {
741         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
742             "nginx was built with SNI support, however, now it is linked "
743             "dynamically to an OpenSSL library which has no tlsext support, "
744             "therefore SNI is not available");
745     }
746 
747 #endif
748 
749 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
750     SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
751 #endif
752 
753     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
754                         conf->prefer_server_ciphers)
755         != NGX_OK)
756     {
757         return NGX_CONF_ERROR;
758     }
759 
760     if (ngx_http_ssl_compile_certificates(cf, conf) != NGX_OK) {
761         return NGX_CONF_ERROR;
762     }
763 
764     if (conf->certificate_values) {
765 
766 #ifdef SSL_R_CERT_CB_ERROR
767 
768         /* install callback to lookup certificates */
769 
770         SSL_CTX_set_cert_cb(conf->ssl.ctx, ngx_http_ssl_certificate, conf);
771 
772 #else
773         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
774                       "variables in "
775                       "\"ssl_certificate\" and \"ssl_certificate_key\" "
776                       "directives are not supported on this platform");
777         return NGX_CONF_ERROR;
778 #endif
779 
780     } else if (conf->certificates) {
781 
782         /* configure certificates */
783 
784         if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
785                                  conf->certificate_keys, conf->passwords)
786             != NGX_OK)
787         {
788             return NGX_CONF_ERROR;
789         }
790     }
791 
792     conf->ssl.buffer_size = conf->buffer_size;
793 
794     if (conf->verify) {
795 
796         if (conf->client_certificate.len == 0 && conf->verify != 3) {
797             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
798                           "no ssl_client_certificate for ssl_verify_client");
799             return NGX_CONF_ERROR;
800         }
801 
802         if (ngx_ssl_client_certificate(cf, &conf->ssl,
803                                        &conf->client_certificate,
804                                        conf->verify_depth)
805             != NGX_OK)
806         {
807             return NGX_CONF_ERROR;
808         }
809     }
810 
811     if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
812                                     &conf->trusted_certificate,
813                                     conf->verify_depth)
814         != NGX_OK)
815     {
816         return NGX_CONF_ERROR;
817     }
818 
819     if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
820         return NGX_CONF_ERROR;
821     }
822 
823     if (conf->ocsp) {
824 
825         if (conf->verify == 3) {
826             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
827                           "\"ssl_ocsp\" is incompatible with "
828                           "\"ssl_verify_client optional_no_ca\"");
829             return NGX_CONF_ERROR;
830         }
831 
832         if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
833                          conf->ocsp_cache_zone)
834             != NGX_OK)
835         {
836             return NGX_CONF_ERROR;
837         }
838     }
839 
840     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
841         return NGX_CONF_ERROR;
842     }
843 
844     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
845         return NGX_CONF_ERROR;
846     }
847 
848     ngx_conf_merge_value(conf->builtin_session_cache,
849                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
850 
851     if (conf->shm_zone == NULL) {
852         conf->shm_zone = prev->shm_zone;
853     }
854 
855     if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
856                               conf->certificates, conf->builtin_session_cache,
857                               conf->shm_zone, conf->session_timeout)
858         != NGX_OK)
859     {
860         return NGX_CONF_ERROR;
861     }
862 
863     ngx_conf_merge_value(conf->session_tickets, prev->session_tickets, 1);
864 
865 #ifdef SSL_OP_NO_TICKET
866     if (!conf->session_tickets) {
867         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
868     }
869 #endif
870 
871     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
872                          prev->session_ticket_keys, NULL);
873 
874     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
875         != NGX_OK)
876     {
877         return NGX_CONF_ERROR;
878     }
879 
880     if (conf->stapling) {
881 
882         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
883                              &conf->stapling_responder, conf->stapling_verify)
884             != NGX_OK)
885         {
886             return NGX_CONF_ERROR;
887         }
888 
889     }
890 
891     if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
892         return NGX_CONF_ERROR;
893     }
894 
895     if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
896         return NGX_CONF_ERROR;
897     }
898 
899     return NGX_CONF_OK;
900 }
901 
902 
903 static ngx_int_t
904 ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
905     ngx_http_ssl_srv_conf_t *conf)
906 {
907     ngx_str_t                         *cert, *key;
908     ngx_uint_t                         i, nelts;
909     ngx_http_complex_value_t          *cv;
910     ngx_http_compile_complex_value_t   ccv;
911 
912     if (conf->certificates == NULL) {
913         return NGX_OK;
914     }
915 
916     cert = conf->certificates->elts;
917     key = conf->certificate_keys->elts;
918     nelts = conf->certificates->nelts;
919 
920     for (i = 0; i < nelts; i++) {
921 
922         if (ngx_http_script_variables_count(&cert[i])) {
923             goto found;
924         }
925 
926         if (ngx_http_script_variables_count(&key[i])) {
927             goto found;
928         }
929     }
930 
931     return NGX_OK;
932 
933 found:
934 
935     conf->certificate_values = ngx_array_create(cf->pool, nelts,
936                                              sizeof(ngx_http_complex_value_t));
937     if (conf->certificate_values == NULL) {
938         return NGX_ERROR;
939     }
940 
941     conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
942                                              sizeof(ngx_http_complex_value_t));
943     if (conf->certificate_key_values == NULL) {
944         return NGX_ERROR;
945     }
946 
947     for (i = 0; i < nelts; i++) {
948 
949         cv = ngx_array_push(conf->certificate_values);
950         if (cv == NULL) {
951             return NGX_ERROR;
952         }
953 
954         ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
955 
956         ccv.cf = cf;
957         ccv.value = &cert[i];
958         ccv.complex_value = cv;
959         ccv.zero = 1;
960 
961         if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
962             return NGX_ERROR;
963         }
964 
965         cv = ngx_array_push(conf->certificate_key_values);
966         if (cv == NULL) {
967             return NGX_ERROR;
968         }
969 
970         ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
971 
972         ccv.cf = cf;
973         ccv.value = &key[i];
974         ccv.complex_value = cv;
975         ccv.zero = 1;
976 
977         if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
978             return NGX_ERROR;
979         }
980     }
981 
982     conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
983     if (conf->passwords == NULL) {
984         return NGX_ERROR;
985     }
986 
987     return NGX_OK;
988 }
989 
990 
991 static char *
992 ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
993 {
994     ngx_http_ssl_srv_conf_t *sscf = conf;
995 
996     char  *rv;
997 
998     rv = ngx_conf_set_flag_slot(cf, cmd, conf);
999 
1000     if (rv != NGX_CONF_OK) {
1001         return rv;
1002     }
1003 
1004     sscf->file = cf->conf_file->file.name.data;
1005     sscf->line = cf->conf_file->line;
1006 
1007     return NGX_CONF_OK;
1008 }
1009 
1010 
1011 static char *
1012 ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1013 {
1014     ngx_http_ssl_srv_conf_t *sscf = conf;
1015 
1016     ngx_str_t  *value;
1017 
1018     if (sscf->passwords != NGX_CONF_UNSET_PTR) {
1019         return "is duplicate";
1020     }
1021 
1022     value = cf->args->elts;
1023 
1024     sscf->passwords = ngx_ssl_read_password_file(cf, &value[1]);
1025 
1026     if (sscf->passwords == NULL) {
1027         return NGX_CONF_ERROR;
1028     }
1029 
1030     return NGX_CONF_OK;
1031 }
1032 
1033 
1034 static char *
1035 ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1036 {
1037     ngx_http_ssl_srv_conf_t *sscf = conf;
1038 
1039     size_t       len;
1040     ngx_str_t   *value, name, size;
1041     ngx_int_t    n;
1042     ngx_uint_t   i, j;
1043 
1044     value = cf->args->elts;
1045 
1046     for (i = 1; i < cf->args->nelts; i++) {
1047 
1048         if (ngx_strcmp(value[i].data, "off") == 0) {
1049             sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
1050             continue;
1051         }
1052 
1053         if (ngx_strcmp(value[i].data, "none") == 0) {
1054             sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
1055             continue;
1056         }
1057 
1058         if (ngx_strcmp(value[i].data, "builtin") == 0) {
1059             sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
1060             continue;
1061         }
1062 
1063         if (value[i].len > sizeof("builtin:") - 1
1064             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
1065                == 0)
1066         {
1067             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
1068                          value[i].len - (sizeof("builtin:") - 1));
1069 
1070             if (n == NGX_ERROR) {
1071                 goto invalid;
1072             }
1073 
1074             sscf->builtin_session_cache = n;
1075 
1076             continue;
1077         }
1078 
1079         if (value[i].len > sizeof("shared:") - 1
1080             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
1081                == 0)
1082         {
1083             len = 0;
1084 
1085             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
1086                 if (value[i].data[j] == ':') {
1087                     break;
1088                 }
1089 
1090                 len++;
1091             }
1092 
1093             if (len == 0) {
1094                 goto invalid;
1095             }
1096 
1097             name.len = len;
1098             name.data = value[i].data + sizeof("shared:") - 1;
1099 
1100             size.len = value[i].len - j - 1;
1101             size.data = name.data + len + 1;
1102 
1103             n = ngx_parse_size(&size);
1104 
1105             if (n == NGX_ERROR) {
1106                 goto invalid;
1107             }
1108 
1109             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
1110                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1111                                    "session cache \"%V\" is too small",
1112                                    &value[i]);
1113 
1114                 return NGX_CONF_ERROR;
1115             }
1116 
1117             sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
1118                                                    &ngx_http_ssl_module);
1119             if (sscf->shm_zone == NULL) {
1120                 return NGX_CONF_ERROR;
1121             }
1122 
1123             sscf->shm_zone->init = ngx_ssl_session_cache_init;
1124 
1125             continue;
1126         }
1127 
1128         goto invalid;
1129     }
1130 
1131     if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
1132         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
1133     }
1134 
1135     return NGX_CONF_OK;
1136 
1137 invalid:
1138 
1139     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1140                        "invalid session cache \"%V\"", &value[i]);
1141 
1142     return NGX_CONF_ERROR;
1143 }
1144 
1145 
1146 static char *
1147 ngx_http_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1148 {
1149     ngx_http_ssl_srv_conf_t *sscf = conf;
1150 
1151     size_t       len;
1152     ngx_int_t    n;
1153     ngx_str_t   *value, name, size;
1154     ngx_uint_t   j;
1155 
1156     if (sscf->ocsp_cache_zone != NGX_CONF_UNSET_PTR) {
1157         return "is duplicate";
1158     }
1159 
1160     value = cf->args->elts;
1161 
1162     if (ngx_strcmp(value[1].data, "off") == 0) {
1163         sscf->ocsp_cache_zone = NULL;
1164         return NGX_CONF_OK;
1165     }
1166 
1167     if (value[1].len <= sizeof("shared:") - 1
1168         || ngx_strncmp(value[1].data, "shared:", sizeof("shared:") - 1) != 0)
1169     {
1170         goto invalid;
1171     }
1172 
1173     len = 0;
1174 
1175     for (j = sizeof("shared:") - 1; j < value[1].len; j++) {
1176         if (value[1].data[j] == ':') {
1177             break;
1178         }
1179 
1180         len++;
1181     }
1182 
1183     if (len == 0) {
1184         goto invalid;
1185     }
1186 
1187     name.len = len;
1188     name.data = value[1].data + sizeof("shared:") - 1;
1189 
1190     size.len = value[1].len - j - 1;
1191     size.data = name.data + len + 1;
1192 
1193     n = ngx_parse_size(&size);
1194 
1195     if (n == NGX_ERROR) {
1196         goto invalid;
1197     }
1198 
1199     if (n < (ngx_int_t) (8 * ngx_pagesize)) {
1200         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1201                            "OCSP cache \"%V\" is too small", &value[1]);
1202 
1203         return NGX_CONF_ERROR;
1204     }
1205 
1206     sscf->ocsp_cache_zone = ngx_shared_memory_add(cf, &name, n,
1207                                                   &ngx_http_ssl_module_ctx);
1208     if (sscf->ocsp_cache_zone == NULL) {
1209         return NGX_CONF_ERROR;
1210     }
1211 
1212     sscf->ocsp_cache_zone->init = ngx_ssl_ocsp_cache_init;
1213 
1214     return NGX_CONF_OK;
1215 
1216 invalid:
1217 
1218     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1219                        "invalid OCSP cache \"%V\"", &value[1]);
1220 
1221     return NGX_CONF_ERROR;
1222 }
1223 
1224 
1225 static char *
1226 ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
1227 {
1228 #ifndef SSL_CONF_FLAG_FILE
1229     return "is not supported on this platform";
1230 #else
1231     return NGX_CONF_OK;
1232 #endif
1233 }
1234 
1235 
1236 static ngx_int_t
1237 ngx_http_ssl_init(ngx_conf_t *cf)
1238 {
1239     ngx_uint_t                   a, p, s;
1240     ngx_http_conf_addr_t        *addr;
1241     ngx_http_conf_port_t        *port;
1242     ngx_http_ssl_srv_conf_t     *sscf;
1243     ngx_http_core_loc_conf_t    *clcf;
1244     ngx_http_core_srv_conf_t   **cscfp, *cscf;
1245     ngx_http_core_main_conf_t   *cmcf;
1246 
1247     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
1248     cscfp = cmcf->servers.elts;
1249 
1250     for (s = 0; s < cmcf->servers.nelts; s++) {
1251 
1252         sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
1253 
1254         if (sscf->ssl.ctx == NULL) {
1255             continue;
1256         }
1257 
1258         clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
1259 
1260         if (sscf->stapling) {
1261             if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
1262                                           clcf->resolver_timeout)
1263                 != NGX_OK)
1264             {
1265                 return NGX_ERROR;
1266             }
1267         }
1268 
1269         if (sscf->ocsp) {
1270             if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl, clcf->resolver,
1271                                       clcf->resolver_timeout)
1272                 != NGX_OK)
1273             {
1274                 return NGX_ERROR;
1275             }
1276         }
1277     }
1278 
1279     if (cmcf->ports == NULL) {
1280         return NGX_OK;
1281     }
1282 
1283     port = cmcf->ports->elts;
1284     for (p = 0; p < cmcf->ports->nelts; p++) {
1285 
1286         addr = port[p].addrs.elts;
1287         for (a = 0; a < port[p].addrs.nelts; a++) {
1288 
1289             if (!addr[a].opt.ssl) {
1290                 continue;
1291             }
1292 
1293             cscf = addr[a].default_server;
1294             sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
1295 
1296             if (sscf->certificates) {
1297                 continue;
1298             }
1299 
1300             if (!sscf->reject_handshake) {
1301                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1302                               "no \"ssl_certificate\" is defined for "
1303                               "the \"listen ... ssl\" directive in %s:%ui",
1304                               cscf->file_name, cscf->line);
1305                 return NGX_ERROR;
1306             }
1307 
1308             /*
1309              * if no certificates are defined in the default server,
1310              * check all non-default server blocks
1311              */
1312 
1313             cscfp = addr[a].servers.elts;
1314             for (s = 0; s < addr[a].servers.nelts; s++) {
1315 
1316                 cscf = cscfp[s];
1317                 sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
1318 
1319                 if (sscf->certificates || sscf->reject_handshake) {
1320                     continue;
1321                 }
1322 
1323                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1324                               "no \"ssl_certificate\" is defined for "
1325                               "the \"listen ... ssl\" directive in %s:%ui",
1326                               cscf->file_name, cscf->line);
1327                 return NGX_ERROR;
1328             }
1329         }
1330     }
1331 
1332     return NGX_OK;
1333 }
1334