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