Annotation of embedaddon/nginx/src/http/modules/ngx_http_ssl_module.c, revision 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>