src/stream/ngx_stream_ssl_module.c - nginx

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_certificate_cache(ngx_conf_t *cf,
  39.     ngx_command_t *cmd, void *conf);
  40. static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
  41.     void *conf);
  42. static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  43.     void *conf);
  44. static char *ngx_stream_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  45.     void *conf);
  46. static char *ngx_stream_ssl_alpn(ngx_conf_t *cf, ngx_command_t *cmd,
  47.     void *conf);

  48. static char *ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post,
  49.     void *data);

  50. static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf);


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


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


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


  73. static ngx_conf_post_t  ngx_stream_ssl_conf_command_post =
  74.     { ngx_stream_ssl_conf_command_check };


  75. static ngx_command_t  ngx_stream_ssl_commands[] = {

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

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

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

  94.     { ngx_string("ssl_certificate_cache"),
  95.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE123,
  96.       ngx_stream_ssl_certificate_cache,
  97.       NGX_STREAM_SRV_CONF_OFFSET,
  98.       0,
  99.       NULL },

  100.     { ngx_string("ssl_ech_file"),
  101.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  102.       ngx_conf_set_str_array_slot,
  103.       NGX_STREAM_SRV_CONF_OFFSET,
  104.       offsetof(ngx_stream_ssl_srv_conf_t, ech_files),
  105.       NULL },

  106.     { ngx_string("ssl_password_file"),
  107.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  108.       ngx_stream_ssl_password_file,
  109.       NGX_STREAM_SRV_CONF_OFFSET,
  110.       0,
  111.       NULL },

  112.     { ngx_string("ssl_certificate_compression"),
  113.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  114.       ngx_conf_set_flag_slot,
  115.       NGX_STREAM_SRV_CONF_OFFSET,
  116.       offsetof(ngx_stream_ssl_srv_conf_t, certificate_compression),
  117.       NULL },

  118.     { ngx_string("ssl_dhparam"),
  119.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  120.       ngx_conf_set_str_slot,
  121.       NGX_STREAM_SRV_CONF_OFFSET,
  122.       offsetof(ngx_stream_ssl_srv_conf_t, dhparam),
  123.       NULL },

  124.     { ngx_string("ssl_ecdh_curve"),
  125.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  126.       ngx_conf_set_str_slot,
  127.       NGX_STREAM_SRV_CONF_OFFSET,
  128.       offsetof(ngx_stream_ssl_srv_conf_t, ecdh_curve),
  129.       NULL },

  130.     { ngx_string("ssl_protocols"),
  131.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  132.       ngx_conf_set_bitmask_slot,
  133.       NGX_STREAM_SRV_CONF_OFFSET,
  134.       offsetof(ngx_stream_ssl_srv_conf_t, protocols),
  135.       &ngx_stream_ssl_protocols },

  136.     { ngx_string("ssl_ciphers"),
  137.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  138.       ngx_conf_set_str_slot,
  139.       NGX_STREAM_SRV_CONF_OFFSET,
  140.       offsetof(ngx_stream_ssl_srv_conf_t, ciphers),
  141.       NULL },

  142.     { ngx_string("ssl_verify_client"),
  143.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  144.       ngx_conf_set_enum_slot,
  145.       NGX_STREAM_SRV_CONF_OFFSET,
  146.       offsetof(ngx_stream_ssl_srv_conf_t, verify),
  147.       &ngx_stream_ssl_verify },

  148.     { ngx_string("ssl_verify_depth"),
  149.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  150.       ngx_conf_set_num_slot,
  151.       NGX_STREAM_SRV_CONF_OFFSET,
  152.       offsetof(ngx_stream_ssl_srv_conf_t, verify_depth),
  153.       NULL },

  154.     { ngx_string("ssl_client_certificate"),
  155.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  156.       ngx_conf_set_str_slot,
  157.       NGX_STREAM_SRV_CONF_OFFSET,
  158.       offsetof(ngx_stream_ssl_srv_conf_t, client_certificate),
  159.       NULL },

  160.     { ngx_string("ssl_trusted_certificate"),
  161.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  162.       ngx_conf_set_str_slot,
  163.       NGX_STREAM_SRV_CONF_OFFSET,
  164.       offsetof(ngx_stream_ssl_srv_conf_t, trusted_certificate),
  165.       NULL },

  166.     { ngx_string("ssl_prefer_server_ciphers"),
  167.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  168.       ngx_conf_set_flag_slot,
  169.       NGX_STREAM_SRV_CONF_OFFSET,
  170.       offsetof(ngx_stream_ssl_srv_conf_t, prefer_server_ciphers),
  171.       NULL },

  172.     { ngx_string("ssl_session_cache"),
  173.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
  174.       ngx_stream_ssl_session_cache,
  175.       NGX_STREAM_SRV_CONF_OFFSET,
  176.       0,
  177.       NULL },

  178.     { ngx_string("ssl_session_tickets"),
  179.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  180.       ngx_conf_set_flag_slot,
  181.       NGX_STREAM_SRV_CONF_OFFSET,
  182.       offsetof(ngx_stream_ssl_srv_conf_t, session_tickets),
  183.       NULL },

  184.     { ngx_string("ssl_session_ticket_key"),
  185.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  186.       ngx_conf_set_str_array_slot,
  187.       NGX_STREAM_SRV_CONF_OFFSET,
  188.       offsetof(ngx_stream_ssl_srv_conf_t, session_ticket_keys),
  189.       NULL },

  190.     { ngx_string("ssl_session_timeout"),
  191.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  192.       ngx_conf_set_sec_slot,
  193.       NGX_STREAM_SRV_CONF_OFFSET,
  194.       offsetof(ngx_stream_ssl_srv_conf_t, session_timeout),
  195.       NULL },

  196.     { ngx_string("ssl_crl"),
  197.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  198.       ngx_conf_set_str_slot,
  199.       NGX_STREAM_SRV_CONF_OFFSET,
  200.       offsetof(ngx_stream_ssl_srv_conf_t, crl),
  201.       NULL },

  202.     { ngx_string("ssl_ocsp"),
  203.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  204.       ngx_conf_set_enum_slot,
  205.       NGX_STREAM_SRV_CONF_OFFSET,
  206.       offsetof(ngx_stream_ssl_srv_conf_t, ocsp),
  207.       &ngx_stream_ssl_ocsp },

  208.     { ngx_string("ssl_ocsp_responder"),
  209.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  210.       ngx_conf_set_str_slot,
  211.       NGX_STREAM_SRV_CONF_OFFSET,
  212.       offsetof(ngx_stream_ssl_srv_conf_t, ocsp_responder),
  213.       NULL },

  214.     { ngx_string("ssl_ocsp_cache"),
  215.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  216.       ngx_stream_ssl_ocsp_cache,
  217.       NGX_STREAM_SRV_CONF_OFFSET,
  218.       0,
  219.       NULL },

  220.     { ngx_string("ssl_stapling"),
  221.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  222.       ngx_conf_set_flag_slot,
  223.       NGX_STREAM_SRV_CONF_OFFSET,
  224.       offsetof(ngx_stream_ssl_srv_conf_t, stapling),
  225.       NULL },

  226.     { ngx_string("ssl_stapling_file"),
  227.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  228.       ngx_conf_set_str_slot,
  229.       NGX_STREAM_SRV_CONF_OFFSET,
  230.       offsetof(ngx_stream_ssl_srv_conf_t, stapling_file),
  231.       NULL },

  232.     { ngx_string("ssl_stapling_responder"),
  233.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
  234.       ngx_conf_set_str_slot,
  235.       NGX_STREAM_SRV_CONF_OFFSET,
  236.       offsetof(ngx_stream_ssl_srv_conf_t, stapling_responder),
  237.       NULL },

  238.     { ngx_string("ssl_stapling_verify"),
  239.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  240.       ngx_conf_set_flag_slot,
  241.       NGX_STREAM_SRV_CONF_OFFSET,
  242.       offsetof(ngx_stream_ssl_srv_conf_t, stapling_verify),
  243.       NULL },

  244.     { ngx_string("ssl_conf_command"),
  245.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
  246.       ngx_conf_set_keyval_slot,
  247.       NGX_STREAM_SRV_CONF_OFFSET,
  248.       offsetof(ngx_stream_ssl_srv_conf_t, conf_commands),
  249.       &ngx_stream_ssl_conf_command_post },

  250.     { ngx_string("ssl_reject_handshake"),
  251.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
  252.       ngx_conf_set_flag_slot,
  253.       NGX_STREAM_SRV_CONF_OFFSET,
  254.       offsetof(ngx_stream_ssl_srv_conf_t, reject_handshake),
  255.       NULL },

  256.     { ngx_string("ssl_alpn"),
  257.       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
  258.       ngx_stream_ssl_alpn,
  259.       NGX_STREAM_SRV_CONF_OFFSET,
  260.       0,
  261.       NULL },

  262.       ngx_null_command
  263. };


  264. static ngx_stream_module_t  ngx_stream_ssl_module_ctx = {
  265.     ngx_stream_ssl_add_variables,          /* preconfiguration */
  266.     ngx_stream_ssl_init,                   /* postconfiguration */

  267.     NULL,                                  /* create main configuration */
  268.     NULL,                                  /* init main configuration */

  269.     ngx_stream_ssl_create_srv_conf,        /* create server configuration */
  270.     ngx_stream_ssl_merge_srv_conf          /* merge server configuration */
  271. };


  272. ngx_module_t  ngx_stream_ssl_module = {
  273.     NGX_MODULE_V1,
  274.     &ngx_stream_ssl_module_ctx,            /* module context */
  275.     ngx_stream_ssl_commands,               /* module directives */
  276.     NGX_STREAM_MODULE,                     /* module type */
  277.     NULL,                                  /* init master */
  278.     NULL,                                  /* init module */
  279.     NULL,                                  /* init process */
  280.     NULL,                                  /* init thread */
  281.     NULL,                                  /* exit thread */
  282.     NULL,                                  /* exit process */
  283.     NULL,                                  /* exit master */
  284.     NGX_MODULE_V1_PADDING
  285. };


  286. static ngx_stream_variable_t  ngx_stream_ssl_vars[] = {

  287.     { ngx_string("ssl_protocol"), NULL, ngx_stream_ssl_static_variable,
  288.       (uintptr_t) ngx_ssl_get_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },

  289.     { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable,
  290.       (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 },

  291.     { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable,
  292.       (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 },

  293.     { ngx_string("ssl_curve"), NULL, ngx_stream_ssl_variable,
  294.       (uintptr_t) ngx_ssl_get_curve, NGX_STREAM_VAR_CHANGEABLE, 0 },

  295.     { ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable,
  296.       (uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 },

  297.     { ngx_string("ssl_sigalg"), NULL, ngx_stream_ssl_variable,
  298.       (uintptr_t) ngx_ssl_get_sigalg, NGX_STREAM_VAR_CHANGEABLE, 0 },

  299.     { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
  300.       (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },

  301.     { ngx_string("ssl_session_reused"), NULL, ngx_stream_ssl_variable,
  302.       (uintptr_t) ngx_ssl_get_session_reused, NGX_STREAM_VAR_CHANGEABLE, 0 },

  303.     { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable,
  304.       (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 },

  305.     { ngx_string("ssl_alpn_protocol"), NULL, ngx_stream_ssl_variable,
  306.       (uintptr_t) ngx_ssl_get_alpn_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },

  307.     { ngx_string("ssl_ech_status"), NULL, ngx_stream_ssl_variable,
  308.       (uintptr_t) ngx_ssl_get_ech_status, NGX_STREAM_VAR_CHANGEABLE, 0 },

  309.     { ngx_string("ssl_ech_outer_server_name"), NULL, ngx_stream_ssl_variable,
  310.       (uintptr_t) ngx_ssl_get_ech_outer_server_name,
  311.       NGX_STREAM_VAR_CHANGEABLE, 0 },

  312.     { ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable,
  313.       (uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 },

  314.     { ngx_string("ssl_client_raw_cert"), NULL, ngx_stream_ssl_variable,
  315.       (uintptr_t) ngx_ssl_get_raw_certificate,
  316.       NGX_STREAM_VAR_CHANGEABLE, 0 },

  317.     { ngx_string("ssl_client_escaped_cert"), NULL, ngx_stream_ssl_variable,
  318.       (uintptr_t) ngx_ssl_get_escaped_certificate,
  319.       NGX_STREAM_VAR_CHANGEABLE, 0 },

  320.     { ngx_string("ssl_client_s_dn"), NULL, ngx_stream_ssl_variable,
  321.       (uintptr_t) ngx_ssl_get_subject_dn, NGX_STREAM_VAR_CHANGEABLE, 0 },

  322.     { ngx_string("ssl_client_i_dn"), NULL, ngx_stream_ssl_variable,
  323.       (uintptr_t) ngx_ssl_get_issuer_dn, NGX_STREAM_VAR_CHANGEABLE, 0 },

  324.     { ngx_string("ssl_client_serial"), NULL, ngx_stream_ssl_variable,
  325.       (uintptr_t) ngx_ssl_get_serial_number, NGX_STREAM_VAR_CHANGEABLE, 0 },

  326.     { ngx_string("ssl_client_fingerprint"), NULL, ngx_stream_ssl_variable,
  327.       (uintptr_t) ngx_ssl_get_fingerprint, NGX_STREAM_VAR_CHANGEABLE, 0 },

  328.     { ngx_string("ssl_client_verify"), NULL, ngx_stream_ssl_variable,
  329.       (uintptr_t) ngx_ssl_get_client_verify, NGX_STREAM_VAR_CHANGEABLE, 0 },

  330.     { ngx_string("ssl_client_v_start"), NULL, ngx_stream_ssl_variable,
  331.       (uintptr_t) ngx_ssl_get_client_v_start, NGX_STREAM_VAR_CHANGEABLE, 0 },

  332.     { ngx_string("ssl_client_v_end"), NULL, ngx_stream_ssl_variable,
  333.       (uintptr_t) ngx_ssl_get_client_v_end, NGX_STREAM_VAR_CHANGEABLE, 0 },

  334.     { ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable,
  335.       (uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 },

  336.     { ngx_string("ssl_client_sigalg"), NULL, ngx_stream_ssl_variable,
  337.       (uintptr_t) ngx_ssl_get_client_sigalg, NGX_STREAM_VAR_CHANGEABLE, 0 },

  338.       ngx_stream_null_variable
  339. };


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


  341. static ngx_int_t
  342. ngx_stream_ssl_handler(ngx_stream_session_t *s)
  343. {
  344.     long                        rc;
  345.     X509                       *cert;
  346.     ngx_int_t                   rv;
  347.     const char                 *str;
  348.     ngx_connection_t           *c;
  349.     ngx_stream_ssl_srv_conf_t  *sscf;

  350.     if (!s->ssl) {
  351.         return NGX_OK;
  352.     }

  353.     c = s->connection;

  354.     sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

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

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

  358.         if (rv != NGX_OK) {
  359.             return rv;
  360.         }
  361.     }

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

  364.         if (rc != X509_V_OK
  365.             && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
  366.         {
  367.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  368.                           "client SSL certificate verify error: (%l:%s)",
  369.                           rc, X509_verify_cert_error_string(rc));

  370.             ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  371.                                        (SSL_get0_session(c->ssl->connection)));
  372.             return NGX_ERROR;
  373.         }

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

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

  379.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  380.                                        (SSL_get0_session(c->ssl->connection)));
  381.                 return NGX_ERROR;
  382.             }

  383.             X509_free(cert);
  384.         }

  385.         if (ngx_ssl_ocsp_get_status(c, &str) != NGX_OK) {
  386.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  387.                           "client SSL certificate verify error: %s", str);

  388.             ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  389.                                        (SSL_get0_session(c->ssl->connection)));
  390.             return NGX_ERROR;
  391.         }
  392.     }

  393.     return NGX_OK;
  394. }


  395. static ngx_int_t
  396. ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
  397. {
  398.     ngx_int_t                    rc;
  399.     ngx_stream_session_t        *s;
  400.     ngx_stream_ssl_srv_conf_t   *sscf;
  401.     ngx_stream_core_srv_conf_t  *cscf;

  402.     s = c->data;

  403.     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);

  404.     if (cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  405.         return NGX_ERROR;
  406.     }

  407.     if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) {
  408.         return NGX_ERROR;
  409.     }

  410.     rc = ngx_ssl_handshake(c);

  411.     if (rc == NGX_ERROR) {
  412.         return NGX_ERROR;
  413.     }

  414.     if (rc == NGX_AGAIN) {
  415.         sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

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

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

  418.         return NGX_AGAIN;
  419.     }

  420.     /* rc == NGX_OK */

  421.     return NGX_OK;
  422. }


  423. static void
  424. ngx_stream_ssl_handshake_handler(ngx_connection_t *c)
  425. {
  426.     ngx_stream_session_t  *s;

  427.     s = c->data;

  428.     if (!c->ssl->handshaked) {
  429.         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
  430.         return;
  431.     }

  432.     if (c->read->timer_set) {
  433.         ngx_del_timer(c->read);
  434.     }

  435.     ngx_stream_core_run_phases(s);
  436. }


  437. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  438. static int
  439. ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
  440. {
  441.     ngx_int_t                    rc;
  442.     ngx_str_t                    host;
  443.     const char                  *servername;
  444.     ngx_connection_t            *c;
  445.     ngx_stream_session_t        *s;
  446.     ngx_stream_ssl_srv_conf_t   *sscf;
  447.     ngx_stream_core_srv_conf_t  *cscf;

  448.     c = ngx_ssl_get_connection(ssl_conn);

  449.     if (c->ssl->handshaked) {
  450.         *ad = SSL_AD_NO_RENEGOTIATION;
  451.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  452.     }

  453.     if (c->ssl->sni_accepted) {
  454.         return SSL_TLSEXT_ERR_OK;
  455.     }

  456.     if (c->ssl->handshake_rejected) {
  457.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  458.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  459.     }

  460.     s = c->data;

  461.     if (arg) {
  462.         host = *(ngx_str_t *) arg;

  463.         if (host.data == NULL) {
  464.             ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  465.                            "SSL server name: null");
  466.             goto done;
  467.         }

  468.     } else {
  469.         servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);

  470.         if (servername == NULL) {
  471.             ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
  472.                            "SSL server name: null");
  473.             goto done;
  474.         }

  475.         host.len = ngx_strlen(servername);
  476.         host.data = (u_char *) servername;
  477.     }

  478.     ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
  479.                    "SSL server name: \"%V\"", &host);

  480.     if (host.len == 0) {
  481.         goto done;
  482.     }

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

  484.     if (rc == NGX_ERROR) {
  485.         goto error;
  486.     }

  487.     if (rc == NGX_DECLINED) {
  488.         goto done;
  489.     }

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

  491.     if (rc == NGX_ERROR) {
  492.         goto error;
  493.     }

  494.     if (rc == NGX_DECLINED) {
  495.         goto done;
  496.     }

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

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

  499.     sscf = ngx_stream_get_module_srv_conf(cscf->ctx, ngx_stream_ssl_module);

  500.     if (sscf->ssl.ctx) {
  501.         if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
  502.             goto error;
  503.         }

  504.         /*
  505.          * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
  506.          * adjust other things we care about
  507.          */

  508.         SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
  509.                        SSL_CTX_get_verify_callback(sscf->ssl.ctx));

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

  511. #if OPENSSL_VERSION_NUMBER >= 0x009080dfL
  512.         /* only in 0.9.8m+ */
  513.         SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
  514.                                     ~SSL_CTX_get_options(sscf->ssl.ctx));
  515. #endif

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

  517. #ifdef SSL_OP_NO_RENEGOTIATION
  518.         SSL_set_options(ssl_conn, SSL_OP_NO_RENEGOTIATION);
  519. #endif
  520.     }

  521. done:

  522.     sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);

  523.     if (sscf->reject_handshake) {
  524.         c->ssl->handshake_rejected = 1;
  525.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  526.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  527.     }

  528.     c->ssl->sni_accepted = 1;
  529.     return SSL_TLSEXT_ERR_OK;

  530. error:

  531.     *ad = SSL_AD_INTERNAL_ERROR;
  532.     return SSL_TLSEXT_ERR_ALERT_FATAL;
  533. }

  534. #endif


  535. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  536. static int
  537. ngx_stream_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
  538.     unsigned char *outlen, const unsigned char *in, unsigned int inlen,
  539.     void *arg)
  540. {
  541.     ngx_str_t         *alpn;
  542. #if (NGX_DEBUG)
  543.     unsigned int       i;
  544.     ngx_connection_t  *c;

  545.     c = ngx_ssl_get_connection(ssl_conn);

  546.     for (i = 0; i < inlen; i += in[i] + 1) {
  547.         ngx_log_debug2(NGX_LOG_DEBUG_STREAM, c->log, 0,
  548.                        "SSL ALPN supported by client: %*s",
  549.                        (size_t) in[i], &in[i + 1]);
  550.     }

  551. #endif

  552.     alpn = arg;

  553.     if (SSL_select_next_proto((unsigned char **) out, outlen, alpn->data,
  554.                               alpn->len, in, inlen)
  555.         != OPENSSL_NPN_NEGOTIATED)
  556.     {
  557.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  558.     }

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

  561.     return SSL_TLSEXT_ERR_OK;
  562. }

  563. #endif


  564. #ifdef SSL_R_CERT_CB_ERROR

  565. static int
  566. ngx_stream_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
  567. {
  568.     ngx_str_t                    cert, key;
  569.     ngx_uint_t                   i, nelts;
  570.     ngx_connection_t            *c;
  571.     ngx_stream_session_t        *s;
  572.     ngx_stream_ssl_srv_conf_t   *sscf;
  573.     ngx_stream_complex_value_t  *certs, *keys;

  574.     c = ngx_ssl_get_connection(ssl_conn);

  575.     if (c->ssl->handshaked) {
  576.         return 0;
  577.     }

  578.     s = c->data;

  579.     sscf = arg;

  580.     nelts = sscf->certificate_values->nelts;
  581.     certs = sscf->certificate_values->elts;
  582.     keys = sscf->certificate_key_values->elts;

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

  584.         if (ngx_stream_complex_value(s, &certs[i], &cert) != NGX_OK) {
  585.             return 0;
  586.         }

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

  589.         if (ngx_stream_complex_value(s, &keys[i], &key) != NGX_OK) {
  590.             return 0;
  591.         }

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

  594.         if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
  595.                                            sscf->certificate_cache,
  596.                                            sscf->passwords)
  597.             != NGX_OK)
  598.         {
  599.             return 0;
  600.         }
  601.     }

  602.     return 1;
  603. }

  604. #endif


  605. static ngx_int_t
  606. ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
  607.     ngx_stream_variable_value_t *v, uintptr_t data)
  608. {
  609.     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;

  610.     size_t     len;
  611.     ngx_str_t  str;

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

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

  614.         v->data = str.data;

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

  616.         v->len = len;
  617.         v->valid = 1;
  618.         v->no_cacheable = 0;
  619.         v->not_found = 0;

  620.         return NGX_OK;
  621.     }

  622.     v->not_found = 1;

  623.     return NGX_OK;
  624. }


  625. static ngx_int_t
  626. ngx_stream_ssl_variable(ngx_stream_session_t *s,
  627.     ngx_stream_variable_value_t *v, uintptr_t data)
  628. {
  629.     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;

  630.     ngx_str_t  str;

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

  632.         if (handler(s->connection, s->connection->pool, &str) != NGX_OK) {
  633.             return NGX_ERROR;
  634.         }

  635.         v->len = str.len;
  636.         v->data = str.data;

  637.         if (v->len) {
  638.             v->valid = 1;
  639.             v->no_cacheable = 0;
  640.             v->not_found = 0;

  641.             return NGX_OK;
  642.         }
  643.     }

  644.     v->not_found = 1;

  645.     return NGX_OK;
  646. }


  647. static ngx_int_t
  648. ngx_stream_ssl_add_variables(ngx_conf_t *cf)
  649. {
  650.     ngx_stream_variable_t  *var, *v;

  651.     for (v = ngx_stream_ssl_vars; v->name.len; v++) {
  652.         var = ngx_stream_add_variable(cf, &v->name, v->flags);
  653.         if (var == NULL) {
  654.             return NGX_ERROR;
  655.         }

  656.         var->get_handler = v->get_handler;
  657.         var->data = v->data;
  658.     }

  659.     return NGX_OK;
  660. }


  661. static void *
  662. ngx_stream_ssl_create_srv_conf(ngx_conf_t *cf)
  663. {
  664.     ngx_stream_ssl_srv_conf_t  *sscf;

  665.     sscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_srv_conf_t));
  666.     if (sscf == NULL) {
  667.         return NULL;
  668.     }

  669.     /*
  670.      * set by ngx_pcalloc():
  671.      *
  672.      *     sscf->protocols = 0;
  673.      *     sscf->certificate_values = NULL;
  674.      *     sscf->dhparam = { 0, NULL };
  675.      *     sscf->ecdh_curve = { 0, NULL };
  676.      *     sscf->client_certificate = { 0, NULL };
  677.      *     sscf->trusted_certificate = { 0, NULL };
  678.      *     sscf->crl = { 0, NULL };
  679.      *     sscf->alpn = { 0, NULL };
  680.      *     sscf->ciphers = { 0, NULL };
  681.      *     sscf->shm_zone = NULL;
  682.      *     sscf->ocsp_responder = { 0, NULL };
  683.      *     sscf->stapling_file = { 0, NULL };
  684.      *     sscf->stapling_responder = { 0, NULL };
  685.      */

  686.     sscf->handshake_timeout = NGX_CONF_UNSET_MSEC;
  687.     sscf->certificates = NGX_CONF_UNSET_PTR;
  688.     sscf->certificate_keys = NGX_CONF_UNSET_PTR;
  689.     sscf->certificate_cache = NGX_CONF_UNSET_PTR;
  690.     sscf->ech_files = NGX_CONF_UNSET_PTR;
  691.     sscf->passwords = NGX_CONF_UNSET_PTR;
  692.     sscf->conf_commands = NGX_CONF_UNSET_PTR;
  693.     sscf->prefer_server_ciphers = NGX_CONF_UNSET;
  694.     sscf->certificate_compression = NGX_CONF_UNSET;
  695.     sscf->reject_handshake = NGX_CONF_UNSET;
  696.     sscf->verify = NGX_CONF_UNSET_UINT;
  697.     sscf->verify_depth = NGX_CONF_UNSET_UINT;
  698.     sscf->builtin_session_cache = NGX_CONF_UNSET;
  699.     sscf->session_timeout = NGX_CONF_UNSET;
  700.     sscf->session_tickets = NGX_CONF_UNSET;
  701.     sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
  702.     sscf->ocsp = NGX_CONF_UNSET_UINT;
  703.     sscf->ocsp_cache_zone = NGX_CONF_UNSET_PTR;
  704.     sscf->stapling = NGX_CONF_UNSET;
  705.     sscf->stapling_verify = NGX_CONF_UNSET;

  706.     return sscf;
  707. }


  708. static char *
  709. ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  710. {
  711.     ngx_stream_ssl_srv_conf_t *prev = parent;
  712.     ngx_stream_ssl_srv_conf_t *conf = child;

  713.     ngx_pool_cleanup_t  *cln;

  714.     ngx_conf_merge_msec_value(conf->handshake_timeout,
  715.                          prev->handshake_timeout, 60000);

  716.     ngx_conf_merge_value(conf->session_timeout,
  717.                          prev->session_timeout, 300);

  718.     ngx_conf_merge_value(conf->prefer_server_ciphers,
  719.                          prev->prefer_server_ciphers, 0);

  720.     ngx_conf_merge_value(conf->certificate_compression,
  721.                          prev->certificate_compression, 0);

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

  723.     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
  724.                          (NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));

  725.     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
  726.     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);

  727.     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
  728.     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
  729.                          NULL);

  730.     ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
  731.                          NULL);

  732.     ngx_conf_merge_ptr_value(conf->ech_files, prev->ech_files, NULL);

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

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

  735.     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
  736.                          "");
  737.     ngx_conf_merge_str_value(conf->trusted_certificate,
  738.                          prev->trusted_certificate, "");
  739.     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
  740.     ngx_conf_merge_str_value(conf->alpn, prev->alpn, "");

  741.     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
  742.                          NGX_DEFAULT_ECDH_CURVE);

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

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

  745.     ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0);
  746.     ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, "");
  747.     ngx_conf_merge_ptr_value(conf->ocsp_cache_zone,
  748.                          prev->ocsp_cache_zone, NULL);

  749.     ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
  750.     ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
  751.     ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
  752.     ngx_conf_merge_str_value(conf->stapling_responder,
  753.                          prev->stapling_responder, "");

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

  755.     if (conf->certificates) {

  756.         if (conf->certificate_keys == NULL
  757.             || conf->certificate_keys->nelts < conf->certificates->nelts)
  758.         {
  759.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  760.                           "no \"ssl_certificate_key\" is defined "
  761.                           "for certificate \"%V\"",
  762.                           ((ngx_str_t *) conf->certificates->elts)
  763.                           + conf->certificates->nelts - 1);
  764.             return NGX_CONF_ERROR;
  765.         }

  766.     } else if (!conf->reject_handshake) {
  767.         return NGX_CONF_OK;
  768.     }

  769.     if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) {
  770.         return NGX_CONF_ERROR;
  771.     }

  772.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  773.     if (cln == NULL) {
  774.         ngx_ssl_cleanup_ctx(&conf->ssl);
  775.         return NGX_CONF_ERROR;
  776.     }

  777.     cln->handler = ngx_ssl_cleanup_ctx;
  778.     cln->data = &conf->ssl;

  779. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  780.     {
  781.     static ngx_ssl_client_hello_arg cb = { ngx_stream_ssl_servername };

  782.     if (ngx_ssl_set_client_hello_callback(&conf->ssl, &cb) != NGX_OK) {
  783.         return NGX_CONF_ERROR;
  784.     }

  785.     SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
  786.                                            ngx_stream_ssl_servername);
  787.     }
  788. #endif

  789. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  790.     if (conf->alpn.len) {
  791.         SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_stream_ssl_alpn_select,
  792.                                    &conf->alpn);
  793.     }
  794. #endif

  795.     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
  796.                         conf->prefer_server_ciphers)
  797.         != NGX_OK)
  798.     {
  799.         return NGX_CONF_ERROR;
  800.     }

  801.     if (ngx_stream_ssl_compile_certificates(cf, conf) != NGX_OK) {
  802.         return NGX_CONF_ERROR;
  803.     }

  804.     if (conf->certificate_values) {

  805. #ifdef SSL_R_CERT_CB_ERROR

  806.         /* install callback to lookup certificates */

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

  808. #else
  809.         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  810.                       "variables in "
  811.                       "\"ssl_certificate\" and \"ssl_certificate_key\" "
  812.                       "directives are not supported on this platform");
  813.         return NGX_CONF_ERROR;
  814. #endif

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

  816.         /* configure certificates */

  817.         if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
  818.                                  conf->certificate_keys, conf->passwords)
  819.             != NGX_OK)
  820.         {
  821.             return NGX_CONF_ERROR;
  822.         }

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

  830.     if (conf->verify) {

  831.         if (conf->verify != 3
  832.             && conf->client_certificate.len == 0
  833.             && conf->trusted_certificate.len == 0)
  834.         {
  835.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  836.                           "no ssl_client_certificate or "
  837.                           "ssl_trusted_certificate for ssl_verify_client");
  838.             return NGX_CONF_ERROR;
  839.         }

  840.         if (ngx_ssl_client_certificate(cf, &conf->ssl,
  841.                                        &conf->client_certificate,
  842.                                        conf->verify_depth)
  843.             != NGX_OK)
  844.         {
  845.             return NGX_CONF_ERROR;
  846.         }
  847.     }

  848.     if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
  849.                                     &conf->trusted_certificate,
  850.                                     conf->verify_depth)
  851.         != NGX_OK)
  852.     {
  853.         return NGX_CONF_ERROR;
  854.     }

  855.     if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
  856.         return NGX_CONF_ERROR;
  857.     }

  858.     if (conf->ocsp) {

  859.         if (conf->verify == 3) {
  860.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  861.                           "\"ssl_ocsp\" is incompatible with "
  862.                           "\"ssl_verify_client optional_no_ca\"");
  863.             return NGX_CONF_ERROR;
  864.         }

  865.         if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
  866.                          conf->ocsp_cache_zone)
  867.             != NGX_OK)
  868.         {
  869.             return NGX_CONF_ERROR;
  870.         }
  871.     }

  872.     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
  873.         return NGX_CONF_ERROR;
  874.     }

  875.     if (ngx_ssl_ech_files(cf, &conf->ssl, conf->ech_files) != NGX_OK) {
  876.         return NGX_CONF_ERROR;
  877.     }

  878.     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
  879.         return NGX_CONF_ERROR;
  880.     }

  881.     ngx_conf_merge_value(conf->builtin_session_cache,
  882.                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);

  883.     if (conf->shm_zone == NULL) {
  884.         conf->shm_zone = prev->shm_zone;
  885.     }

  886.     if (ngx_ssl_session_cache(&conf->ssl, &ngx_stream_ssl_sess_id_ctx,
  887.                               conf->certificates, conf->builtin_session_cache,
  888.                               conf->shm_zone, conf->session_timeout)
  889.         != NGX_OK)
  890.     {
  891.         return NGX_CONF_ERROR;
  892.     }

  893.     ngx_conf_merge_value(conf->session_tickets,
  894.                          prev->session_tickets, 1);

  895. #ifdef SSL_OP_NO_TICKET
  896.     if (!conf->session_tickets) {
  897.         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
  898.     }
  899. #endif

  900.     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
  901.                          prev->session_ticket_keys, NULL);

  902.     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
  903.         != NGX_OK)
  904.     {
  905.         return NGX_CONF_ERROR;
  906.     }

  907.     if (conf->stapling) {

  908.         if (conf->certificate_compression) {
  909.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  910.                           "\"ssl_stapling\" is incompatible with "
  911.                           "\"ssl_certificate_compression\"");
  912.             return NGX_CONF_ERROR;
  913.         }

  914.         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
  915.                              &conf->stapling_responder, conf->stapling_verify)
  916.             != NGX_OK)
  917.         {
  918.             return NGX_CONF_ERROR;
  919.         }
  920.     }

  921.     if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) {
  922.         return NGX_CONF_ERROR;
  923.     }

  924.     return NGX_CONF_OK;
  925. }


  926. static ngx_int_t
  927. ngx_stream_ssl_compile_certificates(ngx_conf_t *cf,
  928.     ngx_stream_ssl_srv_conf_t *conf)
  929. {
  930.     ngx_str_t                           *cert, *key;
  931.     ngx_uint_t                           i, nelts;
  932.     ngx_stream_complex_value_t          *cv;
  933.     ngx_stream_compile_complex_value_t   ccv;

  934.     if (conf->certificates == NULL) {
  935.         return NGX_OK;
  936.     }

  937.     cert = conf->certificates->elts;
  938.     key = conf->certificate_keys->elts;
  939.     nelts = conf->certificates->nelts;

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

  941.         if (ngx_stream_script_variables_count(&cert[i])) {
  942.             goto found;
  943.         }

  944.         if (ngx_stream_script_variables_count(&key[i])) {
  945.             goto found;
  946.         }
  947.     }

  948.     return NGX_OK;

  949. found:

  950.     conf->certificate_values = ngx_array_create(cf->pool, nelts,
  951.                                            sizeof(ngx_stream_complex_value_t));
  952.     if (conf->certificate_values == NULL) {
  953.         return NGX_ERROR;
  954.     }

  955.     conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
  956.                                            sizeof(ngx_stream_complex_value_t));
  957.     if (conf->certificate_key_values == NULL) {
  958.         return NGX_ERROR;
  959.     }

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

  961.         cv = ngx_array_push(conf->certificate_values);
  962.         if (cv == NULL) {
  963.             return NGX_ERROR;
  964.         }

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

  966.         ccv.cf = cf;
  967.         ccv.value = &cert[i];
  968.         ccv.complex_value = cv;
  969.         ccv.zero = 1;

  970.         if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  971.             return NGX_ERROR;
  972.         }

  973.         cv = ngx_array_push(conf->certificate_key_values);
  974.         if (cv == NULL) {
  975.             return NGX_ERROR;
  976.         }

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

  978.         ccv.cf = cf;
  979.         ccv.value = &key[i];
  980.         ccv.complex_value = cv;
  981.         ccv.zero = 1;

  982.         if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
  983.             return NGX_ERROR;
  984.         }
  985.     }

  986.     conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
  987.     if (conf->passwords == NULL) {
  988.         return NGX_ERROR;
  989.     }

  990.     return NGX_OK;
  991. }


  992. static char *
  993. ngx_stream_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  994. {
  995.     ngx_stream_ssl_srv_conf_t *sscf = conf;

  996.     time_t       inactive, valid;
  997.     ngx_str_t   *value, s;
  998.     ngx_int_t    max;
  999.     ngx_uint_t   i;

  1000.     if (sscf->certificate_cache != NGX_CONF_UNSET_PTR) {
  1001.         return "is duplicate";
  1002.     }

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

  1004.     max = 0;
  1005.     inactive = 10;
  1006.     valid = 60;

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

  1008.         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {

  1009.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  1010.             if (max <= 0) {
  1011.                 goto failed;
  1012.             }

  1013.             continue;
  1014.         }

  1015.         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {

  1016.             s.len = value[i].len - 9;
  1017.             s.data = value[i].data + 9;

  1018.             inactive = ngx_parse_time(&s, 1);
  1019.             if (inactive == (time_t) NGX_ERROR) {
  1020.                 goto failed;
  1021.             }

  1022.             continue;
  1023.         }

  1024.         if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {

  1025.             s.len = value[i].len - 6;
  1026.             s.data = value[i].data + 6;

  1027.             valid = ngx_parse_time(&s, 1);
  1028.             if (valid == (time_t) NGX_ERROR) {
  1029.                 goto failed;
  1030.             }

  1031.             continue;
  1032.         }

  1033.         if (ngx_strcmp(value[i].data, "off") == 0) {

  1034.             sscf->certificate_cache = NULL;

  1035.             continue;
  1036.         }

  1037.     failed:

  1038.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1039.                            "invalid parameter \"%V\"", &value[i]);
  1040.         return NGX_CONF_ERROR;
  1041.     }

  1042.     if (sscf->certificate_cache == NULL) {
  1043.         return NGX_CONF_OK;
  1044.     }

  1045.     if (max == 0) {
  1046.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1047.                            "\"ssl_certificate_cache\" must have "
  1048.                            "the \"max\" parameter");
  1049.         return NGX_CONF_ERROR;
  1050.     }

  1051.     sscf->certificate_cache = ngx_ssl_cache_init(cf->pool, max, valid,
  1052.                                                  inactive);
  1053.     if (sscf->certificate_cache == NULL) {
  1054.         return NGX_CONF_ERROR;
  1055.     }

  1056.     return NGX_CONF_OK;
  1057. }


  1058. static char *
  1059. ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1060. {
  1061.     ngx_stream_ssl_srv_conf_t  *sscf = conf;

  1062.     ngx_str_t  *value;

  1063.     if (sscf->passwords != NGX_CONF_UNSET_PTR) {
  1064.         return "is duplicate";
  1065.     }

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

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

  1068.     if (sscf->passwords == NULL) {
  1069.         return NGX_CONF_ERROR;
  1070.     }

  1071.     return NGX_CONF_OK;
  1072. }


  1073. static char *
  1074. ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1075. {
  1076.     ngx_stream_ssl_srv_conf_t  *sscf = conf;

  1077.     size_t       len;
  1078.     ngx_str_t   *value, name, size;
  1079.     ngx_int_t    n;
  1080.     ngx_uint_t   i, j;

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

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

  1083.         if (ngx_strcmp(value[i].data, "off") == 0) {
  1084.             sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
  1085.             continue;
  1086.         }

  1087.         if (ngx_strcmp(value[i].data, "none") == 0) {
  1088.             sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
  1089.             continue;
  1090.         }

  1091.         if (ngx_strcmp(value[i].data, "builtin") == 0) {
  1092.             sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
  1093.             continue;
  1094.         }

  1095.         if (value[i].len > sizeof("builtin:") - 1
  1096.             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
  1097.                == 0)
  1098.         {
  1099.             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
  1100.                          value[i].len - (sizeof("builtin:") - 1));

  1101.             if (n == NGX_ERROR) {
  1102.                 goto invalid;
  1103.             }

  1104.             sscf->builtin_session_cache = n;

  1105.             continue;
  1106.         }

  1107.         if (value[i].len > sizeof("shared:") - 1
  1108.             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
  1109.                == 0)
  1110.         {
  1111.             len = 0;

  1112.             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
  1113.                 if (value[i].data[j] == ':') {
  1114.                     break;
  1115.                 }

  1116.                 len++;
  1117.             }

  1118.             if (len == 0 || j == value[i].len) {
  1119.                 goto invalid;
  1120.             }

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

  1123.             size.len = value[i].len - j - 1;
  1124.             size.data = name.data + len + 1;

  1125.             n = ngx_parse_size(&size);

  1126.             if (n == NGX_ERROR) {
  1127.                 goto invalid;
  1128.             }

  1129.             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
  1130.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1131.                                    "session cache \"%V\" is too small",
  1132.                                    &value[i]);

  1133.                 return NGX_CONF_ERROR;
  1134.             }

  1135.             sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
  1136.                                                    &ngx_stream_ssl_module);
  1137.             if (sscf->shm_zone == NULL) {
  1138.                 return NGX_CONF_ERROR;
  1139.             }

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

  1141.             continue;
  1142.         }

  1143.         goto invalid;
  1144.     }

  1145.     if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
  1146.         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
  1147.     }

  1148.     return NGX_CONF_OK;

  1149. invalid:

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

  1152.     return NGX_CONF_ERROR;
  1153. }


  1154. static char *
  1155. ngx_stream_ssl_ocsp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1156. {
  1157.     ngx_stream_ssl_srv_conf_t *sscf = conf;

  1158.     size_t       len;
  1159.     ngx_int_t    n;
  1160.     ngx_str_t   *value, name, size;
  1161.     ngx_uint_t   j;

  1162.     if (sscf->ocsp_cache_zone != NGX_CONF_UNSET_PTR) {
  1163.         return "is duplicate";
  1164.     }

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

  1166.     if (ngx_strcmp(value[1].data, "off") == 0) {
  1167.         sscf->ocsp_cache_zone = NULL;
  1168.         return NGX_CONF_OK;
  1169.     }

  1170.     if (value[1].len <= sizeof("shared:") - 1
  1171.         || ngx_strncmp(value[1].data, "shared:", sizeof("shared:") - 1) != 0)
  1172.     {
  1173.         goto invalid;
  1174.     }

  1175.     len = 0;

  1176.     for (j = sizeof("shared:") - 1; j < value[1].len; j++) {
  1177.         if (value[1].data[j] == ':') {
  1178.             break;
  1179.         }

  1180.         len++;
  1181.     }

  1182.     if (len == 0 || j == value[1].len) {
  1183.         goto invalid;
  1184.     }

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

  1187.     size.len = value[1].len - j - 1;
  1188.     size.data = name.data + len + 1;

  1189.     n = ngx_parse_size(&size);

  1190.     if (n == NGX_ERROR) {
  1191.         goto invalid;
  1192.     }

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

  1196.         return NGX_CONF_ERROR;
  1197.     }

  1198.     sscf->ocsp_cache_zone = ngx_shared_memory_add(cf, &name, n,
  1199.                                                   &ngx_stream_ssl_module_ctx);
  1200.     if (sscf->ocsp_cache_zone == NULL) {
  1201.         return NGX_CONF_ERROR;
  1202.     }

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

  1204.     return NGX_CONF_OK;

  1205. invalid:

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

  1208.     return NGX_CONF_ERROR;
  1209. }


  1210. static char *
  1211. ngx_stream_ssl_alpn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1212. {
  1213. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  1214.     ngx_stream_ssl_srv_conf_t  *sscf = conf;

  1215.     u_char      *p;
  1216.     size_t       len;
  1217.     ngx_str_t   *value;
  1218.     ngx_uint_t   i;

  1219.     if (sscf->alpn.len) {
  1220.         return "is duplicate";
  1221.     }

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

  1223.     len = 0;

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

  1225.         if (value[i].len > 255) {
  1226.             return "protocol too long";
  1227.         }

  1228.         len += value[i].len + 1;
  1229.     }

  1230.     sscf->alpn.data = ngx_pnalloc(cf->pool, len);
  1231.     if (sscf->alpn.data == NULL) {
  1232.         return NGX_CONF_ERROR;
  1233.     }

  1234.     p = sscf->alpn.data;

  1235.     for (i = 1; i < cf->args->nelts; i++) {
  1236.         *p++ = value[i].len;
  1237.         p = ngx_cpymem(p, value[i].data, value[i].len);
  1238.     }

  1239.     sscf->alpn.len = len;

  1240.     return NGX_CONF_OK;

  1241. #else
  1242.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1243.                        "the \"ssl_alpn\" directive requires OpenSSL "
  1244.                        "with ALPN support");
  1245.     return NGX_CONF_ERROR;
  1246. #endif
  1247. }


  1248. static char *
  1249. ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
  1250. {
  1251. #ifndef SSL_CONF_FLAG_FILE
  1252.     return "is not supported on this platform";
  1253. #else
  1254.     return NGX_CONF_OK;
  1255. #endif
  1256. }


  1257. static ngx_int_t
  1258. ngx_stream_ssl_init(ngx_conf_t *cf)
  1259. {
  1260.     ngx_uint_t                     a, p, s;
  1261.     ngx_stream_handler_pt         *h;
  1262.     ngx_stream_conf_addr_t        *addr;
  1263.     ngx_stream_conf_port_t        *port;
  1264.     ngx_stream_ssl_srv_conf_t     *sscf;
  1265.     ngx_stream_core_srv_conf_t   **cscfp, *cscf;
  1266.     ngx_stream_core_main_conf_t   *cmcf;

  1267.     cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
  1268.     cscfp = cmcf->servers.elts;

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

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

  1271.         if (sscf->ssl.ctx == NULL) {
  1272.             continue;
  1273.         }

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

  1275.         if (sscf->stapling) {
  1276.             if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, cscf->resolver,
  1277.                                           cscf->resolver_timeout)
  1278.                 != NGX_OK)
  1279.             {
  1280.                 return NGX_ERROR;
  1281.             }
  1282.         }

  1283.         if (sscf->ocsp) {
  1284.             if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl, cscf->resolver,
  1285.                                       cscf->resolver_timeout)
  1286.                 != NGX_OK)
  1287.             {
  1288.                 return NGX_ERROR;
  1289.             }
  1290.         }
  1291.     }

  1292.     h = ngx_array_push(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers);
  1293.     if (h == NULL) {
  1294.         return NGX_ERROR;
  1295.     }

  1296.     *h = ngx_stream_ssl_handler;

  1297.     if (cmcf->ports == NULL) {
  1298.         return NGX_OK;
  1299.     }

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

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

  1304.             if (!addr[a].opt.ssl) {
  1305.                 continue;
  1306.             }

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

  1309.             if (sscf->certificates) {
  1310.                 continue;
  1311.             }

  1312.             if (!sscf->reject_handshake) {
  1313.                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1314.                               "no \"ssl_certificate\" is defined for "
  1315.                               "the \"listen ... ssl\" directive in %s:%ui",
  1316.                               cscf->file_name, cscf->line);
  1317.                 return NGX_ERROR;
  1318.             }

  1319.             /*
  1320.              * if no certificates are defined in the default server,
  1321.              * check all non-default server blocks
  1322.              */

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

  1325.                 cscf = cscfp[s];
  1326.                 sscf = cscf->ctx->srv_conf[ngx_stream_ssl_module.ctx_index];

  1327.                 if (sscf->certificates || sscf->reject_handshake) {
  1328.                     continue;
  1329.                 }

  1330.                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1331.                               "no \"ssl_certificate\" is defined for "
  1332.                               "the \"listen ... ssl\" directive in %s:%ui",
  1333.                               cscf->file_name, cscf->line);
  1334.                 return NGX_ERROR;
  1335.             }
  1336.         }
  1337.     }

  1338.     return NGX_OK;
  1339. }