Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_http.h>
0011 
0012 
0013 typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
0014     ngx_pool_t *pool, ngx_str_t *s);
0015 
0016 
0017 #define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
0018 #define NGX_DEFAULT_ECDH_CURVE  "auto"
0019 
0020 #define NGX_HTTP_NPN_ADVERTISE  "\x08http/1.1"
0021 
0022 
0023 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
0024 static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
0025     const unsigned char **out, unsigned char *outlen,
0026     const unsigned char *in, unsigned int inlen, void *arg);
0027 #endif
0028 
0029 #ifdef TLSEXT_TYPE_next_proto_neg
0030 static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
0031     const unsigned char **out, unsigned int *outlen, void *arg);
0032 #endif
0033 
0034 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
0035     ngx_http_variable_value_t *v, uintptr_t data);
0036 static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
0037     ngx_http_variable_value_t *v, uintptr_t data);
0038 
0039 static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
0040 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
0041 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
0042     void *parent, void *child);
0043 
0044 static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
0045     void *conf);
0046 static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
0047     void *conf);
0048 static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
0049     void *conf);
0050 
0051 static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
0052 
0053 
0054 static ngx_conf_bitmask_t  ngx_http_ssl_protocols[] = {
0055     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
0056     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
0057     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
0058     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
0059     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
0060     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
0061     { ngx_null_string, 0 }
0062 };
0063 
0064 
0065 static ngx_conf_enum_t  ngx_http_ssl_verify[] = {
0066     { ngx_string("off"), 0 },
0067     { ngx_string("on"), 1 },
0068     { ngx_string("optional"), 2 },
0069     { ngx_string("optional_no_ca"), 3 },
0070     { ngx_null_string, 0 }
0071 };
0072 
0073 
0074 static ngx_command_t  ngx_http_ssl_commands[] = {
0075 
0076     { ngx_string("ssl"),
0077       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
0078       ngx_http_ssl_enable,
0079       NGX_HTTP_SRV_CONF_OFFSET,
0080       offsetof(ngx_http_ssl_srv_conf_t, enable),
0081       NULL },
0082 
0083     { ngx_string("ssl_certificate"),
0084       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0085       ngx_conf_set_str_array_slot,
0086       NGX_HTTP_SRV_CONF_OFFSET,
0087       offsetof(ngx_http_ssl_srv_conf_t, certificates),
0088       NULL },
0089 
0090     { ngx_string("ssl_certificate_key"),
0091       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0092       ngx_conf_set_str_array_slot,
0093       NGX_HTTP_SRV_CONF_OFFSET,
0094       offsetof(ngx_http_ssl_srv_conf_t, certificate_keys),
0095       NULL },
0096 
0097     { ngx_string("ssl_password_file"),
0098       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0099       ngx_http_ssl_password_file,
0100       NGX_HTTP_SRV_CONF_OFFSET,
0101       0,
0102       NULL },
0103 
0104     { ngx_string("ssl_dhparam"),
0105       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0106       ngx_conf_set_str_slot,
0107       NGX_HTTP_SRV_CONF_OFFSET,
0108       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
0109       NULL },
0110 
0111     { ngx_string("ssl_ecdh_curve"),
0112       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0113       ngx_conf_set_str_slot,
0114       NGX_HTTP_SRV_CONF_OFFSET,
0115       offsetof(ngx_http_ssl_srv_conf_t, ecdh_curve),
0116       NULL },
0117 
0118     { ngx_string("ssl_protocols"),
0119       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
0120       ngx_conf_set_bitmask_slot,
0121       NGX_HTTP_SRV_CONF_OFFSET,
0122       offsetof(ngx_http_ssl_srv_conf_t, protocols),
0123       &ngx_http_ssl_protocols },
0124 
0125     { ngx_string("ssl_ciphers"),
0126       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0127       ngx_conf_set_str_slot,
0128       NGX_HTTP_SRV_CONF_OFFSET,
0129       offsetof(ngx_http_ssl_srv_conf_t, ciphers),
0130       NULL },
0131 
0132     { ngx_string("ssl_buffer_size"),
0133       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0134       ngx_conf_set_size_slot,
0135       NGX_HTTP_SRV_CONF_OFFSET,
0136       offsetof(ngx_http_ssl_srv_conf_t, buffer_size),
0137       NULL },
0138 
0139     { ngx_string("ssl_verify_client"),
0140       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0141       ngx_conf_set_enum_slot,
0142       NGX_HTTP_SRV_CONF_OFFSET,
0143       offsetof(ngx_http_ssl_srv_conf_t, verify),
0144       &ngx_http_ssl_verify },
0145 
0146     { ngx_string("ssl_verify_depth"),
0147       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0148       ngx_conf_set_num_slot,
0149       NGX_HTTP_SRV_CONF_OFFSET,
0150       offsetof(ngx_http_ssl_srv_conf_t, verify_depth),
0151       NULL },
0152 
0153     { ngx_string("ssl_client_certificate"),
0154       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0155       ngx_conf_set_str_slot,
0156       NGX_HTTP_SRV_CONF_OFFSET,
0157       offsetof(ngx_http_ssl_srv_conf_t, client_certificate),
0158       NULL },
0159 
0160     { ngx_string("ssl_trusted_certificate"),
0161       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0162       ngx_conf_set_str_slot,
0163       NGX_HTTP_SRV_CONF_OFFSET,
0164       offsetof(ngx_http_ssl_srv_conf_t, trusted_certificate),
0165       NULL },
0166 
0167     { ngx_string("ssl_prefer_server_ciphers"),
0168       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
0169       ngx_conf_set_flag_slot,
0170       NGX_HTTP_SRV_CONF_OFFSET,
0171       offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
0172       NULL },
0173 
0174     { ngx_string("ssl_session_cache"),
0175       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
0176       ngx_http_ssl_session_cache,
0177       NGX_HTTP_SRV_CONF_OFFSET,
0178       0,
0179       NULL },
0180 
0181     { ngx_string("ssl_session_tickets"),
0182       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
0183       ngx_conf_set_flag_slot,
0184       NGX_HTTP_SRV_CONF_OFFSET,
0185       offsetof(ngx_http_ssl_srv_conf_t, session_tickets),
0186       NULL },
0187 
0188     { ngx_string("ssl_session_ticket_key"),
0189       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0190       ngx_conf_set_str_array_slot,
0191       NGX_HTTP_SRV_CONF_OFFSET,
0192       offsetof(ngx_http_ssl_srv_conf_t, session_ticket_keys),
0193       NULL },
0194 
0195     { ngx_string("ssl_session_timeout"),
0196       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0197       ngx_conf_set_sec_slot,
0198       NGX_HTTP_SRV_CONF_OFFSET,
0199       offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
0200       NULL },
0201 
0202     { ngx_string("ssl_crl"),
0203       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0204       ngx_conf_set_str_slot,
0205       NGX_HTTP_SRV_CONF_OFFSET,
0206       offsetof(ngx_http_ssl_srv_conf_t, crl),
0207       NULL },
0208 
0209     { ngx_string("ssl_stapling"),
0210       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
0211       ngx_conf_set_flag_slot,
0212       NGX_HTTP_SRV_CONF_OFFSET,
0213       offsetof(ngx_http_ssl_srv_conf_t, stapling),
0214       NULL },
0215 
0216     { ngx_string("ssl_stapling_file"),
0217       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0218       ngx_conf_set_str_slot,
0219       NGX_HTTP_SRV_CONF_OFFSET,
0220       offsetof(ngx_http_ssl_srv_conf_t, stapling_file),
0221       NULL },
0222 
0223     { ngx_string("ssl_stapling_responder"),
0224       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
0225       ngx_conf_set_str_slot,
0226       NGX_HTTP_SRV_CONF_OFFSET,
0227       offsetof(ngx_http_ssl_srv_conf_t, stapling_responder),
0228       NULL },
0229 
0230     { ngx_string("ssl_stapling_verify"),
0231       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
0232       ngx_conf_set_flag_slot,
0233       NGX_HTTP_SRV_CONF_OFFSET,
0234       offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
0235       NULL },
0236 
0237       ngx_null_command
0238 };
0239 
0240 
0241 static ngx_http_module_t  ngx_http_ssl_module_ctx = {
0242     ngx_http_ssl_add_variables,            /* preconfiguration */
0243     ngx_http_ssl_init,                     /* postconfiguration */
0244 
0245     NULL,                                  /* create main configuration */
0246     NULL,                                  /* init main configuration */
0247 
0248     ngx_http_ssl_create_srv_conf,          /* create server configuration */
0249     ngx_http_ssl_merge_srv_conf,           /* merge server configuration */
0250 
0251     NULL,                                  /* create location configuration */
0252     NULL                                   /* merge location configuration */
0253 };
0254 
0255 
0256 ngx_module_t  ngx_http_ssl_module = {
0257     NGX_MODULE_V1,
0258     &ngx_http_ssl_module_ctx,              /* module context */
0259     ngx_http_ssl_commands,                 /* module directives */
0260     NGX_HTTP_MODULE,                       /* module type */
0261     NULL,                                  /* init master */
0262     NULL,                                  /* init module */
0263     NULL,                                  /* init process */
0264     NULL,                                  /* init thread */
0265     NULL,                                  /* exit thread */
0266     NULL,                                  /* exit process */
0267     NULL,                                  /* exit master */
0268     NGX_MODULE_V1_PADDING
0269 };
0270 
0271 
0272 static ngx_http_variable_t  ngx_http_ssl_vars[] = {
0273 
0274     { ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
0275       (uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
0276 
0277     { ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
0278       (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
0279 
0280     { ngx_string("ssl_ciphers"), NULL, ngx_http_ssl_variable,
0281       (uintptr_t) ngx_ssl_get_ciphers, NGX_HTTP_VAR_CHANGEABLE, 0 },
0282 
0283     { ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable,
0284       (uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 },
0285 
0286     { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
0287       (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
0288 
0289     { ngx_string("ssl_session_reused"), NULL, ngx_http_ssl_variable,
0290       (uintptr_t) ngx_ssl_get_session_reused, NGX_HTTP_VAR_CHANGEABLE, 0 },
0291 
0292     { ngx_string("ssl_server_name"), NULL, ngx_http_ssl_variable,
0293       (uintptr_t) ngx_ssl_get_server_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
0294 
0295     { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
0296       (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
0297 
0298     { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable,
0299       (uintptr_t) ngx_ssl_get_raw_certificate,
0300       NGX_HTTP_VAR_CHANGEABLE, 0 },
0301 
0302     { ngx_string("ssl_client_escaped_cert"), NULL, ngx_http_ssl_variable,
0303       (uintptr_t) ngx_ssl_get_escaped_certificate,
0304       NGX_HTTP_VAR_CHANGEABLE, 0 },
0305 
0306     { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
0307       (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
0308 
0309     { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
0310       (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
0311 
0312     { ngx_string("ssl_client_s_dn_legacy"), NULL, ngx_http_ssl_variable,
0313       (uintptr_t) ngx_ssl_get_subject_dn_legacy, NGX_HTTP_VAR_CHANGEABLE, 0 },
0314 
0315     { ngx_string("ssl_client_i_dn_legacy"), NULL, ngx_http_ssl_variable,
0316       (uintptr_t) ngx_ssl_get_issuer_dn_legacy, NGX_HTTP_VAR_CHANGEABLE, 0 },
0317 
0318     { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
0319       (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
0320 
0321     { ngx_string("ssl_client_fingerprint"), NULL, ngx_http_ssl_variable,
0322       (uintptr_t) ngx_ssl_get_fingerprint, NGX_HTTP_VAR_CHANGEABLE, 0 },
0323 
0324     { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
0325       (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
0326 
0327     { ngx_string("ssl_client_v_start"), NULL, ngx_http_ssl_variable,
0328       (uintptr_t) ngx_ssl_get_client_v_start, NGX_HTTP_VAR_CHANGEABLE, 0 },
0329 
0330     { ngx_string("ssl_client_v_end"), NULL, ngx_http_ssl_variable,
0331       (uintptr_t) ngx_ssl_get_client_v_end, NGX_HTTP_VAR_CHANGEABLE, 0 },
0332 
0333     { ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
0334       (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },
0335 
0336       ngx_http_null_variable
0337 };
0338 
0339 
0340 static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
0341 
0342 
0343 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
0344 
0345 static int
0346 ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
0347     unsigned char *outlen, const unsigned char *in, unsigned int inlen,
0348     void *arg)
0349 {
0350     unsigned int            srvlen;
0351     unsigned char          *srv;
0352 #if (NGX_DEBUG)
0353     unsigned int            i;
0354 #endif
0355 #if (NGX_HTTP_V2)
0356     ngx_http_connection_t  *hc;
0357 #endif
0358 #if (NGX_HTTP_V2 || NGX_DEBUG)
0359     ngx_connection_t       *c;
0360 
0361     c = ngx_ssl_get_connection(ssl_conn);
0362 #endif
0363 
0364 #if (NGX_DEBUG)
0365     for (i = 0; i < inlen; i += in[i] + 1) {
0366         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
0367                        "SSL ALPN supported by client: %*s",
0368                        (size_t) in[i], &in[i + 1]);
0369     }
0370 #endif
0371 
0372 #if (NGX_HTTP_V2)
0373     hc = c->data;
0374 
0375     if (hc->addr_conf->http2) {
0376         srv =
0377            (unsigned char *) NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
0378         srvlen = sizeof(NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
0379 
0380     } else
0381 #endif
0382     {
0383         srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
0384         srvlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
0385     }
0386 
0387     if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
0388                               in, inlen)
0389         != OPENSSL_NPN_NEGOTIATED)
0390     {
0391         return SSL_TLSEXT_ERR_NOACK;
0392     }
0393 
0394     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
0395                    "SSL ALPN selected: %*s", (size_t) *outlen, *out);
0396 
0397     return SSL_TLSEXT_ERR_OK;
0398 }
0399 
0400 #endif
0401 
0402 
0403 #ifdef TLSEXT_TYPE_next_proto_neg
0404 
0405 static int
0406 ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
0407     const unsigned char **out, unsigned int *outlen, void *arg)
0408 {
0409 #if (NGX_HTTP_V2 || NGX_DEBUG)
0410     ngx_connection_t  *c;
0411 
0412     c = ngx_ssl_get_connection(ssl_conn);
0413     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised");
0414 #endif
0415 
0416 #if (NGX_HTTP_V2)
0417     {
0418     ngx_http_connection_t  *hc;
0419 
0420     hc = c->data;
0421 
0422     if (hc->addr_conf->http2) {
0423         *out =
0424             (unsigned char *) NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
0425         *outlen = sizeof(NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
0426 
0427         return SSL_TLSEXT_ERR_OK;
0428     }
0429     }
0430 #endif
0431 
0432     *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
0433     *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
0434 
0435     return SSL_TLSEXT_ERR_OK;
0436 }
0437 
0438 #endif
0439 
0440 
0441 static ngx_int_t
0442 ngx_http_ssl_static_variable(ngx_http_request_t *r,
0443     ngx_http_variable_value_t *v, uintptr_t data)
0444 {
0445     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
0446 
0447     size_t     len;
0448     ngx_str_t  s;
0449 
0450     if (r->connection->ssl) {
0451 
0452         (void) handler(r->connection, NULL, &s);
0453 
0454         v->data = s.data;
0455 
0456         for (len = 0; v->data[len]; len++) { /* void */ }
0457 
0458         v->len = len;
0459         v->valid = 1;
0460         v->no_cacheable = 0;
0461         v->not_found = 0;
0462 
0463         return NGX_OK;
0464     }
0465 
0466     v->not_found = 1;
0467 
0468     return NGX_OK;
0469 }
0470 
0471 
0472 static ngx_int_t
0473 ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
0474     uintptr_t data)
0475 {
0476     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
0477 
0478     ngx_str_t  s;
0479 
0480     if (r->connection->ssl) {
0481 
0482         if (handler(r->connection, r->pool, &s) != NGX_OK) {
0483             return NGX_ERROR;
0484         }
0485 
0486         v->len = s.len;
0487         v->data = s.data;
0488 
0489         if (v->len) {
0490             v->valid = 1;
0491             v->no_cacheable = 0;
0492             v->not_found = 0;
0493 
0494             return NGX_OK;
0495         }
0496     }
0497 
0498     v->not_found = 1;
0499 
0500     return NGX_OK;
0501 }
0502 
0503 
0504 static ngx_int_t
0505 ngx_http_ssl_add_variables(ngx_conf_t *cf)
0506 {
0507     ngx_http_variable_t  *var, *v;
0508 
0509     for (v = ngx_http_ssl_vars; v->name.len; v++) {
0510         var = ngx_http_add_variable(cf, &v->name, v->flags);
0511         if (var == NULL) {
0512             return NGX_ERROR;
0513         }
0514 
0515         var->get_handler = v->get_handler;
0516         var->data = v->data;
0517     }
0518 
0519     return NGX_OK;
0520 }
0521 
0522 
0523 static void *
0524 ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
0525 {
0526     ngx_http_ssl_srv_conf_t  *sscf;
0527 
0528     sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
0529     if (sscf == NULL) {
0530         return NULL;
0531     }
0532 
0533     /*
0534      * set by ngx_pcalloc():
0535      *
0536      *     sscf->protocols = 0;
0537      *     sscf->dhparam = { 0, NULL };
0538      *     sscf->ecdh_curve = { 0, NULL };
0539      *     sscf->client_certificate = { 0, NULL };
0540      *     sscf->trusted_certificate = { 0, NULL };
0541      *     sscf->crl = { 0, NULL };
0542      *     sscf->ciphers = { 0, NULL };
0543      *     sscf->shm_zone = NULL;
0544      *     sscf->stapling_file = { 0, NULL };
0545      *     sscf->stapling_responder = { 0, NULL };
0546      */
0547 
0548     sscf->enable = NGX_CONF_UNSET;
0549     sscf->prefer_server_ciphers = NGX_CONF_UNSET;
0550     sscf->buffer_size = NGX_CONF_UNSET_SIZE;
0551     sscf->verify = NGX_CONF_UNSET_UINT;
0552     sscf->verify_depth = NGX_CONF_UNSET_UINT;
0553     sscf->certificates = NGX_CONF_UNSET_PTR;
0554     sscf->certificate_keys = NGX_CONF_UNSET_PTR;
0555     sscf->passwords = NGX_CONF_UNSET_PTR;
0556     sscf->builtin_session_cache = NGX_CONF_UNSET;
0557     sscf->session_timeout = NGX_CONF_UNSET;
0558     sscf->session_tickets = NGX_CONF_UNSET;
0559     sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
0560     sscf->stapling = NGX_CONF_UNSET;
0561     sscf->stapling_verify = NGX_CONF_UNSET;
0562 
0563     return sscf;
0564 }
0565 
0566 
0567 static char *
0568 ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
0569 {
0570     ngx_http_ssl_srv_conf_t *prev = parent;
0571     ngx_http_ssl_srv_conf_t *conf = child;
0572 
0573     ngx_pool_cleanup_t  *cln;
0574 
0575     if (conf->enable == NGX_CONF_UNSET) {
0576         if (prev->enable == NGX_CONF_UNSET) {
0577             conf->enable = 0;
0578 
0579         } else {
0580             conf->enable = prev->enable;
0581             conf->file = prev->file;
0582             conf->line = prev->line;
0583         }
0584     }
0585 
0586     ngx_conf_merge_value(conf->session_timeout,
0587                          prev->session_timeout, 300);
0588 
0589     ngx_conf_merge_value(conf->prefer_server_ciphers,
0590                          prev->prefer_server_ciphers, 0);
0591 
0592     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
0593                          (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
0594                           |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
0595 
0596     ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
0597                          NGX_SSL_BUFSIZE);
0598 
0599     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
0600     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
0601 
0602     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
0603     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
0604                          NULL);
0605 
0606     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
0607 
0608     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
0609 
0610     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
0611                          "");
0612     ngx_conf_merge_str_value(conf->trusted_certificate,
0613                          prev->trusted_certificate, "");
0614     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
0615 
0616     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
0617                          NGX_DEFAULT_ECDH_CURVE);
0618 
0619     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
0620 
0621     ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
0622     ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
0623     ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
0624     ngx_conf_merge_str_value(conf->stapling_responder,
0625                          prev->stapling_responder, "");
0626 
0627     conf->ssl.log = cf->log;
0628 
0629     if (conf->enable) {
0630 
0631         if (conf->certificates == NULL) {
0632             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0633                           "no \"ssl_certificate\" is defined for "
0634                           "the \"ssl\" directive in %s:%ui",
0635                           conf->file, conf->line);
0636             return NGX_CONF_ERROR;
0637         }
0638 
0639         if (conf->certificate_keys == NULL) {
0640             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0641                           "no \"ssl_certificate_key\" is defined for "
0642                           "the \"ssl\" directive in %s:%ui",
0643                           conf->file, conf->line);
0644             return NGX_CONF_ERROR;
0645         }
0646 
0647         if (conf->certificate_keys->nelts < conf->certificates->nelts) {
0648             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0649                           "no \"ssl_certificate_key\" is defined "
0650                           "for certificate \"%V\" and "
0651                           "the \"ssl\" directive in %s:%ui",
0652                           ((ngx_str_t *) conf->certificates->elts)
0653                           + conf->certificates->nelts - 1,
0654                           conf->file, conf->line);
0655             return NGX_CONF_ERROR;
0656         }
0657 
0658     } else {
0659 
0660         if (conf->certificates == NULL) {
0661             return NGX_CONF_OK;
0662         }
0663 
0664         if (conf->certificate_keys == NULL
0665             || conf->certificate_keys->nelts < conf->certificates->nelts)
0666         {
0667             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0668                           "no \"ssl_certificate_key\" is defined "
0669                           "for certificate \"%V\"",
0670                           ((ngx_str_t *) conf->certificates->elts)
0671                           + conf->certificates->nelts - 1);
0672             return NGX_CONF_ERROR;
0673         }
0674     }
0675 
0676     if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
0677         return NGX_CONF_ERROR;
0678     }
0679 
0680 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
0681 
0682     if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
0683                                                ngx_http_ssl_servername)
0684         == 0)
0685     {
0686         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
0687             "nginx was built with SNI support, however, now it is linked "
0688             "dynamically to an OpenSSL library which has no tlsext support, "
0689             "therefore SNI is not available");
0690     }
0691 
0692 #endif
0693 
0694 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
0695     SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
0696 #endif
0697 
0698 #ifdef TLSEXT_TYPE_next_proto_neg
0699     SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
0700                                           ngx_http_ssl_npn_advertised, NULL);
0701 #endif
0702 
0703     cln = ngx_pool_cleanup_add(cf->pool, 0);
0704     if (cln == NULL) {
0705         return NGX_CONF_ERROR;
0706     }
0707 
0708     cln->handler = ngx_ssl_cleanup_ctx;
0709     cln->data = &conf->ssl;
0710 
0711     if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
0712                              conf->certificate_keys, conf->passwords)
0713         != NGX_OK)
0714     {
0715         return NGX_CONF_ERROR;
0716     }
0717 
0718     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
0719                         conf->prefer_server_ciphers)
0720         != NGX_OK)
0721     {
0722         return NGX_CONF_ERROR;
0723     }
0724 
0725     conf->ssl.buffer_size = conf->buffer_size;
0726 
0727     if (conf->verify) {
0728 
0729         if (conf->client_certificate.len == 0 && conf->verify != 3) {
0730             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0731                           "no ssl_client_certificate for ssl_client_verify");
0732             return NGX_CONF_ERROR;
0733         }
0734 
0735         if (ngx_ssl_client_certificate(cf, &conf->ssl,
0736                                        &conf->client_certificate,
0737                                        conf->verify_depth)
0738             != NGX_OK)
0739         {
0740             return NGX_CONF_ERROR;
0741         }
0742     }
0743 
0744     if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
0745                                     &conf->trusted_certificate,
0746                                     conf->verify_depth)
0747         != NGX_OK)
0748     {
0749         return NGX_CONF_ERROR;
0750     }
0751 
0752     if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
0753         return NGX_CONF_ERROR;
0754     }
0755 
0756     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
0757         return NGX_CONF_ERROR;
0758     }
0759 
0760     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
0761         return NGX_CONF_ERROR;
0762     }
0763 
0764     ngx_conf_merge_value(conf->builtin_session_cache,
0765                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
0766 
0767     if (conf->shm_zone == NULL) {
0768         conf->shm_zone = prev->shm_zone;
0769     }
0770 
0771     if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
0772                               conf->builtin_session_cache,
0773                               conf->shm_zone, conf->session_timeout)
0774         != NGX_OK)
0775     {
0776         return NGX_CONF_ERROR;
0777     }
0778 
0779     ngx_conf_merge_value(conf->session_tickets, prev->session_tickets, 1);
0780 
0781 #ifdef SSL_OP_NO_TICKET
0782     if (!conf->session_tickets) {
0783         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
0784     }
0785 #endif
0786 
0787     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
0788                          prev->session_ticket_keys, NULL);
0789 
0790     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
0791         != NGX_OK)
0792     {
0793         return NGX_CONF_ERROR;
0794     }
0795 
0796     if (conf->stapling) {
0797 
0798         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
0799                              &conf->stapling_responder, conf->stapling_verify)
0800             != NGX_OK)
0801         {
0802             return NGX_CONF_ERROR;
0803         }
0804 
0805     }
0806 
0807     return NGX_CONF_OK;
0808 }
0809 
0810 
0811 static char *
0812 ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0813 {
0814     ngx_http_ssl_srv_conf_t *sscf = conf;
0815 
0816     char  *rv;
0817 
0818     rv = ngx_conf_set_flag_slot(cf, cmd, conf);
0819 
0820     if (rv != NGX_CONF_OK) {
0821         return rv;
0822     }
0823 
0824     sscf->file = cf->conf_file->file.name.data;
0825     sscf->line = cf->conf_file->line;
0826 
0827     return NGX_CONF_OK;
0828 }
0829 
0830 
0831 static char *
0832 ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0833 {
0834     ngx_http_ssl_srv_conf_t *sscf = conf;
0835 
0836     ngx_str_t  *value;
0837 
0838     if (sscf->passwords != NGX_CONF_UNSET_PTR) {
0839         return "is duplicate";
0840     }
0841 
0842     value = cf->args->elts;
0843 
0844     sscf->passwords = ngx_ssl_read_password_file(cf, &value[1]);
0845 
0846     if (sscf->passwords == NULL) {
0847         return NGX_CONF_ERROR;
0848     }
0849 
0850     return NGX_CONF_OK;
0851 }
0852 
0853 
0854 static char *
0855 ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0856 {
0857     ngx_http_ssl_srv_conf_t *sscf = conf;
0858 
0859     size_t       len;
0860     ngx_str_t   *value, name, size;
0861     ngx_int_t    n;
0862     ngx_uint_t   i, j;
0863 
0864     value = cf->args->elts;
0865 
0866     for (i = 1; i < cf->args->nelts; i++) {
0867 
0868         if (ngx_strcmp(value[i].data, "off") == 0) {
0869             sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
0870             continue;
0871         }
0872 
0873         if (ngx_strcmp(value[i].data, "none") == 0) {
0874             sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
0875             continue;
0876         }
0877 
0878         if (ngx_strcmp(value[i].data, "builtin") == 0) {
0879             sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
0880             continue;
0881         }
0882 
0883         if (value[i].len > sizeof("builtin:") - 1
0884             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
0885                == 0)
0886         {
0887             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
0888                          value[i].len - (sizeof("builtin:") - 1));
0889 
0890             if (n == NGX_ERROR) {
0891                 goto invalid;
0892             }
0893 
0894             sscf->builtin_session_cache = n;
0895 
0896             continue;
0897         }
0898 
0899         if (value[i].len > sizeof("shared:") - 1
0900             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
0901                == 0)
0902         {
0903             len = 0;
0904 
0905             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
0906                 if (value[i].data[j] == ':') {
0907                     break;
0908                 }
0909 
0910                 len++;
0911             }
0912 
0913             if (len == 0) {
0914                 goto invalid;
0915             }
0916 
0917             name.len = len;
0918             name.data = value[i].data + sizeof("shared:") - 1;
0919 
0920             size.len = value[i].len - j - 1;
0921             size.data = name.data + len + 1;
0922 
0923             n = ngx_parse_size(&size);
0924 
0925             if (n == NGX_ERROR) {
0926                 goto invalid;
0927             }
0928 
0929             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
0930                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0931                                    "session cache \"%V\" is too small",
0932                                    &value[i]);
0933 
0934                 return NGX_CONF_ERROR;
0935             }
0936 
0937             sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
0938                                                    &ngx_http_ssl_module);
0939             if (sscf->shm_zone == NULL) {
0940                 return NGX_CONF_ERROR;
0941             }
0942 
0943             sscf->shm_zone->init = ngx_ssl_session_cache_init;
0944 
0945             continue;
0946         }
0947 
0948         goto invalid;
0949     }
0950 
0951     if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
0952         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
0953     }
0954 
0955     return NGX_CONF_OK;
0956 
0957 invalid:
0958 
0959     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0960                        "invalid session cache \"%V\"", &value[i]);
0961 
0962     return NGX_CONF_ERROR;
0963 }
0964 
0965 
0966 static ngx_int_t
0967 ngx_http_ssl_init(ngx_conf_t *cf)
0968 {
0969     ngx_uint_t                   s;
0970     ngx_http_ssl_srv_conf_t     *sscf;
0971     ngx_http_core_loc_conf_t    *clcf;
0972     ngx_http_core_srv_conf_t   **cscfp;
0973     ngx_http_core_main_conf_t   *cmcf;
0974 
0975     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
0976     cscfp = cmcf->servers.elts;
0977 
0978     for (s = 0; s < cmcf->servers.nelts; s++) {
0979 
0980         sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
0981 
0982         if (sscf->ssl.ctx == NULL || !sscf->stapling) {
0983             continue;
0984         }
0985 
0986         clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
0987 
0988         if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
0989                                       clcf->resolver_timeout)
0990             != NGX_OK)
0991         {
0992             return NGX_ERROR;
0993         }
0994     }
0995 
0996     return NGX_OK;
0997 }