src/event/ngx_event_openssl.c - nginx-1.31.9 nginx/ @ 2a3a19c6f

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_event.h>

  8. #if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
  9. #include <zlib.h>
  10. #endif


  11. ‌#define NGX_SSL_PASSWORD_BUFFER_SIZE  4096


  12. ‌typedef struct {
  13.     ngx_uint_t  engine;   /* unsigned  engine:1; */
  14. ‌} ngx_openssl_conf_t;


  15. static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void);
  16. #if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)
  17. static int ngx_ssl_cert_compression_callback(ngx_ssl_conn_t *ssl_conn,
  18.     CBB *out, const uint8_t *in, size_t in_len);
  19. static void *ngx_ssl_cert_compression_alloc(void *opaque, u_int items,
  20.     u_int size);
  21. static void ngx_ssl_cert_compression_free(void *opaque, void *address);
  22. #endif
  23. static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
  24. static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
  25.     int ret);
  26. static int ngx_ssl_cmp_x509_name(const X509_NAME *const *a,
  27.     const X509_NAME *const *b);
  28. static void ngx_ssl_passwords_cleanup(void *data);
  29. static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn,
  30.     ngx_ssl_session_t *sess);
  31. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  32. static ngx_int_t ngx_ssl_try_early_data(ngx_connection_t *c);
  33. #endif
  34. static void ngx_ssl_handshake_handler(ngx_event_t *ev);
  35. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  36. static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
  37.     size_t size);
  38. #endif
  39. static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
  40. static void ngx_ssl_write_handler(ngx_event_t *wev);
  41. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  42. static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
  43.     size_t size);
  44. #endif
  45. static ssize_t ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file,
  46.     size_t size);
  47. static void ngx_ssl_read_handler(ngx_event_t *rev);
  48. static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
  49. static void ngx_ssl_clear_error(ngx_log_t *log);

  50. static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl,
  51.     ngx_str_t *sess_ctx, ngx_array_t *certificates);
  52. static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
  53.     ngx_ssl_session_t *sess);
  54. static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
  55. #if OPENSSL_VERSION_NUMBER >= 0x10100003L
  56.     const
  57. #endif
  58.     u_char *id, int len, int *copy);
  59. static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
  60. static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
  61.     ngx_slab_pool_t *shpool, ngx_uint_t n);
  62. static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
  63.     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

  64. #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
  65. static int ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
  66.     unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
  67.     HMAC_CTX *hctx, int enc);
  68. static ngx_int_t ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log);
  69. static void ngx_ssl_ticket_keys_cleanup(void *data);
  70. #endif

  71. #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT
  72. static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str);
  73. #endif

  74. static time_t ngx_ssl_parse_time(
  75. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  76.     const
  77. #endif
  78.     ASN1_TIME *asn1time, ngx_log_t *log);

  79. static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
  80. static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  81. static void ngx_openssl_exit(ngx_cycle_t *cycle);


  82. ‌static ngx_command_t  ngx_openssl_commands[] = {

  83.     { ngx_string("ssl_engine"),
  84.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
  85.       ngx_openssl_engine,
  86.       0,
  87.       0,
  88.       NULL },

  89.       ngx_null_command
  90. };


  91. ‌static ngx_core_module_t  ngx_openssl_module_ctx = {
  92.     ngx_string("openssl"),
  93.     ngx_openssl_create_conf,
  94.     NULL
  95. };


  96. ‌ngx_module_t  ngx_openssl_module = {
  97.     NGX_MODULE_V1,
  98.     &ngx_openssl_module_ctx,               /* module context */
  99.     ngx_openssl_commands,                  /* module directives */
  100.     NGX_CORE_MODULE,                       /* module type */
  101.     NULL,                                  /* init master */
  102.     NULL,                                  /* init module */
  103.     NULL,                                  /* init process */
  104.     NULL,                                  /* init thread */
  105.     NULL,                                  /* exit thread */
  106.     NULL,                                  /* exit process */
  107.     ngx_openssl_exit,                      /* exit master */
  108.     NGX_MODULE_V1_PADDING
  109. };


  110. ‌int  ngx_ssl_connection_index;
  111. ‌int  ngx_ssl_server_conf_index;
  112. ‌int  ngx_ssl_session_cache_index;
  113. ‌int  ngx_ssl_ticket_keys_index;
  114. ‌int  ngx_ssl_ocsp_index;
  115. ‌int  ngx_ssl_index;
  116. ‌int  ngx_ssl_certificate_name_index;
  117. ‌int  ngx_ssl_certificate_comp_index;
  118. ‌int  ngx_ssl_client_hello_arg_index;


  119. ‌u_char  ngx_ssl_session_buffer[NGX_SSL_MAX_SESSION_SIZE];


  120. ngx_int_t
  121. ‌ngx_ssl_init(ngx_log_t *log)
  122. {
  123. #if (OPENSSL_INIT_LOAD_CONFIG && !defined LIBRESSL_VERSION_NUMBER)

  124.     uint64_t                opts;
  125.     OPENSSL_INIT_SETTINGS  *init;

  126.     opts = OPENSSL_INIT_LOAD_CONFIG;

  127. #if (NGX_OPENSSL_NO_CONFIG)

  128.     if (getenv("OPENSSL_CONF") == NULL) {
  129.         opts = OPENSSL_INIT_NO_LOAD_CONFIG;
  130.     }

  131. #endif

  132.     init = OPENSSL_INIT_new();
  133.     if (init == NULL) {
  134.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_INIT_new() failed");
  135.         return NGX_ERROR;
  136.     }

  137. #ifndef OPENSSL_NO_STDIO
  138.     if (OPENSSL_INIT_set_config_appname(init, "nginx") == 0) {
  139.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  140.                       "OPENSSL_INIT_set_config_appname() failed");
  141.         return NGX_ERROR;
  142.     }
  143. #endif

  144.     if (OPENSSL_init_ssl(opts, init) == 0) {
  145.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_init_ssl() failed");
  146.         return NGX_ERROR;
  147.     }

  148.     OPENSSL_INIT_free(init);

  149.     /*
  150.      * OPENSSL_init_ssl() may leave errors in the error queue
  151.      * while returning success
  152.      */

  153.     ERR_clear_error();

  154. #else

  155. #if (NGX_OPENSSL_NO_CONFIG)

  156.     if (getenv("OPENSSL_CONF") == NULL) {
  157.         OPENSSL_no_config();
  158.     }

  159. #endif

  160.     OPENSSL_config("nginx");

  161.     SSL_library_init();
  162.     SSL_load_error_strings();

  163.     OpenSSL_add_all_algorithms();

  164. #endif

  165. #ifndef SSL_OP_NO_COMPRESSION
  166.     {
  167.     /*
  168.      * Disable gzip compression in OpenSSL prior to 1.0.0 version,
  169.      * this saves about 522K per connection.
  170.      */
  171.     int                  n;
  172.     STACK_OF(SSL_COMP)  *ssl_comp_methods;

  173.     ssl_comp_methods = SSL_COMP_get_compression_methods();
  174.     n = sk_SSL_COMP_num(ssl_comp_methods);

  175.     while (n--) {
  176.         (void) sk_SSL_COMP_pop(ssl_comp_methods);
  177.     }
  178.     }
  179. #endif

  180.     ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);

  181.     if (ngx_ssl_connection_index == -1) {
  182.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed");
  183.         return NGX_ERROR;
  184.     }

  185.     ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
  186.                                                          NULL);
  187.     if (ngx_ssl_server_conf_index == -1) {
  188.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  189.                       "SSL_CTX_get_ex_new_index() failed");
  190.         return NGX_ERROR;
  191.     }

  192.     ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
  193.                                                            NULL);
  194.     if (ngx_ssl_session_cache_index == -1) {
  195.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  196.                       "SSL_CTX_get_ex_new_index() failed");
  197.         return NGX_ERROR;
  198.     }

  199.     ngx_ssl_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
  200.                                                          NULL);
  201.     if (ngx_ssl_ticket_keys_index == -1) {
  202.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  203.                       "SSL_CTX_get_ex_new_index() failed");
  204.         return NGX_ERROR;
  205.     }

  206.     ngx_ssl_ocsp_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
  207.     if (ngx_ssl_ocsp_index == -1) {
  208.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  209.                       "SSL_CTX_get_ex_new_index() failed");
  210.         return NGX_ERROR;
  211.     }

  212.     ngx_ssl_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);

  213.     if (ngx_ssl_index == -1) {
  214.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  215.                       "SSL_CTX_get_ex_new_index() failed");
  216.         return NGX_ERROR;
  217.     }

  218.     ngx_ssl_certificate_name_index = X509_get_ex_new_index(0, NULL, NULL, NULL,
  219.                                                            NULL);

  220.     if (ngx_ssl_certificate_name_index == -1) {
  221.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed");
  222.         return NGX_ERROR;
  223.     }

  224.     ngx_ssl_certificate_comp_index = X509_get_ex_new_index(0, NULL, NULL, NULL,
  225.                                                            NULL);
  226.     if (ngx_ssl_certificate_comp_index == -1) {
  227.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed");
  228.         return NGX_ERROR;
  229.     }

  230.     ngx_ssl_client_hello_arg_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
  231.                                                               NULL, NULL);
  232.     if (ngx_ssl_client_hello_arg_index == -1) {
  233.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  234.                       "SSL_CTX_get_ex_new_index() failed");
  235.         return NGX_ERROR;
  236.     }

  237.     return NGX_OK;
  238. }


  239. ngx_int_t
  240. ‌ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
  241. {
  242.     ssl->ctx = SSL_CTX_new(SSLv23_method());

  243.     if (ssl->ctx == NULL) {
  244.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed");
  245.         return NGX_ERROR;
  246.     }

  247.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) {
  248.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  249.                       "SSL_CTX_set_ex_data() failed");
  250.         return NGX_ERROR;
  251.     }

  252.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_index, ssl) == 0) {
  253.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  254.                       "SSL_CTX_set_ex_data() failed");
  255.         return NGX_ERROR;
  256.     }

  257.     ngx_rbtree_init(&ssl->staple_rbtree, &ssl->staple_sentinel,
  258.                     ngx_rbtree_insert_value);

  259.     ssl->buffer_size = NGX_SSL_BUFSIZE;

  260.     /* client side options */

  261. #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
  262.     SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
  263. #endif

  264. #ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
  265.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
  266. #endif

  267.     /* server side options */

  268. #ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
  269.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
  270. #endif

  271. #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
  272.     SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
  273. #endif

  274. #ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
  275.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
  276. #endif

  277. #ifdef SSL_OP_TLS_D5_BUG
  278.     SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
  279. #endif

  280. #ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
  281.     SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
  282. #endif

  283. #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
  284.     SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
  285. #endif

  286.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);

  287. #if OPENSSL_VERSION_NUMBER >= 0x009080dfL
  288.     /* only in 0.9.8m+ */
  289.     SSL_CTX_clear_options(ssl->ctx,
  290.                           SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
  291. #endif

  292.     if (!(protocols & NGX_SSL_SSLv2)) {
  293.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2);
  294.     }
  295.     if (!(protocols & NGX_SSL_SSLv3)) {
  296.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv3);
  297.     }
  298.     if (!(protocols & NGX_SSL_TLSv1)) {
  299.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1);
  300.     }
  301. #ifdef SSL_OP_NO_TLSv1_1
  302.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_1);
  303.     if (!(protocols & NGX_SSL_TLSv1_1)) {
  304.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_1);
  305.     }
  306. #endif
  307. #ifdef SSL_OP_NO_TLSv1_2
  308.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
  309.     if (!(protocols & NGX_SSL_TLSv1_2)) {
  310.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
  311.     }
  312. #endif
  313. #ifdef SSL_OP_NO_TLSv1_3
  314.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_3);
  315.     if (!(protocols & NGX_SSL_TLSv1_3)) {
  316.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_3);
  317.     }
  318. #endif

  319. #ifdef SSL_CTX_set_min_proto_version
  320.     SSL_CTX_set_min_proto_version(ssl->ctx, 0);
  321.     SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_2_VERSION);
  322. #endif

  323. #ifdef TLS1_3_VERSION
  324.     SSL_CTX_set_min_proto_version(ssl->ctx, 0);
  325.     SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_3_VERSION);
  326. #endif

  327. #ifdef SSL_OP_NO_COMPRESSION
  328.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
  329. #endif

  330. #ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
  331.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
  332.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_RX_CERTIFICATE_COMPRESSION);
  333. #endif

  334. #ifdef SSL_OP_NO_ANTI_REPLAY
  335.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY);
  336. #endif

  337. #ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
  338.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
  339. #endif

  340. #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
  341.     SSL_CTX_set_options(ssl->ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
  342. #endif

  343. #ifdef SSL_MODE_RELEASE_BUFFERS
  344.     SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
  345. #endif

  346. #ifdef SSL_MODE_NO_AUTO_CHAIN
  347.     SSL_CTX_set_mode(ssl->ctx, SSL_MODE_NO_AUTO_CHAIN);
  348. #endif

  349.     SSL_CTX_set_read_ahead(ssl->ctx, 1);

  350.     SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);

  351.     return NGX_OK;
  352. }


  353. ngx_int_t
  354. ‌ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs,
  355.     ngx_array_t *keys, ngx_array_t *passwords)
  356. {
  357.     ngx_str_t   *cert, *key;
  358.     ngx_uint_t   i;

  359.     cert = certs->elts;
  360.     key = keys->elts;

  361.     for (i = 0; i < certs->nelts; i++) {

  362.         if (ngx_ssl_certificate(cf, ssl, &cert[i], &key[i], passwords)
  363.             != NGX_OK)
  364.         {
  365.             return NGX_ERROR;
  366.         }
  367.     }

  368.     return NGX_OK;
  369. }


  370. ngx_int_t
  371. ‌ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
  372.     ngx_str_t *key, ngx_array_t *passwords)
  373. {
  374.     char            *err;
  375.     X509            *x509, **elm;
  376.     u_long           n;
  377.     EVP_PKEY        *pkey;
  378.     ngx_uint_t       mask;
  379.     STACK_OF(X509)  *chain;

  380.     mask = 0;
  381.     elm = NULL;

  382. retry:

  383.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT | mask,
  384.                                 &err, cert, NULL);
  385.     if (chain == NULL) {
  386.         if (err != NULL) {
  387.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  388.                           "cannot load certificate \"%s\": %s",
  389.                           cert->data, err);
  390.         }

  391.         return NGX_ERROR;
  392.     }

  393.     x509 = sk_X509_shift(chain);

  394.     if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) {
  395.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  396.                       "SSL_CTX_use_certificate(\"%s\") failed", cert->data);
  397.         X509_free(x509);
  398.         sk_X509_pop_free(chain, X509_free);
  399.         return NGX_ERROR;
  400.     }

  401.     if (X509_set_ex_data(x509, ngx_ssl_certificate_name_index, cert->data)
  402.         == 0)
  403.     {
  404.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed");
  405.         X509_free(x509);
  406.         sk_X509_pop_free(chain, X509_free);
  407.         return NGX_ERROR;
  408.     }

  409.     if (ssl->certs.elts == NULL) {
  410.         if (ngx_array_init(&ssl->certs, cf->pool, 1, sizeof(X509 *))
  411.             != NGX_OK)
  412.         {
  413.             X509_free(x509);
  414.             sk_X509_pop_free(chain, X509_free);
  415.             return NGX_ERROR;
  416.         }
  417.     }

  418.     if (elm == NULL) {
  419.         elm = ngx_array_push(&ssl->certs);
  420.         if (elm == NULL) {
  421.             X509_free(x509);
  422.             sk_X509_pop_free(chain, X509_free);
  423.             return NGX_ERROR;
  424.         }

  425.     } else {
  426.         X509_free(*elm);
  427.     }

  428.     *elm = x509;

  429.     /*
  430.      * Note that x509 is not freed here, but will be instead freed in
  431.      * ngx_ssl_cleanup_ctx().  This is because we need to preserve all
  432.      * certificates to be able to iterate all of them through ssl->certs,
  433.      * while OpenSSL can free a certificate if it is replaced with another
  434.      * certificate of the same type.
  435.      */

  436. #ifdef SSL_CTX_set0_chain

  437.     if (SSL_CTX_set0_chain(ssl->ctx, chain) == 0) {
  438.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  439.                       "SSL_CTX_set0_chain(\"%s\") failed", cert->data);
  440.         sk_X509_pop_free(chain, X509_free);
  441.         return NGX_ERROR;
  442.     }

  443. #else

  444.     /* SSL_CTX_set0_chain() is only available in OpenSSL 1.0.2+ */

  445. #ifdef SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS
  446.     /* OpenSSL 1.0.1+ */
  447.     SSL_CTX_clear_extra_chain_certs(ssl->ctx);
  448. #else

  449.     if (ssl->ctx->extra_certs) {
  450.         sk_X509_pop_free(ssl->ctx->extra_certs, X509_free);
  451.         ssl->ctx->extra_certs = NULL;
  452.     }

  453. #endif

  454.     n = sk_X509_num(chain);

  455.     while (n--) {
  456.         x509 = sk_X509_shift(chain);

  457.         if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
  458.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  459.                           "SSL_CTX_add_extra_chain_cert(\"%s\") failed",
  460.                           cert->data);
  461.             sk_X509_pop_free(chain, X509_free);
  462.             return NGX_ERROR;
  463.         }
  464.     }

  465.     sk_X509_free(chain);

  466. #endif

  467.     pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY | mask,
  468.                                &err, key, passwords);
  469.     if (pkey == NULL) {
  470.         if (err != NULL) {
  471.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  472.                           "cannot load certificate key \"%s\": %s",
  473.                           key->data, err);
  474.         }

  475.         return NGX_ERROR;
  476.     }

  477.     if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
  478.         EVP_PKEY_free(pkey);

  479.         /* there can be mismatched pairs on uneven cache update */

  480.         n = ERR_peek_last_error();

  481.         if (ERR_GET_LIB(n) == ERR_LIB_X509
  482.             && ERR_GET_REASON(n) == X509_R_KEY_VALUES_MISMATCH
  483.             && mask == 0)
  484.         {
  485.             ERR_clear_error();
  486.             mask = NGX_SSL_CACHE_INVALIDATE;
  487.             goto retry;
  488.         }

  489.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  490.                       "SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
  491.         return NGX_ERROR;
  492.     }

  493.     EVP_PKEY_free(pkey);

  494.     return NGX_OK;
  495. }


  496. ngx_int_t
  497. ‌ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
  498.     ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache,
  499.     ngx_array_t *passwords)
  500. {
  501.     char            *err;
  502.     X509            *x509;
  503.     u_long           n;
  504.     EVP_PKEY        *pkey;
  505.     ngx_uint_t       mask;
  506.     STACK_OF(X509)  *chain;

  507.     mask = 0;

  508. retry:

  509.     chain = ngx_ssl_cache_connection_fetch(cache, pool,
  510.                                            NGX_SSL_CACHE_CERT | mask,
  511.                                            &err, cert, NULL);
  512.     if (chain == NULL) {
  513.         if (err != NULL) {
  514.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  515.                           "cannot load certificate \"%s\": %s",
  516.                           cert->data, err);
  517.         }

  518.         return NGX_ERROR;
  519.     }

  520.     x509 = sk_X509_shift(chain);

  521.     if (SSL_use_certificate(c->ssl->connection, x509) == 0) {
  522.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  523.                       "SSL_use_certificate(\"%s\") failed", cert->data);
  524.         X509_free(x509);
  525.         sk_X509_pop_free(chain, X509_free);
  526.         return NGX_ERROR;
  527.     }

  528.     X509_free(x509);

  529. #ifdef SSL_set0_chain

  530.     /*
  531.      * SSL_set0_chain() is only available in OpenSSL 1.0.2+,
  532.      * but this function is only called via certificate callback,
  533.      * which is only available in OpenSSL 1.0.2+ as well
  534.      */

  535.     if (SSL_set0_chain(c->ssl->connection, chain) == 0) {
  536.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  537.                       "SSL_set0_chain(\"%s\") failed", cert->data);
  538.         sk_X509_pop_free(chain, X509_free);
  539.         return NGX_ERROR;
  540.     }

  541. #endif

  542.     pkey = ngx_ssl_cache_connection_fetch(cache, pool,
  543.                                           NGX_SSL_CACHE_PKEY | mask,
  544.                                           &err, key, passwords);
  545.     if (pkey == NULL) {
  546.         if (err != NULL) {
  547.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  548.                           "cannot load certificate key \"%s\": %s",
  549.                           key->data, err);
  550.         }

  551.         return NGX_ERROR;
  552.     }

  553.     if (SSL_use_PrivateKey(c->ssl->connection, pkey) == 0) {
  554.         EVP_PKEY_free(pkey);

  555.         /* there can be mismatched pairs on uneven cache update */

  556.         n = ERR_peek_last_error();

  557.         if (ERR_GET_LIB(n) == ERR_LIB_X509
  558.             && ERR_GET_REASON(n) == X509_R_KEY_VALUES_MISMATCH
  559.             && mask == 0)
  560.         {
  561.             ERR_clear_error();
  562.             mask = NGX_SSL_CACHE_INVALIDATE;
  563.             goto retry;
  564.         }

  565.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  566.                       "SSL_use_PrivateKey(\"%s\") failed", key->data);
  567.         return NGX_ERROR;
  568.     }

  569.     EVP_PKEY_free(pkey);

  570.     return NGX_OK;
  571. }


  572. ngx_int_t
  573. ‌ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
  574.     ngx_uint_t enable)
  575. {
  576.     if (!enable) {
  577.         return NGX_OK;
  578.     }

  579. #ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION

  580.     if (SSL_CTX_compress_certs(ssl->ctx, 0) == 0) {
  581.         ngx_ssl_error(NGX_LOG_WARN, ssl->log, 0,
  582.                       "SSL_CTX_compress_certs() failed, ignored");
  583.         return NGX_OK;
  584.     }

  585.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);

  586. #elif (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)

  587.     if (SSL_CTX_add_cert_compression_alg(ssl->ctx, TLSEXT_cert_compression_zlib,
  588.                                          ngx_ssl_cert_compression_callback,
  589.                                          NULL)
  590.         == 0)
  591.     {
  592.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  593.                       "SSL_CTX_add_cert_compression_alg() failed");
  594.         return NGX_ERROR;
  595.     }

  596. #else

  597.     ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  598.                   "\"ssl_certificate_compression\" is not supported "
  599.                   "on this platform, ignored");

  600. #endif

  601.     return NGX_OK;
  602. }


  603. #if (NGX_ZLIB && defined TLSEXT_cert_compression_zlib)

  604. static int
  605. ‌ngx_ssl_cert_compression_callback(ngx_ssl_conn_t *ssl_conn, CBB *out,
  606.     const uint8_t *in, size_t in_len)
  607. {
  608.     int                rc;
  609.     X509              *cert;
  610.     u_char            *p;
  611.     z_stream           zstream;
  612.     ngx_str_t         *comp, tmp;
  613.     ngx_pool_t        *pool;
  614.     ngx_connection_t  *c;

  615. #ifdef OPENSSL_IS_BORINGSSL
  616.     {
  617.     SSL_CTX    *ssl_ctx;
  618.     ngx_ssl_t  *ssl;

  619.     /* BoringSSL doesn't have certificate slots, we take the last set */

  620.     ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
  621.     ssl = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_index);
  622.     cert = ((X509 **) ssl->certs.elts)[ssl->certs.nelts - 1];
  623.     }
  624. #else

  625.     /*
  626.      * AWS-LC saves leaf certificate in SSL to associate with SSL_CTX,
  627.      * see https://github.com/aws/aws-lc/commit/e1ba2b3e5
  628.      */

  629.     cert = SSL_get_certificate(ssl_conn);

  630. #endif

  631.     comp = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);

  632.     if (comp != NULL) {
  633.         return CBB_add_bytes(out, comp->data, comp->len);
  634.     }

  635.     c = ngx_ssl_get_connection(ssl_conn);

  636.     pool = ngx_create_pool(256, c->log);
  637.     if (pool == NULL) {
  638.         return 0;
  639.     }

  640.     pool->log = c->log;

  641.     ngx_memzero(&zstream, sizeof(z_stream));

  642.     zstream.zalloc = ngx_ssl_cert_compression_alloc;
  643.     zstream.zfree = ngx_ssl_cert_compression_free;
  644.     zstream.opaque = pool;

  645.     rc = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);

  646.     if (rc != Z_OK) {
  647.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflateInit() failed: %d", rc);
  648.         goto error;
  649.     }

  650.     tmp.len = deflateBound(&zstream, in_len);
  651.     tmp.data = ngx_palloc(pool, tmp.len);
  652.     if (tmp.data == NULL) {
  653.         goto error;
  654.     }

  655.     zstream.next_in = (u_char *) in;
  656.     zstream.avail_in = in_len;
  657.     zstream.next_out = tmp.data;
  658.     zstream.avail_out = tmp.len;

  659.     rc = deflate(&zstream, Z_FINISH);

  660.     if (rc != Z_STREAM_END) {
  661.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  662.                       "deflate(Z_FINISH) failed: %d", rc);
  663.         goto error;
  664.     }

  665.     tmp.len -= zstream.avail_out;

  666.     rc = deflateEnd(&zstream);

  667.     if (rc != Z_OK) {
  668.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "deflateEnd() failed: %d", rc);
  669.         goto error;
  670.     }

  671.     p = ngx_alloc(sizeof(ngx_str_t) + tmp.len, c->log);
  672.     if (p == NULL) {
  673.         goto error;
  674.     }

  675.     comp = (ngx_str_t *) p;

  676.     comp->len = tmp.len;
  677.     comp->data = p + sizeof(ngx_str_t);

  678.     ngx_memcpy(comp->data, tmp.data, tmp.len);

  679.     if (X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, p) == 0) {
  680.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_set_ex_data() failed");
  681.         ngx_free(p);
  682.     }

  683.     rc = CBB_add_bytes(out, tmp.data, tmp.len);

  684.     ngx_destroy_pool(pool);

  685.     return rc;

  686. error:

  687.     ngx_destroy_pool(pool);

  688.     return 0;
  689. }


  690. static void *
  691. ‌ngx_ssl_cert_compression_alloc(void *opaque, u_int items, u_int size)
  692. {
  693.     ngx_pool_t *pool = opaque;

  694.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pool->log, 0,
  695.                    "cert compression alloc: n:%ud s:%ud", items, size);

  696.     return ngx_palloc(pool, items * size);
  697. }


  698. static void
  699. ‌ngx_ssl_cert_compression_free(void *opaque, void *address)
  700. {
  701. #if 0
  702.     ngx_pool_t *pool = opaque;

  703.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pool->log, 0,
  704.                    "cert compression free: %p", address);
  705. #endif
  706. }

  707. #endif


  708. ngx_int_t
  709. ‌ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
  710.     ngx_uint_t prefer_server_ciphers)
  711. {
  712.     if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) {
  713.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  714.                       "SSL_CTX_set_cipher_list(\"%V\") failed",
  715.                       ciphers);
  716.         return NGX_ERROR;
  717.     }

  718.     if (prefer_server_ciphers) {
  719.         SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
  720.     }

  721.     return NGX_OK;
  722. }


  723. ngx_int_t
  724. ‌ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
  725.     ngx_int_t depth)
  726. {
  727.     int                   n, i;
  728.     char                 *err;
  729.     X509                 *x509;
  730.     X509_NAME            *name;
  731. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  732.     const
  733. #endif
  734.     X509_NAME            *sname;
  735.     X509_STORE           *store;
  736.     STACK_OF(X509)       *chain;
  737.     STACK_OF(X509_NAME)  *list;

  738.     SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback);

  739.     SSL_CTX_set_verify_depth(ssl->ctx, depth);

  740.     if (cert->len == 0) {
  741.         return NGX_OK;
  742.     }

  743.     list = sk_X509_NAME_new(ngx_ssl_cmp_x509_name);
  744.     if (list == NULL) {
  745.         return NGX_ERROR;
  746.     }

  747.     store = SSL_CTX_get_cert_store(ssl->ctx);

  748.     if (store == NULL) {
  749.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  750.                       "SSL_CTX_get_cert_store() failed");
  751.         return NGX_ERROR;
  752.     }

  753.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL);
  754.     if (chain == NULL) {
  755.         if (err != NULL) {
  756.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  757.                           "cannot load certificate \"%s\": %s",
  758.                           cert->data, err);
  759.         }

  760.         sk_X509_NAME_pop_free(list, X509_NAME_free);
  761.         return NGX_ERROR;
  762.     }

  763.     n = sk_X509_num(chain);

  764.     for (i = 0; i < n; i++) {
  765.         x509 = sk_X509_value(chain, i);

  766.         if (X509_STORE_add_cert(store, x509) != 1) {

  767.             if (ngx_ssl_cert_already_in_hash()) {
  768.                 continue;
  769.             }

  770.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  771.                           "X509_STORE_add_cert(\"%s\") failed", cert->data);
  772.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  773.             sk_X509_pop_free(chain, X509_free);
  774.             return NGX_ERROR;
  775.         }

  776.         sname = X509_get_subject_name(x509);
  777.         if (sname == NULL) {
  778.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  779.                           "X509_get_subject_name(\"%s\") failed", cert->data);
  780.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  781.             sk_X509_pop_free(chain, X509_free);
  782.             return NGX_ERROR;
  783.         }

  784.         name = X509_NAME_dup(sname);
  785.         if (name == NULL) {
  786.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  787.             sk_X509_pop_free(chain, X509_free);
  788.             return NGX_ERROR;
  789.         }

  790. #ifdef OPENSSL_IS_BORINGSSL
  791.         if (sk_X509_NAME_find(list, NULL, name) > 0) {
  792. #else
  793.         if (sk_X509_NAME_find(list, name) >= 0) {
  794. #endif
  795.             X509_NAME_free(name);
  796.             continue;
  797.         }

  798.         if (sk_X509_NAME_push(list, name) == 0) {
  799.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  800.             sk_X509_pop_free(chain, X509_free);
  801.             X509_NAME_free(name);
  802.             return NGX_ERROR;
  803.         }
  804.     }

  805.     sk_X509_pop_free(chain, X509_free);

  806.     SSL_CTX_set_client_CA_list(ssl->ctx, list);

  807.     return NGX_OK;
  808. }


  809. ngx_int_t
  810. ‌ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
  811.     ngx_int_t depth)
  812. {
  813.     int              i, n;
  814.     char            *err;
  815.     X509            *x509;
  816.     X509_STORE      *store;
  817.     STACK_OF(X509)  *chain;

  818.     SSL_CTX_set_verify(ssl->ctx, SSL_CTX_get_verify_mode(ssl->ctx),
  819.                        ngx_ssl_verify_callback);

  820.     SSL_CTX_set_verify_depth(ssl->ctx, depth);

  821.     if (cert->len == 0) {
  822.         return NGX_OK;
  823.     }

  824.     store = SSL_CTX_get_cert_store(ssl->ctx);

  825.     if (store == NULL) {
  826.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  827.                       "SSL_CTX_get_cert_store() failed");
  828.         return NGX_ERROR;
  829.     }

  830.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL);
  831.     if (chain == NULL) {
  832.         if (err != NULL) {
  833.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  834.                           "cannot load certificate \"%s\": %s",
  835.                           cert->data, err);
  836.         }

  837.         return NGX_ERROR;
  838.     }

  839.     n = sk_X509_num(chain);

  840.     for (i = 0; i < n; i++) {
  841.         x509 = sk_X509_value(chain, i);

  842.         if (X509_STORE_add_cert(store, x509) != 1) {

  843.             if (ngx_ssl_cert_already_in_hash()) {
  844.                 continue;
  845.             }

  846.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  847.                           "X509_STORE_add_cert(\"%s\") failed", cert->data);
  848.             sk_X509_pop_free(chain, X509_free);
  849.             return NGX_ERROR;
  850.         }
  851.     }

  852.     sk_X509_pop_free(chain, X509_free);

  853.     return NGX_OK;
  854. }


  855. ngx_int_t
  856. ‌ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
  857. {
  858.     int                  n, i;
  859.     char                *err;
  860.     X509_CRL            *x509;
  861.     X509_STORE          *store;
  862.     STACK_OF(X509_CRL)  *chain;

  863.     if (crl->len == 0) {
  864.         return NGX_OK;
  865.     }

  866.     store = SSL_CTX_get_cert_store(ssl->ctx);

  867.     if (store == NULL) {
  868.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  869.                       "SSL_CTX_get_cert_store() failed");
  870.         return NGX_ERROR;
  871.     }

  872.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CRL, &err, crl, NULL);
  873.     if (chain == NULL) {
  874.         if (err != NULL) {
  875.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  876.                           "cannot load CRL \"%s\": %s", crl->data, err);
  877.         }

  878.         return NGX_ERROR;
  879.     }

  880.     n = sk_X509_CRL_num(chain);

  881.     for (i = 0; i < n; i++) {
  882.         x509 = sk_X509_CRL_value(chain, i);

  883.         if (X509_STORE_add_crl(store, x509) != 1) {

  884.             if (ngx_ssl_cert_already_in_hash()) {
  885.                 continue;
  886.             }

  887.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  888.                           "X509_STORE_add_crl(\"%s\") failed", crl->data);
  889.             sk_X509_CRL_pop_free(chain, X509_CRL_free);
  890.             return NGX_ERROR;
  891.         }
  892.     }

  893.     sk_X509_CRL_pop_free(chain, X509_CRL_free);

  894.     X509_STORE_set_flags(store,
  895.                          X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);

  896.     return NGX_OK;
  897. }


  898. static ngx_inline ngx_int_t
  899. ‌ngx_ssl_cert_already_in_hash(void)
  900. {
  901. #if !(OPENSSL_VERSION_NUMBER >= 0x1010009fL                                   \
  902.       || LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
  903.     u_long  error;

  904.     /*
  905.      * OpenSSL prior to 1.1.0i doesn't ignore duplicate certificate entries,
  906.      * see https://github.com/openssl/openssl/commit/c0452248
  907.      */

  908.     error = ERR_peek_last_error();

  909.     if (ERR_GET_LIB(error) == ERR_LIB_X509
  910.         && ERR_GET_REASON(error) == X509_R_CERT_ALREADY_IN_HASH_TABLE)
  911.     {
  912.         ERR_clear_error();
  913.         return 1;
  914.     }
  915. #endif

  916.     return 0;
  917. }


  918. static int
  919. ‌ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
  920. {
  921. #if (NGX_DEBUG)
  922.     char              *subject, *issuer;
  923.     int                err, depth;
  924.     X509              *cert;
  925. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  926.     const
  927. #endif
  928.     X509_NAME         *sname, *iname;
  929.     ngx_connection_t  *c;
  930.     ngx_ssl_conn_t    *ssl_conn;

  931.     ssl_conn = X509_STORE_CTX_get_ex_data(x509_store,
  932.                                           SSL_get_ex_data_X509_STORE_CTX_idx());

  933.     c = ngx_ssl_get_connection(ssl_conn);

  934.     if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
  935.         return 1;
  936.     }

  937.     cert = X509_STORE_CTX_get_current_cert(x509_store);
  938.     err = X509_STORE_CTX_get_error(x509_store);
  939.     depth = X509_STORE_CTX_get_error_depth(x509_store);

  940.     sname = X509_get_subject_name(cert);

  941.     if (sname) {
  942.         subject = X509_NAME_oneline(sname, NULL, 0);
  943.         if (subject == NULL) {
  944.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  945.                           "X509_NAME_oneline() failed");
  946.         }

  947.     } else {
  948.         subject = NULL;
  949.     }

  950.     iname = X509_get_issuer_name(cert);

  951.     if (iname) {
  952.         issuer = X509_NAME_oneline(iname, NULL, 0);
  953.         if (issuer == NULL) {
  954.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  955.                           "X509_NAME_oneline() failed");
  956.         }

  957.     } else {
  958.         issuer = NULL;
  959.     }

  960.     ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
  961.                    "verify:%d, error:%d, depth:%d, "
  962.                    "subject:\"%s\", issuer:\"%s\"",
  963.                    ok, err, depth,
  964.                    subject ? subject : "(none)",
  965.                    issuer ? issuer : "(none)");

  966.     if (subject) {
  967.         OPENSSL_free(subject);
  968.     }

  969.     if (issuer) {
  970.         OPENSSL_free(issuer);
  971.     }
  972. #endif

  973.     return 1;
  974. }


  975. static void
  976. ‌ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
  977. {
  978.     BIO               *rbio, *wbio;
  979.     ngx_connection_t  *c;

  980. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  981.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

  982.     if ((where & SSL_CB_HANDSHAKE_START)
  983.         && SSL_is_server((ngx_ssl_conn_t *) ssl_conn))
  984.     {
  985.         c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);

  986.         if (c->ssl->handshaked) {
  987.             c->ssl->renegotiation = 1;
  988.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation");
  989.         }
  990.     }

  991. #endif

  992. #ifdef TLS1_3_VERSION

  993.     if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP
  994.         && SSL_version(ssl_conn) == TLS1_3_VERSION)
  995.     {
  996.         time_t        now, time, timeout, conf_timeout;
  997.         SSL_SESSION  *sess;

  998.         /*
  999.          * OpenSSL with TLSv1.3 updates the session creation time on
  1000.          * session resumption and keeps the session timeout unmodified,
  1001.          * making it possible to maintain the session forever, bypassing
  1002.          * client certificate expiration and revocation.  To make sure
  1003.          * session timeouts are actually used, we now update the session
  1004.          * creation time and reduce the session timeout accordingly.
  1005.          *
  1006.          * BoringSSL with TLSv1.3 ignores configured session timeouts
  1007.          * and uses a hardcoded timeout instead, 7 days.  So we update
  1008.          * session timeout to the configured value as soon as a session
  1009.          * is created.
  1010.          */

  1011.         c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
  1012.         sess = SSL_get0_session(ssl_conn);

  1013.         if (!c->ssl->session_timeout_set && sess) {
  1014.             c->ssl->session_timeout_set = 1;

  1015.             now = ngx_time();
  1016.             time = SSL_SESSION_get_time(sess);
  1017.             timeout = SSL_SESSION_get_timeout(sess);
  1018.             conf_timeout = SSL_CTX_get_timeout(c->ssl->session_ctx);

  1019.             timeout = ngx_min(timeout, conf_timeout);

  1020.             if (now - time >= timeout) {
  1021.                 SSL_SESSION_set1_id_context(sess, (unsigned char *) "", 0);

  1022.             } else {
  1023.                 SSL_SESSION_set_time(sess, now);
  1024.                 SSL_SESSION_set_timeout(sess, timeout - (now - time));
  1025.             }
  1026.         }
  1027.     }

  1028. #endif

  1029.     if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
  1030.         c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);

  1031.         if (!c->ssl->handshake_buffer_set) {
  1032.             /*
  1033.              * By default OpenSSL uses 4k buffer during a handshake,
  1034.              * which is too low for long certificate chains and might
  1035.              * result in extra round-trips.
  1036.              *
  1037.              * To adjust a buffer size we detect that buffering was added
  1038.              * to write side of the connection by comparing rbio and wbio.
  1039.              * If they are different, we assume that it's due to buffering
  1040.              * added to wbio, and set buffer size.
  1041.              */

  1042.             rbio = SSL_get_rbio(ssl_conn);
  1043.             wbio = SSL_get_wbio(ssl_conn);

  1044.             if (rbio != wbio) {
  1045.                 (void) BIO_set_write_buffer_size(wbio, NGX_SSL_BUFSIZE);
  1046.                 c->ssl->handshake_buffer_set = 1;
  1047.             }
  1048.         }
  1049.     }
  1050. }


  1051. static int
  1052. ‌ngx_ssl_cmp_x509_name(const X509_NAME *const *a, const X509_NAME *const *b)
  1053. {
  1054.     return (X509_NAME_cmp(*a, *b));
  1055. }


  1056. ngx_array_t *
  1057. ‌ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file)
  1058. {
  1059.     u_char              *p, *last, *end;
  1060.     size_t               len;
  1061.     ssize_t              n;
  1062.     ngx_fd_t             fd;
  1063.     ngx_str_t           *pwd;
  1064.     ngx_array_t         *passwords;
  1065.     ngx_pool_cleanup_t  *cln;
  1066.     u_char               buf[NGX_SSL_PASSWORD_BUFFER_SIZE];

  1067.     if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
  1068.         return NULL;
  1069.     }

  1070.     passwords = ngx_array_create(cf->temp_pool, 4, sizeof(ngx_str_t));
  1071.     if (passwords == NULL) {
  1072.         return NULL;
  1073.     }

  1074.     cln = ngx_pool_cleanup_add(cf->temp_pool, 0);
  1075.     if (cln == NULL) {
  1076.         return NULL;
  1077.     }

  1078.     cln->handler = ngx_ssl_passwords_cleanup;
  1079.     cln->data = passwords;

  1080.     fd = ngx_open_file(file->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);

  1081.     if (fd == NGX_INVALID_FILE) {
  1082.         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  1083.                            ngx_open_file_n " \"%s\" failed", file->data);
  1084.         return NULL;
  1085.     }

  1086.     len = 0;
  1087.     last = buf;

  1088.     do {
  1089.         n = ngx_read_fd(fd, last, NGX_SSL_PASSWORD_BUFFER_SIZE - len);

  1090.         if (n == -1) {
  1091.             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  1092.                                ngx_read_fd_n " \"%s\" failed", file->data);
  1093.             passwords = NULL;
  1094.             goto cleanup;
  1095.         }

  1096.         end = last + n;

  1097.         if (len && n == 0) {
  1098.             *end++ = LF;
  1099.         }

  1100.         p = buf;

  1101.         for ( ;; ) {
  1102.             last = ngx_strlchr(last, end, LF);

  1103.             if (last == NULL) {
  1104.                 break;
  1105.             }

  1106.             len = last++ - p;

  1107.             if (len && p[len - 1] == CR) {
  1108.                 len--;
  1109.             }

  1110.             if (len) {
  1111.                 pwd = ngx_array_push(passwords);
  1112.                 if (pwd == NULL) {
  1113.                     passwords = NULL;
  1114.                     goto cleanup;
  1115.                 }

  1116.                 pwd->len = len;
  1117.                 pwd->data = ngx_pnalloc(cf->temp_pool, len);

  1118.                 if (pwd->data == NULL) {
  1119.                     passwords->nelts--;
  1120.                     passwords = NULL;
  1121.                     goto cleanup;
  1122.                 }

  1123.                 ngx_memcpy(pwd->data, p, len);
  1124.             }

  1125.             p = last;
  1126.         }

  1127.         len = end - p;

  1128.         if (len == NGX_SSL_PASSWORD_BUFFER_SIZE) {
  1129.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1130.                                "too long line in \"%s\"", file->data);
  1131.             passwords = NULL;
  1132.             goto cleanup;
  1133.         }

  1134.         ngx_memmove(buf, p, len);
  1135.         last = buf + len;

  1136.     } while (n != 0);

  1137.     if (passwords->nelts == 0) {
  1138.         pwd = ngx_array_push(passwords);
  1139.         if (pwd == NULL) {
  1140.             passwords = NULL;
  1141.             goto cleanup;
  1142.         }

  1143.         ngx_memzero(pwd, sizeof(ngx_str_t));
  1144.     }

  1145. cleanup:

  1146.     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  1147.         ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno,
  1148.                            ngx_close_file_n " \"%s\" failed", file->data);
  1149.     }

  1150.     ngx_explicit_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE);

  1151.     return passwords;
  1152. }


  1153. ngx_array_t *
  1154. ‌ngx_ssl_preserve_passwords(ngx_conf_t *cf, ngx_array_t *passwords)
  1155. {
  1156.     ngx_str_t           *opwd, *pwd;
  1157.     ngx_uint_t           i;
  1158.     ngx_array_t         *pwds;
  1159.     ngx_pool_cleanup_t  *cln;
  1160.     static ngx_array_t   empty_passwords;

  1161.     if (passwords == NULL) {

  1162.         /*
  1163.          * If there are no passwords, an empty array is used
  1164.          * to make sure OpenSSL's default password callback
  1165.          * won't block on reading from stdin.
  1166.          */

  1167.         return &empty_passwords;
  1168.     }

  1169.     /*
  1170.      * Passwords are normally allocated from the temporary pool
  1171.      * and cleared after parsing configuration.  To be used at
  1172.      * runtime they have to be copied to the configuration pool.
  1173.      */

  1174.     pwds = ngx_array_create(cf->pool, passwords->nelts, sizeof(ngx_str_t));
  1175.     if (pwds == NULL) {
  1176.         return NULL;
  1177.     }

  1178.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  1179.     if (cln == NULL) {
  1180.         return NULL;
  1181.     }

  1182.     cln->handler = ngx_ssl_passwords_cleanup;
  1183.     cln->data = pwds;

  1184.     opwd = passwords->elts;

  1185.     for (i = 0; i < passwords->nelts; i++) {

  1186.         pwd = ngx_array_push(pwds);
  1187.         if (pwd == NULL) {
  1188.             return NULL;
  1189.         }

  1190.         pwd->len = opwd[i].len;
  1191.         pwd->data = ngx_pnalloc(cf->pool, pwd->len);

  1192.         if (pwd->data == NULL) {
  1193.             pwds->nelts--;
  1194.             return NULL;
  1195.         }

  1196.         ngx_memcpy(pwd->data, opwd[i].data, opwd[i].len);
  1197.     }

  1198.     return pwds;
  1199. }


  1200. static void
  1201. ‌ngx_ssl_passwords_cleanup(void *data)
  1202. {
  1203.     ngx_array_t *passwords = data;

  1204.     ngx_str_t   *pwd;
  1205.     ngx_uint_t   i;

  1206.     pwd = passwords->elts;

  1207.     for (i = 0; i < passwords->nelts; i++) {
  1208.         ngx_explicit_memzero(pwd[i].data, pwd[i].len);
  1209.     }
  1210. }


  1211. ngx_int_t
  1212. ‌ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
  1213. {
  1214. #ifndef OPENSSL_NO_DH

  1215.     BIO  *bio;

  1216.     if (file->len == 0) {
  1217.         return NGX_OK;
  1218.     }

  1219.     if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
  1220.         return NGX_ERROR;
  1221.     }

  1222.     bio = BIO_new_file((char *) file->data, "r");
  1223.     if (bio == NULL) {
  1224.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1225.                       "BIO_new_file(\"%s\") failed", file->data);
  1226.         return NGX_ERROR;
  1227.     }

  1228. #ifdef SSL_CTX_set_tmp_dh
  1229.     {
  1230.     DH  *dh;

  1231.     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
  1232.     if (dh == NULL) {
  1233.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1234.                       "PEM_read_bio_DHparams(\"%s\") failed", file->data);
  1235.         BIO_free(bio);
  1236.         return NGX_ERROR;
  1237.     }

  1238.     if (SSL_CTX_set_tmp_dh(ssl->ctx, dh) != 1) {
  1239.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1240.                       "SSL_CTX_set_tmp_dh(\"%s\") failed", file->data);
  1241.         DH_free(dh);
  1242.         BIO_free(bio);
  1243.         return NGX_ERROR;
  1244.     }

  1245.     DH_free(dh);
  1246.     }
  1247. #else
  1248.     {
  1249.     EVP_PKEY  *dh;

  1250.     /*
  1251.      * PEM_read_bio_DHparams() and SSL_CTX_set_tmp_dh()
  1252.      * are deprecated in OpenSSL 3.0
  1253.      */

  1254.     dh = PEM_read_bio_Parameters(bio, NULL);
  1255.     if (dh == NULL) {
  1256.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1257.                       "PEM_read_bio_Parameters(\"%s\") failed", file->data);
  1258.         BIO_free(bio);
  1259.         return NGX_ERROR;
  1260.     }

  1261.     if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
  1262.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1263.                       "SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed", file->data);
  1264. #if (OPENSSL_VERSION_NUMBER >= 0x30000010L)
  1265.         EVP_PKEY_free(dh);
  1266. #endif
  1267.         BIO_free(bio);
  1268.         return NGX_ERROR;
  1269.     }
  1270.     }
  1271. #endif

  1272.     BIO_free(bio);

  1273. #endif

  1274.     return NGX_OK;
  1275. }


  1276. ngx_int_t
  1277. ‌ngx_ssl_ech_files(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *filenames)
  1278. {
  1279. #ifdef SSL_OP_ECH_GREASE
  1280.     int             numkeys;
  1281.     BIO            *in;
  1282.     ngx_int_t       rc;
  1283.     ngx_str_t      *filename;
  1284.     ngx_uint_t      i;
  1285.     OSSL_ECHSTORE  *es;

  1286.     if (filenames == NULL) {
  1287.         return NGX_OK;
  1288.     }

  1289.     es = OSSL_ECHSTORE_new(NULL, NULL);
  1290.     if (es == NULL) {
  1291.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "OSSL_ECHSTORE_new() failed");
  1292.         return NGX_ERROR;
  1293.     }

  1294.     rc = NGX_ERROR;
  1295.     filename = filenames->elts;

  1296.     for (i = 0; i < filenames->nelts; i++) {

  1297.         if (ngx_conf_full_name(cf->cycle, &filename[i], 1) != NGX_OK) {
  1298.             goto cleanup;
  1299.         }

  1300.         in = BIO_new_file((char *) filename[i].data, "r");
  1301.         if (in == NULL) {
  1302.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1303.                           "BIO_new_file(\"%s\") failed", filename[i].data);
  1304.             goto cleanup;
  1305.         }

  1306.         /*
  1307.          * We only set the ECHConfigList from the first file read to use
  1308.          * in ECH retry-configs.
  1309.          *
  1310.          * That allows many sensible key rotation schemes so that the
  1311.          * values sent in ECH retry-configs are smaller and current.
  1312.          * For example, if the first file name has the current ECH
  1313.          * private key, and a second one has the previously used key
  1314.          * that some clients may still use due to DNS caching.
  1315.          */

  1316.          if (OSSL_ECHSTORE_read_pem(es, in, i ? OSSL_ECH_NO_RETRY
  1317.                                               : OSSL_ECH_FOR_RETRY)
  1318.              != 1)
  1319.          {
  1320.              ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1321.                            "OSSL_ECHSTORE_read_pem(%s) failed",
  1322.                            filename[i].data);
  1323.              BIO_free(in);
  1324.              goto cleanup;
  1325.          }

  1326.          BIO_free(in);
  1327.     }

  1328.     /*
  1329.      * load the ECH store after checking there's at least one ECH
  1330.      * private key in there (the PEM file spec allows zero or one
  1331.      * private key per file)
  1332.      */

  1333.     if (OSSL_ECHSTORE_num_keys(es, &numkeys) != 1) {
  1334.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1335.                       "OSSL_ECHSTORE_num_keys() failed");
  1336.         goto cleanup;
  1337.     }

  1338.     if (numkeys > 0 && SSL_CTX_set1_echstore(ssl->ctx, es) != 1) {
  1339.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1340.                       "SSL_CTX_set1_echstore() failed");
  1341.         goto cleanup;
  1342.     }

  1343.     rc = NGX_OK;

  1344. cleanup:

  1345.     OSSL_ECHSTORE_free(es);
  1346.     return rc;

  1347. #else
  1348.     if (filenames != NULL) {
  1349.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  1350.                       "\"ssl_ech_file\" is not supported on this platform, "
  1351.                       "ignored");
  1352.     }

  1353.     return NGX_OK;
  1354. #endif
  1355. }


  1356. ngx_int_t
  1357. ‌ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
  1358. {
  1359. #ifndef OPENSSL_NO_ECDH

  1360.     /*
  1361.      * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
  1362.      * from RFC 4492 section 5.1.1, or explicitly described curves over
  1363.      * binary fields.  OpenSSL only supports the "named curves", which provide
  1364.      * maximum interoperability.
  1365.      */

  1366. #if (defined SSL_CTX_set1_curves_list || defined SSL_CTRL_SET_CURVES_LIST)

  1367.     /*
  1368.      * OpenSSL 1.0.2+ allows configuring a curve list instead of a single
  1369.      * curve previously supported.  By default an internal list is used,
  1370.      * with prime256v1 being preferred by server in OpenSSL 1.0.2b+
  1371.      * and X25519 in OpenSSL 1.1.0+.
  1372.      *
  1373.      * By default a curve preferred by the client will be used for
  1374.      * key exchange.  The SSL_OP_CIPHER_SERVER_PREFERENCE option can
  1375.      * be used to prefer server curves instead, similar to what it
  1376.      * does for ciphers.
  1377.      */

  1378.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);

  1379. #ifdef SSL_CTRL_SET_ECDH_AUTO
  1380.     /* not needed in OpenSSL 1.1.0+ */
  1381.     (void) SSL_CTX_set_ecdh_auto(ssl->ctx, 1);
  1382. #endif

  1383.     if (ngx_strcmp(name->data, "auto") == 0) {
  1384.         return NGX_OK;
  1385.     }

  1386.     if (SSL_CTX_set1_curves_list(ssl->ctx, (char *) name->data) == 0) {
  1387.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1388.                       "SSL_CTX_set1_curves_list(\"%s\") failed", name->data);
  1389.         return NGX_ERROR;
  1390.     }

  1391. #else

  1392.     int      nid;
  1393.     char    *curve;
  1394.     EC_KEY  *ecdh;

  1395.     if (ngx_strcmp(name->data, "auto") == 0) {
  1396.         curve = "prime256v1";

  1397.     } else {
  1398.         curve = (char *) name->data;
  1399.     }

  1400.     nid = OBJ_sn2nid(curve);
  1401.     if (nid == 0) {
  1402.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1403.                       "OBJ_sn2nid(\"%s\") failed: unknown curve", curve);
  1404.         return NGX_ERROR;
  1405.     }

  1406.     ecdh = EC_KEY_new_by_curve_name(nid);
  1407.     if (ecdh == NULL) {
  1408.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1409.                       "EC_KEY_new_by_curve_name(\"%s\") failed", curve);
  1410.         return NGX_ERROR;
  1411.     }

  1412.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);

  1413.     SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);

  1414.     EC_KEY_free(ecdh);
  1415. #endif
  1416. #endif

  1417.     return NGX_OK;
  1418. }


  1419. ngx_int_t
  1420. ‌ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
  1421. {
  1422.     if (!enable) {
  1423.         return NGX_OK;
  1424.     }

  1425. #ifdef SSL_ERROR_EARLY_DATA_REJECTED

  1426.     /* BoringSSL */

  1427.     SSL_CTX_set_early_data_enabled(ssl->ctx, 1);

  1428. #elif defined SSL_READ_EARLY_DATA_SUCCESS

  1429.     /* OpenSSL */

  1430.     SSL_CTX_set_max_early_data(ssl->ctx, NGX_SSL_BUFSIZE);

  1431. #else
  1432.     ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  1433.                   "\"ssl_early_data\" is not supported on this platform, "
  1434.                   "ignored");
  1435. #endif

  1436.     return NGX_OK;
  1437. }


  1438. ngx_int_t
  1439. ‌ngx_ssl_conf_commands(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *commands)
  1440. {
  1441.     if (commands == NULL) {
  1442.         return NGX_OK;
  1443.     }

  1444. #ifdef SSL_CONF_FLAG_FILE
  1445.     {
  1446.     int            type;
  1447.     u_char        *key, *value;
  1448.     ngx_uint_t     i;
  1449.     ngx_keyval_t  *cmd;
  1450.     SSL_CONF_CTX  *cctx;

  1451.     cctx = SSL_CONF_CTX_new();
  1452.     if (cctx == NULL) {
  1453.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1454.                       "SSL_CONF_CTX_new() failed");
  1455.         return NGX_ERROR;
  1456.     }

  1457.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
  1458.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
  1459.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
  1460.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
  1461.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS);

  1462.     SSL_CONF_CTX_set_ssl_ctx(cctx, ssl->ctx);

  1463.     cmd = commands->elts;
  1464.     for (i = 0; i < commands->nelts; i++) {

  1465.         key = cmd[i].key.data;
  1466.         type = SSL_CONF_cmd_value_type(cctx, (char *) key);

  1467.         if (type == SSL_CONF_TYPE_FILE || type == SSL_CONF_TYPE_DIR) {
  1468.             if (ngx_conf_full_name(cf->cycle, &cmd[i].value, 1) != NGX_OK) {
  1469.                 SSL_CONF_CTX_free(cctx);
  1470.                 return NGX_ERROR;
  1471.             }
  1472.         }

  1473.         value = cmd[i].value.data;

  1474.         if (SSL_CONF_cmd(cctx, (char *) key, (char *) value) <= 0) {
  1475.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1476.                           "SSL_CONF_cmd(\"%s\", \"%s\") failed", key, value);
  1477.             SSL_CONF_CTX_free(cctx);
  1478.             return NGX_ERROR;
  1479.         }
  1480.     }

  1481.     if (SSL_CONF_CTX_finish(cctx) != 1) {
  1482.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1483.                       "SSL_CONF_finish() failed");
  1484.         SSL_CONF_CTX_free(cctx);
  1485.         return NGX_ERROR;
  1486.     }

  1487.     SSL_CONF_CTX_free(cctx);

  1488.     return NGX_OK;
  1489.     }
  1490. #else
  1491.     ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,
  1492.                   "SSL_CONF_cmd() is not available on this platform");
  1493.     return NGX_ERROR;
  1494. #endif
  1495. }


  1496. ngx_int_t
  1497. ‌ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
  1498. {
  1499.     if (!enable) {
  1500.         return NGX_OK;
  1501.     }

  1502.     SSL_CTX_set_session_cache_mode(ssl->ctx,
  1503.                                    SSL_SESS_CACHE_CLIENT
  1504.                                    |SSL_SESS_CACHE_NO_INTERNAL);

  1505.     SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_client_session);

  1506.     return NGX_OK;
  1507. }


  1508. static int
  1509. ‌ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
  1510. {
  1511.     ngx_connection_t  *c;

  1512.     c = ngx_ssl_get_connection(ssl_conn);

  1513.     if (c->ssl->save_session) {
  1514.         c->ssl->session = sess;

  1515.         c->ssl->save_session(c);

  1516.         c->ssl->session = NULL;
  1517.     }

  1518.     return 0;
  1519. }


  1520. ngx_int_t
  1521. ‌ngx_ssl_set_client_hello_callback(ngx_ssl_t *ssl, ngx_ssl_client_hello_arg *cb)
  1522. {
  1523. #ifdef SSL_CLIENT_HELLO_SUCCESS

  1524.     SSL_CTX_set_client_hello_cb(ssl->ctx, ngx_ssl_client_hello_callback, NULL);

  1525.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_client_hello_arg_index, cb) == 0)
  1526.     {
  1527.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1528.                       "SSL_CTX_set_ex_data() failed");
  1529.         return NGX_ERROR;
  1530.     }

  1531. #elif defined OPENSSL_IS_BORINGSSL

  1532.     SSL_CTX_set_select_certificate_cb(ssl->ctx, ngx_ssl_select_certificate);

  1533.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_client_hello_arg_index, cb) == 0)
  1534.     {
  1535.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1536.                       "SSL_CTX_set_ex_data() failed");
  1537.         return NGX_ERROR;
  1538.     }

  1539. #endif

  1540.     return NGX_OK;
  1541. }


  1542. #ifdef SSL_CLIENT_HELLO_SUCCESS

  1543. int
  1544. ‌ngx_ssl_client_hello_callback(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
  1545. {
  1546.     u_char                    *p;
  1547.     size_t                     len;
  1548.     ngx_int_t                  rc;
  1549.     ngx_str_t                  host;
  1550.     ngx_connection_t          *c;
  1551.     ngx_ssl_client_hello_arg  *cb;

  1552.     c = ngx_ssl_get_connection(ssl_conn);
  1553.     cb = SSL_CTX_get_ex_data(c->ssl->session_ctx,
  1554.                              ngx_ssl_client_hello_arg_index);

  1555.     if (SSL_client_hello_get0_ext(ssl_conn, TLSEXT_TYPE_server_name,
  1556.                                   (const unsigned char **) &p, &len)
  1557.         == 0)
  1558.     {
  1559.         ngx_str_null(&host);
  1560.         goto done;
  1561.     }

  1562.     /*
  1563.      * RFC 6066 mandates non-zero HostName length, we follow OpenSSL.
  1564.      * No more than one ServerName is expected.
  1565.      */

  1566.     if (len < 5
  1567.         || (size_t) (p[0] << 8) + p[1] + 2 != len
  1568.         || p[2] != TLSEXT_NAMETYPE_host_name
  1569.         || (size_t) (p[3] << 8) + p[4] + 2 + 3 != len)
  1570.     {
  1571.         *ad = SSL_AD_DECODE_ERROR;
  1572.         return SSL_CLIENT_HELLO_ERROR;
  1573.     }

  1574.     len -= 5;
  1575.     p += 5;

  1576.     if (len > TLSEXT_MAXLEN_host_name || ngx_strlchr(p, p + len, '\0')) {
  1577.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  1578.         return SSL_CLIENT_HELLO_ERROR;
  1579.     }

  1580.     host.len = len;
  1581.     host.data = p;

  1582. done:

  1583.     rc = cb->servername(ssl_conn, ad, &host);

  1584.     if (rc == SSL_TLSEXT_ERR_ALERT_FATAL) {
  1585.         return SSL_CLIENT_HELLO_ERROR;
  1586.     }

  1587.     return SSL_CLIENT_HELLO_SUCCESS;
  1588. }

  1589. #elif defined OPENSSL_IS_BORINGSSL

  1590. ‌enum ssl_select_cert_result_t ngx_ssl_select_certificate(
  1591.     const SSL_CLIENT_HELLO *client_hello)
  1592. {
  1593.     int                        ad;
  1594.     ngx_int_t                  rc;
  1595.     ngx_ssl_conn_t            *ssl_conn;
  1596.     ngx_connection_t          *c;
  1597.     ngx_ssl_client_hello_arg  *cb;

  1598.     ssl_conn = client_hello->ssl;
  1599.     c = ngx_ssl_get_connection(ssl_conn);
  1600.     cb = SSL_CTX_get_ex_data(c->ssl->session_ctx,
  1601.                              ngx_ssl_client_hello_arg_index);

  1602.     /*
  1603.      * BoringSSL sends a hardcoded "handshake_failure" alert on errors,
  1604.      * we use it to map SSL_AD_INTERNAL_ERROR.  To preserve other alert
  1605.      * values, error handling is postponed to the servername callback.
  1606.      */

  1607.     rc = cb->servername(ssl_conn, &ad, NULL);

  1608.     if (rc == SSL_TLSEXT_ERR_ALERT_FATAL && ad == SSL_AD_INTERNAL_ERROR) {
  1609.         return ssl_select_cert_error;
  1610.     }

  1611.     return ssl_select_cert_success;
  1612. }

  1613. #endif


  1614. ngx_int_t
  1615. ‌ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
  1616. {
  1617.     ngx_ssl_connection_t  *sc;

  1618.     sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t));
  1619.     if (sc == NULL) {
  1620.         return NGX_ERROR;
  1621.     }

  1622.     sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
  1623.     sc->buffer_size = ssl->buffer_size;

  1624.     sc->session_ctx = ssl->ctx;

  1625. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  1626.     if (SSL_CTX_get_max_early_data(ssl->ctx)) {
  1627.         sc->try_early_data = 1;
  1628.     }
  1629. #endif

  1630.     sc->connection = SSL_new(ssl->ctx);

  1631.     if (sc->connection == NULL) {
  1632.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed");
  1633.         return NGX_ERROR;
  1634.     }

  1635.     if (SSL_set_fd(sc->connection, c->fd) == 0) {
  1636.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");
  1637.         return NGX_ERROR;
  1638.     }

  1639.     if (flags & NGX_SSL_CLIENT) {
  1640.         SSL_set_connect_state(sc->connection);

  1641.     } else {
  1642.         SSL_set_accept_state(sc->connection);

  1643. #ifdef SSL_OP_NO_RENEGOTIATION
  1644.         SSL_set_options(sc->connection, SSL_OP_NO_RENEGOTIATION);
  1645. #endif
  1646.     }

  1647.     if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) {
  1648.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
  1649.         return NGX_ERROR;
  1650.     }

  1651.     c->ssl = sc;

  1652.     return NGX_OK;
  1653. }


  1654. ngx_ssl_session_t *
  1655. ‌ngx_ssl_get_session(ngx_connection_t *c)
  1656. {
  1657. #ifdef TLS1_3_VERSION
  1658.     if (c->ssl->session) {
  1659.         SSL_SESSION_up_ref(c->ssl->session);
  1660.         return c->ssl->session;
  1661.     }
  1662. #endif

  1663.     return SSL_get1_session(c->ssl->connection);
  1664. }


  1665. ngx_ssl_session_t *
  1666. ‌ngx_ssl_get0_session(ngx_connection_t *c)
  1667. {
  1668.     if (c->ssl->session) {
  1669.         return c->ssl->session;
  1670.     }

  1671.     return SSL_get0_session(c->ssl->connection);
  1672. }


  1673. ngx_int_t
  1674. ‌ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
  1675. {
  1676.     if (session) {
  1677.         if (SSL_set_session(c->ssl->connection, session) == 0) {
  1678.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed");
  1679.             return NGX_ERROR;
  1680.         }
  1681.     }

  1682.     return NGX_OK;
  1683. }


  1684. ngx_int_t
  1685. ‌ngx_ssl_handshake(ngx_connection_t *c)
  1686. {
  1687.     int        n, sslerr;
  1688.     ngx_err_t  err;
  1689.     ngx_int_t  rc;

  1690. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  1691.     if (c->ssl->try_early_data) {
  1692.         return ngx_ssl_try_early_data(c);
  1693.     }
  1694. #endif

  1695.     if (c->ssl->in_ocsp) {
  1696.         return ngx_ssl_ocsp_validate(c);
  1697.     }

  1698.     ngx_ssl_clear_error(c->log);

  1699.     n = SSL_do_handshake(c->ssl->connection);

  1700.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);

  1701.     if (n == 1) {

  1702.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1703.             return NGX_ERROR;
  1704.         }

  1705.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1706.             return NGX_ERROR;
  1707.         }

  1708. #if (NGX_DEBUG)
  1709.         ngx_ssl_handshake_log(c);
  1710. #endif

  1711.         c->recv = ngx_ssl_recv;
  1712.         c->send = ngx_ssl_write;
  1713.         c->recv_chain = ngx_ssl_recv_chain;
  1714.         c->send_chain = ngx_ssl_send_chain;

  1715.         c->read->ready = 1;
  1716.         c->write->ready = 1;

  1717. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  1718.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION                               \
  1719.      && defined SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS                             \
  1720.      && OPENSSL_VERSION_NUMBER < 0x10100000L)

  1721.         /* initial handshake done, disable renegotiation (CVE-2009-3555) */
  1722.         if (c->ssl->connection->s3 && SSL_is_server(c->ssl->connection)) {
  1723.             c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
  1724.         }

  1725. #endif

  1726. #if (defined BIO_get_ktls_send && !NGX_WIN32)

  1727.         if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
  1728.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1729.                            "BIO_get_ktls_send(): 1");
  1730.             c->ssl->sendfile = 1;
  1731.         }

  1732. #endif

  1733.         rc = ngx_ssl_ocsp_validate(c);

  1734.         if (rc == NGX_ERROR) {
  1735.             return NGX_ERROR;
  1736.         }

  1737.         if (rc == NGX_AGAIN) {
  1738.             c->read->handler = ngx_ssl_handshake_handler;
  1739.             c->write->handler = ngx_ssl_handshake_handler;
  1740.             return NGX_AGAIN;
  1741.         }

  1742.         c->ssl->handshaked = 1;

  1743.         return NGX_OK;
  1744.     }

  1745.     sslerr = SSL_get_error(c->ssl->connection, n);

  1746.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

  1747.     if (sslerr == SSL_ERROR_WANT_READ) {
  1748.         c->read->ready = 0;
  1749.         c->read->handler = ngx_ssl_handshake_handler;
  1750.         c->write->handler = ngx_ssl_handshake_handler;

  1751.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1752.             return NGX_ERROR;
  1753.         }

  1754.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1755.             return NGX_ERROR;
  1756.         }

  1757.         return NGX_AGAIN;
  1758.     }

  1759.     if (sslerr == SSL_ERROR_WANT_WRITE) {
  1760.         c->write->ready = 0;
  1761.         c->read->handler = ngx_ssl_handshake_handler;
  1762.         c->write->handler = ngx_ssl_handshake_handler;

  1763.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1764.             return NGX_ERROR;
  1765.         }

  1766.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1767.             return NGX_ERROR;
  1768.         }

  1769.         return NGX_AGAIN;
  1770.     }

  1771.     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  1772.     if (sslerr == SSL_ERROR_SYSCALL && ERR_peek_error() == 0 && err == 0) {

  1773.         /*
  1774.          * OpenSSL up to 3.0 returns SSL_ERROR_SYSCALL
  1775.          * without an error queue and with errno set to 0
  1776.          * if connection is closed cleanly
  1777.          */

  1778.         sslerr = SSL_ERROR_ZERO_RETURN;
  1779.     }

  1780.     c->ssl->no_wait_shutdown = 1;
  1781.     c->ssl->no_send_shutdown = 1;
  1782.     c->read->eof = 1;

  1783.     if (sslerr == SSL_ERROR_ZERO_RETURN) {
  1784.         ngx_connection_error(c, err,
  1785.                              "peer closed connection in SSL handshake");

  1786.         return NGX_ERROR;
  1787.     }

  1788.     if (c->ssl->handshake_rejected) {
  1789.         ngx_connection_error(c, err, "handshake rejected");
  1790.         ERR_clear_error();

  1791.         return NGX_ERROR;
  1792.     }

  1793.     c->read->error = 1;

  1794.     ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");

  1795.     return NGX_ERROR;
  1796. }


  1797. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  1798. static ngx_int_t
  1799. ‌ngx_ssl_try_early_data(ngx_connection_t *c)
  1800. {
  1801.     int        n, sslerr;
  1802.     u_char     buf;
  1803.     size_t     readbytes;
  1804.     ngx_err_t  err;
  1805.     ngx_int_t  rc;

  1806.     ngx_ssl_clear_error(c->log);

  1807.     readbytes = 0;

  1808.     n = SSL_read_early_data(c->ssl->connection, &buf, 1, &readbytes);

  1809.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1810.                    "SSL_read_early_data: %d, %uz", n, readbytes);

  1811.     if (n == SSL_READ_EARLY_DATA_FINISH) {
  1812.         c->ssl->try_early_data = 0;
  1813.         return ngx_ssl_handshake(c);
  1814.     }

  1815.     if (n == SSL_READ_EARLY_DATA_SUCCESS) {

  1816.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1817.             return NGX_ERROR;
  1818.         }

  1819.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1820.             return NGX_ERROR;
  1821.         }

  1822. #if (NGX_DEBUG)
  1823.         ngx_ssl_handshake_log(c);
  1824. #endif

  1825.         c->ssl->try_early_data = 0;

  1826.         c->ssl->early_buf = buf;
  1827.         c->ssl->early_preread = 1;

  1828.         c->ssl->in_early = 1;

  1829.         c->recv = ngx_ssl_recv;
  1830.         c->send = ngx_ssl_write;
  1831.         c->recv_chain = ngx_ssl_recv_chain;
  1832.         c->send_chain = ngx_ssl_send_chain;

  1833.         c->read->ready = 1;
  1834.         c->write->ready = 1;

  1835. #if (defined BIO_get_ktls_send && !NGX_WIN32)

  1836.         if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
  1837.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1838.                            "BIO_get_ktls_send(): 1");
  1839.             c->ssl->sendfile = 1;
  1840.         }

  1841. #endif

  1842.         rc = ngx_ssl_ocsp_validate(c);

  1843.         if (rc == NGX_ERROR) {
  1844.             return NGX_ERROR;
  1845.         }

  1846.         if (rc == NGX_AGAIN) {
  1847.             c->read->handler = ngx_ssl_handshake_handler;
  1848.             c->write->handler = ngx_ssl_handshake_handler;
  1849.             return NGX_AGAIN;
  1850.         }

  1851.         c->ssl->handshaked = 1;

  1852.         return NGX_OK;
  1853.     }

  1854.     /* SSL_READ_EARLY_DATA_ERROR */

  1855.     sslerr = SSL_get_error(c->ssl->connection, n);

  1856.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

  1857.     if (sslerr == SSL_ERROR_WANT_READ) {
  1858.         c->read->ready = 0;
  1859.         c->read->handler = ngx_ssl_handshake_handler;
  1860.         c->write->handler = ngx_ssl_handshake_handler;

  1861.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1862.             return NGX_ERROR;
  1863.         }

  1864.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1865.             return NGX_ERROR;
  1866.         }

  1867.         return NGX_AGAIN;
  1868.     }

  1869.     if (sslerr == SSL_ERROR_WANT_WRITE) {
  1870.         c->write->ready = 0;
  1871.         c->read->handler = ngx_ssl_handshake_handler;
  1872.         c->write->handler = ngx_ssl_handshake_handler;

  1873.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1874.             return NGX_ERROR;
  1875.         }

  1876.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1877.             return NGX_ERROR;
  1878.         }

  1879.         return NGX_AGAIN;
  1880.     }

  1881.     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  1882.     if (sslerr == SSL_ERROR_SYSCALL && ERR_peek_error() == 0 && err == 0) {

  1883.         /*
  1884.          * OpenSSL up to 3.0 returns SSL_ERROR_SYSCALL
  1885.          * without an error queue and with errno set to 0
  1886.          * if connection is closed cleanly
  1887.          */

  1888.         sslerr = SSL_ERROR_ZERO_RETURN;
  1889.     }

  1890.     c->ssl->no_wait_shutdown = 1;
  1891.     c->ssl->no_send_shutdown = 1;
  1892.     c->read->eof = 1;

  1893.     if (sslerr == SSL_ERROR_ZERO_RETURN) {
  1894.         ngx_connection_error(c, err,
  1895.                              "peer closed connection in SSL handshake");

  1896.         return NGX_ERROR;
  1897.     }

  1898.     c->read->error = 1;

  1899.     ngx_ssl_connection_error(c, sslerr, err, "SSL_read_early_data() failed");

  1900.     return NGX_ERROR;
  1901. }

  1902. #endif


  1903. #if (NGX_DEBUG)

  1904. void
  1905. ‌ngx_ssl_handshake_log(ngx_connection_t *c)
  1906. {
  1907.     char         buf[129], *s, *d;
  1908. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  1909.     const
  1910. #endif
  1911.     SSL_CIPHER  *cipher;

  1912.     if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
  1913.         return;
  1914.     }

  1915.     cipher = SSL_get_current_cipher(c->ssl->connection);

  1916.     if (cipher) {
  1917.         SSL_CIPHER_description(cipher, &buf[1], 128);

  1918.         for (s = &buf[1], d = buf; *s; s++) {
  1919.             if (*s == ' ' && *d == ' ') {
  1920.                 continue;
  1921.             }

  1922.             if (*s == LF || *s == CR) {
  1923.                 continue;
  1924.             }

  1925.             *++d = *s;
  1926.         }

  1927.         if (*d != ' ') {
  1928.             d++;
  1929.         }

  1930.         *d = '\0';

  1931.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1932.                        "SSL: %s, cipher: \"%s\"",
  1933.                        SSL_get_version(c->ssl->connection), &buf[1]);

  1934.         if (SSL_session_reused(c->ssl->connection)) {
  1935.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1936.                            "SSL reused session");
  1937.         }

  1938.     } else {
  1939.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1940.                        "SSL no shared ciphers");
  1941.     }
  1942. }

  1943. #endif


  1944. static void
  1945. ‌ngx_ssl_handshake_handler(ngx_event_t *ev)
  1946. {
  1947.     ngx_connection_t  *c;

  1948.     c = ev->data;

  1949.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1950.                    "SSL handshake handler: %d", ev->write);

  1951.     if (ev->timedout) {
  1952.         c->ssl->handler(c);
  1953.         return;
  1954.     }

  1955.     if (ngx_ssl_handshake(c) == NGX_AGAIN) {
  1956.         return;
  1957.     }

  1958.     c->ssl->handler(c);
  1959. }


  1960. ssize_t
  1961. ‌ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl, off_t limit)
  1962. {
  1963.     u_char     *last;
  1964.     ssize_t     n, bytes, size;
  1965.     ngx_buf_t  *b;

  1966.     bytes = 0;

  1967.     b = cl->buf;
  1968.     last = b->last;

  1969.     for ( ;; ) {
  1970.         size = b->end - last;

  1971.         if (limit) {
  1972.             if (bytes >= limit) {
  1973.                 return bytes;
  1974.             }

  1975.             if (bytes + size > limit) {
  1976.                 size = (ssize_t) (limit - bytes);
  1977.             }
  1978.         }

  1979.         n = ngx_ssl_recv(c, last, size);

  1980.         if (n > 0) {
  1981.             last += n;
  1982.             bytes += n;

  1983.             if (!c->read->ready) {
  1984.                 return bytes;
  1985.             }

  1986.             if (last == b->end) {
  1987.                 cl = cl->next;

  1988.                 if (cl == NULL) {
  1989.                     return bytes;
  1990.                 }

  1991.                 b = cl->buf;
  1992.                 last = b->last;
  1993.             }

  1994.             continue;
  1995.         }

  1996.         if (bytes) {

  1997.             if (n == 0 || n == NGX_ERROR) {
  1998.                 c->read->ready = 1;
  1999.             }

  2000.             return bytes;
  2001.         }

  2002.         return n;
  2003.     }
  2004. }


  2005. ssize_t
  2006. ‌ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
  2007. {
  2008.     int  n, bytes;

  2009. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  2010.     if (c->ssl->in_early) {
  2011.         return ngx_ssl_recv_early(c, buf, size);
  2012.     }
  2013. #endif

  2014.     if (c->ssl->last == NGX_ERROR) {
  2015.         c->read->ready = 0;
  2016.         c->read->error = 1;
  2017.         return NGX_ERROR;
  2018.     }

  2019.     if (c->ssl->last == NGX_DONE) {
  2020.         c->read->ready = 0;
  2021.         c->read->eof = 1;
  2022.         return 0;
  2023.     }

  2024.     bytes = 0;

  2025.     ngx_ssl_clear_error(c->log);

  2026.     /*
  2027.      * SSL_read() may return data in parts, so try to read
  2028.      * until SSL_read() would return no data
  2029.      */

  2030.     for ( ;; ) {

  2031.         n = SSL_read(c->ssl->connection, buf, size);

  2032.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);

  2033.         if (n > 0) {
  2034.             bytes += n;
  2035.         }

  2036.         c->ssl->last = ngx_ssl_handle_recv(c, n);

  2037.         if (c->ssl->last == NGX_OK) {

  2038.             size -= n;

  2039.             if (size == 0) {
  2040.                 c->read->ready = 1;

  2041.                 if (c->read->available >= 0) {
  2042.                     c->read->available -= bytes;

  2043.                     /*
  2044.                      * there can be data buffered at SSL layer,
  2045.                      * so we post an event to continue reading on the next
  2046.                      * iteration of the event loop
  2047.                      */

  2048.                     if (c->read->available < 0) {
  2049.                         c->read->available = 0;
  2050.                         c->read->ready = 0;

  2051.                         if (c->read->posted) {
  2052.                             ngx_delete_posted_event(c->read);
  2053.                         }

  2054.                         ngx_post_event(c->read, &ngx_posted_next_events);
  2055.                     }

  2056.                     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2057.                                    "SSL_read: avail:%d", c->read->available);

  2058.                 } else {

  2059. #if (NGX_HAVE_FIONREAD)

  2060.                     if (ngx_socket_nread(c->fd, &c->read->available) == -1) {
  2061.                         c->read->ready = 0;
  2062.                         c->read->error = 1;
  2063.                         ngx_connection_error(c, ngx_socket_errno,
  2064.                                              ngx_socket_nread_n " failed");
  2065.                         return NGX_ERROR;
  2066.                     }

  2067.                     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2068.                                    "SSL_read: avail:%d", c->read->available);

  2069. #endif
  2070.                 }

  2071.                 return bytes;
  2072.             }

  2073.             buf += n;

  2074.             continue;
  2075.         }

  2076.         if (bytes) {
  2077.             if (c->ssl->last != NGX_AGAIN) {
  2078.                 c->read->ready = 1;
  2079.             }

  2080.             return bytes;
  2081.         }

  2082.         switch (c->ssl->last) {

  2083.         case NGX_DONE:
  2084.             c->read->ready = 0;
  2085.             c->read->eof = 1;
  2086.             return 0;

  2087.         case NGX_ERROR:
  2088.             c->read->ready = 0;
  2089.             c->read->error = 1;

  2090.             /* fall through */

  2091.         case NGX_AGAIN:
  2092.             return c->ssl->last;
  2093.         }
  2094.     }
  2095. }


  2096. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  2097. static ssize_t
  2098. ‌ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size)
  2099. {
  2100.     int        n, bytes;
  2101.     size_t     readbytes;

  2102.     if (c->ssl->last == NGX_ERROR) {
  2103.         c->read->ready = 0;
  2104.         c->read->error = 1;
  2105.         return NGX_ERROR;
  2106.     }

  2107.     if (c->ssl->last == NGX_DONE) {
  2108.         c->read->ready = 0;
  2109.         c->read->eof = 1;
  2110.         return 0;
  2111.     }

  2112.     bytes = 0;

  2113.     ngx_ssl_clear_error(c->log);

  2114.     if (c->ssl->early_preread) {

  2115.         if (size == 0) {
  2116.             c->read->ready = 0;
  2117.             c->read->eof = 1;
  2118.             return 0;
  2119.         }

  2120.         *buf = c->ssl->early_buf;

  2121.         c->ssl->early_preread = 0;

  2122.         bytes = 1;
  2123.         size -= 1;
  2124.         buf += 1;
  2125.     }

  2126.     if (c->ssl->write_blocked) {
  2127.         return NGX_AGAIN;
  2128.     }

  2129.     /*
  2130.      * SSL_read_early_data() may return data in parts, so try to read
  2131.      * until SSL_read_early_data() would return no data
  2132.      */

  2133.     for ( ;; ) {

  2134.         readbytes = 0;

  2135.         n = SSL_read_early_data(c->ssl->connection, buf, size, &readbytes);

  2136.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2137.                        "SSL_read_early_data: %d, %uz", n, readbytes);

  2138.         if (n == SSL_READ_EARLY_DATA_SUCCESS) {

  2139.             c->ssl->last = ngx_ssl_handle_recv(c, 1);

  2140.             bytes += readbytes;
  2141.             size -= readbytes;

  2142.             if (size == 0) {
  2143.                 c->read->ready = 1;
  2144.                 return bytes;
  2145.             }

  2146.             buf += readbytes;

  2147.             continue;
  2148.         }

  2149.         if (n == SSL_READ_EARLY_DATA_FINISH) {

  2150.             c->ssl->last = ngx_ssl_handle_recv(c, 1);
  2151.             c->ssl->in_early = 0;

  2152.             if (bytes) {
  2153.                 c->read->ready = 1;
  2154.                 return bytes;
  2155.             }

  2156.             return ngx_ssl_recv(c, buf, size);
  2157.         }

  2158.         /* SSL_READ_EARLY_DATA_ERROR */

  2159.         c->ssl->last = ngx_ssl_handle_recv(c, 0);

  2160.         if (bytes) {
  2161.             if (c->ssl->last != NGX_AGAIN) {
  2162.                 c->read->ready = 1;
  2163.             }

  2164.             return bytes;
  2165.         }

  2166.         switch (c->ssl->last) {

  2167.         case NGX_DONE:
  2168.             c->read->ready = 0;
  2169.             c->read->eof = 1;
  2170.             return 0;

  2171.         case NGX_ERROR:
  2172.             c->read->ready = 0;
  2173.             c->read->error = 1;

  2174.             /* fall through */

  2175.         case NGX_AGAIN:
  2176.             return c->ssl->last;
  2177.         }
  2178.     }
  2179. }

  2180. #endif


  2181. static ngx_int_t
  2182. ‌ngx_ssl_handle_recv(ngx_connection_t *c, int n)
  2183. {
  2184.     int        sslerr;
  2185.     ngx_err_t  err;

  2186. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  2187.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

  2188.     if (c->ssl->renegotiation) {
  2189.         /*
  2190.          * disable renegotiation (CVE-2009-3555):
  2191.          * OpenSSL (at least up to 0.9.8l) does not handle disabled
  2192.          * renegotiation gracefully, so drop connection here
  2193.          */

  2194.         ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled");

  2195.         while (ERR_peek_error()) {
  2196.             ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0,
  2197.                           "ignoring stale global SSL error");
  2198.         }

  2199.         ERR_clear_error();

  2200.         c->ssl->no_wait_shutdown = 1;
  2201.         c->ssl->no_send_shutdown = 1;

  2202.         return NGX_ERROR;
  2203.     }

  2204. #endif

  2205.     if (n > 0) {

  2206.         if (c->ssl->saved_write_handler) {

  2207.             c->write->handler = c->ssl->saved_write_handler;
  2208.             c->ssl->saved_write_handler = NULL;
  2209.             c->write->ready = 1;

  2210.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2211.                 return NGX_ERROR;
  2212.             }

  2213.             ngx_post_event(c->write, &ngx_posted_events);
  2214.         }

  2215.         return NGX_OK;
  2216.     }

  2217.     sslerr = SSL_get_error(c->ssl->connection, n);

  2218.     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  2219.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

  2220.     if (sslerr == SSL_ERROR_WANT_READ) {

  2221.         if (c->ssl->saved_write_handler) {

  2222.             c->write->handler = c->ssl->saved_write_handler;
  2223.             c->ssl->saved_write_handler = NULL;
  2224.             c->write->ready = 1;

  2225.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2226.                 return NGX_ERROR;
  2227.             }

  2228.             ngx_post_event(c->write, &ngx_posted_events);
  2229.         }

  2230.         c->read->ready = 0;
  2231.         return NGX_AGAIN;
  2232.     }

  2233.     if (sslerr == SSL_ERROR_WANT_WRITE) {

  2234.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2235.                        "SSL_read: want write");

  2236.         c->write->ready = 0;

  2237.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2238.             return NGX_ERROR;
  2239.         }

  2240.         /*
  2241.          * we do not set the timer because there is already the read event timer
  2242.          */

  2243.         if (c->ssl->saved_write_handler == NULL) {
  2244.             c->ssl->saved_write_handler = c->write->handler;
  2245.             c->write->handler = ngx_ssl_write_handler;
  2246.         }

  2247.         return NGX_AGAIN;
  2248.     }

  2249.     if (sslerr == SSL_ERROR_SYSCALL && ERR_peek_error() == 0 && err == 0) {

  2250.         /*
  2251.          * OpenSSL up to 3.0 returns SSL_ERROR_SYSCALL
  2252.          * without an error queue and with errno set to 0
  2253.          * if connection is closed cleanly
  2254.          */

  2255.         sslerr = SSL_ERROR_ZERO_RETURN;
  2256.     }

  2257.     c->ssl->no_wait_shutdown = 1;
  2258.     c->ssl->no_send_shutdown = 1;

  2259.     if (sslerr == SSL_ERROR_ZERO_RETURN) {
  2260.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2261.                        "peer shutdown SSL cleanly");
  2262.         return NGX_DONE;
  2263.     }

  2264.     ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed");

  2265.     return NGX_ERROR;
  2266. }


  2267. static void
  2268. ‌ngx_ssl_write_handler(ngx_event_t *wev)
  2269. {
  2270.     ngx_connection_t  *c;

  2271.     c = wev->data;

  2272.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL write handler");

  2273.     c->read->handler(c->read);
  2274. }


  2275. /*
  2276. * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
  2277. * before the SSL_write() call to decrease a SSL overhead.
  2278. *
  2279. * Besides for protocols such as HTTP it is possible to always buffer
  2280. * the output to decrease a SSL overhead some more.
  2281. */

  2282. ngx_chain_t *
  2283. ‌ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
  2284. {
  2285.     int           n;
  2286.     ngx_uint_t    flush;
  2287.     ssize_t       send, size, file_size;
  2288.     ngx_buf_t    *buf;
  2289.     ngx_chain_t  *cl;

  2290.     if (!c->ssl->buffer) {

  2291.         while (in) {
  2292.             if (ngx_buf_special(in->buf)) {
  2293.                 in = in->next;
  2294.                 continue;
  2295.             }

  2296.             n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos);

  2297.             if (n == NGX_ERROR) {
  2298.                 return NGX_CHAIN_ERROR;
  2299.             }

  2300.             if (n == NGX_AGAIN) {
  2301.                 return in;
  2302.             }

  2303.             in->buf->pos += n;

  2304.             if (in->buf->pos == in->buf->last) {
  2305.                 in = in->next;
  2306.             }
  2307.         }

  2308.         return in;
  2309.     }


  2310.     /* the maximum limit size is the maximum int32_t value - the page size */

  2311.     if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) {
  2312.         limit = NGX_MAX_INT32_VALUE - ngx_pagesize;
  2313.     }

  2314.     buf = c->ssl->buf;

  2315.     if (buf == NULL) {
  2316.         buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size);
  2317.         if (buf == NULL) {
  2318.             return NGX_CHAIN_ERROR;
  2319.         }

  2320.         c->ssl->buf = buf;
  2321.     }

  2322.     if (buf->start == NULL) {
  2323.         buf->start = ngx_palloc(c->pool, c->ssl->buffer_size);
  2324.         if (buf->start == NULL) {
  2325.             return NGX_CHAIN_ERROR;
  2326.         }

  2327.         buf->pos = buf->start;
  2328.         buf->last = buf->start;
  2329.         buf->end = buf->start + c->ssl->buffer_size;
  2330.     }

  2331.     send = buf->last - buf->pos;
  2332.     flush = (in == NULL) ? 1 : buf->flush;

  2333.     for ( ;; ) {

  2334.         while (in && buf->last < buf->end && send < limit) {
  2335.             if (in->buf->last_buf || in->buf->flush) {
  2336.                 flush = 1;
  2337.             }

  2338.             if (ngx_buf_special(in->buf)) {
  2339.                 in = in->next;
  2340.                 continue;
  2341.             }

  2342.             if (in->buf->in_file && c->ssl->sendfile) {
  2343.                 flush = 1;
  2344.                 break;
  2345.             }

  2346.             size = in->buf->last - in->buf->pos;

  2347.             if (size > buf->end - buf->last) {
  2348.                 size = buf->end - buf->last;
  2349.             }

  2350.             if (send + size > limit) {
  2351.                 size = (ssize_t) (limit - send);
  2352.             }

  2353.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2354.                            "SSL buf copy: %z", size);

  2355.             ngx_memcpy(buf->last, in->buf->pos, size);

  2356.             buf->last += size;
  2357.             in->buf->pos += size;
  2358.             send += size;

  2359.             if (in->buf->pos == in->buf->last) {
  2360.                 in = in->next;
  2361.             }
  2362.         }

  2363.         if (!flush && send < limit && buf->last < buf->end) {
  2364.             break;
  2365.         }

  2366.         size = buf->last - buf->pos;

  2367.         if (size == 0) {

  2368.             if (in && in->buf->in_file && send < limit) {

  2369.                 /* coalesce the neighbouring file bufs */

  2370.                 cl = in;
  2371.                 file_size = (size_t) ngx_chain_coalesce_file(&cl, limit - send);

  2372.                 n = ngx_ssl_sendfile(c, in->buf, file_size);

  2373.                 if (n == NGX_ERROR) {
  2374.                     return NGX_CHAIN_ERROR;
  2375.                 }

  2376.                 if (n == NGX_AGAIN) {
  2377.                     break;
  2378.                 }

  2379.                 in = ngx_chain_update_sent(in, n);

  2380.                 send += n;
  2381.                 flush = 0;

  2382.                 continue;
  2383.             }

  2384.             buf->flush = 0;
  2385.             c->buffered &= ~NGX_SSL_BUFFERED;

  2386.             return in;
  2387.         }

  2388.         n = ngx_ssl_write(c, buf->pos, size);

  2389.         if (n == NGX_ERROR) {
  2390.             return NGX_CHAIN_ERROR;
  2391.         }

  2392.         if (n == NGX_AGAIN) {
  2393.             break;
  2394.         }

  2395.         buf->pos += n;

  2396.         if (n < size) {
  2397.             break;
  2398.         }

  2399.         flush = 0;

  2400.         buf->pos = buf->start;
  2401.         buf->last = buf->start;

  2402.         if (in == NULL || send >= limit) {
  2403.             break;
  2404.         }
  2405.     }

  2406.     buf->flush = flush;

  2407.     if (buf->pos < buf->last) {
  2408.         c->buffered |= NGX_SSL_BUFFERED;

  2409.     } else {
  2410.         c->buffered &= ~NGX_SSL_BUFFERED;
  2411.     }

  2412.     return in;
  2413. }


  2414. ssize_t
  2415. ‌ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
  2416. {
  2417.     int        n, sslerr;
  2418.     ngx_err_t  err;

  2419.     if (c->ssl->last == NGX_ERROR) {
  2420.         c->write->ready = 0;
  2421.         c->write->error = 1;
  2422.         return NGX_ERROR;
  2423.     }

  2424. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  2425.     if (c->ssl->in_early) {
  2426.         return ngx_ssl_write_early(c, data, size);
  2427.     }
  2428. #endif

  2429.     ngx_ssl_clear_error(c->log);

  2430.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size);

  2431.     n = SSL_write(c->ssl->connection, data, size);

  2432.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);

  2433.     if (n > 0) {

  2434.         if (c->ssl->saved_read_handler) {

  2435.             c->read->handler = c->ssl->saved_read_handler;
  2436.             c->ssl->saved_read_handler = NULL;
  2437.             c->read->ready = 1;

  2438.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2439.                 return NGX_ERROR;
  2440.             }

  2441.             ngx_post_event(c->read, &ngx_posted_events);
  2442.         }

  2443.         c->sent += n;

  2444.         return n;
  2445.     }

  2446.     sslerr = SSL_get_error(c->ssl->connection, n);

  2447.     if (sslerr == SSL_ERROR_ZERO_RETURN) {

  2448.         /*
  2449.          * OpenSSL 1.1.1 fails to return SSL_ERROR_SYSCALL if an error
  2450.          * happens during SSL_write() after close_notify alert from the
  2451.          * peer, and returns SSL_ERROR_ZERO_RETURN instead,
  2452.          * see https://github.com/openssl/openssl/commit/8051ab2
  2453.          */

  2454.         sslerr = SSL_ERROR_SYSCALL;
  2455.     }

  2456.     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  2457.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

  2458.     if (sslerr == SSL_ERROR_WANT_WRITE) {

  2459.         if (c->ssl->saved_read_handler) {

  2460.             c->read->handler = c->ssl->saved_read_handler;
  2461.             c->ssl->saved_read_handler = NULL;
  2462.             c->read->ready = 1;

  2463.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2464.                 return NGX_ERROR;
  2465.             }

  2466.             ngx_post_event(c->read, &ngx_posted_events);
  2467.         }

  2468.         c->write->ready = 0;
  2469.         return NGX_AGAIN;
  2470.     }

  2471.     if (sslerr == SSL_ERROR_WANT_READ) {

  2472.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2473.                        "SSL_write: want read");

  2474.         c->read->ready = 0;

  2475.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2476.             return NGX_ERROR;
  2477.         }

  2478.         /*
  2479.          * we do not set the timer because there is already
  2480.          * the write event timer
  2481.          */

  2482.         if (c->ssl->saved_read_handler == NULL) {
  2483.             c->ssl->saved_read_handler = c->read->handler;
  2484.             c->read->handler = ngx_ssl_read_handler;
  2485.         }

  2486.         return NGX_AGAIN;
  2487.     }

  2488.     c->ssl->no_wait_shutdown = 1;
  2489.     c->ssl->no_send_shutdown = 1;
  2490.     c->write->error = 1;

  2491.     ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed");

  2492.     return NGX_ERROR;
  2493. }


  2494. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  2495. static ssize_t
  2496. ‌ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size)
  2497. {
  2498.     int        n, sslerr;
  2499.     size_t     written;
  2500.     ngx_err_t  err;

  2501.     ngx_ssl_clear_error(c->log);

  2502.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size);

  2503.     written = 0;

  2504.     n = SSL_write_early_data(c->ssl->connection, data, size, &written);

  2505.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2506.                    "SSL_write_early_data: %d, %uz", n, written);

  2507.     if (n > 0) {

  2508.         if (c->ssl->saved_read_handler) {

  2509.             c->read->handler = c->ssl->saved_read_handler;
  2510.             c->ssl->saved_read_handler = NULL;
  2511.             c->read->ready = 1;

  2512.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2513.                 return NGX_ERROR;
  2514.             }

  2515.             ngx_post_event(c->read, &ngx_posted_events);
  2516.         }

  2517.         if (c->ssl->write_blocked) {
  2518.             c->ssl->write_blocked = 0;
  2519.             ngx_post_event(c->read, &ngx_posted_events);
  2520.         }

  2521.         c->sent += written;

  2522.         return written;
  2523.     }

  2524.     sslerr = SSL_get_error(c->ssl->connection, n);

  2525.     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  2526.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

  2527.     if (sslerr == SSL_ERROR_WANT_WRITE) {

  2528.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2529.                        "SSL_write_early_data: want write");

  2530.         if (c->ssl->saved_read_handler) {

  2531.             c->read->handler = c->ssl->saved_read_handler;
  2532.             c->ssl->saved_read_handler = NULL;
  2533.             c->read->ready = 1;

  2534.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2535.                 return NGX_ERROR;
  2536.             }

  2537.             ngx_post_event(c->read, &ngx_posted_events);
  2538.         }

  2539.         /*
  2540.          * OpenSSL 1.1.1a fails to handle SSL_read_early_data()
  2541.          * if an SSL_write_early_data() call blocked on writing,
  2542.          * see https://github.com/openssl/openssl/issues/7757
  2543.          */

  2544.         c->ssl->write_blocked = 1;

  2545.         c->write->ready = 0;
  2546.         return NGX_AGAIN;
  2547.     }

  2548.     if (sslerr == SSL_ERROR_WANT_READ) {

  2549.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2550.                        "SSL_write_early_data: want read");

  2551.         c->read->ready = 0;

  2552.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2553.             return NGX_ERROR;
  2554.         }

  2555.         /*
  2556.          * we do not set the timer because there is already
  2557.          * the write event timer
  2558.          */

  2559.         if (c->ssl->saved_read_handler == NULL) {
  2560.             c->ssl->saved_read_handler = c->read->handler;
  2561.             c->read->handler = ngx_ssl_read_handler;
  2562.         }

  2563.         return NGX_AGAIN;
  2564.     }

  2565.     c->ssl->no_wait_shutdown = 1;
  2566.     c->ssl->no_send_shutdown = 1;
  2567.     c->write->error = 1;

  2568.     ngx_ssl_connection_error(c, sslerr, err, "SSL_write_early_data() failed");

  2569.     return NGX_ERROR;
  2570. }

  2571. #endif


  2572. static ssize_t
  2573. ‌ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
  2574. {
  2575. #if (defined BIO_get_ktls_send && !NGX_WIN32)

  2576.     int        sslerr, flags;
  2577.     ssize_t    n;
  2578.     ngx_err_t  err;

  2579.     if (c->ssl->last == NGX_ERROR) {
  2580.         c->write->ready = 0;
  2581.         c->write->error = 1;
  2582.         return NGX_ERROR;
  2583.     }

  2584.     ngx_ssl_clear_error(c->log);

  2585.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2586.                    "SSL to sendfile: @%O %uz",
  2587.                    file->file_pos, size);

  2588.     ngx_set_errno(0);

  2589. #if (NGX_HAVE_SENDFILE_NODISKIO)

  2590.     flags = (c->busy_count <= 2) ? SF_NODISKIO : 0;

  2591.     if (file->file->directio) {
  2592.         flags |= SF_NOCACHE;
  2593.     }

  2594. #else
  2595.     flags = 0;
  2596. #endif

  2597.     n = SSL_sendfile(c->ssl->connection, file->file->fd, file->file_pos,
  2598.                      size, flags);

  2599.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_sendfile: %z", n);

  2600.     if (n > 0) {

  2601.         if (c->ssl->saved_read_handler) {

  2602.             c->read->handler = c->ssl->saved_read_handler;
  2603.             c->ssl->saved_read_handler = NULL;
  2604.             c->read->ready = 1;

  2605.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2606.                 return NGX_ERROR;
  2607.             }

  2608.             ngx_post_event(c->read, &ngx_posted_events);
  2609.         }

  2610. #if (NGX_HAVE_SENDFILE_NODISKIO)
  2611.         c->busy_count = 0;
  2612. #endif

  2613.         c->sent += n;

  2614.         return n;
  2615.     }

  2616.     if (n == 0) {

  2617.         /*
  2618.          * if sendfile returns zero, then someone has truncated the file,
  2619.          * so the offset became beyond the end of the file
  2620.          */

  2621.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2622.                       "SSL_sendfile() reported that \"%s\" was truncated at %O",
  2623.                       file->file->name.data, file->file_pos);

  2624.         return NGX_ERROR;
  2625.     }

  2626.     sslerr = SSL_get_error(c->ssl->connection, n);

  2627.     if (sslerr == SSL_ERROR_ZERO_RETURN) {

  2628.         /*
  2629.          * OpenSSL fails to return SSL_ERROR_SYSCALL if an error
  2630.          * happens during writing after close_notify alert from the
  2631.          * peer, and returns SSL_ERROR_ZERO_RETURN instead
  2632.          */

  2633.         sslerr = SSL_ERROR_SYSCALL;
  2634.     }

  2635.     if (sslerr == SSL_ERROR_SSL
  2636.         && ERR_GET_REASON(ERR_peek_error()) == SSL_R_UNINITIALIZED
  2637.         && ngx_errno != 0)
  2638.     {
  2639.         /*
  2640.          * OpenSSL fails to return SSL_ERROR_SYSCALL if an error
  2641.          * happens in sendfile(), and returns SSL_ERROR_SSL with
  2642.          * SSL_R_UNINITIALIZED reason instead
  2643.          */

  2644.         sslerr = SSL_ERROR_SYSCALL;
  2645.     }

  2646.     err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  2647.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);

  2648.     if (sslerr == SSL_ERROR_WANT_WRITE) {

  2649.         if (c->ssl->saved_read_handler) {

  2650.             c->read->handler = c->ssl->saved_read_handler;
  2651.             c->ssl->saved_read_handler = NULL;
  2652.             c->read->ready = 1;

  2653.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2654.                 return NGX_ERROR;
  2655.             }

  2656.             ngx_post_event(c->read, &ngx_posted_events);
  2657.         }

  2658. #if (NGX_HAVE_SENDFILE_NODISKIO)

  2659.         if (ngx_errno == EBUSY) {
  2660.             c->busy_count++;

  2661.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2662.                            "SSL_sendfile() busy, count:%d", c->busy_count);

  2663.             if (c->write->posted) {
  2664.                 ngx_delete_posted_event(c->write);
  2665.             }

  2666.             ngx_post_event(c->write, &ngx_posted_next_events);
  2667.         }

  2668. #endif

  2669.         c->write->ready = 0;
  2670.         return NGX_AGAIN;
  2671.     }

  2672.     if (sslerr == SSL_ERROR_WANT_READ) {

  2673.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2674.                        "SSL_sendfile: want read");

  2675.         c->read->ready = 0;

  2676.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2677.             return NGX_ERROR;
  2678.         }

  2679.         /*
  2680.          * we do not set the timer because there is already
  2681.          * the write event timer
  2682.          */

  2683.         if (c->ssl->saved_read_handler == NULL) {
  2684.             c->ssl->saved_read_handler = c->read->handler;
  2685.             c->read->handler = ngx_ssl_read_handler;
  2686.         }

  2687.         return NGX_AGAIN;
  2688.     }

  2689.     c->ssl->no_wait_shutdown = 1;
  2690.     c->ssl->no_send_shutdown = 1;
  2691.     c->write->error = 1;

  2692.     ngx_ssl_connection_error(c, sslerr, err, "SSL_sendfile() failed");

  2693. #else
  2694.     ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2695.                   "SSL_sendfile() not available");
  2696. #endif

  2697.     return NGX_ERROR;
  2698. }


  2699. static void
  2700. ‌ngx_ssl_read_handler(ngx_event_t *rev)
  2701. {
  2702.     ngx_connection_t  *c;

  2703.     c = rev->data;

  2704.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL read handler");

  2705.     c->write->handler(c->write);
  2706. }


  2707. void
  2708. ‌ngx_ssl_free_buffer(ngx_connection_t *c)
  2709. {
  2710.     if (c->ssl->buf && c->ssl->buf->start) {
  2711.         if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
  2712.             c->ssl->buf->start = NULL;
  2713.         }
  2714.     }
  2715. }


  2716. ngx_int_t
  2717. ‌ngx_ssl_shutdown(ngx_connection_t *c)
  2718. {
  2719.     int         n, sslerr, mode;
  2720.     ngx_int_t   rc;
  2721.     ngx_err_t   err;
  2722.     ngx_uint_t  tries;

  2723. #if (NGX_QUIC)
  2724.     if (c->quic) {
  2725.         /* QUIC streams inherit SSL object */
  2726.         return NGX_OK;
  2727.     }
  2728. #endif

  2729.     rc = NGX_OK;

  2730.     ngx_ssl_ocsp_cleanup(c);

  2731.     if (SSL_in_init(c->ssl->connection)) {
  2732.         /*
  2733.          * OpenSSL 1.0.2f complains if SSL_shutdown() is called during
  2734.          * an SSL handshake, while previous versions always return 0.
  2735.          * Avoid calling SSL_shutdown() if handshake wasn't completed.
  2736.          */

  2737.         goto done;
  2738.     }

  2739.     if (c->timedout || c->error || c->buffered) {
  2740.         mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
  2741.         SSL_set_quiet_shutdown(c->ssl->connection, 1);

  2742.     } else {
  2743.         mode = SSL_get_shutdown(c->ssl->connection);

  2744.         if (c->ssl->no_wait_shutdown) {
  2745.             mode |= SSL_RECEIVED_SHUTDOWN;
  2746.         }

  2747.         if (c->ssl->no_send_shutdown) {
  2748.             mode |= SSL_SENT_SHUTDOWN;
  2749.         }

  2750.         if (c->ssl->no_wait_shutdown && c->ssl->no_send_shutdown) {
  2751.             SSL_set_quiet_shutdown(c->ssl->connection, 1);
  2752.         }
  2753.     }

  2754.     SSL_set_shutdown(c->ssl->connection, mode);

  2755.     ngx_ssl_clear_error(c->log);

  2756.     tries = 2;

  2757.     for ( ;; ) {

  2758.         /*
  2759.          * For bidirectional shutdown, SSL_shutdown() needs to be called
  2760.          * twice: first call sends the "close notify" alert and returns 0,
  2761.          * second call waits for the peer's "close notify" alert.
  2762.          */

  2763.         n = SSL_shutdown(c->ssl->connection);

  2764.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);

  2765.         if (n == 1) {
  2766.             goto done;
  2767.         }

  2768.         if (n == 0 && tries-- > 1) {
  2769.             continue;
  2770.         }

  2771.         /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */

  2772.         sslerr = SSL_get_error(c->ssl->connection, n);

  2773.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2774.                        "SSL_get_error: %d", sslerr);

  2775.         if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
  2776.             c->read->handler = ngx_ssl_shutdown_handler;
  2777.             c->write->handler = ngx_ssl_shutdown_handler;

  2778.             if (sslerr == SSL_ERROR_WANT_READ) {
  2779.                 c->read->ready = 0;

  2780.             } else {
  2781.                 c->write->ready = 0;
  2782.             }

  2783.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2784.                 goto failed;
  2785.             }

  2786.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2787.                 goto failed;
  2788.             }

  2789.             ngx_add_timer(c->read, 3000);

  2790.             return NGX_AGAIN;
  2791.         }

  2792.         err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;

  2793.         if (sslerr == SSL_ERROR_SYSCALL && ERR_peek_error() == 0 && err == 0) {

  2794.             /*
  2795.              * OpenSSL up to 3.0 returns SSL_ERROR_SYSCALL
  2796.              * without an error queue and with errno set to 0
  2797.              * if connection is closed cleanly
  2798.              */

  2799.             sslerr = SSL_ERROR_ZERO_RETURN;
  2800.         }

  2801.         if (sslerr == SSL_ERROR_ZERO_RETURN) {
  2802.             goto done;
  2803.         }

  2804.         ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");

  2805.         break;
  2806.     }

  2807. failed:

  2808.     rc = NGX_ERROR;

  2809. done:

  2810. #if (defined BIO_get_ktls_recv && NGX_LINUX)

  2811.     /*
  2812.      * with kernel TLS, recv() fails with EIO on a record
  2813.      * other than application data, such as "close notify"
  2814.      */

  2815.     if (BIO_get_ktls_recv(SSL_get_rbio(c->ssl->connection)) == 1) {
  2816.         c->ktls_recv = 1;
  2817.     }

  2818. #endif

  2819.     if (c->ssl->shutdown_without_free) {
  2820.         c->ssl->shutdown_without_free = 0;
  2821.         c->recv = ngx_recv;
  2822.         return rc;
  2823.     }

  2824.     SSL_free(c->ssl->connection);
  2825.     c->ssl = NULL;
  2826.     c->recv = ngx_recv;

  2827.     return rc;
  2828. }


  2829. static void
  2830. ‌ngx_ssl_shutdown_handler(ngx_event_t *ev)
  2831. {
  2832.     ngx_connection_t           *c;
  2833.     ngx_connection_handler_pt   handler;

  2834.     c = ev->data;
  2835.     handler = c->ssl->handler;

  2836.     if (ev->timedout) {
  2837.         c->timedout = 1;
  2838.     }

  2839.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "SSL shutdown handler");

  2840.     if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2841.         return;
  2842.     }

  2843.     handler(c);
  2844. }


  2845. void
  2846. ‌ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
  2847.     char *text)
  2848. {
  2849.     int         n;
  2850.     ngx_uint_t  level;

  2851.     level = NGX_LOG_CRIT;

  2852.     if (sslerr == SSL_ERROR_SYSCALL) {

  2853.         if (err == NGX_ECONNRESET
  2854. #if (NGX_WIN32)
  2855.             || err == NGX_ECONNABORTED
  2856. #endif
  2857.             || err == NGX_EPIPE
  2858.             || err == NGX_ENOTCONN
  2859.             || err == NGX_ETIMEDOUT
  2860.             || err == NGX_ECONNREFUSED
  2861.             || err == NGX_ENETDOWN
  2862.             || err == NGX_ENETUNREACH
  2863.             || err == NGX_EHOSTDOWN
  2864.             || err == NGX_EHOSTUNREACH)
  2865.         {
  2866.             switch (c->log_error) {

  2867.             case NGX_ERROR_IGNORE_ECONNRESET:
  2868.             case NGX_ERROR_INFO:
  2869.                 level = NGX_LOG_INFO;
  2870.                 break;

  2871.             case NGX_ERROR_ERR:
  2872.                 level = NGX_LOG_ERR;
  2873.                 break;

  2874.             default:
  2875.                 break;
  2876.             }
  2877.         }

  2878.     } else if (sslerr == SSL_ERROR_SSL) {

  2879.         n = ERR_GET_REASON(ERR_peek_last_error());

  2880.             /* handshake failures */
  2881.         if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC                        /*  103 */
  2882. #ifdef SSL_R_NO_SUITABLE_KEY_SHARE
  2883.             || n == SSL_R_NO_SUITABLE_KEY_SHARE                      /*  101 */
  2884. #endif
  2885. #ifdef SSL_R_BAD_ALERT
  2886.             || n == SSL_R_BAD_ALERT                                  /*  102 */
  2887. #endif
  2888. #ifdef SSL_R_BAD_KEY_SHARE
  2889.             || n == SSL_R_BAD_KEY_SHARE                              /*  108 */
  2890. #endif
  2891. #ifdef SSL_R_BAD_EXTENSION
  2892.             || n == SSL_R_BAD_EXTENSION                              /*  110 */
  2893. #endif
  2894.             || n == SSL_R_BAD_DIGEST_LENGTH                          /*  111 */
  2895. #ifdef SSL_R_MISSING_SIGALGS_EXTENSION
  2896.             || n == SSL_R_MISSING_SIGALGS_EXTENSION                  /*  112 */
  2897. #endif
  2898.             || n == SSL_R_BAD_PACKET_LENGTH                          /*  115 */
  2899. #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM
  2900.             || n == SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM            /*  118 */
  2901. #endif
  2902. #ifdef SSL_R_BAD_KEY_UPDATE
  2903.             || n == SSL_R_BAD_KEY_UPDATE                             /*  122 */
  2904. #endif
  2905.             || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */
  2906.             || n == SSL_R_CCS_RECEIVED_EARLY                         /*  133 */
  2907. #ifdef SSL_R_DECODE_ERROR
  2908.             || n == SSL_R_DECODE_ERROR                               /*  137 */
  2909. #endif
  2910. #ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED
  2911.             || n == SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              /*  145 */
  2912. #endif
  2913.             || n == SSL_R_DATA_LENGTH_TOO_LONG                       /*  146 */
  2914.             || n == SSL_R_DIGEST_CHECK_FAILED                        /*  149 */
  2915.             || n == SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  /*  150 */
  2916.             || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              /*  151 */
  2917.             || n == SSL_R_EXCESSIVE_MESSAGE_SIZE                     /*  152 */
  2918. #ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS
  2919.             || n == SSL_R_GOT_A_FIN_BEFORE_A_CCS                     /*  154 */
  2920. #endif
  2921.             || n == SSL_R_HTTPS_PROXY_REQUEST                        /*  155 */
  2922.             || n == SSL_R_HTTP_REQUEST                               /*  156 */
  2923.             || n == SSL_R_LENGTH_MISMATCH                            /*  159 */
  2924. #ifdef SSL_R_LENGTH_TOO_SHORT
  2925.             || n == SSL_R_LENGTH_TOO_SHORT                           /*  160 */
  2926. #endif
  2927. #ifdef SSL_R_NO_RENEGOTIATION
  2928.             || n == SSL_R_NO_RENEGOTIATION                           /*  182 */
  2929. #endif
  2930. #ifdef SSL_R_NO_CIPHERS_PASSED
  2931.             || n == SSL_R_NO_CIPHERS_PASSED                          /*  182 */
  2932. #endif
  2933.             || n == SSL_R_NO_CIPHERS_SPECIFIED                       /*  183 */
  2934. #ifdef SSL_R_BAD_CIPHER
  2935.             || n == SSL_R_BAD_CIPHER                                 /*  186 */
  2936. #endif
  2937.             || n == SSL_R_NO_COMPRESSION_SPECIFIED                   /*  187 */
  2938.             || n == SSL_R_NO_SHARED_CIPHER                           /*  193 */
  2939. #ifdef SSL_R_PACKET_LENGTH_TOO_LONG
  2940.             || n == SSL_R_PACKET_LENGTH_TOO_LONG                     /*  198 */
  2941. #endif
  2942. #ifdef SSL_R_INVALID_ALERT
  2943.             || n == SSL_R_INVALID_ALERT                              /*  205 */
  2944. #endif
  2945.             || n == SSL_R_RECORD_LENGTH_MISMATCH                     /*  213 */
  2946. #ifdef SSL_R_TOO_MANY_WARNING_ALERTS
  2947.             || n == SSL_R_TOO_MANY_WARNING_ALERTS                    /*  220 */
  2948. #endif
  2949. #ifdef SSL_R_CLIENTHELLO_TLSEXT
  2950.             || n == SSL_R_CLIENTHELLO_TLSEXT                         /*  226 */
  2951. #endif
  2952. #ifdef SSL_R_PARSE_TLSEXT
  2953.             || n == SSL_R_PARSE_TLSEXT                               /*  227 */
  2954. #endif
  2955. #ifdef SSL_R_CALLBACK_FAILED
  2956.             || n == SSL_R_CALLBACK_FAILED                            /*  234 */
  2957. #endif
  2958. #ifdef SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
  2959.             || n == SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    /*  234 */
  2960. #endif
  2961. #ifdef SSL_R_NO_APPLICATION_PROTOCOL
  2962.             || n == SSL_R_NO_APPLICATION_PROTOCOL                    /*  235 */
  2963. #endif
  2964.             || n == SSL_R_UNEXPECTED_MESSAGE                         /*  244 */
  2965.             || n == SSL_R_UNEXPECTED_RECORD                          /*  245 */
  2966.             || n == SSL_R_UNKNOWN_ALERT_TYPE                         /*  246 */
  2967.             || n == SSL_R_UNKNOWN_PROTOCOL                           /*  252 */
  2968. #ifdef SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS
  2969.             || n == SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS             /*  253 */
  2970. #endif
  2971. #ifdef SSL_R_INVALID_COMPRESSION_LIST
  2972.             || n == SSL_R_INVALID_COMPRESSION_LIST                   /*  256 */
  2973. #endif
  2974. #ifdef SSL_R_MISSING_KEY_SHARE
  2975.             || n == SSL_R_MISSING_KEY_SHARE                          /*  258 */
  2976. #endif
  2977.             || n == SSL_R_UNSUPPORTED_PROTOCOL                       /*  258 */
  2978. #ifdef SSL_R_NO_SHARED_GROUP
  2979.             || n == SSL_R_NO_SHARED_GROUP                            /*  266 */
  2980. #endif
  2981.             || n == SSL_R_WRONG_VERSION_NUMBER                       /*  267 */
  2982. #ifdef SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA
  2983.             || n == SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA                /*  270 */
  2984. #endif
  2985.             || n == SSL_R_BAD_LENGTH                                 /*  271 */
  2986.             || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        /*  281 */
  2987. #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY
  2988.             || n == SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY        /*  291 */
  2989. #endif
  2990. #ifdef SSL_R_APPLICATION_DATA_ON_SHUTDOWN
  2991.             || n == SSL_R_APPLICATION_DATA_ON_SHUTDOWN               /*  291 */
  2992. #endif
  2993. #ifdef SSL_R_BAD_LEGACY_VERSION
  2994.             || n == SSL_R_BAD_LEGACY_VERSION                         /*  292 */
  2995. #endif
  2996. #ifdef SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA
  2997.             || n == SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA     /*  293 */
  2998. #endif
  2999. #ifdef SSL_R_RECORD_TOO_SMALL
  3000.             || n == SSL_R_RECORD_TOO_SMALL                           /*  298 */
  3001. #endif
  3002. #ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG
  3003.             || n == SSL_R_SSL3_SESSION_ID_TOO_LONG                   /*  300 */
  3004. #elif (defined SSL_R_TLS_SESSION_ID_TOO_LONG)
  3005.             || n == SSL_R_TLS_SESSION_ID_TOO_LONG                    /*  300 */
  3006. #endif
  3007. #ifdef SSL_R_BAD_ECPOINT
  3008.             || n == SSL_R_BAD_ECPOINT                                /*  306 */
  3009. #endif
  3010. #ifdef SSL_R_RECORD_LAYER_FAILURE
  3011.             || n == SSL_R_RECORD_LAYER_FAILURE                       /*  313 */
  3012. #endif
  3013. #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
  3014.             || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG                   /*  335 */
  3015.             || n == SSL_R_RENEGOTIATION_ENCODING_ERR                 /*  336 */
  3016.             || n == SSL_R_RENEGOTIATION_MISMATCH                     /*  337 */
  3017. #endif
  3018. #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
  3019.             || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       /*  338 */
  3020. #endif
  3021. #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
  3022.             || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           /*  345 */
  3023. #endif
  3024. #ifdef SSL_R_INAPPROPRIATE_FALLBACK
  3025.             || n == SSL_R_INAPPROPRIATE_FALLBACK                     /*  373 */
  3026. #endif
  3027. #ifdef SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS
  3028.             || n == SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS             /*  376 */
  3029. #endif
  3030. #ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS
  3031.             || n == SSL_R_NO_SHARED_SIGATURE_ALGORITHMS              /*  376 */
  3032. #endif
  3033. #ifdef SSL_R_CERT_CB_ERROR
  3034.             || n == SSL_R_CERT_CB_ERROR                              /*  377 */
  3035. #endif
  3036. #ifdef SSL_R_VERSION_TOO_LOW
  3037.             || n == SSL_R_VERSION_TOO_LOW                            /*  396 */
  3038. #endif
  3039. #ifdef SSL_R_TOO_MANY_WARN_ALERTS
  3040.             || n == SSL_R_TOO_MANY_WARN_ALERTS                       /*  409 */
  3041. #endif
  3042. #ifdef SSL_R_BAD_RECORD_TYPE
  3043.             || n == SSL_R_BAD_RECORD_TYPE                            /*  443 */
  3044. #endif
  3045.             || (n >= SSL_AD_REASON_OFFSET                            /* 1000 */
  3046.                 && n <= SSL_AD_REASON_OFFSET + 255)
  3047.             )
  3048.         {
  3049.             switch (c->log_error) {

  3050.             case NGX_ERROR_IGNORE_ECONNRESET:
  3051.             case NGX_ERROR_INFO:
  3052.                 level = NGX_LOG_INFO;
  3053.                 break;

  3054.             case NGX_ERROR_ERR:
  3055.                 level = NGX_LOG_ERR;
  3056.                 break;

  3057.             default:
  3058.                 break;
  3059.             }
  3060.         }
  3061.     }

  3062.     ngx_ssl_error(level, c->log, err, text);
  3063. }


  3064. static void
  3065. ‌ngx_ssl_clear_error(ngx_log_t *log)
  3066. {
  3067.     while (ERR_peek_error()) {
  3068.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
  3069.     }

  3070.     ERR_clear_error();
  3071. }


  3072. void ngx_cdecl
  3073. ‌ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
  3074. {
  3075.     int          flags;
  3076.     u_long       n;
  3077.     va_list      args;
  3078.     u_char      *p, *last;
  3079.     u_char       errstr[NGX_MAX_CONF_ERRSTR];
  3080.     const char  *data;

  3081.     last = errstr + NGX_MAX_CONF_ERRSTR;

  3082.     va_start(args, fmt);
  3083.     p = ngx_vslprintf(errstr, last - 1, fmt, args);
  3084.     va_end(args);

  3085.     if (ERR_peek_error()) {
  3086.         p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);

  3087.         for ( ;; ) {

  3088.             n = ERR_peek_error_data(&data, &flags);

  3089.             if (n == 0) {
  3090.                 break;
  3091.             }

  3092.             /* ERR_error_string_n() requires at least one byte */

  3093.             if (p >= last - 1) {
  3094.                 goto next;
  3095.             }

  3096.             *p++ = ' ';

  3097.             ERR_error_string_n(n, (char *) p, last - p);

  3098.             while (p < last && *p) {
  3099.                 p++;
  3100.             }

  3101.             if (p < last && *data && (flags & ERR_TXT_STRING)) {
  3102.                 *p++ = ':';
  3103.                 p = ngx_cpystrn(p, (u_char *) data, last - p);
  3104.             }

  3105.         next:

  3106.             (void) ERR_get_error();
  3107.         }

  3108.         if (p < last) {
  3109.             *p++ = ')';
  3110.         }
  3111.     }

  3112.     ngx_log_error(level, log, err, "%*s", p - errstr, errstr);
  3113. }


  3114. ngx_int_t
  3115. ‌ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  3116.     ngx_array_t *certificates, ssize_t builtin_session_cache,
  3117.     ngx_shm_zone_t *shm_zone, time_t timeout)
  3118. {
  3119.     long  cache_mode;

  3120.     SSL_CTX_set_timeout(ssl->ctx, (long) timeout);

  3121.     if (ngx_ssl_session_id_context(ssl, sess_ctx, certificates) != NGX_OK) {
  3122.         return NGX_ERROR;
  3123.     }

  3124.     if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
  3125.         SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
  3126.         return NGX_OK;
  3127.     }

  3128.     if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {

  3129.         /*
  3130.          * If the server explicitly says that it does not support
  3131.          * session reuse (see SSL_SESS_CACHE_OFF above), then
  3132.          * Outlook Express fails to upload a sent email to
  3133.          * the Sent Items folder on the IMAP server via a separate IMAP
  3134.          * connection in the background.  Therefore we have a special
  3135.          * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
  3136.          * where the server pretends that it supports session reuse,
  3137.          * but it does not actually store any session.
  3138.          */

  3139.         SSL_CTX_set_session_cache_mode(ssl->ctx,
  3140.                                        SSL_SESS_CACHE_SERVER
  3141.                                        |SSL_SESS_CACHE_NO_AUTO_CLEAR
  3142.                                        |SSL_SESS_CACHE_NO_INTERNAL_STORE);

  3143.         SSL_CTX_sess_set_cache_size(ssl->ctx, 1);

  3144.         return NGX_OK;
  3145.     }

  3146.     cache_mode = SSL_SESS_CACHE_SERVER;

  3147.     if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
  3148.         cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
  3149.     }

  3150.     SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode);

  3151.     if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {

  3152.         if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
  3153.             SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
  3154.         }
  3155.     }

  3156.     if (shm_zone) {
  3157.         SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
  3158.         SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
  3159.         SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);

  3160.         if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone)
  3161.             == 0)
  3162.         {
  3163.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3164.                           "SSL_CTX_set_ex_data() failed");
  3165.             return NGX_ERROR;
  3166.         }
  3167.     }

  3168.     return NGX_OK;
  3169. }


  3170. static ngx_int_t
  3171. ‌ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  3172.     ngx_array_t *certificates)
  3173. {
  3174.     int                   n, i;
  3175.     X509                 *cert;
  3176.     X509_NAME            *name;
  3177.     ngx_str_t            *certs;
  3178.     ngx_uint_t            k;
  3179.     EVP_MD_CTX           *md;
  3180.     unsigned int          len;
  3181.     STACK_OF(X509_NAME)  *list;
  3182.     u_char                buf[EVP_MAX_MD_SIZE];

  3183.     /*
  3184.      * Session ID context is set based on the string provided,
  3185.      * the server certificates, and the client CA list.
  3186.      */

  3187.     md = EVP_MD_CTX_create();
  3188.     if (md == NULL) {
  3189.         return NGX_ERROR;
  3190.     }

  3191.     if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) {
  3192.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3193.                       "EVP_DigestInit_ex() failed");
  3194.         goto failed;
  3195.     }

  3196.     if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) {
  3197.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3198.                       "EVP_DigestUpdate() failed");
  3199.         goto failed;
  3200.     }

  3201.     for (k = 0; k < ssl->certs.nelts; k++) {
  3202.         cert = ((X509 **) ssl->certs.elts)[k];

  3203.         if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
  3204.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3205.                           "X509_digest() failed");
  3206.             goto failed;
  3207.         }

  3208.         if (EVP_DigestUpdate(md, buf, len) == 0) {
  3209.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3210.                           "EVP_DigestUpdate() failed");
  3211.             goto failed;
  3212.         }
  3213.     }

  3214.     if (ssl->certs.nelts == 0 && certificates != NULL) {
  3215.         /*
  3216.          * If certificates are loaded dynamically, we use certificate
  3217.          * names as specified in the configuration (with variables).
  3218.          */

  3219.         certs = certificates->elts;
  3220.         for (k = 0; k < certificates->nelts; k++) {

  3221.             if (EVP_DigestUpdate(md, certs[k].data, certs[k].len) == 0) {
  3222.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3223.                               "EVP_DigestUpdate() failed");
  3224.                 goto failed;
  3225.             }
  3226.         }
  3227.     }

  3228.     list = SSL_CTX_get_client_CA_list(ssl->ctx);

  3229.     if (list != NULL) {
  3230.         n = sk_X509_NAME_num(list);

  3231.         for (i = 0; i < n; i++) {
  3232.             name = sk_X509_NAME_value(list, i);

  3233.             if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
  3234.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3235.                               "X509_NAME_digest() failed");
  3236.                 goto failed;
  3237.             }

  3238.             if (EVP_DigestUpdate(md, buf, len) == 0) {
  3239.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3240.                               "EVP_DigestUpdate() failed");
  3241.                 goto failed;
  3242.             }
  3243.         }
  3244.     }

  3245.     if (EVP_DigestFinal_ex(md, buf, &len) == 0) {
  3246.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3247.                       "EVP_DigestFinal_ex() failed");
  3248.         goto failed;
  3249.     }

  3250.     EVP_MD_CTX_destroy(md);

  3251.     if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
  3252.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3253.                       "SSL_CTX_set_session_id_context() failed");
  3254.         return NGX_ERROR;
  3255.     }

  3256.     return NGX_OK;

  3257. failed:

  3258.     EVP_MD_CTX_destroy(md);

  3259.     return NGX_ERROR;
  3260. }


  3261. ngx_int_t
  3262. ‌ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  3263. {
  3264.     size_t                    len;
  3265.     ngx_slab_pool_t          *shpool;
  3266.     ngx_ssl_session_cache_t  *cache;

  3267.     if (data) {
  3268.         shm_zone->data = data;
  3269.         return NGX_OK;
  3270.     }

  3271.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3272.     if (shm_zone->shm.exists) {
  3273.         shm_zone->data = shpool->data;
  3274.         return NGX_OK;
  3275.     }

  3276.     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
  3277.     if (cache == NULL) {
  3278.         return NGX_ERROR;
  3279.     }

  3280.     shpool->data = cache;
  3281.     shm_zone->data = cache;

  3282.     ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
  3283.                     ngx_ssl_session_rbtree_insert_value);

  3284.     ngx_queue_init(&cache->expire_queue);

  3285.     cache->ticket_keys[0].expire = 0;
  3286.     cache->ticket_keys[1].expire = 0;
  3287.     cache->ticket_keys[2].expire = 0;

  3288.     cache->fail_time = 0;

  3289.     len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len;

  3290.     shpool->log_ctx = ngx_slab_alloc(shpool, len);
  3291.     if (shpool->log_ctx == NULL) {
  3292.         return NGX_ERROR;
  3293.     }

  3294.     ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z",
  3295.                 &shm_zone->shm.name);

  3296.     shpool->log_nomem = 0;

  3297.     return NGX_OK;
  3298. }


  3299. /*
  3300. * The length of the session id is 16 bytes for SSLv2 sessions and
  3301. * between 1 and 32 bytes for SSLv3 and TLS, typically 32 bytes.
  3302. * Typical length of the external ASN1 representation of a session
  3303. * is about 150 bytes plus SNI server name.
  3304. *
  3305. * On 32-bit platforms we allocate an rbtree node, a session id, and
  3306. * an ASN1 representation in a single allocation, it typically takes
  3307. * 256 bytes.
  3308. *
  3309. * On 64-bit platforms we allocate separately an rbtree node + session_id,
  3310. * and an ASN1 representation, they take accordingly 128 and 256 bytes.
  3311. *
  3312. * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
  3313. * so they are outside the code locked by shared pool mutex
  3314. */

  3315. static int
  3316. ‌ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
  3317. {
  3318.     int                       len;
  3319.     u_char                   *p, *session_id;
  3320.     size_t                    n;
  3321.     uint32_t                  hash;
  3322.     SSL_CTX                  *ssl_ctx;
  3323.     unsigned int              session_id_length;
  3324.     ngx_shm_zone_t           *shm_zone;
  3325.     ngx_connection_t         *c;
  3326.     ngx_slab_pool_t          *shpool;
  3327.     ngx_ssl_sess_id_t        *sess_id;
  3328.     ngx_ssl_session_cache_t  *cache;

  3329. #ifdef TLS1_3_VERSION

  3330.     /*
  3331.      * OpenSSL tries to save TLSv1.3 sessions into session cache
  3332.      * even when using tickets for stateless session resumption,
  3333.      * "because some applications just want to know about the creation
  3334.      * of a session"; do not cache such sessions
  3335.      */

  3336.     if (SSL_version(ssl_conn) == TLS1_3_VERSION
  3337.         && (SSL_get_options(ssl_conn) & SSL_OP_NO_TICKET) == 0)
  3338.     {
  3339.         return 0;
  3340.     }

  3341. #endif

  3342.     session_id = (u_char *) SSL_SESSION_get_id(sess, &session_id_length);

  3343.     /* do not cache sessions with too long session id */

  3344.     if (session_id_length > 32) {
  3345.         return 0;
  3346.     }

  3347.     len = i2d_SSL_SESSION(sess, NULL);

  3348.     /* do not cache too big session */

  3349.     if (len <= 0 || len > NGX_SSL_MAX_SESSION_SIZE) {
  3350.         return 0;
  3351.     }

  3352.     p = ngx_ssl_session_buffer;
  3353.     i2d_SSL_SESSION(sess, &p);

  3354.     c = ngx_ssl_get_connection(ssl_conn);

  3355.     ssl_ctx = c->ssl->session_ctx;
  3356.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3357.     cache = shm_zone->data;
  3358.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3359.     ngx_shmtx_lock(&shpool->mutex);

  3360.     /* drop one or two expired sessions */
  3361.     ngx_ssl_expire_sessions(cache, shpool, 1);

  3362. #if (NGX_PTR_SIZE == 8)
  3363.     n = sizeof(ngx_ssl_sess_id_t);
  3364. #else
  3365.     n = offsetof(ngx_ssl_sess_id_t, session) + len;
  3366. #endif

  3367.     sess_id = ngx_slab_alloc_locked(shpool, n);

  3368.     if (sess_id == NULL) {

  3369.         /* drop the oldest non-expired session and try once more */

  3370.         ngx_ssl_expire_sessions(cache, shpool, 0);

  3371.         sess_id = ngx_slab_alloc_locked(shpool, n);

  3372.         if (sess_id == NULL) {
  3373.             goto failed;
  3374.         }
  3375.     }

  3376. #if (NGX_PTR_SIZE == 8)

  3377.     sess_id->session = ngx_slab_alloc_locked(shpool, len);

  3378.     if (sess_id->session == NULL) {

  3379.         /* drop the oldest non-expired session and try once more */

  3380.         ngx_ssl_expire_sessions(cache, shpool, 0);

  3381.         sess_id->session = ngx_slab_alloc_locked(shpool, len);

  3382.         if (sess_id->session == NULL) {
  3383.             goto failed;
  3384.         }
  3385.     }

  3386. #endif

  3387.     ngx_memcpy(sess_id->session, ngx_ssl_session_buffer, len);
  3388.     ngx_memcpy(sess_id->id, session_id, session_id_length);

  3389.     hash = ngx_crc32_short(session_id, session_id_length);

  3390.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3391.                    "ssl new session: %08XD:%ud:%d",
  3392.                    hash, session_id_length, len);

  3393.     sess_id->node.key = hash;
  3394.     sess_id->node.data = (u_char) session_id_length;
  3395.     sess_id->len = len;

  3396.     sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx);

  3397.     ngx_queue_insert_head(&cache->expire_queue, &sess_id->queue);

  3398.     ngx_rbtree_insert(&cache->session_rbtree, &sess_id->node);

  3399.     ngx_shmtx_unlock(&shpool->mutex);

  3400.     ngx_explicit_memzero(ngx_ssl_session_buffer, len);

  3401.     return 0;

  3402. failed:

  3403.     if (sess_id) {
  3404.         ngx_slab_free_locked(shpool, sess_id);
  3405.     }

  3406.     ngx_shmtx_unlock(&shpool->mutex);

  3407.     ngx_explicit_memzero(ngx_ssl_session_buffer, len);

  3408.     if (cache->fail_time != ngx_time()) {
  3409.         cache->fail_time = ngx_time();
  3410.         ngx_log_error(NGX_LOG_WARN, c->log, 0,
  3411.                       "could not allocate new session%s", shpool->log_ctx);
  3412.     }

  3413.     return 0;
  3414. }


  3415. static ngx_ssl_session_t *
  3416. ‌ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
  3417. #if OPENSSL_VERSION_NUMBER >= 0x10100003L
  3418.     const
  3419. #endif
  3420.     u_char *id, int len, int *copy)
  3421. {
  3422.     size_t                    slen;
  3423.     uint32_t                  hash;
  3424.     ngx_int_t                 rc;
  3425.     const u_char             *p;
  3426.     ngx_shm_zone_t           *shm_zone;
  3427.     ngx_slab_pool_t          *shpool;
  3428.     ngx_connection_t         *c;
  3429.     ngx_rbtree_node_t        *node, *sentinel;
  3430.     ngx_ssl_session_t        *sess;
  3431.     ngx_ssl_sess_id_t        *sess_id;
  3432.     ngx_ssl_session_cache_t  *cache;

  3433.     hash = ngx_crc32_short((u_char *) (uintptr_t) id, (size_t) len);
  3434.     *copy = 0;

  3435.     c = ngx_ssl_get_connection(ssl_conn);

  3436.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3437.                    "ssl get session: %08XD:%d", hash, len);

  3438.     shm_zone = SSL_CTX_get_ex_data(c->ssl->session_ctx,
  3439.                                    ngx_ssl_session_cache_index);

  3440.     cache = shm_zone->data;

  3441.     sess = NULL;

  3442.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3443.     ngx_shmtx_lock(&shpool->mutex);

  3444.     node = cache->session_rbtree.root;
  3445.     sentinel = cache->session_rbtree.sentinel;

  3446.     while (node != sentinel) {

  3447.         if (hash < node->key) {
  3448.             node = node->left;
  3449.             continue;
  3450.         }

  3451.         if (hash > node->key) {
  3452.             node = node->right;
  3453.             continue;
  3454.         }

  3455.         /* hash == node->key */

  3456.         sess_id = (ngx_ssl_sess_id_t *) node;

  3457.         rc = ngx_memn2cmp((u_char *) (uintptr_t) id, sess_id->id,
  3458.                           (size_t) len, (size_t) node->data);

  3459.         if (rc == 0) {

  3460.             if (sess_id->expire > ngx_time()) {
  3461.                 slen = sess_id->len;

  3462.                 ngx_memcpy(ngx_ssl_session_buffer, sess_id->session, slen);

  3463.                 ngx_shmtx_unlock(&shpool->mutex);

  3464.                 p = ngx_ssl_session_buffer;
  3465.                 sess = d2i_SSL_SESSION(NULL, &p, slen);

  3466.                 ngx_explicit_memzero(ngx_ssl_session_buffer, slen);

  3467.                 return sess;
  3468.             }

  3469.             ngx_queue_remove(&sess_id->queue);

  3470.             ngx_rbtree_delete(&cache->session_rbtree, node);

  3471.             ngx_explicit_memzero(sess_id->session, sess_id->len);

  3472. #if (NGX_PTR_SIZE == 8)
  3473.             ngx_slab_free_locked(shpool, sess_id->session);
  3474. #endif
  3475.             ngx_slab_free_locked(shpool, sess_id);

  3476.             sess = NULL;

  3477.             goto done;
  3478.         }

  3479.         node = (rc < 0) ? node->left : node->right;
  3480.     }

  3481. done:

  3482.     ngx_shmtx_unlock(&shpool->mutex);

  3483.     return sess;
  3484. }


  3485. void
  3486. ‌ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3487. {
  3488.     SSL_CTX_remove_session(ssl, sess);

  3489.     ngx_ssl_remove_session(ssl, sess);
  3490. }


  3491. static void
  3492. ‌ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3493. {
  3494.     u_char                   *id;
  3495.     uint32_t                  hash;
  3496.     ngx_int_t                 rc;
  3497.     unsigned int              len;
  3498.     ngx_shm_zone_t           *shm_zone;
  3499.     ngx_slab_pool_t          *shpool;
  3500.     ngx_rbtree_node_t        *node, *sentinel;
  3501.     ngx_ssl_sess_id_t        *sess_id;
  3502.     ngx_ssl_session_cache_t  *cache;

  3503.     shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);

  3504.     if (shm_zone == NULL) {
  3505.         return;
  3506.     }

  3507.     cache = shm_zone->data;

  3508.     id = (u_char *) SSL_SESSION_get_id(sess, &len);

  3509.     hash = ngx_crc32_short(id, len);

  3510.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
  3511.                    "ssl remove session: %08XD:%ud", hash, len);

  3512.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3513.     ngx_shmtx_lock(&shpool->mutex);

  3514.     node = cache->session_rbtree.root;
  3515.     sentinel = cache->session_rbtree.sentinel;

  3516.     while (node != sentinel) {

  3517.         if (hash < node->key) {
  3518.             node = node->left;
  3519.             continue;
  3520.         }

  3521.         if (hash > node->key) {
  3522.             node = node->right;
  3523.             continue;
  3524.         }

  3525.         /* hash == node->key */

  3526.         sess_id = (ngx_ssl_sess_id_t *) node;

  3527.         rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);

  3528.         if (rc == 0) {

  3529.             ngx_queue_remove(&sess_id->queue);

  3530.             ngx_rbtree_delete(&cache->session_rbtree, node);

  3531.             ngx_explicit_memzero(sess_id->session, sess_id->len);

  3532. #if (NGX_PTR_SIZE == 8)
  3533.             ngx_slab_free_locked(shpool, sess_id->session);
  3534. #endif
  3535.             ngx_slab_free_locked(shpool, sess_id);

  3536.             goto done;
  3537.         }

  3538.         node = (rc < 0) ? node->left : node->right;
  3539.     }

  3540. done:

  3541.     ngx_shmtx_unlock(&shpool->mutex);
  3542. }


  3543. static void
  3544. ‌ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
  3545.     ngx_slab_pool_t *shpool, ngx_uint_t n)
  3546. {
  3547.     time_t              now;
  3548.     ngx_queue_t        *q;
  3549.     ngx_ssl_sess_id_t  *sess_id;

  3550.     now = ngx_time();

  3551.     while (n < 3) {

  3552.         if (ngx_queue_empty(&cache->expire_queue)) {
  3553.             return;
  3554.         }

  3555.         q = ngx_queue_last(&cache->expire_queue);

  3556.         sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);

  3557.         if (n++ != 0 && sess_id->expire > now) {
  3558.             return;
  3559.         }

  3560.         ngx_queue_remove(q);

  3561.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
  3562.                        "expire session: %08Xi", sess_id->node.key);

  3563.         ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);

  3564.         ngx_explicit_memzero(sess_id->session, sess_id->len);

  3565. #if (NGX_PTR_SIZE == 8)
  3566.         ngx_slab_free_locked(shpool, sess_id->session);
  3567. #endif
  3568.         ngx_slab_free_locked(shpool, sess_id);
  3569.     }
  3570. }


  3571. static void
  3572. ‌ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
  3573.     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
  3574. {
  3575.     ngx_rbtree_node_t  **p;
  3576.     ngx_ssl_sess_id_t   *sess_id, *sess_id_temp;

  3577.     for ( ;; ) {

  3578.         if (node->key < temp->key) {

  3579.             p = &temp->left;

  3580.         } else if (node->key > temp->key) {

  3581.             p = &temp->right;

  3582.         } else { /* node->key == temp->key */

  3583.             sess_id = (ngx_ssl_sess_id_t *) node;
  3584.             sess_id_temp = (ngx_ssl_sess_id_t *) temp;

  3585.             p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
  3586.                               (size_t) node->data, (size_t) temp->data)
  3587.                  < 0) ? &temp->left : &temp->right;
  3588.         }

  3589.         if (*p == sentinel) {
  3590.             break;
  3591.         }

  3592.         temp = *p;
  3593.     }

  3594.     *p = node;
  3595.     node->parent = temp;
  3596.     node->left = sentinel;
  3597.     node->right = sentinel;
  3598.     ngx_rbt_red(node);
  3599. }


  3600. #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB

  3601. ngx_int_t
  3602. ‌ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3603. {
  3604.     u_char                 buf[80];
  3605.     size_t                 size;
  3606.     ssize_t                n;
  3607.     ngx_str_t             *path;
  3608.     ngx_file_t             file;
  3609.     ngx_uint_t             i;
  3610.     ngx_array_t           *keys;
  3611.     ngx_file_info_t        fi;
  3612.     ngx_pool_cleanup_t    *cln;
  3613.     ngx_ssl_ticket_key_t  *key;

  3614.     if (paths == NULL
  3615.         && SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_session_cache_index) == NULL)
  3616.     {
  3617.         return NGX_OK;
  3618.     }

  3619.     keys = ngx_array_create(cf->pool, paths ? paths->nelts : 3,
  3620.                             sizeof(ngx_ssl_ticket_key_t));
  3621.     if (keys == NULL) {
  3622.         return NGX_ERROR;
  3623.     }

  3624.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  3625.     if (cln == NULL) {
  3626.         return NGX_ERROR;
  3627.     }

  3628.     cln->handler = ngx_ssl_ticket_keys_cleanup;
  3629.     cln->data = keys;

  3630.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ticket_keys_index, keys) == 0) {
  3631.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3632.                       "SSL_CTX_set_ex_data() failed");
  3633.         return NGX_ERROR;
  3634.     }

  3635.     if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx, ngx_ssl_ticket_key_callback)
  3636.         == 0)
  3637.     {
  3638.         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
  3639.                       "nginx was built with Session Tickets support, however, "
  3640.                       "now it is linked dynamically to an OpenSSL library "
  3641.                       "which has no tlsext support, therefore Session Tickets "
  3642.                       "are not available");
  3643.         return NGX_OK;
  3644.     }

  3645.     if (paths == NULL) {

  3646.         /* placeholder for keys in shared memory */

  3647.         key = ngx_array_push_n(keys, 3);
  3648.         key[0].shared = 1;
  3649.         key[0].expire = 0;
  3650.         key[1].shared = 1;
  3651.         key[1].expire = 0;
  3652.         key[2].shared = 1;
  3653.         key[2].expire = 0;

  3654.         return NGX_OK;
  3655.     }

  3656.     path = paths->elts;
  3657.     for (i = 0; i < paths->nelts; i++) {

  3658.         if (ngx_conf_full_name(cf->cycle, &path[i], 1) != NGX_OK) {
  3659.             return NGX_ERROR;
  3660.         }

  3661.         ngx_memzero(&file, sizeof(ngx_file_t));
  3662.         file.name = path[i];
  3663.         file.log = cf->log;

  3664.         file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
  3665.                                 NGX_FILE_OPEN, 0);

  3666.         if (file.fd == NGX_INVALID_FILE) {
  3667.             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  3668.                                ngx_open_file_n " \"%V\" failed", &file.name);
  3669.             return NGX_ERROR;
  3670.         }

  3671.         if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
  3672.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3673.                                ngx_fd_info_n " \"%V\" failed", &file.name);
  3674.             goto failed;
  3675.         }

  3676.         size = ngx_file_size(&fi);

  3677.         if (size != 48 && size != 80) {
  3678.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3679.                                "\"%V\" must be 48 or 80 bytes", &file.name);
  3680.             goto failed;
  3681.         }

  3682.         n = ngx_read_file(&file, buf, size, 0);

  3683.         if (n == NGX_ERROR) {
  3684.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3685.                                ngx_read_file_n " \"%V\" failed", &file.name);
  3686.             goto failed;
  3687.         }

  3688.         if ((size_t) n != size) {
  3689.             ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
  3690.                                ngx_read_file_n " \"%V\" returned only "
  3691.                                "%z bytes instead of %uz", &file.name, n, size);
  3692.             goto failed;
  3693.         }

  3694.         key = ngx_array_push(keys);
  3695.         if (key == NULL) {
  3696.             goto failed;
  3697.         }

  3698.         key->shared = 0;
  3699.         key->expire = 1;

  3700.         if (size == 48) {
  3701.             key->size = 48;
  3702.             ngx_memcpy(key->name, buf, 16);
  3703.             ngx_memcpy(key->aes_key, buf + 16, 16);
  3704.             ngx_memcpy(key->hmac_key, buf + 32, 16);

  3705.         } else {
  3706.             key->size = 80;
  3707.             ngx_memcpy(key->name, buf, 16);
  3708.             ngx_memcpy(key->hmac_key, buf + 16, 32);
  3709.             ngx_memcpy(key->aes_key, buf + 48, 32);
  3710.         }

  3711.         if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3712.             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3713.                           ngx_close_file_n " \"%V\" failed", &file.name);
  3714.         }

  3715.         ngx_explicit_memzero(&buf, 80);
  3716.     }

  3717.     return NGX_OK;

  3718. failed:

  3719.     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3720.         ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3721.                       ngx_close_file_n " \"%V\" failed", &file.name);
  3722.     }

  3723.     ngx_explicit_memzero(&buf, 80);

  3724.     return NGX_ERROR;
  3725. }


  3726. static int
  3727. ‌ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
  3728.     unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
  3729.     HMAC_CTX *hctx, int enc)
  3730. {
  3731.     size_t                 size;
  3732.     SSL_CTX               *ssl_ctx;
  3733.     ngx_uint_t             i;
  3734.     ngx_array_t           *keys;
  3735.     ngx_connection_t      *c;
  3736.     ngx_ssl_ticket_key_t  *key;
  3737.     const EVP_MD          *digest;
  3738.     const EVP_CIPHER      *cipher;

  3739.     c = ngx_ssl_get_connection(ssl_conn);
  3740.     ssl_ctx = c->ssl->session_ctx;

  3741.     if (ngx_ssl_rotate_ticket_keys(ssl_ctx, c->log) != NGX_OK) {
  3742.         return -1;
  3743.     }

  3744. #ifdef OPENSSL_NO_SHA256
  3745.     digest = EVP_sha1();
  3746. #else
  3747.     digest = EVP_sha256();
  3748. #endif

  3749.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3750.     if (keys == NULL) {
  3751.         return -1;
  3752.     }

  3753.     key = keys->elts;

  3754.     if (enc == 1) {
  3755.         /* encrypt session ticket */

  3756.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3757.                        "ssl ticket encrypt, key: \"%*xs\" (%s session)",
  3758.                        (size_t) 16, key[0].name,
  3759.                        SSL_session_reused(ssl_conn) ? "reused" : "new");

  3760.         if (key[0].size == 48) {
  3761.             cipher = EVP_aes_128_cbc();
  3762.             size = 16;

  3763.         } else {
  3764.             cipher = EVP_aes_256_cbc();
  3765.             size = 32;
  3766.         }

  3767.         if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
  3768.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed");
  3769.             return -1;
  3770.         }

  3771.         if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) {
  3772.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3773.                           "EVP_EncryptInit_ex() failed");
  3774.             return -1;
  3775.         }

  3776. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3777.         if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) {
  3778.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3779.             return -1;
  3780.         }
  3781. #else
  3782.         HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL);
  3783. #endif

  3784.         ngx_memcpy(name, key[0].name, 16);

  3785.         return 1;

  3786.     } else {
  3787.         /* decrypt session ticket */

  3788.         for (i = 0; i < keys->nelts; i++) {
  3789.             if (ngx_memcmp(name, key[i].name, 16) == 0) {
  3790.                 goto found;
  3791.             }
  3792.         }

  3793.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3794.                        "ssl ticket decrypt, key: \"%*xs\" not found",
  3795.                        (size_t) 16, name);

  3796.         return 0;

  3797.     found:

  3798.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3799.                        "ssl ticket decrypt, key: \"%*xs\"%s",
  3800.                        (size_t) 16, key[i].name, (i == 0) ? " (default)" : "");

  3801.         if (key[i].size == 48) {
  3802.             cipher = EVP_aes_128_cbc();
  3803.             size = 16;

  3804.         } else {
  3805.             cipher = EVP_aes_256_cbc();
  3806.             size = 32;
  3807.         }

  3808. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3809.         if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) {
  3810.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3811.             return -1;
  3812.         }
  3813. #else
  3814.         HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL);
  3815. #endif

  3816.         if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) {
  3817.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3818.                           "EVP_DecryptInit_ex() failed");
  3819.             return -1;
  3820.         }

  3821.         /* renew if TLSv1.3 */

  3822. #ifdef TLS1_3_VERSION
  3823.         if (SSL_version(ssl_conn) == TLS1_3_VERSION) {
  3824.             return 2;
  3825.         }
  3826. #endif

  3827.         /* renew if non-default key */

  3828.         if (i != 0 && key[i].expire) {
  3829.             return 2;
  3830.         }

  3831.         return 1;
  3832.     }
  3833. }


  3834. static ngx_int_t
  3835. ‌ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
  3836. {
  3837.     time_t                    now, expire;
  3838.     ngx_array_t              *keys;
  3839.     ngx_shm_zone_t           *shm_zone;
  3840.     ngx_slab_pool_t          *shpool;
  3841.     ngx_ssl_ticket_key_t     *key;
  3842.     ngx_ssl_session_cache_t  *cache;
  3843.     u_char                    buf[80];

  3844.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3845.     if (keys == NULL) {
  3846.         return NGX_OK;
  3847.     }

  3848.     key = keys->elts;

  3849.     if (!key[0].shared) {
  3850.         return NGX_OK;
  3851.     }

  3852.     /*
  3853.      * if we don't need to update expiration of the current key
  3854.      * and the previous key is still needed, don't sync with shared
  3855.      * memory to save some work; in the worst case other worker process
  3856.      * will switch to the next key, but this process will still be able
  3857.      * to decrypt tickets encrypted with it
  3858.      */

  3859.     now = ngx_time();
  3860.     expire = now + SSL_CTX_get_timeout(ssl_ctx);

  3861.     if (key[0].expire >= expire && key[1].expire >= now) {
  3862.         return NGX_OK;
  3863.     }

  3864.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3865.     cache = shm_zone->data;
  3866.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3867.     ngx_shmtx_lock(&shpool->mutex);

  3868.     key = cache->ticket_keys;

  3869.     if (key[0].expire == 0) {

  3870.         /* initialize the current key */

  3871.         if (RAND_bytes(buf, 80) != 1) {
  3872.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3873.             ngx_shmtx_unlock(&shpool->mutex);
  3874.             return NGX_ERROR;
  3875.         }

  3876.         key[0].shared = 1;
  3877.         key[0].expire = expire;
  3878.         key[0].size = 80;
  3879.         ngx_memcpy(key[0].name, buf, 16);
  3880.         ngx_memcpy(key[0].hmac_key, buf + 16, 32);
  3881.         ngx_memcpy(key[0].aes_key, buf + 48, 32);

  3882.         ngx_explicit_memzero(&buf, 80);

  3883.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3884.                        "ssl ticket key: \"%*xs\"",
  3885.                        (size_t) 16, key[0].name);

  3886.         /*
  3887.          * copy the current key to the next key, as initialization of
  3888.          * the previous key will replace the current key with the next
  3889.          * key
  3890.          */

  3891.         key[2] = key[0];
  3892.     }

  3893.     if (key[1].expire < now) {

  3894.         /*
  3895.          * if the previous key is no longer needed (or not initialized),
  3896.          * replace it with the current key, replace the current key with
  3897.          * the next key, and generate new next key
  3898.          */

  3899.         key[1] = key[0];
  3900.         key[0] = key[2];

  3901.         if (RAND_bytes(buf, 80) != 1) {
  3902.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3903.             ngx_shmtx_unlock(&shpool->mutex);
  3904.             return NGX_ERROR;
  3905.         }

  3906.         key[2].shared = 1;
  3907.         key[2].expire = 0;
  3908.         key[2].size = 80;
  3909.         ngx_memcpy(key[2].name, buf, 16);
  3910.         ngx_memcpy(key[2].hmac_key, buf + 16, 32);
  3911.         ngx_memcpy(key[2].aes_key, buf + 48, 32);

  3912.         ngx_explicit_memzero(&buf, 80);

  3913.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3914.                        "ssl ticket key: \"%*xs\"",
  3915.                        (size_t) 16, key[2].name);
  3916.     }

  3917.     /*
  3918.      * update expiration of the current key: it is going to be needed
  3919.      * at least till the session being created expires
  3920.      */

  3921.     if (expire > key[0].expire) {
  3922.         key[0].expire = expire;
  3923.     }

  3924.     /* sync keys to the worker process memory */

  3925.     ngx_memcpy(keys->elts, cache->ticket_keys,
  3926.                keys->nelts * sizeof(ngx_ssl_ticket_key_t));

  3927.     ngx_shmtx_unlock(&shpool->mutex);

  3928.     return NGX_OK;
  3929. }


  3930. static void
  3931. ‌ngx_ssl_ticket_keys_cleanup(void *data)
  3932. {
  3933.     ngx_array_t  *keys = data;

  3934.     ngx_explicit_memzero(keys->elts,
  3935.                          keys->nelts * sizeof(ngx_ssl_ticket_key_t));
  3936. }

  3937. #else

  3938. ngx_int_t
  3939. ‌ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3940. {
  3941.     if (paths) {
  3942.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  3943.                       "\"ssl_session_ticket_key\" ignored, not supported");
  3944.     }

  3945.     return NGX_OK;
  3946. }

  3947. #endif


  3948. void
  3949. ‌ngx_ssl_cleanup_ctx(void *data)
  3950. {
  3951.     ngx_ssl_t  *ssl = data;

  3952.     X509        *cert;
  3953.     u_char      *p;
  3954.     ngx_uint_t   i;

  3955.     for (i = 0; i < ssl->certs.nelts; i++) {
  3956.         cert = ((X509 **) ssl->certs.elts)[i];

  3957.         p = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);

  3958.         if (p) {
  3959.             ngx_free(p);
  3960.             X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, NULL);
  3961.         }

  3962.         X509_free(cert);
  3963.     }

  3964.     SSL_CTX_free(ssl->ctx);
  3965. }


  3966. ngx_int_t
  3967. ‌ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
  3968. {
  3969.     X509       *cert;
  3970.     u_char     *addr;
  3971.     size_t      alen;
  3972.     in_addr_t   addr4;
  3973. #if (NGX_HAVE_INET6)
  3974.     u_char      addr6[16];
  3975. #endif

  3976.     cert = SSL_get_peer_certificate(c->ssl->connection);
  3977.     if (cert == NULL) {
  3978.         return NGX_ERROR;
  3979.     }

  3980.     if (name->len == 0) {
  3981.         goto failed;
  3982.     }

  3983.     addr4 = ngx_inet_addr(name->data, name->len);

  3984.     if (addr4 != INADDR_NONE) {
  3985.         addr = (u_char *) &addr4;
  3986.         alen = 4;

  3987. #if (NGX_HAVE_INET6)
  3988.     } else if (name->data[0] == '[') {

  3989.         if (name->data[name->len - 1] != ']') {
  3990.             goto failed;
  3991.         }

  3992.         if (ngx_inet6_addr(name->data + 1, name->len - 2, addr6) != NGX_OK) {
  3993.             goto failed;
  3994.         }

  3995.         addr = addr6;
  3996.         alen = 16;

  3997. #endif
  3998.     } else {
  3999.         addr = NULL;
  4000.         alen = 0;
  4001.     }

  4002. #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

  4003.     /* X509_check_host() is only available in OpenSSL 1.0.2+ */

  4004.     if (addr) {
  4005.         if (X509_check_ip(cert, addr, alen, 0) != 1) {
  4006.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4007.                            "X509_check_ip(): no match");
  4008.             goto failed;
  4009.         }

  4010.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4011.                        "X509_check_ip(): match");
  4012.         goto found;
  4013.     }

  4014.     if (X509_check_host(cert, (char *) name->data, name->len, 0, NULL) != 1) {
  4015.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4016.                        "X509_check_host(): no match");
  4017.         goto failed;
  4018.     }

  4019.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4020.                    "X509_check_host(): match");
  4021.     goto found;

  4022. #else
  4023.     {
  4024.     int                      n, i;
  4025.     size_t                   dlen;
  4026.     u_char                  *data;
  4027.     X509_NAME               *sname;
  4028.     ASN1_STRING             *str;
  4029.     X509_NAME_ENTRY         *entry;
  4030.     GENERAL_NAME            *altname;
  4031.     STACK_OF(GENERAL_NAME)  *altnames;

  4032.     /*
  4033.      * As per RFC6125 and RFC2818, we check subjectAltName extension,
  4034.      * and if it's not present - commonName in Subject is checked.
  4035.      */

  4036.     altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);

  4037.     if (altnames) {
  4038.         n = sk_GENERAL_NAME_num(altnames);

  4039.         for (i = 0; i < n; i++) {
  4040.             altname = sk_GENERAL_NAME_value(altnames, i);

  4041.             if (altname->type == GEN_DNS) {

  4042.                 str = altname->d.dNSName;

  4043.                 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4044.                                "SSL subjectAltName: \"%*s\"",
  4045.                                (size_t) ASN1_STRING_length(str),
  4046.                                ASN1_STRING_data(str));

  4047.                 if (addr == NULL && ngx_ssl_check_name(name, str) == NGX_OK) {
  4048.                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4049.                                    "SSL subjectAltName: match");
  4050.                     GENERAL_NAMES_free(altnames);
  4051.                     goto found;
  4052.                 }

  4053.             } else if (altname->type == GEN_IPADD) {

  4054.                 str = altname->d.iPAddress;
  4055.                 data = ASN1_STRING_data(str);
  4056.                 dlen = ASN1_STRING_length(str);

  4057. #if (NGX_DEBUG)
  4058.                 {
  4059.                 size_t  al;
  4060.                 u_char  at[NGX_INET6_ADDRSTRLEN];

  4061.                 if (dlen == 4) {
  4062.                     al = ngx_inet_ntop(AF_INET, data, at,
  4063.                                        NGX_INET6_ADDRSTRLEN);

  4064. #if (NGX_HAVE_INET6)
  4065.                 } else if (dlen == 16) {
  4066.                     al = ngx_inet_ntop(AF_INET6, data, at,
  4067.                                        NGX_INET6_ADDRSTRLEN);

  4068. #endif
  4069.                 } else {
  4070.                     al = ngx_cpymem(at, "<invalid>", sizeof("<invalid>") - 1)
  4071.                          - at;
  4072.                 }

  4073.                 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4074.                                "SSL subjectAltName: \"%*s\"",
  4075.                                al, at);
  4076.                 }
  4077. #endif

  4078.                 if (addr
  4079.                     && alen == dlen
  4080.                     && ngx_memcmp(addr, data, dlen) == 0)
  4081.                 {
  4082.                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4083.                                    "SSL subjectAltName: match");
  4084.                     GENERAL_NAMES_free(altnames);
  4085.                     goto found;
  4086.                 }
  4087.             }
  4088.         }

  4089.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4090.                        "SSL subjectAltName: no match");

  4091.         GENERAL_NAMES_free(altnames);
  4092.         goto failed;
  4093.     }

  4094.     /*
  4095.      * If there is no subjectAltName extension, check commonName
  4096.      * in Subject.  While RFC2818 requires to only check "most specific"
  4097.      * CN, both Apache and OpenSSL check all CNs, and so do we.
  4098.      */

  4099.     if (addr) {
  4100.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4101.                        "SSL commonName: no match");
  4102.         goto failed;
  4103.     }

  4104.     sname = X509_get_subject_name(cert);

  4105.     if (sname == NULL) {
  4106.         goto failed;
  4107.     }

  4108.     i = -1;
  4109.     for ( ;; ) {
  4110.         i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);

  4111.         if (i < 0) {
  4112.             break;
  4113.         }

  4114.         entry = X509_NAME_get_entry(sname, i);
  4115.         str = X509_NAME_ENTRY_get_data(entry);

  4116.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4117.                        "SSL commonName: \"%*s\"",
  4118.                        (size_t) ASN1_STRING_length(str),
  4119.                        ASN1_STRING_data(str));

  4120.         if (ngx_ssl_check_name(name, str) == NGX_OK) {
  4121.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4122.                            "SSL commonName: match");
  4123.             goto found;
  4124.         }
  4125.     }

  4126.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4127.                    "SSL commonName: no match");
  4128.     }
  4129. #endif

  4130. failed:

  4131.     X509_free(cert);
  4132.     return NGX_ERROR;

  4133. found:

  4134.     X509_free(cert);
  4135.     return NGX_OK;
  4136. }


  4137. #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

  4138. static ngx_int_t
  4139. ‌ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern)
  4140. {
  4141.     u_char  *s, *p, *end;
  4142.     size_t   slen, plen;

  4143.     s = name->data;
  4144.     slen = name->len;

  4145.     p = ASN1_STRING_data(pattern);
  4146.     plen = ASN1_STRING_length(pattern);

  4147.     if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) {
  4148.         return NGX_OK;
  4149.     }

  4150.     if (plen > 2 && p[0] == '*' && p[1] == '.') {
  4151.         plen -= 1;
  4152.         p += 1;

  4153.         end = s + slen;
  4154.         s = ngx_strlchr(s, end, '.');

  4155.         if (s == NULL) {
  4156.             return NGX_ERROR;
  4157.         }

  4158.         slen = end - s;

  4159.         if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) {
  4160.             return NGX_OK;
  4161.         }
  4162.     }

  4163.     return NGX_ERROR;
  4164. }

  4165. #endif


  4166. ngx_int_t
  4167. ‌ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4168. {
  4169.     s->data = (u_char *) SSL_get_version(c->ssl->connection);
  4170.     return NGX_OK;
  4171. }


  4172. ngx_int_t
  4173. ‌ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4174. {
  4175.     s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);
  4176.     return NGX_OK;
  4177. }


  4178. ngx_int_t
  4179. ‌ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4180. {
  4181. #ifdef SSL_CTRL_GET_RAW_CIPHERLIST

  4182.     int                n, i, bytes;
  4183.     size_t             len;
  4184.     u_char            *ciphers, *p;
  4185.     const SSL_CIPHER  *cipher;

  4186.     bytes = SSL_get0_raw_cipherlist(c->ssl->connection, NULL);
  4187.     n = SSL_get0_raw_cipherlist(c->ssl->connection, &ciphers);

  4188.     if (n <= 0) {
  4189.         s->len = 0;
  4190.         return NGX_OK;
  4191.     }

  4192.     len = 0;
  4193.     n /= bytes;

  4194.     for (i = 0; i < n; i++) {
  4195.         cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes);

  4196.         if (cipher) {
  4197.             len += ngx_strlen(SSL_CIPHER_get_name(cipher));

  4198.         } else {
  4199.             len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1);
  4200.         }

  4201.         len += sizeof(":") - 1;
  4202.     }

  4203.     s->data = ngx_pnalloc(pool, len);
  4204.     if (s->data == NULL) {
  4205.         return NGX_ERROR;
  4206.     }

  4207.     p = s->data;

  4208.     for (i = 0; i < n; i++) {
  4209.         cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes);

  4210.         if (cipher) {
  4211.             p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher));

  4212.         } else {
  4213.             p = ngx_sprintf(p, "0x");
  4214.             p = ngx_hex_dump(p, ciphers + i * bytes, bytes);
  4215.         }

  4216.         *p++ = ':';
  4217.     }

  4218.     p--;

  4219.     s->len = p - s->data;

  4220. #else

  4221.     u_char  buf[4096];

  4222.     if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096)
  4223.         == NULL)
  4224.     {
  4225.         s->len = 0;
  4226.         return NGX_OK;
  4227.     }

  4228.     s->len = ngx_strlen(buf);
  4229.     s->data = ngx_pnalloc(pool, s->len);
  4230.     if (s->data == NULL) {
  4231.         return NGX_ERROR;
  4232.     }

  4233.     ngx_memcpy(s->data, buf, s->len);

  4234. #endif

  4235.     return NGX_OK;
  4236. }


  4237. ngx_int_t
  4238. ‌ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4239. {
  4240. #ifdef SSL_get_negotiated_group

  4241.     int          nid;
  4242.     const char  *name;

  4243.     nid = SSL_get_negotiated_group(c->ssl->connection);

  4244.     if (nid != NID_undef) {

  4245.         if ((nid & TLSEXT_nid_unknown) == 0) {
  4246.             s->len = ngx_strlen(OBJ_nid2sn(nid));
  4247.             s->data = (u_char *) OBJ_nid2sn(nid);
  4248.             return NGX_OK;
  4249.         }

  4250.         name = SSL_group_to_name(c->ssl->connection, nid);

  4251.         s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
  4252.         s->data = ngx_pnalloc(pool, s->len);
  4253.         if (s->data == NULL) {
  4254.             return NGX_ERROR;
  4255.         }

  4256.         if (name) {
  4257.             ngx_memcpy(s->data, name, s->len);

  4258.         } else {
  4259.             ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);
  4260.         }

  4261.         return NGX_OK;
  4262.     }

  4263. #endif

  4264.     s->len = 0;
  4265.     return NGX_OK;
  4266. }


  4267. ngx_int_t
  4268. ‌ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4269. {
  4270. #ifdef SSL_CTRL_GET_CURVES

  4271.     int         *curves, n, i, nid;
  4272.     u_char      *p;
  4273.     size_t       len;
  4274.     const char  *name;

  4275.     n = SSL_get1_curves(c->ssl->connection, NULL);

  4276.     if (n <= 0) {
  4277.         s->len = 0;
  4278.         return NGX_OK;
  4279.     }

  4280.     curves = ngx_palloc(pool, n * sizeof(int));
  4281.     if (curves == NULL) {
  4282.         return NGX_ERROR;
  4283.     }

  4284.     n = SSL_get1_curves(c->ssl->connection, curves);
  4285.     len = 0;

  4286.     for (i = 0; i < n; i++) {
  4287.         nid = curves[i];

  4288.         if (nid & TLSEXT_nid_unknown) {
  4289.             name = SSL_group_to_name(c->ssl->connection, nid);

  4290.             len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;

  4291.         } else {
  4292.             len += ngx_strlen(OBJ_nid2sn(nid));
  4293.         }

  4294.         len += sizeof(":") - 1;
  4295.     }

  4296.     s->data = ngx_pnalloc(pool, len);
  4297.     if (s->data == NULL) {
  4298.         return NGX_ERROR;
  4299.     }

  4300.     p = s->data;

  4301.     for (i = 0; i < n; i++) {
  4302.         nid = curves[i];

  4303.         if (nid & TLSEXT_nid_unknown) {
  4304.             name = SSL_group_to_name(c->ssl->connection, nid);

  4305.             p = name ? ngx_cpymem(p, name, ngx_strlen(name))
  4306.                      : ngx_sprintf(p, "0x%04xd", nid & 0xffff);

  4307.         } else {
  4308.             p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));
  4309.         }

  4310.         *p++ = ':';
  4311.     }

  4312.     p--;

  4313.     s->len = p - s->data;

  4314. #else

  4315.     s->len = 0;

  4316. #endif

  4317.     return NGX_OK;
  4318. }


  4319. ngx_int_t
  4320. ‌ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4321. {
  4322. #ifdef SSL_get0_signature_name

  4323.     const char  *name;

  4324.     if (SSL_get0_signature_name(c->ssl->connection, &name)) {
  4325.         s->len = ngx_strlen(name);
  4326.         s->data = ngx_pnalloc(pool, s->len);
  4327.         if (s->data == NULL) {
  4328.             return NGX_ERROR;
  4329.         }

  4330.         ngx_memcpy(s->data, name, s->len);

  4331.         return NGX_OK;
  4332.     }

  4333. #endif

  4334.     s->len = 0;
  4335.     return NGX_OK;
  4336. }


  4337. ngx_int_t
  4338. ‌ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4339. {
  4340. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)

  4341.     int            n, i;
  4342.     size_t         len;
  4343.     u_char        *p;
  4344.     const char    *name;
  4345.     unsigned int   codepoint;

  4346.     n = SSL_get0_sigalg(c->ssl->connection, -1, NULL, NULL);

  4347.     if (n <= 0) {
  4348.         s->len = 0;
  4349.         return NGX_OK;
  4350.     }

  4351.     len = 0;

  4352.     for (i = 0; i < n; i++) {
  4353.         SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name);
  4354.         len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
  4355.         len += sizeof(":") - 1;
  4356.     }

  4357.     s->data = ngx_pnalloc(pool, len);
  4358.     if (s->data == NULL) {
  4359.         return NGX_ERROR;
  4360.     }

  4361.     p = s->data;

  4362.     for (i = 0; i < n; i++) {
  4363.         SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name);

  4364.         if (name) {
  4365.             p = ngx_cpymem(p, name, ngx_strlen(name));

  4366.         } else {
  4367.             p = ngx_sprintf(p, "0x%04xd", codepoint);
  4368.         }

  4369.         *p++ = ':';
  4370.     }

  4371.     p--;

  4372.     s->len = p - s->data;

  4373. #elif defined SSL_CTRL_SET_SIGALGS

  4374.     /*
  4375.      * SSL_get_sigalgs() is only available in OpenSSL 1.0.2+,
  4376.      * but uses a different naming, so emit raw codes
  4377.      */

  4378.     int             n, i;
  4379.     size_t          len;
  4380.     u_char         *p;
  4381.     unsigned char   rsig, rhash;

  4382.     n = SSL_get_sigalgs(c->ssl->connection, -1, NULL, NULL, NULL, NULL, NULL);

  4383.     if (n <= 0) {
  4384.         s->len = 0;
  4385.         return NGX_OK;
  4386.     }

  4387.     len = n * (sizeof("0x0000") - 1 + sizeof(":") - 1);

  4388.     s->data = ngx_pnalloc(pool, len);
  4389.     if (s->data == NULL) {
  4390.         return NGX_ERROR;
  4391.     }

  4392.     p = s->data;

  4393.     for (i = 0; i < n; i++) {
  4394.         SSL_get_sigalgs(c->ssl->connection, i, NULL, NULL, NULL, &rsig, &rhash);
  4395.         p = ngx_sprintf(p, "0x%04xd", rhash << 8 | rsig);
  4396.         *p++ = ':';
  4397.     }

  4398.     p--;

  4399.     s->len = p - s->data;

  4400. #else

  4401.     s->len = 0;

  4402. #endif

  4403.     return NGX_OK;
  4404. }


  4405. ngx_int_t
  4406. ‌ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4407. {
  4408.     u_char        *buf;
  4409.     SSL_SESSION   *sess;
  4410.     unsigned int   len;

  4411.     sess = SSL_get0_session(c->ssl->connection);
  4412.     if (sess == NULL) {
  4413.         s->len = 0;
  4414.         return NGX_OK;
  4415.     }

  4416.     buf = (u_char *) SSL_SESSION_get_id(sess, &len);

  4417.     s->len = 2 * len;
  4418.     s->data = ngx_pnalloc(pool, 2 * len);
  4419.     if (s->data == NULL) {
  4420.         return NGX_ERROR;
  4421.     }

  4422.     ngx_hex_dump(s->data, buf, len);

  4423.     return NGX_OK;
  4424. }


  4425. ngx_int_t
  4426. ‌ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4427. {
  4428.     if (SSL_session_reused(c->ssl->connection)) {
  4429.         ngx_str_set(s, "r");

  4430.     } else {
  4431.         ngx_str_set(s, ".");
  4432.     }

  4433.     return NGX_OK;
  4434. }


  4435. ngx_int_t
  4436. ‌ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4437. {
  4438.     s->len = 0;

  4439. #ifdef SSL_ERROR_EARLY_DATA_REJECTED

  4440.     /* BoringSSL */

  4441.     if (SSL_in_early_data(c->ssl->connection)) {
  4442.         ngx_str_set(s, "1");
  4443.     }

  4444. #elif defined SSL_READ_EARLY_DATA_SUCCESS

  4445.     /* OpenSSL */

  4446.     if (!SSL_is_init_finished(c->ssl->connection)) {
  4447.         ngx_str_set(s, "1");
  4448.     }

  4449. #endif

  4450.     return NGX_OK;
  4451. }


  4452. ngx_int_t
  4453. ‌ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4454. {
  4455. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  4456.     size_t       len;
  4457.     const char  *name;

  4458.     name = SSL_get_servername(c->ssl->connection, TLSEXT_NAMETYPE_host_name);

  4459.     if (name) {
  4460.         len = ngx_strlen(name);

  4461.         s->len = len;
  4462.         s->data = ngx_pnalloc(pool, len);
  4463.         if (s->data == NULL) {
  4464.             return NGX_ERROR;
  4465.         }

  4466.         ngx_memcpy(s->data, name, len);

  4467.         return NGX_OK;
  4468.     }

  4469. #endif

  4470.     s->len = 0;
  4471.     return NGX_OK;
  4472. }


  4473. ngx_int_t
  4474. ‌ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4475. {
  4476. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  4477.     unsigned int          len;
  4478.     const unsigned char  *data;

  4479.     SSL_get0_alpn_selected(c->ssl->connection, &data, &len);

  4480.     if (len > 0) {

  4481.         s->data = ngx_pnalloc(pool, len);
  4482.         if (s->data == NULL) {
  4483.             return NGX_ERROR;
  4484.         }

  4485.         ngx_memcpy(s->data, data, len);
  4486.         s->len = len;

  4487.         return NGX_OK;
  4488.     }

  4489. #endif

  4490.     s->len = 0;
  4491.     return NGX_OK;
  4492. }


  4493. ngx_int_t
  4494. ‌ngx_ssl_get_ech_status(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4495. {
  4496. #ifdef SSL_OP_ECH_GREASE
  4497.     int    echrv;
  4498.     char  *inner_sni, *outer_sni;

  4499.     inner_sni = NULL;
  4500.     outer_sni = NULL;

  4501.     echrv = SSL_ech_get1_status(c->ssl->connection, &inner_sni, &outer_sni);

  4502.     switch (echrv) {
  4503.     case SSL_ECH_STATUS_NOT_TRIED:
  4504.         ngx_str_set(s, "NOT_TRIED");
  4505.         break;
  4506.     case SSL_ECH_STATUS_SUCCESS:
  4507.         ngx_str_set(s, "SUCCESS");
  4508.         break;
  4509.     case SSL_ECH_STATUS_GREASE:
  4510.         ngx_str_set(s, "GREASE");
  4511.         break;
  4512.     case SSL_ECH_STATUS_BACKEND:
  4513.         ngx_str_set(s, "BACKEND");
  4514.         break;
  4515.     default:
  4516.         ngx_str_set(s, "FAILED");
  4517.         break;
  4518.     }

  4519.     OPENSSL_free(inner_sni);
  4520.     OPENSSL_free(outer_sni);
  4521. #else
  4522.     s->len = 0;
  4523. #endif
  4524.     return NGX_OK;
  4525. }


  4526. ngx_int_t
  4527. ‌ngx_ssl_get_ech_outer_server_name(ngx_connection_t *c, ngx_pool_t *pool,
  4528.     ngx_str_t *s)
  4529. {
  4530. #if defined(SSL_OP_ECH_GREASE)
  4531.     int    echrv;
  4532.     char  *inner_sni, *outer_sni;

  4533.     inner_sni = NULL;
  4534.     outer_sni = NULL;

  4535.     echrv = SSL_ech_get1_status(c->ssl->connection, &inner_sni, &outer_sni);

  4536.     if (echrv == SSL_ECH_STATUS_SUCCESS && outer_sni) {
  4537.         s->len = ngx_strlen(outer_sni);

  4538.         s->data = ngx_pnalloc(pool, s->len);
  4539.         if (s->data == NULL) {
  4540.             OPENSSL_free(inner_sni);
  4541.             OPENSSL_free(outer_sni);
  4542.             return NGX_ERROR;
  4543.         }

  4544.         ngx_memcpy(s->data, outer_sni, s->len);

  4545.     } else {
  4546.         s->len = 0;
  4547.     }

  4548.     OPENSSL_free(inner_sni);
  4549.     OPENSSL_free(outer_sni);
  4550. #else
  4551.     s->len = 0;
  4552. #endif
  4553.     return NGX_OK;
  4554. }


  4555. ngx_int_t
  4556. ‌ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4557. {
  4558.     size_t   len;
  4559.     BIO     *bio;
  4560.     X509    *cert;

  4561.     s->len = 0;

  4562.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4563.     if (cert == NULL) {
  4564.         return NGX_OK;
  4565.     }

  4566.     bio = BIO_new(BIO_s_mem());
  4567.     if (bio == NULL) {
  4568.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4569.         X509_free(cert);
  4570.         return NGX_ERROR;
  4571.     }

  4572.     if (PEM_write_bio_X509(bio, cert) == 0) {
  4573.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
  4574.         goto failed;
  4575.     }

  4576.     len = BIO_pending(bio);
  4577.     s->len = len;

  4578.     s->data = ngx_pnalloc(pool, len);
  4579.     if (s->data == NULL) {
  4580.         goto failed;
  4581.     }

  4582.     BIO_read(bio, s->data, len);

  4583.     BIO_free(bio);
  4584.     X509_free(cert);

  4585.     return NGX_OK;

  4586. failed:

  4587.     BIO_free(bio);
  4588.     X509_free(cert);

  4589.     return NGX_ERROR;
  4590. }


  4591. ngx_int_t
  4592. ‌ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4593. {
  4594.     u_char      *p;
  4595.     size_t       len;
  4596.     ngx_uint_t   i;
  4597.     ngx_str_t    cert;

  4598.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  4599.         return NGX_ERROR;
  4600.     }

  4601.     if (cert.len == 0) {
  4602.         s->len = 0;
  4603.         return NGX_OK;
  4604.     }

  4605.     len = cert.len - 1;

  4606.     for (i = 0; i < cert.len - 1; i++) {
  4607.         if (cert.data[i] == LF) {
  4608.             len++;
  4609.         }
  4610.     }

  4611.     s->len = len;
  4612.     s->data = ngx_pnalloc(pool, len);
  4613.     if (s->data == NULL) {
  4614.         return NGX_ERROR;
  4615.     }

  4616.     p = s->data;

  4617.     for (i = 0; i < cert.len - 1; i++) {
  4618.         *p++ = cert.data[i];
  4619.         if (cert.data[i] == LF) {
  4620.             *p++ = '\t';
  4621.         }
  4622.     }

  4623.     return NGX_OK;
  4624. }


  4625. ngx_int_t
  4626. ‌ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool,
  4627.     ngx_str_t *s)
  4628. {
  4629.     ngx_str_t  cert;
  4630.     uintptr_t  n;

  4631.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  4632.         return NGX_ERROR;
  4633.     }

  4634.     if (cert.len == 0) {
  4635.         s->len = 0;
  4636.         return NGX_OK;
  4637.     }

  4638.     n = ngx_escape_uri(NULL, cert.data, cert.len, NGX_ESCAPE_URI_COMPONENT);

  4639.     s->len = cert.len + n * 2;
  4640.     s->data = ngx_pnalloc(pool, s->len);
  4641.     if (s->data == NULL) {
  4642.         return NGX_ERROR;
  4643.     }

  4644.     ngx_escape_uri(s->data, cert.data, cert.len, NGX_ESCAPE_URI_COMPONENT);

  4645.     return NGX_OK;
  4646. }


  4647. ngx_int_t
  4648. ‌ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4649. {
  4650.     BIO        *bio;
  4651.     X509       *cert;
  4652. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4653.     const
  4654. #endif
  4655.     X509_NAME  *name;

  4656.     s->len = 0;

  4657.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4658.     if (cert == NULL) {
  4659.         return NGX_OK;
  4660.     }

  4661.     name = X509_get_subject_name(cert);
  4662.     if (name == NULL) {
  4663.         X509_free(cert);
  4664.         return NGX_ERROR;
  4665.     }

  4666.     bio = BIO_new(BIO_s_mem());
  4667.     if (bio == NULL) {
  4668.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4669.         X509_free(cert);
  4670.         return NGX_ERROR;
  4671.     }

  4672.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4673.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4674.         goto failed;
  4675.     }

  4676.     s->len = BIO_pending(bio);
  4677.     s->data = ngx_pnalloc(pool, s->len);
  4678.     if (s->data == NULL) {
  4679.         goto failed;
  4680.     }

  4681.     BIO_read(bio, s->data, s->len);

  4682.     BIO_free(bio);
  4683.     X509_free(cert);

  4684.     return NGX_OK;

  4685. failed:

  4686.     BIO_free(bio);
  4687.     X509_free(cert);

  4688.     return NGX_ERROR;
  4689. }


  4690. ngx_int_t
  4691. ‌ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4692. {
  4693.     BIO        *bio;
  4694.     X509       *cert;
  4695. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4696.     const
  4697. #endif
  4698.     X509_NAME  *name;

  4699.     s->len = 0;

  4700.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4701.     if (cert == NULL) {
  4702.         return NGX_OK;
  4703.     }

  4704.     name = X509_get_issuer_name(cert);
  4705.     if (name == NULL) {
  4706.         X509_free(cert);
  4707.         return NGX_ERROR;
  4708.     }

  4709.     bio = BIO_new(BIO_s_mem());
  4710.     if (bio == NULL) {
  4711.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4712.         X509_free(cert);
  4713.         return NGX_ERROR;
  4714.     }

  4715.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4716.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4717.         goto failed;
  4718.     }

  4719.     s->len = BIO_pending(bio);
  4720.     s->data = ngx_pnalloc(pool, s->len);
  4721.     if (s->data == NULL) {
  4722.         goto failed;
  4723.     }

  4724.     BIO_read(bio, s->data, s->len);

  4725.     BIO_free(bio);
  4726.     X509_free(cert);

  4727.     return NGX_OK;

  4728. failed:

  4729.     BIO_free(bio);
  4730.     X509_free(cert);

  4731.     return NGX_ERROR;
  4732. }


  4733. ngx_int_t
  4734. ‌ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4735.     ngx_str_t *s)
  4736. {
  4737.     char       *p;
  4738.     size_t      len;
  4739.     X509       *cert;
  4740. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4741.     const
  4742. #endif
  4743.     X509_NAME  *name;

  4744.     s->len = 0;

  4745.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4746.     if (cert == NULL) {
  4747.         return NGX_OK;
  4748.     }

  4749.     name = X509_get_subject_name(cert);
  4750.     if (name == NULL) {
  4751.         X509_free(cert);
  4752.         return NGX_ERROR;
  4753.     }

  4754.     p = X509_NAME_oneline(name, NULL, 0);
  4755.     if (p == NULL) {
  4756.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4757.         X509_free(cert);
  4758.         return NGX_ERROR;
  4759.     }

  4760.     for (len = 0; p[len]; len++) { /* void */ }

  4761.     s->len = len;
  4762.     s->data = ngx_pnalloc(pool, len);
  4763.     if (s->data == NULL) {
  4764.         OPENSSL_free(p);
  4765.         X509_free(cert);
  4766.         return NGX_ERROR;
  4767.     }

  4768.     ngx_memcpy(s->data, p, len);

  4769.     OPENSSL_free(p);
  4770.     X509_free(cert);

  4771.     return NGX_OK;
  4772. }


  4773. ngx_int_t
  4774. ‌ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4775.     ngx_str_t *s)
  4776. {
  4777.     char       *p;
  4778.     size_t      len;
  4779.     X509       *cert;
  4780. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4781.     const
  4782. #endif
  4783.     X509_NAME  *name;

  4784.     s->len = 0;

  4785.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4786.     if (cert == NULL) {
  4787.         return NGX_OK;
  4788.     }

  4789.     name = X509_get_issuer_name(cert);
  4790.     if (name == NULL) {
  4791.         X509_free(cert);
  4792.         return NGX_ERROR;
  4793.     }

  4794.     p = X509_NAME_oneline(name, NULL, 0);
  4795.     if (p == NULL) {
  4796.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4797.         X509_free(cert);
  4798.         return NGX_ERROR;
  4799.     }

  4800.     for (len = 0; p[len]; len++) { /* void */ }

  4801.     s->len = len;
  4802.     s->data = ngx_pnalloc(pool, len);
  4803.     if (s->data == NULL) {
  4804.         OPENSSL_free(p);
  4805.         X509_free(cert);
  4806.         return NGX_ERROR;
  4807.     }

  4808.     ngx_memcpy(s->data, p, len);

  4809.     OPENSSL_free(p);
  4810.     X509_free(cert);

  4811.     return NGX_OK;
  4812. }


  4813. ngx_int_t
  4814. ‌ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4815. {
  4816.     size_t   len;
  4817.     X509    *cert;
  4818.     BIO     *bio;

  4819.     s->len = 0;

  4820.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4821.     if (cert == NULL) {
  4822.         return NGX_OK;
  4823.     }

  4824.     bio = BIO_new(BIO_s_mem());
  4825.     if (bio == NULL) {
  4826.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4827.         X509_free(cert);
  4828.         return NGX_ERROR;
  4829.     }

  4830.     i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
  4831.     len = BIO_pending(bio);

  4832.     s->len = len;
  4833.     s->data = ngx_pnalloc(pool, len);
  4834.     if (s->data == NULL) {
  4835.         BIO_free(bio);
  4836.         X509_free(cert);
  4837.         return NGX_ERROR;
  4838.     }

  4839.     BIO_read(bio, s->data, len);
  4840.     BIO_free(bio);
  4841.     X509_free(cert);

  4842.     return NGX_OK;
  4843. }


  4844. ngx_int_t
  4845. ‌ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4846. {
  4847.     X509          *cert;
  4848.     unsigned int   len;
  4849.     u_char         buf[EVP_MAX_MD_SIZE];

  4850.     s->len = 0;

  4851.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4852.     if (cert == NULL) {
  4853.         return NGX_OK;
  4854.     }

  4855.     if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
  4856.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed");
  4857.         X509_free(cert);
  4858.         return NGX_ERROR;
  4859.     }

  4860.     s->len = 2 * len;
  4861.     s->data = ngx_pnalloc(pool, 2 * len);
  4862.     if (s->data == NULL) {
  4863.         X509_free(cert);
  4864.         return NGX_ERROR;
  4865.     }

  4866.     ngx_hex_dump(s->data, buf, len);

  4867.     X509_free(cert);

  4868.     return NGX_OK;
  4869. }


  4870. ngx_int_t
  4871. ‌ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4872. {
  4873.     X509        *cert;
  4874.     long         rc;
  4875.     const char  *str;

  4876.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4877.     if (cert == NULL) {
  4878.         ngx_str_set(s, "NONE");
  4879.         return NGX_OK;
  4880.     }

  4881.     X509_free(cert);

  4882.     rc = SSL_get_verify_result(c->ssl->connection);

  4883.     if (rc == X509_V_OK) {
  4884.         if (ngx_ssl_ocsp_get_status(c, &str) == NGX_OK) {
  4885.             ngx_str_set(s, "SUCCESS");
  4886.             return NGX_OK;
  4887.         }

  4888.     } else {
  4889.         str = X509_verify_cert_error_string(rc);
  4890.     }

  4891.     s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str));
  4892.     if (s->data == NULL) {
  4893.         return NGX_ERROR;
  4894.     }

  4895.     s->len = ngx_sprintf(s->data, "FAILED:%s", str) - s->data;

  4896.     return NGX_OK;
  4897. }


  4898. ngx_int_t
  4899. ‌ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4900. {
  4901.     BIO     *bio;
  4902.     X509    *cert;
  4903.     size_t   len;

  4904.     s->len = 0;

  4905.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4906.     if (cert == NULL) {
  4907.         return NGX_OK;
  4908.     }

  4909.     bio = BIO_new(BIO_s_mem());
  4910.     if (bio == NULL) {
  4911.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4912.         X509_free(cert);
  4913.         return NGX_ERROR;
  4914.     }

  4915. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4916.     ASN1_TIME_print(bio, X509_get0_notBefore(cert));
  4917. #else
  4918.     ASN1_TIME_print(bio, X509_get_notBefore(cert));
  4919. #endif

  4920.     len = BIO_pending(bio);

  4921.     s->len = len;
  4922.     s->data = ngx_pnalloc(pool, len);
  4923.     if (s->data == NULL) {
  4924.         BIO_free(bio);
  4925.         X509_free(cert);
  4926.         return NGX_ERROR;
  4927.     }

  4928.     BIO_read(bio, s->data, len);
  4929.     BIO_free(bio);
  4930.     X509_free(cert);

  4931.     return NGX_OK;
  4932. }


  4933. ngx_int_t
  4934. ‌ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4935. {
  4936.     BIO     *bio;
  4937.     X509    *cert;
  4938.     size_t   len;

  4939.     s->len = 0;

  4940.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4941.     if (cert == NULL) {
  4942.         return NGX_OK;
  4943.     }

  4944.     bio = BIO_new(BIO_s_mem());
  4945.     if (bio == NULL) {
  4946.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4947.         X509_free(cert);
  4948.         return NGX_ERROR;
  4949.     }

  4950. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4951.     ASN1_TIME_print(bio, X509_get0_notAfter(cert));
  4952. #else
  4953.     ASN1_TIME_print(bio, X509_get_notAfter(cert));
  4954. #endif

  4955.     len = BIO_pending(bio);

  4956.     s->len = len;
  4957.     s->data = ngx_pnalloc(pool, len);
  4958.     if (s->data == NULL) {
  4959.         BIO_free(bio);
  4960.         X509_free(cert);
  4961.         return NGX_ERROR;
  4962.     }

  4963.     BIO_read(bio, s->data, len);
  4964.     BIO_free(bio);
  4965.     X509_free(cert);

  4966.     return NGX_OK;
  4967. }


  4968. ngx_int_t
  4969. ‌ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4970. {
  4971.     X509    *cert;
  4972.     time_t   now, end;

  4973.     s->len = 0;

  4974.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4975.     if (cert == NULL) {
  4976.         return NGX_OK;
  4977.     }

  4978. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4979.     end = ngx_ssl_parse_time(X509_get0_notAfter(cert), c->log);
  4980. #else
  4981.     end = ngx_ssl_parse_time(X509_get_notAfter(cert), c->log);
  4982. #endif

  4983.     if (end == (time_t) NGX_ERROR) {
  4984.         X509_free(cert);
  4985.         return NGX_OK;
  4986.     }

  4987.     now = ngx_time();

  4988.     if (end < now + 86400) {
  4989.         ngx_str_set(s, "0");
  4990.         X509_free(cert);
  4991.         return NGX_OK;
  4992.     }

  4993.     s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN);
  4994.     if (s->data == NULL) {
  4995.         X509_free(cert);
  4996.         return NGX_ERROR;
  4997.     }

  4998.     s->len = ngx_sprintf(s->data, "%T", (end - now) / 86400) - s->data;

  4999.     X509_free(cert);

  5000.     return NGX_OK;
  5001. }


  5002. static time_t
  5003. ‌ngx_ssl_parse_time(
  5004. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  5005.     const
  5006. #endif
  5007.     ASN1_TIME *asn1time, ngx_log_t *log)
  5008. {
  5009.     BIO     *bio;
  5010.     char    *value;
  5011.     size_t   len;
  5012.     time_t   time;

  5013.     /*
  5014.      * OpenSSL doesn't provide a way to convert ASN1_TIME
  5015.      * into time_t.  To do this, we use ASN1_TIME_print(),
  5016.      * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g.,
  5017.      * "Feb  3 00:55:52 2015 GMT"), and parse the result.
  5018.      */

  5019.     bio = BIO_new(BIO_s_mem());
  5020.     if (bio == NULL) {
  5021.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "BIO_new() failed");
  5022.         return NGX_ERROR;
  5023.     }

  5024.     /* fake weekday prepended to match C asctime() format */

  5025.     BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
  5026.     ASN1_TIME_print(bio, asn1time);
  5027.     len = BIO_get_mem_data(bio, &value);

  5028.     time = ngx_parse_http_time((u_char *) value, len);

  5029.     BIO_free(bio);

  5030.     return time;
  5031. }


  5032. ngx_int_t
  5033. ‌ngx_ssl_get_client_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  5034. {
  5035. #ifdef SSL_get0_peer_signature_name

  5036.     const char  *name;

  5037.     if (SSL_get0_peer_signature_name(c->ssl->connection, &name)) {
  5038.         s->len = ngx_strlen(name);
  5039.         s->data = ngx_pnalloc(pool, s->len);
  5040.         if (s->data == NULL) {
  5041.             return NGX_ERROR;
  5042.         }

  5043.         ngx_memcpy(s->data, name, s->len);

  5044.         return NGX_OK;
  5045.     }

  5046. #endif

  5047.     s->len = 0;
  5048.     return NGX_OK;
  5049. }


  5050. static void *
  5051. ‌ngx_openssl_create_conf(ngx_cycle_t *cycle)
  5052. {
  5053.     ngx_openssl_conf_t  *oscf;

  5054.     oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
  5055.     if (oscf == NULL) {
  5056.         return NULL;
  5057.     }

  5058.     /*
  5059.      * set by ngx_pcalloc():
  5060.      *
  5061.      *     oscf->engine = 0;
  5062.      */

  5063.     return oscf;
  5064. }


  5065. static char *
  5066. ‌ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  5067. {
  5068. #ifndef OPENSSL_NO_ENGINE

  5069.     ngx_openssl_conf_t *oscf = conf;

  5070.     ENGINE     *engine;
  5071.     ngx_str_t  *value;

  5072.     if (oscf->engine) {
  5073.         return "is duplicate";
  5074.     }

  5075.     oscf->engine = 1;

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

  5077.     engine = ENGINE_by_id((char *) value[1].data);

  5078.     if (engine == NULL) {
  5079.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  5080.                       "ENGINE_by_id(\"%V\") failed", &value[1]);
  5081.         return NGX_CONF_ERROR;
  5082.     }

  5083.     if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
  5084.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  5085.                       "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",
  5086.                       &value[1]);

  5087.         ENGINE_free(engine);

  5088.         return NGX_CONF_ERROR;
  5089.     }

  5090.     ENGINE_free(engine);

  5091.     return NGX_CONF_OK;

  5092. #else

  5093.     return "is not supported";

  5094. #endif
  5095. }


  5096. static void
  5097. ‌ngx_openssl_exit(ngx_cycle_t *cycle)
  5098. {
  5099. #if OPENSSL_VERSION_NUMBER < 0x10100003L

  5100.     EVP_cleanup();
  5101. #ifndef OPENSSL_NO_ENGINE
  5102.     ENGINE_cleanup();
  5103. #endif

  5104. #endif
  5105. }