src/stream/ngx_stream_ssl_module.c - nginx source code

Global variables defined

Data types defined

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_stream.h>


  8. typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
  9.     ngx_pool_t *pool, ngx_str_t *s);


  10. #define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
  11. #define NGX_DEFAULT_ECDH_CURVE  "auto"


  12. static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s);
  13. static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl,
  14.     ngx_connection_t *c);
  15. static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c);
  16. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  17. static int ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad,
  18.     void *arg);
  19. #endif
  20. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  21. static int ngx_stream_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
  22.     const unsigned char **out, unsigned char *outlen,
  23.     const unsigned char *in, unsigned int inlen, void *arg);
  24. #endif
  25. #ifdef SSL_R_CERT_CB_ERROR
  26. static int ngx_stream_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg);
  27. #endif
  28. static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
  29.     ngx_stream_variable_value_t *v, uintptr_t data);
  30. static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s,
  31.     ngx_stream_variable_value_t *v, uintptr_t data);

  32. static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf);
  33. static void *ngx_stream_ssl_create_srv_conf(ngx_conf_t *cf);
  34. static char *ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent,
  35.     void *child);

  36. static ngx_int_t ngx_stream_ssl_compile_certificates(ngx_conf_t *cf,
  37.     ngx_stream_ssl_srv_conf_t *conf);

  38. static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
  39.     void *conf);
  40. static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  41.     void *conf);
  42. static char *ngx_stream_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  43.     void *conf);
  44. static char *ngx_stream_ssl_alpn(ngx_conf_t *cf, ngx_command_t *cmd,
  45.     void *conf);

  46. static char *ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post,
  47.     void *data);

  48. static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf);


  49. static ngx_conf_bitmask_t  ngx_stream_ssl_protocols[] = {
  50.     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
  51.     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
  52.     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
  53.     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
  54.     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
  55.     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
  56.     { ngx_null_string, 0 }
  57. };


  58. static ngx_conf_enum_t  ngx_stream_ssl_verify[] = {
  59.     { ngx_string("off"), 0 },
  60.     { ngx_string("on"), 1 },
  61.     { ngx_string("optional"), 2 },
  62.     { ngx_string("optional_no_ca"), 3 },
  63.     { ngx_null_string, 0 }
  64. };


  65. static ngx_conf_enum_t  ngx_stream_ssl_ocsp[] = {
  66.     { ngx_string("off"), 0 },
  67.     { ngx_string("on"), 1 },
  68.     { ngx_string("leaf"), 2 },
  69.     { ngx_null_string, 0 }
  70. };


  71. static ngx_conf_post_t  ngx_stream_ssl_conf_command_post =
  72.     { ngx_stream_ssl_conf_command_check };


  73. static ngx_command_t  ngx_stream_ssl_commands[] = {

  74.     { ngx_string("ssl_handshake_timeout"),
  75.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  76.       ngx_conf_set_msec_slot,
  77.       NGX_STREAM_SRV_CONF_OFFSET,
  78.       offsetof(ngx_stream_ssl_srv_conf_t, handshake_timeout),
  79.       NULL },

  80.     { ngx_string("ssl_certificate"),
  81.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  82.       ngx_conf_set_str_array_slot,
  83.       NGX_STREAM_SRV_CONF_OFFSET,
  84.       offsetof(ngx_stream_ssl_srv_conf_t, certificates),
  85.       NULL },

  86.     { ngx_string("ssl_certificate_key"),
  87.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  88.       ngx_conf_set_str_array_slot,
  89.       NGX_STREAM_SRV_CONF_OFFSET,
  90.       offsetof(ngx_stream_ssl_srv_conf_t, certificate_keys),
  91.       NULL },

  92.     { ngx_string("ssl_password_file"),
  93.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  94.       ngx_stream_ssl_password_file,
  95.       NGX_STREAM_SRV_CONF_OFFSET,
  96.       0,
  97.       NULL },

  98.     { ngx_string("ssl_dhparam"),
  99.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  100.       ngx_conf_set_str_slot,
  101.       NGX_STREAM_SRV_CONF_OFFSET,
  102.       offsetof(ngx_stream_ssl_srv_conf_t, dhparam),
  103.       NULL },

  104.     { ngx_string("ssl_ecdh_curve"),
  105.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  106.       ngx_conf_set_str_slot,
  107.       NGX_STREAM_SRV_CONF_OFFSET,
  108.       offsetof(ngx_stream_ssl_srv_conf_t, ecdh_curve),
  109.       NULL },

  110.     { ngx_string("ssl_protocols"),
  111.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  112.       ngx_conf_set_bitmask_slot,
  113.       NGX_STREAM_SRV_CONF_OFFSET,
  114.       offsetof(ngx_stream_ssl_srv_conf_t, protocols),
  115.       &ngx_stream_ssl_protocols },

  116.     { ngx_string("ssl_ciphers"),
  117.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  118.       ngx_conf_set_str_slot,
  119.       NGX_STREAM_SRV_CONF_OFFSET,
  120.       offsetof(ngx_stream_ssl_srv_conf_t, ciphers),
  121.       NULL },

  122.     { ngx_string("ssl_verify_client"),
  123.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  124.       ngx_conf_set_enum_slot,
  125.       NGX_STREAM_SRV_CONF_OFFSET,
  126.       offsetof(ngx_stream_ssl_srv_conf_t, verify),
  127.       &ngx_stream_ssl_verify },

  128.     { ngx_string("ssl_verify_depth"),
  129.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  130.       ngx_conf_set_num_slot,
  131.       NGX_STREAM_SRV_CONF_OFFSET,
  132.       offsetof(ngx_stream_ssl_srv_conf_t, verify_depth),
  133.       NULL },

  134.     { ngx_string("ssl_client_certificate"),
  135.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  136.       ngx_conf_set_str_slot,
  137.       NGX_STREAM_SRV_CONF_OFFSET,
  138.       offsetof(ngx_stream_ssl_srv_conf_t, client_certificate),
  139.       NULL },

  140.     { ngx_string("ssl_trusted_certificate"),
  141.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  142.       ngx_conf_set_str_slot,
  143.       NGX_STREAM_SRV_CONF_OFFSET,
  144.       offsetof(ngx_stream_ssl_srv_conf_t, trusted_certificate),
  145.       NULL },

  146.     { ngx_string("ssl_prefer_server_ciphers"),
  147.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  148.       ngx_conf_set_flag_slot,
  149.       NGX_STREAM_SRV_CONF_OFFSET,
  150.       offsetof(ngx_stream_ssl_srv_conf_t, prefer_server_ciphers),
  151.       NULL },

  152.     { ngx_string("ssl_session_cache"),
  153.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
  154.       ngx_stream_ssl_session_cache,
  155.       NGX_STREAM_SRV_CONF_OFFSET,
  156.       0,
  157.       NULL },

  158.     { ngx_string("ssl_session_tickets"),
  159.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  160.       ngx_conf_set_flag_slot,
  161.       NGX_STREAM_SRV_CONF_OFFSET,
  162.       offsetof(ngx_stream_ssl_srv_conf_t, session_tickets),
  163.       NULL },

  164.     { ngx_string("ssl_session_ticket_key"),
  165.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  166.       ngx_conf_set_str_array_slot,
  167.       NGX_STREAM_SRV_CONF_OFFSET,
  168.       offsetof(ngx_stream_ssl_srv_conf_t, session_ticket_keys),
  169.       NULL },

  170.     { ngx_string("ssl_session_timeout"),
  171.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  172.       ngx_conf_set_sec_slot,
  173.       NGX_STREAM_SRV_CONF_OFFSET,
  174.       offsetof(ngx_stream_ssl_srv_conf_t, session_timeout),
  175.       NULL },

  176.     { ngx_string("ssl_crl"),
  177.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  178.       ngx_conf_set_str_slot,
  179.       NGX_STREAM_SRV_CONF_OFFSET,
  180.       offsetof(ngx_stream_ssl_srv_conf_t, crl),
  181.       NULL },

  182.     { ngx_string("ssl_ocsp"),
  183.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  184.       ngx_conf_set_enum_slot,
  185.       NGX_STREAM_SRV_CONF_OFFSET,
  186.       offsetof(ngx_stream_ssl_srv_conf_t, ocsp),
  187.       &ngx_stream_ssl_ocsp },

  188.     { ngx_string("ssl_ocsp_responder"),
  189.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  190.       ngx_conf_set_str_slot,
  191.       NGX_STREAM_SRV_CONF_OFFSET,
  192.       offsetof(ngx_stream_ssl_srv_conf_t, ocsp_responder),
  193.       NULL },

  194.     { ngx_string("ssl_ocsp_cache"),
  195.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  196.       ngx_stream_ssl_ocsp_cache,
  197.       NGX_STREAM_SRV_CONF_OFFSET,
  198.       0,
  199.       NULL },

  200.     { ngx_string("ssl_stapling"),
  201.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  202.       ngx_conf_set_flag_slot,
  203.       NGX_STREAM_SRV_CONF_OFFSET,
  204.       offsetof(ngx_stream_ssl_srv_conf_t, stapling),
  205.       NULL },

  206.     { ngx_string("ssl_stapling_file"),
  207.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  208.       ngx_conf_set_str_slot,
  209.       NGX_STREAM_SRV_CONF_OFFSET,
  210.       offsetof(ngx_stream_ssl_srv_conf_t, stapling_file),
  211.       NULL },

  212.     { ngx_string("ssl_stapling_responder"),
  213.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  214.       ngx_conf_set_str_slot,
  215.       NGX_STREAM_SRV_CONF_OFFSET,
  216.       offsetof(ngx_stream_ssl_srv_conf_t, stapling_responder),
  217.       NULL },

  218.     { ngx_string("ssl_stapling_verify"),
  219.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  220.       ngx_conf_set_flag_slot,
  221.       NGX_STREAM_SRV_CONF_OFFSET,
  222.       offsetof(ngx_stream_ssl_srv_conf_t, stapling_verify),
  223.       NULL },

  224.     { ngx_string("ssl_conf_command"),
  225.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
  226.       ngx_conf_set_keyval_slot,
  227.       NGX_STREAM_SRV_CONF_OFFSET,
  228.       offsetof(ngx_stream_ssl_srv_conf_t, conf_commands),
  229.       &ngx_stream_ssl_conf_command_post },

  230.     { ngx_string("ssl_reject_handshake"),
  231.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  232.       ngx_conf_set_flag_slot,
  233.       NGX_STREAM_SRV_CONF_OFFSET,
  234.       offsetof(ngx_stream_ssl_srv_conf_t, reject_handshake),
  235.       NULL },

  236.     { ngx_string("ssl_alpn"),
  237.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  238.       ngx_stream_ssl_alpn,
  239.       NGX_STREAM_SRV_CONF_OFFSET,
  240.       0,
  241.       NULL },

  242.       ngx_null_command
  243. };


  244. static ngx_stream_module_t  ngx_stream_ssl_module_ctx = {
  245.     ngx_stream_ssl_add_variables,          /* preconfiguration */
  246.     ngx_stream_ssl_init,                   /* postconfiguration */

  247.     NULL,                                  /* create main configuration */
  248.     NULL,                                  /* init main configuration */

  249.     ngx_stream_ssl_create_srv_conf,        /* create server configuration */
  250.     ngx_stream_ssl_merge_srv_conf          /* merge server configuration */
  251. };


  252. ngx_module_t  ngx_stream_ssl_module = {
  253.     NGX_MODULE_V1,
  254.     &ngx_stream_ssl_module_ctx,            /* module context */
  255.     ngx_stream_ssl_commands,               /* module directives */
  256.     NGX_STREAM_MODULE,                     /* module type */
  257.     NULL,                                  /* init master */
  258.     NULL,                                  /* init module */
  259.     NULL,                                  /* init process */
  260.     NULL,                                  /* init thread */
  261.     NULL,                                  /* exit thread */
  262.     NULL,                                  /* exit process */
  263.     NULL,                                  /* exit master */
  264.     NGX_MODULE_V1_PADDING
  265. };


  266. static ngx_stream_variable_t  ngx_stream_ssl_vars[] = {

  267.     { ngx_string("ssl_protocol"), NULL, ngx_stream_ssl_static_variable,
  268.       (uintptr_t) ngx_ssl_get_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },

  269.     { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable,
  270.       (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 },

  271.     { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable,
  272.       (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 },

  273.     { ngx_string("ssl_curve"), NULL, ngx_stream_ssl_variable,
  274.       (uintptr_t) ngx_ssl_get_curve, NGX_STREAM_VAR_CHANGEABLE, 0 },

  275.     { ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable,
  276.       (uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 },

  277.     { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
  278.       (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },

  279.     { ngx_string("ssl_session_reused"), NULL, ngx_stream_ssl_variable,
  280.       (uintptr_t) ngx_ssl_get_session_reused, NGX_STREAM_VAR_CHANGEABLE, 0 },

  281.     { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable,
  282.       (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 },

  283.     { ngx_string("ssl_alpn_protocol"), NULL, ngx_stream_ssl_variable,
  284.       (uintptr_t) ngx_ssl_get_alpn_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },

  285.     { ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable,
  286.       (uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 },

  287.     { ngx_string("ssl_client_raw_cert"), NULL, ngx_stream_ssl_variable,
  288.       (uintptr_t) ngx_ssl_get_raw_certificate,
  289.       NGX_STREAM_VAR_CHANGEABLE, 0 },

  290.     { ngx_string("ssl_client_escaped_cert"), NULL, ngx_stream_ssl_variable,
  291.       (uintptr_t) ngx_ssl_get_escaped_certificate,
  292.       NGX_STREAM_VAR_CHANGEABLE, 0 },

  293.     { ngx_string("ssl_client_s_dn"), NULL, ngx_stream_ssl_variable,
  294.       (uintptr_t) ngx_ssl_get_subject_dn, NGX_STREAM_VAR_CHANGEABLE, 0 },

  295.     { ngx_string("ssl_client_i_dn"), NULL, ngx_stream_ssl_variable,
  296.       (uintptr_t) ngx_ssl_get_issuer_dn, NGX_STREAM_VAR_CHANGEABLE, 0 },

  297.     { ngx_string("ssl_client_serial"), NULL, ngx_stream_ssl_variable,
  298.       (uintptr_t) ngx_ssl_get_serial_number, NGX_STREAM_VAR_CHANGEABLE, 0 },

  299.     { ngx_string("ssl_client_fingerprint"), NULL, ngx_stream_ssl_variable,
  300.       (uintptr_t) ngx_ssl_get_fingerprint, NGX_STREAM_VAR_CHANGEABLE, 0 },

  301.     { ngx_string("ssl_client_verify"), NULL, ngx_stream_ssl_variable,
  302.       (uintptr_t) ngx_ssl_get_client_verify, NGX_STREAM_VAR_CHANGEABLE, 0 },

  303.     { ngx_string("ssl_client_v_start"), NULL, ngx_stream_ssl_variable,
  304.       (uintptr_t) ngx_ssl_get_client_v_start, NGX_STREAM_VAR_CHANGEABLE, 0 },

  305.     { ngx_string("ssl_client_v_end"), NULL, ngx_stream_ssl_variable,
  306.       (uintptr_t) ngx_ssl_get_client_v_end, NGX_STREAM_VAR_CHANGEABLE, 0 },

  307.     { ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable,
  308.       (uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 },

  309.       ngx_stream_null_variable
  310. };


  311. static ngx_str_t ngx_stream_ssl_sess_id_ctx = ngx_string("STREAM");


  312. static ngx_int_t
  313. ngx_stream_ssl_handler(ngx_stream_session_t *s)
  314. {
  315.     long                        rc;
  316.     X509                       *cert;
  317.     ngx_int_t                   rv;
  318.     ngx_connection_t           *c;
  319.     ngx_stream_ssl_srv_conf_t  *sscf;

  320.     if (!s->ssl) {
  321.         return NGX_OK;
  322.     }

  323.     c = s->connection;

  324.     sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

  325.     if (c->ssl == NULL) {
  326.         c->log->action = "SSL handshaking";

  327.         rv = ngx_stream_ssl_init_connection(&sscf->ssl, c);

  328.         if (rv != NGX_OK) {
  329.             return rv;
  330.         }
  331.     }

  332.     if (sscf->verify) {
  333.         rc = SSL_get_verify_result(c->ssl->connection);

  334.         if (rc != X509_V_OK
  335.             && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
  336.         {
  337.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  338.                           "client SSL certificate verify error: (%l:%s)",
  339.                           rc, X509_verify_cert_error_string(rc));

  340.             ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  341.                                        (SSL_get0_session(c->ssl->connection)));
  342.             return NGX_ERROR;
  343.         }

  344.         if (sscf->verify == 1) {
  345.             cert = SSL_get_peer_certificate(c->ssl->connection);

  346.             if (cert == NULL) {
  347.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  348.                               "client sent no required SSL certificate");

  349.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  350.                                        (SSL_get0_session(c->ssl->connection)));
  351.                 return NGX_ERROR;
  352.             }

  353.             X509_free(cert);
  354.         }
  355.     }

  356.     return NGX_OK;
  357. }


  358. static ngx_int_t
  359. ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
  360. {
  361.     ngx_int_t                    rc;
  362.     ngx_stream_session_t        *s;
  363.     ngx_stream_ssl_srv_conf_t   *sscf;
  364.     ngx_stream_core_srv_conf_t  *cscf;

  365.     s = c->data;

  366.     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  367.     if (cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  368.         return NGX_ERROR;
  369.     }

  370.     if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) {
  371.         return NGX_ERROR;
  372.     }

  373.     rc = ngx_ssl_handshake(c);

  374.     if (rc == NGX_ERROR) {
  375.         return NGX_ERROR;
  376.     }

  377.     if (rc == NGX_AGAIN) {
  378.         sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

  379.         ngx_add_timer(c->read, sscf->handshake_timeout);

  380.         c->ssl->handler = ngx_stream_ssl_handshake_handler;

  381.         return NGX_AGAIN;
  382.     }

  383.     /* rc == NGX_OK */

  384.     return NGX_OK;
  385. }


  386. static void
  387. ngx_stream_ssl_handshake_handler(ngx_connection_t *c)
  388. {
  389.     ngx_stream_session_t  *s;

  390.     s = c->data;

  391.     if (!c->ssl->handshaked) {
  392.         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  393.         return;
  394.     }

  395.     if (c->read->timer_set) {
  396.         ngx_del_timer(c->read);
  397.     }

  398.     ngx_stream_core_run_phases(s);
  399. }


  400. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  401. static int
  402. ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
  403. {
  404.     ngx_int_t                    rc;
  405.     ngx_str_t                    host;
  406.     const char                  *servername;
  407.     ngx_connection_t            *c;
  408.     ngx_stream_session_t        *s;
  409.     ngx_stream_ssl_srv_conf_t   *sscf;
  410.     ngx_stream_core_srv_conf_t  *cscf;

  411.     c = ngx_ssl_get_connection(ssl_conn);

  412.     if (c->ssl->handshaked) {
  413.         *ad = SSL_AD_NO_RENEGOTIATION;
  414.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  415.     }

  416.     s = c->data;

  417.     servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);

  418.     if (servername == NULL) {
  419.         ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  420.                        "SSL server name: null");
  421.         goto done;
  422.     }

  423.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  424.                    "SSL server name: \"%s\"", servername);

  425.     host.len = ngx_strlen(servername);

  426.     if (host.len == 0) {
  427.         goto done;
  428.     }

  429.     host.data = (u_char *) servername;

  430.     rc = ngx_stream_validate_host(&host, c->pool, 1);

  431.     if (rc == NGX_ERROR) {
  432.         goto error;
  433.     }

  434.     if (rc == NGX_DECLINED) {
  435.         goto done;
  436.     }

  437.     rc = ngx_stream_find_virtual_server(s, &host, &cscf);

  438.     if (rc == NGX_ERROR) {
  439.         goto error;
  440.     }

  441.     if (rc == NGX_DECLINED) {
  442.         goto done;
  443.     }

  444.     s->srv_conf = cscf->ctx->srv_conf;

  445.     ngx_set_connection_log(c, cscf->error_log);

  446.     sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

  447.     if (sscf->ssl.ctx) {
  448.         if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
  449.             goto error;
  450.         }

  451.         /*
  452.          * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
  453.          * adjust other things we care about
  454.          */

  455.         SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
  456.                        SSL_CTX_get_verify_callback(sscf->ssl.ctx));

  457.         SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));

  458. #if OPENSSL_VERSION_NUMBER >= 0x009080dfL
  459.         /* only in 0.9.8m+ */
  460.         SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
  461.                                     ~SSL_CTX_get_options(sscf->ssl.ctx));
  462. #endif

  463.         SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));

  464. #ifdef SSL_OP_NO_RENEGOTIATION
  465.         SSL_set_options(ssl_conn, SSL_OP_NO_RENEGOTIATION);
  466. #endif
  467.     }

  468. done:

  469.     sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

  470.     if (sscf->reject_handshake) {
  471.         c->ssl->handshake_rejected = 1;
  472.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  473.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  474.     }

  475.     return SSL_TLSEXT_ERR_OK;

  476. error:

  477.     *ad = SSL_AD_INTERNAL_ERROR;
  478.     return SSL_TLSEXT_ERR_ALERT_FATAL;
  479. }

  480. #endif


  481. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  482. static int
  483. ngx_stream_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
  484.     unsigned char *outlen, const unsigned char *in, unsigned int inlen,
  485.     void *arg)
  486. {
  487.     ngx_str_t         *alpn;
  488. #if (NGX_DEBUG)
  489.     unsigned int       i;
  490.     ngx_connection_t  *c;

  491.     c = ngx_ssl_get_connection(ssl_conn);

  492.     for (i = 0; i < inlen; i += in[i] + 1) {
  493.         ngx_log_debug2(NGX_LOG_DEBUG_STREAM, c->log, 0,
  494.                        "SSL ALPN supported by client: %*s",
  495.                        (size_t) in[i], &in[i + 1]);
  496.     }

  497. #endif

  498.     alpn = arg;

  499.     if (SSL_select_next_proto((unsigned char **) out, outlen, alpn->data,
  500.                               alpn->len, in, inlen)
  501.         != OPENSSL_NPN_NEGOTIATED)
  502.     {
  503.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  504.     }

  505.     ngx_log_debug2(NGX_LOG_DEBUG_STREAM, c->log, 0,
  506.                    "SSL ALPN selected: %*s", (size_t) *outlen, *out);

  507.     return SSL_TLSEXT_ERR_OK;
  508. }

  509. #endif


  510. #ifdef SSL_R_CERT_CB_ERROR

  511. static int
  512. ngx_stream_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
  513. {
  514.     ngx_str_t                    cert, key;
  515.     ngx_uint_t                   i, nelts;
  516.     ngx_connection_t            *c;
  517.     ngx_stream_session_t        *s;
  518.     ngx_stream_ssl_srv_conf_t   *sscf;
  519.     ngx_stream_complex_value_t  *certs, *keys;

  520.     c = ngx_ssl_get_connection(ssl_conn);

  521.     if (c->ssl->handshaked) {
  522.         return 0;
  523.     }

  524.     s = c->data;

  525.     sscf = arg;

  526.     nelts = sscf->certificate_values->nelts;
  527.     certs = sscf->certificate_values->elts;
  528.     keys = sscf->certificate_key_values->elts;

  529.     for (i = 0; i < nelts; i++) {

  530.         if (ngx_stream_complex_value(s, &certs[i], &cert) != NGX_OK) {
  531.             return 0;
  532.         }

  533.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  534.                        "ssl cert: \"%s\"", cert.data);

  535.         if (ngx_stream_complex_value(s, &keys[i], &key) != NGX_OK) {
  536.             return 0;
  537.         }

  538.         ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  539.                        "ssl key: \"%s\"", key.data);

  540.         if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
  541.                                            sscf->passwords)
  542.             != NGX_OK)
  543.         {
  544.             return 0;
  545.         }
  546.     }

  547.     return 1;
  548. }

  549. #endif


  550. static ngx_int_t
  551. ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
  552.     ngx_stream_variable_value_t *v, uintptr_t data)
  553. {
  554.     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;

  555.     size_t     len;
  556.     ngx_str_t  str;

  557.     if (s->connection->ssl) {

  558.         (void) handler(s->connection, NULL, &str);

  559.         v->data = str.data;

  560.         for (len = 0; v->data[len]; len++) { /* void */ }

  561.         v->len = len;
  562.         v->valid = 1;
  563.         v->no_cacheable = 0;
  564.         v->not_found = 0;

  565.         return NGX_OK;
  566.     }

  567.     v->not_found = 1;

  568.     return NGX_OK;
  569. }


  570. static ngx_int_t
  571. ngx_stream_ssl_variable(ngx_stream_session_t *s,
  572.     ngx_stream_variable_value_t *v, uintptr_t data)
  573. {
  574.     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;

  575.     ngx_str_t  str;

  576.     if (s->connection->ssl) {

  577.         if (handler(s->connection, s->connection->pool, &str) != NGX_OK) {
  578.             return NGX_ERROR;
  579.         }

  580.         v->len = str.len;
  581.         v->data = str.data;

  582.         if (v->len) {
  583.             v->valid = 1;
  584.             v->no_cacheable = 0;
  585.             v->not_found = 0;

  586.             return NGX_OK;
  587.         }
  588.     }

  589.     v->not_found = 1;

  590.     return NGX_OK;
  591. }


  592. static ngx_int_t
  593. ngx_stream_ssl_add_variables(ngx_conf_t *cf)
  594. {
  595.     ngx_stream_variable_t  *var, *v;

  596.     for (v = ngx_stream_ssl_vars; v->name.len; v++) {
  597.         var = ngx_stream_add_variable(cf, &v->name, v->flags);
  598.         if (var == NULL) {
  599.             return NGX_ERROR;
  600.         }

  601.         var->get_handler = v->get_handler;
  602.         var->data = v->data;
  603.     }

  604.     return NGX_OK;
  605. }


  606. static void *
  607. ngx_stream_ssl_create_srv_conf(ngx_conf_t *cf)
  608. {
  609.     ngx_stream_ssl_srv_conf_t  *sscf;

  610.     sscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_srv_conf_t));
  611.     if (sscf == NULL) {
  612.         return NULL;
  613.     }

  614.     /*
  615.      * set by ngx_pcalloc():
  616.      *
  617.      *     sscf->protocols = 0;
  618.      *     sscf->certificate_values = NULL;
  619.      *     sscf->dhparam = { 0, NULL };
  620.      *     sscf->ecdh_curve = { 0, NULL };
  621.      *     sscf->client_certificate = { 0, NULL };
  622.      *     sscf->trusted_certificate = { 0, NULL };
  623.      *     sscf->crl = { 0, NULL };
  624.      *     sscf->alpn = { 0, NULL };
  625.      *     sscf->ciphers = { 0, NULL };
  626.      *     sscf->shm_zone = NULL;
  627.      *     sscf->ocsp_responder = { 0, NULL };
  628.      *     sscf->stapling_file = { 0, NULL };
  629.      *     sscf->stapling_responder = { 0, NULL };
  630.      */

  631.     sscf->handshake_timeout = NGX_CONF_UNSET_MSEC;
  632.     sscf->certificates = NGX_CONF_UNSET_PTR;
  633.     sscf->certificate_keys = NGX_CONF_UNSET_PTR;
  634.     sscf->passwords = NGX_CONF_UNSET_PTR;
  635.     sscf->conf_commands = NGX_CONF_UNSET_PTR;
  636.     sscf->prefer_server_ciphers = NGX_CONF_UNSET;
  637.     sscf->reject_handshake = NGX_CONF_UNSET;
  638.     sscf->verify = NGX_CONF_UNSET_UINT;
  639.     sscf->verify_depth = NGX_CONF_UNSET_UINT;
  640.     sscf->builtin_session_cache = NGX_CONF_UNSET;
  641.     sscf->session_timeout = NGX_CONF_UNSET;
  642.     sscf->session_tickets = NGX_CONF_UNSET;
  643.     sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
  644.     sscf->ocsp = NGX_CONF_UNSET_UINT;
  645.     sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
  646.     sscf->stapling = NGX_CONF_UNSET;
  647.     sscf->stapling_verify = NGX_CONF_UNSET;

  648.     return sscf;
  649. }


  650. static char *
  651. ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  652. {
  653.     ngx_stream_ssl_srv_conf_t *prev = parent;
  654.     ngx_stream_ssl_srv_conf_t *conf = child;

  655.     ngx_pool_cleanup_t  *cln;

  656.     ngx_conf_merge_msec_value(conf->handshake_timeout,
  657.                          prev->handshake_timeout, 60000);

  658.     ngx_conf_merge_value(conf->session_timeout,
  659.                          prev->session_timeout, 300);

  660.     ngx_conf_merge_value(conf->prefer_server_ciphers,
  661.                          prev->prefer_server_ciphers, 0);

  662.     ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);

  663.     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
  664.                          (NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));

  665.     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
  666.     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);

  667.     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
  668.     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
  669.                          NULL);

  670.     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);

  671.     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");

  672.     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
  673.                          "");
  674.     ngx_conf_merge_str_value(conf->trusted_certificate,
  675.                          prev->trusted_certificate, "");
  676.     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
  677.     ngx_conf_merge_str_value(conf->alpn, prev->alpn, "");

  678.     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
  679.                          NGX_DEFAULT_ECDH_CURVE);

  680.     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);

  681.     ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL);

  682.     ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
  683.     ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
  684.     ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
  685.                          prev->ocsp_cache_zone, NULL);

  686.     ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
  687.     ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
  688.     ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
  689.     ngx_conf_merge_str_value(conf->stapling_responder,
  690.                          prev->stapling_responder, "");

  691.     conf->ssl.log = cf->log;

  692.     if (conf->certificates) {

  693.         if (conf->certificate_keys == NULL
  694.             || conf->certificate_keys->nelts < conf->certificates->nelts)
  695.         {
  696.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  697.                           "no \"ssl_certificate_key\" is defined "
  698.                           "for certificate \"%V\"",
  699.                           ((ngx_str_t *) conf->certificates->elts)
  700.                           + conf->certificates->nelts - 1);
  701.             return NGX_CONF_ERROR;
  702.         }

  703.     } else if (!conf->reject_handshake) {
  704.         return NGX_CONF_OK;
  705.     }

  706.     if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) {
  707.         return NGX_CONF_ERROR;
  708.     }

  709.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  710.     if (cln == NULL) {
  711.         ngx_ssl_cleanup_ctx(&conf->ssl);
  712.         return NGX_CONF_ERROR;
  713.     }

  714.     cln->handler = ngx_ssl_cleanup_ctx;
  715.     cln->data = &conf->ssl;

  716. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  717.     SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
  718.                                            ngx_stream_ssl_servername);
  719. #endif

  720. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  721.     if (conf->alpn.len) {
  722.         SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_stream_ssl_alpn_select,
  723.                                    &conf->alpn);
  724.     }
  725. #endif

  726.     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
  727.                         conf->prefer_server_ciphers)
  728.         != NGX_OK)
  729.     {
  730.         return NGX_CONF_ERROR;
  731.     }

  732.     if (ngx_stream_ssl_compile_certificates(cf, conf) != NGX_OK) {
  733.         return NGX_CONF_ERROR;
  734.     }

  735.     if (conf->certificate_values) {

  736. #ifdef SSL_R_CERT_CB_ERROR

  737.         /* install callback to lookup certificates */

  738.         SSL_CTX_set_cert_cb(conf->ssl.ctx, ngx_stream_ssl_certificate, conf);

  739. #else
  740.         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  741.                       "variables in "
  742.                       "\"ssl_certificate\" and \"ssl_certificate_key\" "
  743.                       "directives are not supported on this platform");
  744.         return NGX_CONF_ERROR;
  745. #endif

  746.     } else if (conf->certificates) {

  747.         /* configure certificates */

  748.         if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
  749.                                  conf->certificate_keys, conf->passwords)
  750.             != NGX_OK)
  751.         {
  752.             return NGX_CONF_ERROR;
  753.         }
  754.     }

  755.     if (conf->verify) {

  756.         if (conf->verify != 3
  757.             && conf->client_certificate.len == 0
  758.             && conf->trusted_certificate.len == 0)
  759.         {
  760.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  761.                           "no ssl_client_certificate or "
  762.                           "ssl_trusted_certificate for ssl_verify_client");
  763.             return NGX_CONF_ERROR;
  764.         }

  765.         if (ngx_ssl_client_certificate(cf, &conf->ssl,
  766.                                        &conf->client_certificate,
  767.                                        conf->verify_depth)
  768.             != NGX_OK)
  769.         {
  770.             return NGX_CONF_ERROR;
  771.         }
  772.     }

  773.     if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
  774.                                     &conf->trusted_certificate,
  775.                                     conf->verify_depth)
  776.         != NGX_OK)
  777.     {
  778.         return NGX_CONF_ERROR;
  779.     }

  780.     if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
  781.         return NGX_CONF_ERROR;
  782.     }

  783.     if (conf->ocsp) {

  784.         if (conf->verify == 3) {
  785.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  786.                           "\"ssl_ocsp\" is incompatible with "
  787.                           "\"ssl_verify_client optional_no_ca\"");
  788.             return NGX_CONF_ERROR;
  789.         }

  790.         if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
  791.                          conf->ocsp_cache_zone)
  792.             != NGX_OK)
  793.         {
  794.             return NGX_CONF_ERROR;
  795.         }
  796.     }

  797.     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
  798.         return NGX_CONF_ERROR;
  799.     }

  800.     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
  801.         return NGX_CONF_ERROR;
  802.     }

  803.     ngx_conf_merge_value(conf->builtin_session_cache,
  804.                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);

  805.     if (conf->shm_zone == NULL) {
  806.         conf->shm_zone = prev->shm_zone;
  807.     }

  808.     if (ngx_ssl_session_cache(&conf->ssl, &ngx_stream_ssl_sess_id_ctx,
  809.                               conf->certificates, conf->builtin_session_cache,
  810.                               conf->shm_zone, conf->session_timeout)
  811.         != NGX_OK)
  812.     {
  813.         return NGX_CONF_ERROR;
  814.     }

  815.     ngx_conf_merge_value(conf->session_tickets,
  816.                          prev->session_tickets, 1);

  817. #ifdef SSL_OP_NO_TICKET
  818.     if (!conf->session_tickets) {
  819.         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
  820.     }
  821. #endif

  822.     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
  823.                          prev->session_ticket_keys, NULL);

  824.     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
  825.         != NGX_OK)
  826.     {
  827.         return NGX_CONF_ERROR;
  828.     }

  829.     if (conf->stapling) {

  830.         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
  831.                              &conf->stapling_responder, conf->stapling_verify)
  832.             != NGX_OK)
  833.         {
  834.             return NGX_CONF_ERROR;
  835.         }

  836.     }

  837.     if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
  838.         return NGX_CONF_ERROR;
  839.     }

  840.     return NGX_CONF_OK;
  841. }


  842. static ngx_int_t
  843. ngx_stream_ssl_compile_certificates(ngx_conf_t *cf,
  844.     ngx_stream_ssl_srv_conf_t *conf)
  845. {
  846.     ngx_str_t                           *cert, *key;
  847.     ngx_uint_t                           i, nelts;
  848.     ngx_stream_complex_value_t          *cv;
  849.     ngx_stream_compile_complex_value_t   ccv;

  850.     if (conf->certificates == NULL) {
  851.         return NGX_OK;
  852.     }

  853.     cert = conf->certificates->elts;
  854.     key = conf->certificate_keys->elts;
  855.     nelts = conf->certificates->nelts;

  856.     for (i = 0; i < nelts; i++) {

  857.         if (ngx_stream_script_variables_count(&cert[i])) {
  858.             goto found;
  859.         }

  860.         if (ngx_stream_script_variables_count(&key[i])) {
  861.             goto found;
  862.         }
  863.     }

  864.     return NGX_OK;

  865. found:

  866.     conf->certificate_values = ngx_array_create(cf->pool, nelts,
  867.                                            sizeof(ngx_stream_complex_value_t));
  868.     if (conf->certificate_values == NULL) {
  869.         return NGX_ERROR;
  870.     }

  871.     conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
  872.                                            sizeof(ngx_stream_complex_value_t));
  873.     if (conf->certificate_key_values == NULL) {
  874.         return NGX_ERROR;
  875.     }

  876.     for (i = 0; i < nelts; i++) {

  877.         cv = ngx_array_push(conf->certificate_values);
  878.         if (cv == NULL) {
  879.             return NGX_ERROR;
  880.         }

  881.         ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));

  882.         ccv.cf = cf;
  883.         ccv.value = &cert[i];
  884.         ccv.complex_value = cv;
  885.         ccv.zero = 1;

  886.         if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  887.             return NGX_ERROR;
  888.         }

  889.         cv = ngx_array_push(conf->certificate_key_values);
  890.         if (cv == NULL) {
  891.             return NGX_ERROR;
  892.         }

  893.         ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));

  894.         ccv.cf = cf;
  895.         ccv.value = &key[i];
  896.         ccv.complex_value = cv;
  897.         ccv.zero = 1;

  898.         if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  899.             return NGX_ERROR;
  900.         }
  901.     }

  902.     conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
  903.     if (conf->passwords == NULL) {
  904.         return NGX_ERROR;
  905.     }

  906.     return NGX_OK;
  907. }


  908. static char *
  909. ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  910. {
  911.     ngx_stream_ssl_srv_conf_t  *sscf = conf;

  912.     ngx_str_t  *value;

  913.     if (sscf->passwords != NGX_CONF_UNSET_PTR) {
  914.         return "is duplicate";
  915.     }

  916.     value = cf->args->elts;

  917.     sscf->passwords = ngx_ssl_read_password_file(cf, &value[1]);

  918.     if (sscf->passwords == NULL) {
  919.         return NGX_CONF_ERROR;
  920.     }

  921.     return NGX_CONF_OK;
  922. }


  923. static char *
  924. ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  925. {
  926.     ngx_stream_ssl_srv_conf_t  *sscf = conf;

  927.     size_t       len;
  928.     ngx_str_t   *value, name, size;
  929.     ngx_int_t    n;
  930.     ngx_uint_t   i, j;

  931.     value = cf->args->elts;

  932.     for (i = 1; i < cf->args->nelts; i++) {

  933.         if (ngx_strcmp(value[i].data, "off") == 0) {
  934.             sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
  935.             continue;
  936.         }

  937.         if (ngx_strcmp(value[i].data, "none") == 0) {
  938.             sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
  939.             continue;
  940.         }

  941.         if (ngx_strcmp(value[i].data, "builtin") == 0) {
  942.             sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
  943.             continue;
  944.         }

  945.         if (value[i].len > sizeof("builtin:") - 1
  946.             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
  947.                == 0)
  948.         {
  949.             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
  950.                          value[i].len - (sizeof("builtin:") - 1));

  951.             if (n == NGX_ERROR) {
  952.                 goto invalid;
  953.             }

  954.             sscf->builtin_session_cache = n;

  955.             continue;
  956.         }

  957.         if (value[i].len > sizeof("shared:") - 1
  958.             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
  959.                == 0)
  960.         {
  961.             len = 0;

  962.             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
  963.                 if (value[i].data[j] == ':') {
  964.                     break;
  965.                 }

  966.                 len++;
  967.             }

  968.             if (len == 0 || j == value[i].len) {
  969.                 goto invalid;
  970.             }

  971.             name.len = len;
  972.             name.data = value[i].data + sizeof("shared:") - 1;

  973.             size.len = value[i].len - j - 1;
  974.             size.data = name.data + len + 1;

  975.             n = ngx_parse_size(&size);

  976.             if (n == NGX_ERROR) {
  977.                 goto invalid;
  978.             }

  979.             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
  980.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  981.                                    "session cache \"%V\" is too small",
  982.                                    &value[i]);

  983.                 return NGX_CONF_ERROR;
  984.             }

  985.             sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
  986.                                                    &ngx_stream_ssl_module);
  987.             if (sscf->shm_zone == NULL) {
  988.                 return NGX_CONF_ERROR;
  989.             }

  990.             sscf->shm_zone->init = ngx_ssl_session_cache_init;

  991.             continue;
  992.         }

  993.         goto invalid;
  994.     }

  995.     if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
  996.         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
  997.     }

  998.     return NGX_CONF_OK;

  999. invalid:

  1000.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1001.                        "invalid session cache \"%V\"", &value[i]);

  1002.     return NGX_CONF_ERROR;
  1003. }


  1004. static char *
  1005. ngx_stream_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1006. {
  1007.     ngx_stream_ssl_srv_conf_t *sscf = conf;

  1008.     size_t       len;
  1009.     ngx_int_t    n;
  1010.     ngx_str_t   *value, name, size;
  1011.     ngx_uint_t   j;

  1012.     if (sscf->ocsp_cache_zone != NGX_CONF_UNSET_PTR) {
  1013.         return "is duplicate";
  1014.     }

  1015.     value = cf->args->elts;

  1016.     if (ngx_strcmp(value[1].data, "off") == 0) {
  1017.         sscf->ocsp_cache_zone = NULL;
  1018.         return NGX_CONF_OK;
  1019.     }

  1020.     if (value[1].len <= sizeof("shared:") - 1
  1021.         || ngx_strncmp(value[1].data, "shared:", sizeof("shared:") - 1) != 0)
  1022.     {
  1023.         goto invalid;
  1024.     }

  1025.     len = 0;

  1026.     for (j = sizeof("shared:") - 1; j < value[1].len; j++) {
  1027.         if (value[1].data[j] == ':') {
  1028.             break;
  1029.         }

  1030.         len++;
  1031.     }

  1032.     if (len == 0 || j == value[1].len) {
  1033.         goto invalid;
  1034.     }

  1035.     name.len = len;
  1036.     name.data = value[1].data + sizeof("shared:") - 1;

  1037.     size.len = value[1].len - j - 1;
  1038.     size.data = name.data + len + 1;

  1039.     n = ngx_parse_size(&size);

  1040.     if (n == NGX_ERROR) {
  1041.         goto invalid;
  1042.     }

  1043.     if (n < (ngx_int_t) (8 * ngx_pagesize)) {
  1044.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1045.                            "OCSP cache \"%V\" is too small", &value[1]);

  1046.         return NGX_CONF_ERROR;
  1047.     }

  1048.     sscf->ocsp_cache_zone = ngx_shared_memory_add(cf, &name, n,
  1049.                                                   &ngx_stream_ssl_module_ctx);
  1050.     if (sscf->ocsp_cache_zone == NULL) {
  1051.         return NGX_CONF_ERROR;
  1052.     }

  1053.     sscf->ocsp_cache_zone->init = ngx_ssl_ocsp_cache_init;

  1054.     return NGX_CONF_OK;

  1055. invalid:

  1056.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1057.                        "invalid OCSP cache \"%V\"", &value[1]);

  1058.     return NGX_CONF_ERROR;
  1059. }


  1060. static char *
  1061. ngx_stream_ssl_alpn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1062. {
  1063. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  1064.     ngx_stream_ssl_srv_conf_t  *sscf = conf;

  1065.     u_char      *p;
  1066.     size_t       len;
  1067.     ngx_str_t   *value;
  1068.     ngx_uint_t   i;

  1069.     if (sscf->alpn.len) {
  1070.         return "is duplicate";
  1071.     }

  1072.     value = cf->args->elts;

  1073.     len = 0;

  1074.     for (i = 1; i < cf->args->nelts; i++) {

  1075.         if (value[i].len > 255) {
  1076.             return "protocol too long";
  1077.         }

  1078.         len += value[i].len + 1;
  1079.     }

  1080.     sscf->alpn.data = ngx_pnalloc(cf->pool, len);
  1081.     if (sscf->alpn.data == NULL) {
  1082.         return NGX_CONF_ERROR;
  1083.     }

  1084.     p = sscf->alpn.data;

  1085.     for (i = 1; i < cf->args->nelts; i++) {
  1086.         *p++ = value[i].len;
  1087.         p = ngx_cpymem(p, value[i].data, value[i].len);
  1088.     }

  1089.     sscf->alpn.len = len;

  1090.     return NGX_CONF_OK;

  1091. #else
  1092.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1093.                        "the \"ssl_alpn\" directive requires OpenSSL "
  1094.                        "with ALPN support");
  1095.     return NGX_CONF_ERROR;
  1096. #endif
  1097. }


  1098. static char *
  1099. ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
  1100. {
  1101. #ifndef SSL_CONF_FLAG_FILE
  1102.     return "is not supported on this platform";
  1103. #else
  1104.     return NGX_CONF_OK;
  1105. #endif
  1106. }


  1107. static ngx_int_t
  1108. ngx_stream_ssl_init(ngx_conf_t *cf)
  1109. {
  1110.     ngx_uint_t                     a, p, s;
  1111.     ngx_stream_handler_pt         *h;
  1112.     ngx_stream_conf_addr_t        *addr;
  1113.     ngx_stream_conf_port_t        *port;
  1114.     ngx_stream_ssl_srv_conf_t     *sscf;
  1115.     ngx_stream_core_srv_conf_t   **cscfp, *cscf;
  1116.     ngx_stream_core_main_conf_t   *cmcf;

  1117.     cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
  1118.     cscfp = cmcf->servers.elts;

  1119.     for (s = 0; s < cmcf->servers.nelts; s++) {

  1120.         sscf = cscfp[s]->ctx->srv_conf[ngx_stream_ssl_module.ctx_index];

  1121.         if (sscf->ssl.ctx == NULL) {
  1122.             continue;
  1123.         }

  1124.         cscf = cscfp[s]->ctx->srv_conf[ngx_stream_core_module.ctx_index];

  1125.         if (sscf->stapling) {
  1126.             if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, cscf->resolver,
  1127.                                           cscf->resolver_timeout)
  1128.                 != NGX_OK)
  1129.             {
  1130.                 return NGX_ERROR;
  1131.             }
  1132.         }

  1133.         if (sscf->ocsp) {
  1134.             if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl, cscf->resolver,
  1135.                                       cscf->resolver_timeout)
  1136.                 != NGX_OK)
  1137.             {
  1138.                 return NGX_ERROR;
  1139.             }
  1140.         }
  1141.     }

  1142.     h = ngx_array_push(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers);
  1143.     if (h == NULL) {
  1144.         return NGX_ERROR;
  1145.     }

  1146.     *h = ngx_stream_ssl_handler;

  1147.     if (cmcf->ports == NULL) {
  1148.         return NGX_OK;
  1149.     }

  1150.     port = cmcf->ports->elts;
  1151.     for (p = 0; p < cmcf->ports->nelts; p++) {

  1152.         addr = port[p].addrs.elts;
  1153.         for (a = 0; a < port[p].addrs.nelts; a++) {

  1154.             if (!addr[a].opt.ssl) {
  1155.                 continue;
  1156.             }

  1157.             cscf = addr[a].default_server;
  1158.             sscf = cscf->ctx->srv_conf[ngx_stream_ssl_module.ctx_index];

  1159.             if (sscf->certificates) {
  1160.                 continue;
  1161.             }

  1162.             if (!sscf->reject_handshake) {
  1163.                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1164.                               "no \"ssl_certificate\" is defined for "
  1165.                               "the \"listen ... ssl\" directive in %s:%ui",
  1166.                               cscf->file_name, cscf->line);
  1167.                 return NGX_ERROR;
  1168.             }

  1169.             /*
  1170.              * if no certificates are defined in the default server,
  1171.              * check all non-default server blocks
  1172.              */

  1173.             cscfp = addr[a].servers.elts;
  1174.             for (s = 0; s < addr[a].servers.nelts; s++) {

  1175.                 cscf = cscfp[s];
  1176.                 sscf = cscf->ctx->srv_conf[ngx_stream_ssl_module.ctx_index];

  1177.                 if (sscf->certificates || sscf->reject_handshake) {
  1178.                     continue;
  1179.                 }

  1180.                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1181.                               "no \"ssl_certificate\" is defined for "
  1182.                               "the \"listen ... ssl\" directive in %s:%ui",
  1183.                               cscf->file_name, cscf->line);
  1184.                 return NGX_ERROR;
  1185.             }
  1186.         }
  1187.     }

  1188.     return NGX_OK;
  1189. }