Annotation of embedaddon/nginx/src/http/modules/ngx_http_ssl_module.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>