src/event/ngx_event_openssl.c - nginx-1.31.7 nginx/ @ 939334eff

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 (c->ssl->shutdown_without_free) {
  2811.         c->ssl->shutdown_without_free = 0;
  2812.         c->recv = ngx_recv;
  2813.         return rc;
  2814.     }

  2815.     SSL_free(c->ssl->connection);
  2816.     c->ssl = NULL;
  2817.     c->recv = ngx_recv;

  2818.     return rc;
  2819. }


  2820. static void
  2821. ‌ngx_ssl_shutdown_handler(ngx_event_t *ev)
  2822. {
  2823.     ngx_connection_t           *c;
  2824.     ngx_connection_handler_pt   handler;

  2825.     c = ev->data;
  2826.     handler = c->ssl->handler;

  2827.     if (ev->timedout) {
  2828.         c->timedout = 1;
  2829.     }

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

  2831.     if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2832.         return;
  2833.     }

  2834.     handler(c);
  2835. }


  2836. void
  2837. ‌ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
  2838.     char *text)
  2839. {
  2840.     int         n;
  2841.     ngx_uint_t  level;

  2842.     level = NGX_LOG_CRIT;

  2843.     if (sslerr == SSL_ERROR_SYSCALL) {

  2844.         if (err == NGX_ECONNRESET
  2845. #if (NGX_WIN32)
  2846.             || err == NGX_ECONNABORTED
  2847. #endif
  2848.             || err == NGX_EPIPE
  2849.             || err == NGX_ENOTCONN
  2850.             || err == NGX_ETIMEDOUT
  2851.             || err == NGX_ECONNREFUSED
  2852.             || err == NGX_ENETDOWN
  2853.             || err == NGX_ENETUNREACH
  2854.             || err == NGX_EHOSTDOWN
  2855.             || err == NGX_EHOSTUNREACH)
  2856.         {
  2857.             switch (c->log_error) {

  2858.             case NGX_ERROR_IGNORE_ECONNRESET:
  2859.             case NGX_ERROR_INFO:
  2860.                 level = NGX_LOG_INFO;
  2861.                 break;

  2862.             case NGX_ERROR_ERR:
  2863.                 level = NGX_LOG_ERR;
  2864.                 break;

  2865.             default:
  2866.                 break;
  2867.             }
  2868.         }

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

  2870.         n = ERR_GET_REASON(ERR_peek_last_error());

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

  3041.             case NGX_ERROR_IGNORE_ECONNRESET:
  3042.             case NGX_ERROR_INFO:
  3043.                 level = NGX_LOG_INFO;
  3044.                 break;

  3045.             case NGX_ERROR_ERR:
  3046.                 level = NGX_LOG_ERR;
  3047.                 break;

  3048.             default:
  3049.                 break;
  3050.             }
  3051.         }
  3052.     }

  3053.     ngx_ssl_error(level, c->log, err, text);
  3054. }


  3055. static void
  3056. ‌ngx_ssl_clear_error(ngx_log_t *log)
  3057. {
  3058.     while (ERR_peek_error()) {
  3059.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
  3060.     }

  3061.     ERR_clear_error();
  3062. }


  3063. void ngx_cdecl
  3064. ‌ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
  3065. {
  3066.     int          flags;
  3067.     u_long       n;
  3068.     va_list      args;
  3069.     u_char      *p, *last;
  3070.     u_char       errstr[NGX_MAX_CONF_ERRSTR];
  3071.     const char  *data;

  3072.     last = errstr + NGX_MAX_CONF_ERRSTR;

  3073.     va_start(args, fmt);
  3074.     p = ngx_vslprintf(errstr, last - 1, fmt, args);
  3075.     va_end(args);

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

  3078.         for ( ;; ) {

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

  3080.             if (n == 0) {
  3081.                 break;
  3082.             }

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

  3084.             if (p >= last - 1) {
  3085.                 goto next;
  3086.             }

  3087.             *p++ = ' ';

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

  3089.             while (p < last && *p) {
  3090.                 p++;
  3091.             }

  3092.             if (p < last && *data && (flags & ERR_TXT_STRING)) {
  3093.                 *p++ = ':';
  3094.                 p = ngx_cpystrn(p, (u_char *) data, last - p);
  3095.             }

  3096.         next:

  3097.             (void) ERR_get_error();
  3098.         }

  3099.         if (p < last) {
  3100.             *p++ = ')';
  3101.         }
  3102.     }

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


  3105. ngx_int_t
  3106. ‌ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  3107.     ngx_array_t *certificates, ssize_t builtin_session_cache,
  3108.     ngx_shm_zone_t *shm_zone, time_t timeout)
  3109. {
  3110.     long  cache_mode;

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

  3112.     if (ngx_ssl_session_id_context(ssl, sess_ctx, certificates) != NGX_OK) {
  3113.         return NGX_ERROR;
  3114.     }

  3115.     if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
  3116.         SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
  3117.         return NGX_OK;
  3118.     }

  3119.     if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {

  3120.         /*
  3121.          * If the server explicitly says that it does not support
  3122.          * session reuse (see SSL_SESS_CACHE_OFF above), then
  3123.          * Outlook Express fails to upload a sent email to
  3124.          * the Sent Items folder on the IMAP server via a separate IMAP
  3125.          * connection in the background.  Therefore we have a special
  3126.          * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
  3127.          * where the server pretends that it supports session reuse,
  3128.          * but it does not actually store any session.
  3129.          */

  3130.         SSL_CTX_set_session_cache_mode(ssl->ctx,
  3131.                                        SSL_SESS_CACHE_SERVER
  3132.                                        |SSL_SESS_CACHE_NO_AUTO_CLEAR
  3133.                                        |SSL_SESS_CACHE_NO_INTERNAL_STORE);

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

  3135.         return NGX_OK;
  3136.     }

  3137.     cache_mode = SSL_SESS_CACHE_SERVER;

  3138.     if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
  3139.         cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
  3140.     }

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

  3142.     if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {

  3143.         if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
  3144.             SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
  3145.         }
  3146.     }

  3147.     if (shm_zone) {
  3148.         SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
  3149.         SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
  3150.         SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);

  3151.         if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone)
  3152.             == 0)
  3153.         {
  3154.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3155.                           "SSL_CTX_set_ex_data() failed");
  3156.             return NGX_ERROR;
  3157.         }
  3158.     }

  3159.     return NGX_OK;
  3160. }


  3161. static ngx_int_t
  3162. ‌ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  3163.     ngx_array_t *certificates)
  3164. {
  3165.     int                   n, i;
  3166.     X509                 *cert;
  3167.     X509_NAME            *name;
  3168.     ngx_str_t            *certs;
  3169.     ngx_uint_t            k;
  3170.     EVP_MD_CTX           *md;
  3171.     unsigned int          len;
  3172.     STACK_OF(X509_NAME)  *list;
  3173.     u_char                buf[EVP_MAX_MD_SIZE];

  3174.     /*
  3175.      * Session ID context is set based on the string provided,
  3176.      * the server certificates, and the client CA list.
  3177.      */

  3178.     md = EVP_MD_CTX_create();
  3179.     if (md == NULL) {
  3180.         return NGX_ERROR;
  3181.     }

  3182.     if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) {
  3183.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3184.                       "EVP_DigestInit_ex() failed");
  3185.         goto failed;
  3186.     }

  3187.     if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) {
  3188.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3189.                       "EVP_DigestUpdate() failed");
  3190.         goto failed;
  3191.     }

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

  3194.         if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
  3195.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3196.                           "X509_digest() failed");
  3197.             goto failed;
  3198.         }

  3199.         if (EVP_DigestUpdate(md, buf, len) == 0) {
  3200.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3201.                           "EVP_DigestUpdate() failed");
  3202.             goto failed;
  3203.         }
  3204.     }

  3205.     if (ssl->certs.nelts == 0 && certificates != NULL) {
  3206.         /*
  3207.          * If certificates are loaded dynamically, we use certificate
  3208.          * names as specified in the configuration (with variables).
  3209.          */

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

  3212.             if (EVP_DigestUpdate(md, certs[k].data, certs[k].len) == 0) {
  3213.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3214.                               "EVP_DigestUpdate() failed");
  3215.                 goto failed;
  3216.             }
  3217.         }
  3218.     }

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

  3220.     if (list != NULL) {
  3221.         n = sk_X509_NAME_num(list);

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

  3224.             if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
  3225.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3226.                               "X509_NAME_digest() failed");
  3227.                 goto failed;
  3228.             }

  3229.             if (EVP_DigestUpdate(md, buf, len) == 0) {
  3230.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3231.                               "EVP_DigestUpdate() failed");
  3232.                 goto failed;
  3233.             }
  3234.         }
  3235.     }

  3236.     if (EVP_DigestFinal_ex(md, buf, &len) == 0) {
  3237.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3238.                       "EVP_DigestFinal_ex() failed");
  3239.         goto failed;
  3240.     }

  3241.     EVP_MD_CTX_destroy(md);

  3242.     if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
  3243.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3244.                       "SSL_CTX_set_session_id_context() failed");
  3245.         return NGX_ERROR;
  3246.     }

  3247.     return NGX_OK;

  3248. failed:

  3249.     EVP_MD_CTX_destroy(md);

  3250.     return NGX_ERROR;
  3251. }


  3252. ngx_int_t
  3253. ‌ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  3254. {
  3255.     size_t                    len;
  3256.     ngx_slab_pool_t          *shpool;
  3257.     ngx_ssl_session_cache_t  *cache;

  3258.     if (data) {
  3259.         shm_zone->data = data;
  3260.         return NGX_OK;
  3261.     }

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

  3263.     if (shm_zone->shm.exists) {
  3264.         shm_zone->data = shpool->data;
  3265.         return NGX_OK;
  3266.     }

  3267.     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
  3268.     if (cache == NULL) {
  3269.         return NGX_ERROR;
  3270.     }

  3271.     shpool->data = cache;
  3272.     shm_zone->data = cache;

  3273.     ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
  3274.                     ngx_ssl_session_rbtree_insert_value);

  3275.     ngx_queue_init(&cache->expire_queue);

  3276.     cache->ticket_keys[0].expire = 0;
  3277.     cache->ticket_keys[1].expire = 0;
  3278.     cache->ticket_keys[2].expire = 0;

  3279.     cache->fail_time = 0;

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

  3281.     shpool->log_ctx = ngx_slab_alloc(shpool, len);
  3282.     if (shpool->log_ctx == NULL) {
  3283.         return NGX_ERROR;
  3284.     }

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

  3287.     shpool->log_nomem = 0;

  3288.     return NGX_OK;
  3289. }


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

  3306. static int
  3307. ‌ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
  3308. {
  3309.     int                       len;
  3310.     u_char                   *p, *session_id;
  3311.     size_t                    n;
  3312.     uint32_t                  hash;
  3313.     SSL_CTX                  *ssl_ctx;
  3314.     unsigned int              session_id_length;
  3315.     ngx_shm_zone_t           *shm_zone;
  3316.     ngx_connection_t         *c;
  3317.     ngx_slab_pool_t          *shpool;
  3318.     ngx_ssl_sess_id_t        *sess_id;
  3319.     ngx_ssl_session_cache_t  *cache;

  3320. #ifdef TLS1_3_VERSION

  3321.     /*
  3322.      * OpenSSL tries to save TLSv1.3 sessions into session cache
  3323.      * even when using tickets for stateless session resumption,
  3324.      * "because some applications just want to know about the creation
  3325.      * of a session"; do not cache such sessions
  3326.      */

  3327.     if (SSL_version(ssl_conn) == TLS1_3_VERSION
  3328.         && (SSL_get_options(ssl_conn) & SSL_OP_NO_TICKET) == 0)
  3329.     {
  3330.         return 0;
  3331.     }

  3332. #endif

  3333.     len = i2d_SSL_SESSION(sess, NULL);

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

  3335.     if (len > NGX_SSL_MAX_SESSION_SIZE) {
  3336.         return 0;
  3337.     }

  3338.     p = ngx_ssl_session_buffer;
  3339.     i2d_SSL_SESSION(sess, &p);

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

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

  3342.     if (session_id_length > 32) {
  3343.         return 0;
  3344.     }

  3345.     c = ngx_ssl_get_connection(ssl_conn);

  3346.     ssl_ctx = c->ssl->session_ctx;
  3347.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3348.     cache = shm_zone->data;
  3349.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3350.     ngx_shmtx_lock(&shpool->mutex);

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

  3353. #if (NGX_PTR_SIZE == 8)
  3354.     n = sizeof(ngx_ssl_sess_id_t);
  3355. #else
  3356.     n = offsetof(ngx_ssl_sess_id_t, session) + len;
  3357. #endif

  3358.     sess_id = ngx_slab_alloc_locked(shpool, n);

  3359.     if (sess_id == NULL) {

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

  3361.         ngx_ssl_expire_sessions(cache, shpool, 0);

  3362.         sess_id = ngx_slab_alloc_locked(shpool, n);

  3363.         if (sess_id == NULL) {
  3364.             goto failed;
  3365.         }
  3366.     }

  3367. #if (NGX_PTR_SIZE == 8)

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

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

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

  3371.         ngx_ssl_expire_sessions(cache, shpool, 0);

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

  3373.         if (sess_id->session == NULL) {
  3374.             goto failed;
  3375.         }
  3376.     }

  3377. #endif

  3378.     ngx_memcpy(sess_id->session, ngx_ssl_session_buffer, len);
  3379.     ngx_memcpy(sess_id->id, session_id, session_id_length);

  3380.     hash = ngx_crc32_short(session_id, session_id_length);

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

  3384.     sess_id->node.key = hash;
  3385.     sess_id->node.data = (u_char) session_id_length;
  3386.     sess_id->len = len;

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

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

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

  3390.     ngx_shmtx_unlock(&shpool->mutex);

  3391.     return 0;

  3392. failed:

  3393.     if (sess_id) {
  3394.         ngx_slab_free_locked(shpool, sess_id);
  3395.     }

  3396.     ngx_shmtx_unlock(&shpool->mutex);

  3397.     if (cache->fail_time != ngx_time()) {
  3398.         cache->fail_time = ngx_time();
  3399.         ngx_log_error(NGX_LOG_WARN, c->log, 0,
  3400.                       "could not allocate new session%s", shpool->log_ctx);
  3401.     }

  3402.     return 0;
  3403. }


  3404. static ngx_ssl_session_t *
  3405. ‌ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
  3406. #if OPENSSL_VERSION_NUMBER >= 0x10100003L
  3407.     const
  3408. #endif
  3409.     u_char *id, int len, int *copy)
  3410. {
  3411.     size_t                    slen;
  3412.     uint32_t                  hash;
  3413.     ngx_int_t                 rc;
  3414.     const u_char             *p;
  3415.     ngx_shm_zone_t           *shm_zone;
  3416.     ngx_slab_pool_t          *shpool;
  3417.     ngx_connection_t         *c;
  3418.     ngx_rbtree_node_t        *node, *sentinel;
  3419.     ngx_ssl_session_t        *sess;
  3420.     ngx_ssl_sess_id_t        *sess_id;
  3421.     ngx_ssl_session_cache_t  *cache;

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

  3424.     c = ngx_ssl_get_connection(ssl_conn);

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

  3427.     shm_zone = SSL_CTX_get_ex_data(c->ssl->session_ctx,
  3428.                                    ngx_ssl_session_cache_index);

  3429.     cache = shm_zone->data;

  3430.     sess = NULL;

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

  3432.     ngx_shmtx_lock(&shpool->mutex);

  3433.     node = cache->session_rbtree.root;
  3434.     sentinel = cache->session_rbtree.sentinel;

  3435.     while (node != sentinel) {

  3436.         if (hash < node->key) {
  3437.             node = node->left;
  3438.             continue;
  3439.         }

  3440.         if (hash > node->key) {
  3441.             node = node->right;
  3442.             continue;
  3443.         }

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

  3445.         sess_id = (ngx_ssl_sess_id_t *) node;

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

  3448.         if (rc == 0) {

  3449.             if (sess_id->expire > ngx_time()) {
  3450.                 slen = sess_id->len;

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

  3452.                 ngx_shmtx_unlock(&shpool->mutex);

  3453.                 p = ngx_ssl_session_buffer;
  3454.                 sess = d2i_SSL_SESSION(NULL, &p, slen);

  3455.                 return sess;
  3456.             }

  3457.             ngx_queue_remove(&sess_id->queue);

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

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

  3460. #if (NGX_PTR_SIZE == 8)
  3461.             ngx_slab_free_locked(shpool, sess_id->session);
  3462. #endif
  3463.             ngx_slab_free_locked(shpool, sess_id);

  3464.             sess = NULL;

  3465.             goto done;
  3466.         }

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

  3469. done:

  3470.     ngx_shmtx_unlock(&shpool->mutex);

  3471.     return sess;
  3472. }


  3473. void
  3474. ‌ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3475. {
  3476.     SSL_CTX_remove_session(ssl, sess);

  3477.     ngx_ssl_remove_session(ssl, sess);
  3478. }


  3479. static void
  3480. ‌ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3481. {
  3482.     u_char                   *id;
  3483.     uint32_t                  hash;
  3484.     ngx_int_t                 rc;
  3485.     unsigned int              len;
  3486.     ngx_shm_zone_t           *shm_zone;
  3487.     ngx_slab_pool_t          *shpool;
  3488.     ngx_rbtree_node_t        *node, *sentinel;
  3489.     ngx_ssl_sess_id_t        *sess_id;
  3490.     ngx_ssl_session_cache_t  *cache;

  3491.     shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);

  3492.     if (shm_zone == NULL) {
  3493.         return;
  3494.     }

  3495.     cache = shm_zone->data;

  3496.     id = (u_char *) SSL_SESSION_get_id(sess, &len);

  3497.     hash = ngx_crc32_short(id, len);

  3498.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
  3499.                    "ssl remove session: %08XD:%ud", hash, len);

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

  3501.     ngx_shmtx_lock(&shpool->mutex);

  3502.     node = cache->session_rbtree.root;
  3503.     sentinel = cache->session_rbtree.sentinel;

  3504.     while (node != sentinel) {

  3505.         if (hash < node->key) {
  3506.             node = node->left;
  3507.             continue;
  3508.         }

  3509.         if (hash > node->key) {
  3510.             node = node->right;
  3511.             continue;
  3512.         }

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

  3514.         sess_id = (ngx_ssl_sess_id_t *) node;

  3515.         rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);

  3516.         if (rc == 0) {

  3517.             ngx_queue_remove(&sess_id->queue);

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

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

  3520. #if (NGX_PTR_SIZE == 8)
  3521.             ngx_slab_free_locked(shpool, sess_id->session);
  3522. #endif
  3523.             ngx_slab_free_locked(shpool, sess_id);

  3524.             goto done;
  3525.         }

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

  3528. done:

  3529.     ngx_shmtx_unlock(&shpool->mutex);
  3530. }


  3531. static void
  3532. ‌ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
  3533.     ngx_slab_pool_t *shpool, ngx_uint_t n)
  3534. {
  3535.     time_t              now;
  3536.     ngx_queue_t        *q;
  3537.     ngx_ssl_sess_id_t  *sess_id;

  3538.     now = ngx_time();

  3539.     while (n < 3) {

  3540.         if (ngx_queue_empty(&cache->expire_queue)) {
  3541.             return;
  3542.         }

  3543.         q = ngx_queue_last(&cache->expire_queue);

  3544.         sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);

  3545.         if (n++ != 0 && sess_id->expire > now) {
  3546.             return;
  3547.         }

  3548.         ngx_queue_remove(q);

  3549.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
  3550.                        "expire session: %08Xi", sess_id->node.key);

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

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

  3553. #if (NGX_PTR_SIZE == 8)
  3554.         ngx_slab_free_locked(shpool, sess_id->session);
  3555. #endif
  3556.         ngx_slab_free_locked(shpool, sess_id);
  3557.     }
  3558. }


  3559. static void
  3560. ‌ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
  3561.     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
  3562. {
  3563.     ngx_rbtree_node_t  **p;
  3564.     ngx_ssl_sess_id_t   *sess_id, *sess_id_temp;

  3565.     for ( ;; ) {

  3566.         if (node->key < temp->key) {

  3567.             p = &temp->left;

  3568.         } else if (node->key > temp->key) {

  3569.             p = &temp->right;

  3570.         } else { /* node->key == temp->key */

  3571.             sess_id = (ngx_ssl_sess_id_t *) node;
  3572.             sess_id_temp = (ngx_ssl_sess_id_t *) temp;

  3573.             p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
  3574.                               (size_t) node->data, (size_t) temp->data)
  3575.                  < 0) ? &temp->left : &temp->right;
  3576.         }

  3577.         if (*p == sentinel) {
  3578.             break;
  3579.         }

  3580.         temp = *p;
  3581.     }

  3582.     *p = node;
  3583.     node->parent = temp;
  3584.     node->left = sentinel;
  3585.     node->right = sentinel;
  3586.     ngx_rbt_red(node);
  3587. }


  3588. #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB

  3589. ngx_int_t
  3590. ‌ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3591. {
  3592.     u_char                 buf[80];
  3593.     size_t                 size;
  3594.     ssize_t                n;
  3595.     ngx_str_t             *path;
  3596.     ngx_file_t             file;
  3597.     ngx_uint_t             i;
  3598.     ngx_array_t           *keys;
  3599.     ngx_file_info_t        fi;
  3600.     ngx_pool_cleanup_t    *cln;
  3601.     ngx_ssl_ticket_key_t  *key;

  3602.     if (paths == NULL
  3603.         && SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_session_cache_index) == NULL)
  3604.     {
  3605.         return NGX_OK;
  3606.     }

  3607.     keys = ngx_array_create(cf->pool, paths ? paths->nelts : 3,
  3608.                             sizeof(ngx_ssl_ticket_key_t));
  3609.     if (keys == NULL) {
  3610.         return NGX_ERROR;
  3611.     }

  3612.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  3613.     if (cln == NULL) {
  3614.         return NGX_ERROR;
  3615.     }

  3616.     cln->handler = ngx_ssl_ticket_keys_cleanup;
  3617.     cln->data = keys;

  3618.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ticket_keys_index, keys) == 0) {
  3619.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3620.                       "SSL_CTX_set_ex_data() failed");
  3621.         return NGX_ERROR;
  3622.     }

  3623.     if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx, ngx_ssl_ticket_key_callback)
  3624.         == 0)
  3625.     {
  3626.         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
  3627.                       "nginx was built with Session Tickets support, however, "
  3628.                       "now it is linked dynamically to an OpenSSL library "
  3629.                       "which has no tlsext support, therefore Session Tickets "
  3630.                       "are not available");
  3631.         return NGX_OK;
  3632.     }

  3633.     if (paths == NULL) {

  3634.         /* placeholder for keys in shared memory */

  3635.         key = ngx_array_push_n(keys, 3);
  3636.         key[0].shared = 1;
  3637.         key[0].expire = 0;
  3638.         key[1].shared = 1;
  3639.         key[1].expire = 0;
  3640.         key[2].shared = 1;
  3641.         key[2].expire = 0;

  3642.         return NGX_OK;
  3643.     }

  3644.     path = paths->elts;
  3645.     for (i = 0; i < paths->nelts; i++) {

  3646.         if (ngx_conf_full_name(cf->cycle, &path[i], 1) != NGX_OK) {
  3647.             return NGX_ERROR;
  3648.         }

  3649.         ngx_memzero(&file, sizeof(ngx_file_t));
  3650.         file.name = path[i];
  3651.         file.log = cf->log;

  3652.         file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
  3653.                                 NGX_FILE_OPEN, 0);

  3654.         if (file.fd == NGX_INVALID_FILE) {
  3655.             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  3656.                                ngx_open_file_n " \"%V\" failed", &file.name);
  3657.             return NGX_ERROR;
  3658.         }

  3659.         if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
  3660.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3661.                                ngx_fd_info_n " \"%V\" failed", &file.name);
  3662.             goto failed;
  3663.         }

  3664.         size = ngx_file_size(&fi);

  3665.         if (size != 48 && size != 80) {
  3666.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3667.                                "\"%V\" must be 48 or 80 bytes", &file.name);
  3668.             goto failed;
  3669.         }

  3670.         n = ngx_read_file(&file, buf, size, 0);

  3671.         if (n == NGX_ERROR) {
  3672.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3673.                                ngx_read_file_n " \"%V\" failed", &file.name);
  3674.             goto failed;
  3675.         }

  3676.         if ((size_t) n != size) {
  3677.             ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
  3678.                                ngx_read_file_n " \"%V\" returned only "
  3679.                                "%z bytes instead of %uz", &file.name, n, size);
  3680.             goto failed;
  3681.         }

  3682.         key = ngx_array_push(keys);
  3683.         if (key == NULL) {
  3684.             goto failed;
  3685.         }

  3686.         key->shared = 0;
  3687.         key->expire = 1;

  3688.         if (size == 48) {
  3689.             key->size = 48;
  3690.             ngx_memcpy(key->name, buf, 16);
  3691.             ngx_memcpy(key->aes_key, buf + 16, 16);
  3692.             ngx_memcpy(key->hmac_key, buf + 32, 16);

  3693.         } else {
  3694.             key->size = 80;
  3695.             ngx_memcpy(key->name, buf, 16);
  3696.             ngx_memcpy(key->hmac_key, buf + 16, 32);
  3697.             ngx_memcpy(key->aes_key, buf + 48, 32);
  3698.         }

  3699.         if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3700.             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3701.                           ngx_close_file_n " \"%V\" failed", &file.name);
  3702.         }

  3703.         ngx_explicit_memzero(&buf, 80);
  3704.     }

  3705.     return NGX_OK;

  3706. failed:

  3707.     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3708.         ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3709.                       ngx_close_file_n " \"%V\" failed", &file.name);
  3710.     }

  3711.     ngx_explicit_memzero(&buf, 80);

  3712.     return NGX_ERROR;
  3713. }


  3714. static int
  3715. ‌ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
  3716.     unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
  3717.     HMAC_CTX *hctx, int enc)
  3718. {
  3719.     size_t                 size;
  3720.     SSL_CTX               *ssl_ctx;
  3721.     ngx_uint_t             i;
  3722.     ngx_array_t           *keys;
  3723.     ngx_connection_t      *c;
  3724.     ngx_ssl_ticket_key_t  *key;
  3725.     const EVP_MD          *digest;
  3726.     const EVP_CIPHER      *cipher;

  3727.     c = ngx_ssl_get_connection(ssl_conn);
  3728.     ssl_ctx = c->ssl->session_ctx;

  3729.     if (ngx_ssl_rotate_ticket_keys(ssl_ctx, c->log) != NGX_OK) {
  3730.         return -1;
  3731.     }

  3732. #ifdef OPENSSL_NO_SHA256
  3733.     digest = EVP_sha1();
  3734. #else
  3735.     digest = EVP_sha256();
  3736. #endif

  3737.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3738.     if (keys == NULL) {
  3739.         return -1;
  3740.     }

  3741.     key = keys->elts;

  3742.     if (enc == 1) {
  3743.         /* encrypt session ticket */

  3744.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3745.                        "ssl ticket encrypt, key: \"%*xs\" (%s session)",
  3746.                        (size_t) 16, key[0].name,
  3747.                        SSL_session_reused(ssl_conn) ? "reused" : "new");

  3748.         if (key[0].size == 48) {
  3749.             cipher = EVP_aes_128_cbc();
  3750.             size = 16;

  3751.         } else {
  3752.             cipher = EVP_aes_256_cbc();
  3753.             size = 32;
  3754.         }

  3755.         if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
  3756.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed");
  3757.             return -1;
  3758.         }

  3759.         if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) {
  3760.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3761.                           "EVP_EncryptInit_ex() failed");
  3762.             return -1;
  3763.         }

  3764. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3765.         if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) {
  3766.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3767.             return -1;
  3768.         }
  3769. #else
  3770.         HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL);
  3771. #endif

  3772.         ngx_memcpy(name, key[0].name, 16);

  3773.         return 1;

  3774.     } else {
  3775.         /* decrypt session ticket */

  3776.         for (i = 0; i < keys->nelts; i++) {
  3777.             if (ngx_memcmp(name, key[i].name, 16) == 0) {
  3778.                 goto found;
  3779.             }
  3780.         }

  3781.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3782.                        "ssl ticket decrypt, key: \"%*xs\" not found",
  3783.                        (size_t) 16, name);

  3784.         return 0;

  3785.     found:

  3786.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3787.                        "ssl ticket decrypt, key: \"%*xs\"%s",
  3788.                        (size_t) 16, key[i].name, (i == 0) ? " (default)" : "");

  3789.         if (key[i].size == 48) {
  3790.             cipher = EVP_aes_128_cbc();
  3791.             size = 16;

  3792.         } else {
  3793.             cipher = EVP_aes_256_cbc();
  3794.             size = 32;
  3795.         }

  3796. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3797.         if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) {
  3798.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3799.             return -1;
  3800.         }
  3801. #else
  3802.         HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL);
  3803. #endif

  3804.         if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) {
  3805.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3806.                           "EVP_DecryptInit_ex() failed");
  3807.             return -1;
  3808.         }

  3809.         /* renew if TLSv1.3 */

  3810. #ifdef TLS1_3_VERSION
  3811.         if (SSL_version(ssl_conn) == TLS1_3_VERSION) {
  3812.             return 2;
  3813.         }
  3814. #endif

  3815.         /* renew if non-default key */

  3816.         if (i != 0 && key[i].expire) {
  3817.             return 2;
  3818.         }

  3819.         return 1;
  3820.     }
  3821. }


  3822. static ngx_int_t
  3823. ‌ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
  3824. {
  3825.     time_t                    now, expire;
  3826.     ngx_array_t              *keys;
  3827.     ngx_shm_zone_t           *shm_zone;
  3828.     ngx_slab_pool_t          *shpool;
  3829.     ngx_ssl_ticket_key_t     *key;
  3830.     ngx_ssl_session_cache_t  *cache;
  3831.     u_char                    buf[80];

  3832.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3833.     if (keys == NULL) {
  3834.         return NGX_OK;
  3835.     }

  3836.     key = keys->elts;

  3837.     if (!key[0].shared) {
  3838.         return NGX_OK;
  3839.     }

  3840.     /*
  3841.      * if we don't need to update expiration of the current key
  3842.      * and the previous key is still needed, don't sync with shared
  3843.      * memory to save some work; in the worst case other worker process
  3844.      * will switch to the next key, but this process will still be able
  3845.      * to decrypt tickets encrypted with it
  3846.      */

  3847.     now = ngx_time();
  3848.     expire = now + SSL_CTX_get_timeout(ssl_ctx);

  3849.     if (key[0].expire >= expire && key[1].expire >= now) {
  3850.         return NGX_OK;
  3851.     }

  3852.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3853.     cache = shm_zone->data;
  3854.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3855.     ngx_shmtx_lock(&shpool->mutex);

  3856.     key = cache->ticket_keys;

  3857.     if (key[0].expire == 0) {

  3858.         /* initialize the current key */

  3859.         if (RAND_bytes(buf, 80) != 1) {
  3860.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3861.             ngx_shmtx_unlock(&shpool->mutex);
  3862.             return NGX_ERROR;
  3863.         }

  3864.         key[0].shared = 1;
  3865.         key[0].expire = expire;
  3866.         key[0].size = 80;
  3867.         ngx_memcpy(key[0].name, buf, 16);
  3868.         ngx_memcpy(key[0].hmac_key, buf + 16, 32);
  3869.         ngx_memcpy(key[0].aes_key, buf + 48, 32);

  3870.         ngx_explicit_memzero(&buf, 80);

  3871.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3872.                        "ssl ticket key: \"%*xs\"",
  3873.                        (size_t) 16, key[0].name);

  3874.         /*
  3875.          * copy the current key to the next key, as initialization of
  3876.          * the previous key will replace the current key with the next
  3877.          * key
  3878.          */

  3879.         key[2] = key[0];
  3880.     }

  3881.     if (key[1].expire < now) {

  3882.         /*
  3883.          * if the previous key is no longer needed (or not initialized),
  3884.          * replace it with the current key, replace the current key with
  3885.          * the next key, and generate new next key
  3886.          */

  3887.         key[1] = key[0];
  3888.         key[0] = key[2];

  3889.         if (RAND_bytes(buf, 80) != 1) {
  3890.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3891.             ngx_shmtx_unlock(&shpool->mutex);
  3892.             return NGX_ERROR;
  3893.         }

  3894.         key[2].shared = 1;
  3895.         key[2].expire = 0;
  3896.         key[2].size = 80;
  3897.         ngx_memcpy(key[2].name, buf, 16);
  3898.         ngx_memcpy(key[2].hmac_key, buf + 16, 32);
  3899.         ngx_memcpy(key[2].aes_key, buf + 48, 32);

  3900.         ngx_explicit_memzero(&buf, 80);

  3901.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3902.                        "ssl ticket key: \"%*xs\"",
  3903.                        (size_t) 16, key[2].name);
  3904.     }

  3905.     /*
  3906.      * update expiration of the current key: it is going to be needed
  3907.      * at least till the session being created expires
  3908.      */

  3909.     if (expire > key[0].expire) {
  3910.         key[0].expire = expire;
  3911.     }

  3912.     /* sync keys to the worker process memory */

  3913.     ngx_memcpy(keys->elts, cache->ticket_keys,
  3914.                2 * sizeof(ngx_ssl_ticket_key_t));

  3915.     ngx_shmtx_unlock(&shpool->mutex);

  3916.     return NGX_OK;
  3917. }


  3918. static void
  3919. ‌ngx_ssl_ticket_keys_cleanup(void *data)
  3920. {
  3921.     ngx_array_t  *keys = data;

  3922.     ngx_explicit_memzero(keys->elts,
  3923.                          keys->nelts * sizeof(ngx_ssl_ticket_key_t));
  3924. }

  3925. #else

  3926. ngx_int_t
  3927. ‌ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3928. {
  3929.     if (paths) {
  3930.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  3931.                       "\"ssl_session_ticket_key\" ignored, not supported");
  3932.     }

  3933.     return NGX_OK;
  3934. }

  3935. #endif


  3936. void
  3937. ‌ngx_ssl_cleanup_ctx(void *data)
  3938. {
  3939.     ngx_ssl_t  *ssl = data;

  3940.     X509        *cert;
  3941.     u_char      *p;
  3942.     ngx_uint_t   i;

  3943.     for (i = 0; i < ssl->certs.nelts; i++) {
  3944.         cert = ((X509 **) ssl->certs.elts)[i];

  3945.         p = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);

  3946.         if (p) {
  3947.             ngx_free(p);
  3948.             X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, NULL);
  3949.         }

  3950.         X509_free(cert);
  3951.     }

  3952.     SSL_CTX_free(ssl->ctx);
  3953. }


  3954. ngx_int_t
  3955. ‌ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
  3956. {
  3957.     X509       *cert;
  3958.     u_char     *addr;
  3959.     size_t      alen;
  3960.     in_addr_t   addr4;
  3961. #if (NGX_HAVE_INET6)
  3962.     u_char      addr6[16];
  3963. #endif

  3964.     cert = SSL_get_peer_certificate(c->ssl->connection);
  3965.     if (cert == NULL) {
  3966.         return NGX_ERROR;
  3967.     }

  3968.     if (name->len == 0) {
  3969.         goto failed;
  3970.     }

  3971.     addr4 = ngx_inet_addr(name->data, name->len);

  3972.     if (addr4 != INADDR_NONE) {
  3973.         addr = (u_char *) &addr4;
  3974.         alen = 4;

  3975. #if (NGX_HAVE_INET6)
  3976.     } else if (name->data[0] == '[') {

  3977.         if (name->data[name->len - 1] != ']') {
  3978.             goto failed;
  3979.         }

  3980.         if (ngx_inet6_addr(name->data + 1, name->len - 2, addr6) != NGX_OK) {
  3981.             goto failed;
  3982.         }

  3983.         addr = addr6;
  3984.         alen = 16;

  3985. #endif
  3986.     } else {
  3987.         addr = NULL;
  3988.         alen = 0;
  3989.     }

  3990. #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

  3991.     /* X509_check_host() is only available in OpenSSL 1.0.2+ */

  3992.     if (addr) {
  3993.         if (X509_check_ip(cert, addr, alen, 0) != 1) {
  3994.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3995.                            "X509_check_ip(): no match");
  3996.             goto failed;
  3997.         }

  3998.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3999.                        "X509_check_ip(): match");
  4000.         goto found;
  4001.     }

  4002.     if (X509_check_host(cert, (char *) name->data, name->len, 0, NULL) != 1) {
  4003.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4004.                        "X509_check_host(): no match");
  4005.         goto failed;
  4006.     }

  4007.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4008.                    "X509_check_host(): match");
  4009.     goto found;

  4010. #else
  4011.     {
  4012.     int                      n, i;
  4013.     size_t                   dlen;
  4014.     u_char                  *data;
  4015.     X509_NAME               *sname;
  4016.     ASN1_STRING             *str;
  4017.     X509_NAME_ENTRY         *entry;
  4018.     GENERAL_NAME            *altname;
  4019.     STACK_OF(GENERAL_NAME)  *altnames;

  4020.     /*
  4021.      * As per RFC6125 and RFC2818, we check subjectAltName extension,
  4022.      * and if it's not present - commonName in Subject is checked.
  4023.      */

  4024.     altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);

  4025.     if (altnames) {
  4026.         n = sk_GENERAL_NAME_num(altnames);

  4027.         for (i = 0; i < n; i++) {
  4028.             altname = sk_GENERAL_NAME_value(altnames, i);

  4029.             if (altname->type == GEN_DNS) {

  4030.                 str = altname->d.dNSName;

  4031.                 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4032.                                "SSL subjectAltName: \"%*s\"",
  4033.                                (size_t) ASN1_STRING_length(str),
  4034.                                ASN1_STRING_data(str));

  4035.                 if (addr == NULL && ngx_ssl_check_name(name, str) == NGX_OK) {
  4036.                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4037.                                    "SSL subjectAltName: match");
  4038.                     GENERAL_NAMES_free(altnames);
  4039.                     goto found;
  4040.                 }

  4041.             } else if (altname->type == GEN_IPADD) {

  4042.                 str = altname->d.iPAddress;
  4043.                 data = ASN1_STRING_data(str);
  4044.                 dlen = ASN1_STRING_length(str);

  4045. #if (NGX_DEBUG)
  4046.                 {
  4047.                 size_t  al;
  4048.                 u_char  at[NGX_INET6_ADDRSTRLEN];

  4049.                 if (dlen == 4) {
  4050.                     al = ngx_inet_ntop(AF_INET, data, at,
  4051.                                        NGX_INET6_ADDRSTRLEN);

  4052. #if (NGX_HAVE_INET6)
  4053.                 } else if (dlen == 16) {
  4054.                     al = ngx_inet_ntop(AF_INET6, data, at,
  4055.                                        NGX_INET6_ADDRSTRLEN);

  4056. #endif
  4057.                 } else {
  4058.                     al = ngx_cpymem(at, "<invalid>", sizeof("<invalid>") - 1)
  4059.                          - at;
  4060.                 }

  4061.                 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4062.                                "SSL subjectAltName: \"%*s\"",
  4063.                                al, at);
  4064.                 }
  4065. #endif

  4066.                 if (addr
  4067.                     && alen == dlen
  4068.                     && ngx_memcmp(addr, data, dlen) == 0)
  4069.                 {
  4070.                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4071.                                    "SSL subjectAltName: match");
  4072.                     GENERAL_NAMES_free(altnames);
  4073.                     goto found;
  4074.                 }
  4075.             }
  4076.         }

  4077.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4078.                        "SSL subjectAltName: no match");

  4079.         GENERAL_NAMES_free(altnames);
  4080.         goto failed;
  4081.     }

  4082.     /*
  4083.      * If there is no subjectAltName extension, check commonName
  4084.      * in Subject.  While RFC2818 requires to only check "most specific"
  4085.      * CN, both Apache and OpenSSL check all CNs, and so do we.
  4086.      */

  4087.     if (addr) {
  4088.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4089.                        "SSL commonName: no match");
  4090.         goto failed;
  4091.     }

  4092.     sname = X509_get_subject_name(cert);

  4093.     if (sname == NULL) {
  4094.         goto failed;
  4095.     }

  4096.     i = -1;
  4097.     for ( ;; ) {
  4098.         i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);

  4099.         if (i < 0) {
  4100.             break;
  4101.         }

  4102.         entry = X509_NAME_get_entry(sname, i);
  4103.         str = X509_NAME_ENTRY_get_data(entry);

  4104.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4105.                        "SSL commonName: \"%*s\"",
  4106.                        (size_t) ASN1_STRING_length(str),
  4107.                        ASN1_STRING_data(str));

  4108.         if (ngx_ssl_check_name(name, str) == NGX_OK) {
  4109.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4110.                            "SSL commonName: match");
  4111.             goto found;
  4112.         }
  4113.     }

  4114.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  4115.                    "SSL commonName: no match");
  4116.     }
  4117. #endif

  4118. failed:

  4119.     X509_free(cert);
  4120.     return NGX_ERROR;

  4121. found:

  4122.     X509_free(cert);
  4123.     return NGX_OK;
  4124. }


  4125. #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

  4126. static ngx_int_t
  4127. ‌ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern)
  4128. {
  4129.     u_char  *s, *p, *end;
  4130.     size_t   slen, plen;

  4131.     s = name->data;
  4132.     slen = name->len;

  4133.     p = ASN1_STRING_data(pattern);
  4134.     plen = ASN1_STRING_length(pattern);

  4135.     if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) {
  4136.         return NGX_OK;
  4137.     }

  4138.     if (plen > 2 && p[0] == '*' && p[1] == '.') {
  4139.         plen -= 1;
  4140.         p += 1;

  4141.         end = s + slen;
  4142.         s = ngx_strlchr(s, end, '.');

  4143.         if (s == NULL) {
  4144.             return NGX_ERROR;
  4145.         }

  4146.         slen = end - s;

  4147.         if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) {
  4148.             return NGX_OK;
  4149.         }
  4150.     }

  4151.     return NGX_ERROR;
  4152. }

  4153. #endif


  4154. ngx_int_t
  4155. ‌ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4156. {
  4157.     s->data = (u_char *) SSL_get_version(c->ssl->connection);
  4158.     return NGX_OK;
  4159. }


  4160. ngx_int_t
  4161. ‌ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4162. {
  4163.     s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);
  4164.     return NGX_OK;
  4165. }


  4166. ngx_int_t
  4167. ‌ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4168. {
  4169. #ifdef SSL_CTRL_GET_RAW_CIPHERLIST

  4170.     int                n, i, bytes;
  4171.     size_t             len;
  4172.     u_char            *ciphers, *p;
  4173.     const SSL_CIPHER  *cipher;

  4174.     bytes = SSL_get0_raw_cipherlist(c->ssl->connection, NULL);
  4175.     n = SSL_get0_raw_cipherlist(c->ssl->connection, &ciphers);

  4176.     if (n <= 0) {
  4177.         s->len = 0;
  4178.         return NGX_OK;
  4179.     }

  4180.     len = 0;
  4181.     n /= bytes;

  4182.     for (i = 0; i < n; i++) {
  4183.         cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes);

  4184.         if (cipher) {
  4185.             len += ngx_strlen(SSL_CIPHER_get_name(cipher));

  4186.         } else {
  4187.             len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1);
  4188.         }

  4189.         len += sizeof(":") - 1;
  4190.     }

  4191.     s->data = ngx_pnalloc(pool, len);
  4192.     if (s->data == NULL) {
  4193.         return NGX_ERROR;
  4194.     }

  4195.     p = s->data;

  4196.     for (i = 0; i < n; i++) {
  4197.         cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes);

  4198.         if (cipher) {
  4199.             p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher));

  4200.         } else {
  4201.             p = ngx_sprintf(p, "0x");
  4202.             p = ngx_hex_dump(p, ciphers + i * bytes, bytes);
  4203.         }

  4204.         *p++ = ':';
  4205.     }

  4206.     p--;

  4207.     s->len = p - s->data;

  4208. #else

  4209.     u_char  buf[4096];

  4210.     if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096)
  4211.         == NULL)
  4212.     {
  4213.         s->len = 0;
  4214.         return NGX_OK;
  4215.     }

  4216.     s->len = ngx_strlen(buf);
  4217.     s->data = ngx_pnalloc(pool, s->len);
  4218.     if (s->data == NULL) {
  4219.         return NGX_ERROR;
  4220.     }

  4221.     ngx_memcpy(s->data, buf, s->len);

  4222. #endif

  4223.     return NGX_OK;
  4224. }


  4225. ngx_int_t
  4226. ‌ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4227. {
  4228. #ifdef SSL_get_negotiated_group

  4229.     int          nid;
  4230.     const char  *name;

  4231.     nid = SSL_get_negotiated_group(c->ssl->connection);

  4232.     if (nid != NID_undef) {

  4233.         if ((nid & TLSEXT_nid_unknown) == 0) {
  4234.             s->len = ngx_strlen(OBJ_nid2sn(nid));
  4235.             s->data = (u_char *) OBJ_nid2sn(nid);
  4236.             return NGX_OK;
  4237.         }

  4238.         name = SSL_group_to_name(c->ssl->connection, nid);

  4239.         s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
  4240.         s->data = ngx_pnalloc(pool, s->len);
  4241.         if (s->data == NULL) {
  4242.             return NGX_ERROR;
  4243.         }

  4244.         if (name) {
  4245.             ngx_memcpy(s->data, name, s->len);

  4246.         } else {
  4247.             ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);
  4248.         }

  4249.         return NGX_OK;
  4250.     }

  4251. #endif

  4252.     s->len = 0;
  4253.     return NGX_OK;
  4254. }


  4255. ngx_int_t
  4256. ‌ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4257. {
  4258. #ifdef SSL_CTRL_GET_CURVES

  4259.     int         *curves, n, i, nid;
  4260.     u_char      *p;
  4261.     size_t       len;
  4262.     const char  *name;

  4263.     n = SSL_get1_curves(c->ssl->connection, NULL);

  4264.     if (n <= 0) {
  4265.         s->len = 0;
  4266.         return NGX_OK;
  4267.     }

  4268.     curves = ngx_palloc(pool, n * sizeof(int));
  4269.     if (curves == NULL) {
  4270.         return NGX_ERROR;
  4271.     }

  4272.     n = SSL_get1_curves(c->ssl->connection, curves);
  4273.     len = 0;

  4274.     for (i = 0; i < n; i++) {
  4275.         nid = curves[i];

  4276.         if (nid & TLSEXT_nid_unknown) {
  4277.             name = SSL_group_to_name(c->ssl->connection, nid);

  4278.             len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;

  4279.         } else {
  4280.             len += ngx_strlen(OBJ_nid2sn(nid));
  4281.         }

  4282.         len += sizeof(":") - 1;
  4283.     }

  4284.     s->data = ngx_pnalloc(pool, len);
  4285.     if (s->data == NULL) {
  4286.         return NGX_ERROR;
  4287.     }

  4288.     p = s->data;

  4289.     for (i = 0; i < n; i++) {
  4290.         nid = curves[i];

  4291.         if (nid & TLSEXT_nid_unknown) {
  4292.             name = SSL_group_to_name(c->ssl->connection, nid);

  4293.             p = name ? ngx_cpymem(p, name, ngx_strlen(name))
  4294.                      : ngx_sprintf(p, "0x%04xd", nid & 0xffff);

  4295.         } else {
  4296.             p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));
  4297.         }

  4298.         *p++ = ':';
  4299.     }

  4300.     p--;

  4301.     s->len = p - s->data;

  4302. #else

  4303.     s->len = 0;

  4304. #endif

  4305.     return NGX_OK;
  4306. }


  4307. ngx_int_t
  4308. ‌ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4309. {
  4310. #ifdef SSL_get0_signature_name

  4311.     const char  *name;

  4312.     if (SSL_get0_signature_name(c->ssl->connection, &name)) {
  4313.         s->len = ngx_strlen(name);
  4314.         s->data = ngx_pnalloc(pool, s->len);
  4315.         if (s->data == NULL) {
  4316.             return NGX_ERROR;
  4317.         }

  4318.         ngx_memcpy(s->data, name, s->len);

  4319.         return NGX_OK;
  4320.     }

  4321. #endif

  4322.     s->len = 0;
  4323.     return NGX_OK;
  4324. }


  4325. ngx_int_t
  4326. ‌ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4327. {
  4328. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)

  4329.     int            n, i;
  4330.     size_t         len;
  4331.     u_char        *p;
  4332.     const char    *name;
  4333.     unsigned int   codepoint;

  4334.     n = SSL_get0_sigalg(c->ssl->connection, -1, NULL, NULL);

  4335.     if (n <= 0) {
  4336.         s->len = 0;
  4337.         return NGX_OK;
  4338.     }

  4339.     len = 0;

  4340.     for (i = 0; i < n; i++) {
  4341.         SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name);
  4342.         len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
  4343.         len += sizeof(":") - 1;
  4344.     }

  4345.     s->data = ngx_pnalloc(pool, len);
  4346.     if (s->data == NULL) {
  4347.         return NGX_ERROR;
  4348.     }

  4349.     p = s->data;

  4350.     for (i = 0; i < n; i++) {
  4351.         SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name);

  4352.         if (name) {
  4353.             p = ngx_cpymem(p, name, ngx_strlen(name));

  4354.         } else {
  4355.             p = ngx_sprintf(p, "0x%04xd", codepoint);
  4356.         }

  4357.         *p++ = ':';
  4358.     }

  4359.     p--;

  4360.     s->len = p - s->data;

  4361. #elif defined SSL_CTRL_SET_SIGALGS

  4362.     /*
  4363.      * SSL_get_sigalgs() is only available in OpenSSL 1.0.2+,
  4364.      * but uses a different naming, so emit raw codes
  4365.      */

  4366.     int             n, i;
  4367.     size_t          len;
  4368.     u_char         *p;
  4369.     unsigned char   rsig, rhash;

  4370.     n = SSL_get_sigalgs(c->ssl->connection, -1, NULL, NULL, NULL, NULL, NULL);

  4371.     if (n <= 0) {
  4372.         s->len = 0;
  4373.         return NGX_OK;
  4374.     }

  4375.     len = n * (sizeof("0x0000") - 1 + sizeof(":") - 1);

  4376.     s->data = ngx_pnalloc(pool, len);
  4377.     if (s->data == NULL) {
  4378.         return NGX_ERROR;
  4379.     }

  4380.     p = s->data;

  4381.     for (i = 0; i < n; i++) {
  4382.         SSL_get_sigalgs(c->ssl->connection, i, NULL, NULL, NULL, &rsig, &rhash);
  4383.         p = ngx_sprintf(p, "0x%04xd", rhash << 8 | rsig);
  4384.         *p++ = ':';
  4385.     }

  4386.     p--;

  4387.     s->len = p - s->data;

  4388. #else

  4389.     s->len = 0;

  4390. #endif

  4391.     return NGX_OK;
  4392. }


  4393. ngx_int_t
  4394. ‌ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4395. {
  4396.     u_char        *buf;
  4397.     SSL_SESSION   *sess;
  4398.     unsigned int   len;

  4399.     sess = SSL_get0_session(c->ssl->connection);
  4400.     if (sess == NULL) {
  4401.         s->len = 0;
  4402.         return NGX_OK;
  4403.     }

  4404.     buf = (u_char *) SSL_SESSION_get_id(sess, &len);

  4405.     s->len = 2 * len;
  4406.     s->data = ngx_pnalloc(pool, 2 * len);
  4407.     if (s->data == NULL) {
  4408.         return NGX_ERROR;
  4409.     }

  4410.     ngx_hex_dump(s->data, buf, len);

  4411.     return NGX_OK;
  4412. }


  4413. ngx_int_t
  4414. ‌ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4415. {
  4416.     if (SSL_session_reused(c->ssl->connection)) {
  4417.         ngx_str_set(s, "r");

  4418.     } else {
  4419.         ngx_str_set(s, ".");
  4420.     }

  4421.     return NGX_OK;
  4422. }


  4423. ngx_int_t
  4424. ‌ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4425. {
  4426.     s->len = 0;

  4427. #ifdef SSL_ERROR_EARLY_DATA_REJECTED

  4428.     /* BoringSSL */

  4429.     if (SSL_in_early_data(c->ssl->connection)) {
  4430.         ngx_str_set(s, "1");
  4431.     }

  4432. #elif defined SSL_READ_EARLY_DATA_SUCCESS

  4433.     /* OpenSSL */

  4434.     if (!SSL_is_init_finished(c->ssl->connection)) {
  4435.         ngx_str_set(s, "1");
  4436.     }

  4437. #endif

  4438.     return NGX_OK;
  4439. }


  4440. ngx_int_t
  4441. ‌ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4442. {
  4443. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  4444.     size_t       len;
  4445.     const char  *name;

  4446.     name = SSL_get_servername(c->ssl->connection, TLSEXT_NAMETYPE_host_name);

  4447.     if (name) {
  4448.         len = ngx_strlen(name);

  4449.         s->len = len;
  4450.         s->data = ngx_pnalloc(pool, len);
  4451.         if (s->data == NULL) {
  4452.             return NGX_ERROR;
  4453.         }

  4454.         ngx_memcpy(s->data, name, len);

  4455.         return NGX_OK;
  4456.     }

  4457. #endif

  4458.     s->len = 0;
  4459.     return NGX_OK;
  4460. }


  4461. ngx_int_t
  4462. ‌ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4463. {
  4464. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  4465.     unsigned int          len;
  4466.     const unsigned char  *data;

  4467.     SSL_get0_alpn_selected(c->ssl->connection, &data, &len);

  4468.     if (len > 0) {

  4469.         s->data = ngx_pnalloc(pool, len);
  4470.         if (s->data == NULL) {
  4471.             return NGX_ERROR;
  4472.         }

  4473.         ngx_memcpy(s->data, data, len);
  4474.         s->len = len;

  4475.         return NGX_OK;
  4476.     }

  4477. #endif

  4478.     s->len = 0;
  4479.     return NGX_OK;
  4480. }


  4481. ngx_int_t
  4482. ‌ngx_ssl_get_ech_status(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4483. {
  4484. #ifdef SSL_OP_ECH_GREASE
  4485.     int    echrv;
  4486.     char  *inner_sni, *outer_sni;

  4487.     inner_sni = NULL;
  4488.     outer_sni = NULL;

  4489.     echrv = SSL_ech_get1_status(c->ssl->connection, &inner_sni, &outer_sni);

  4490.     switch (echrv) {
  4491.     case SSL_ECH_STATUS_NOT_TRIED:
  4492.         ngx_str_set(s, "NOT_TRIED");
  4493.         break;
  4494.     case SSL_ECH_STATUS_SUCCESS:
  4495.         ngx_str_set(s, "SUCCESS");
  4496.         break;
  4497.     case SSL_ECH_STATUS_GREASE:
  4498.         ngx_str_set(s, "GREASE");
  4499.         break;
  4500.     case SSL_ECH_STATUS_BACKEND:
  4501.         ngx_str_set(s, "BACKEND");
  4502.         break;
  4503.     default:
  4504.         ngx_str_set(s, "FAILED");
  4505.         break;
  4506.     }

  4507.     OPENSSL_free(inner_sni);
  4508.     OPENSSL_free(outer_sni);
  4509. #else
  4510.     s->len = 0;
  4511. #endif
  4512.     return NGX_OK;
  4513. }


  4514. ngx_int_t
  4515. ‌ngx_ssl_get_ech_outer_server_name(ngx_connection_t *c, ngx_pool_t *pool,
  4516.     ngx_str_t *s)
  4517. {
  4518. #if defined(SSL_OP_ECH_GREASE)
  4519.     int    echrv;
  4520.     char  *inner_sni, *outer_sni;

  4521.     inner_sni = NULL;
  4522.     outer_sni = NULL;

  4523.     echrv = SSL_ech_get1_status(c->ssl->connection, &inner_sni, &outer_sni);

  4524.     if (echrv == SSL_ECH_STATUS_SUCCESS && outer_sni) {
  4525.         s->len = ngx_strlen(outer_sni);

  4526.         s->data = ngx_pnalloc(pool, s->len);
  4527.         if (s->data == NULL) {
  4528.             OPENSSL_free(inner_sni);
  4529.             OPENSSL_free(outer_sni);
  4530.             return NGX_ERROR;
  4531.         }

  4532.         ngx_memcpy(s->data, outer_sni, s->len);

  4533.     } else {
  4534.         s->len = 0;
  4535.     }

  4536.     OPENSSL_free(inner_sni);
  4537.     OPENSSL_free(outer_sni);
  4538. #else
  4539.     s->len = 0;
  4540. #endif
  4541.     return NGX_OK;
  4542. }


  4543. ngx_int_t
  4544. ‌ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4545. {
  4546.     size_t   len;
  4547.     BIO     *bio;
  4548.     X509    *cert;

  4549.     s->len = 0;

  4550.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4551.     if (cert == NULL) {
  4552.         return NGX_OK;
  4553.     }

  4554.     bio = BIO_new(BIO_s_mem());
  4555.     if (bio == NULL) {
  4556.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4557.         X509_free(cert);
  4558.         return NGX_ERROR;
  4559.     }

  4560.     if (PEM_write_bio_X509(bio, cert) == 0) {
  4561.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
  4562.         goto failed;
  4563.     }

  4564.     len = BIO_pending(bio);
  4565.     s->len = len;

  4566.     s->data = ngx_pnalloc(pool, len);
  4567.     if (s->data == NULL) {
  4568.         goto failed;
  4569.     }

  4570.     BIO_read(bio, s->data, len);

  4571.     BIO_free(bio);
  4572.     X509_free(cert);

  4573.     return NGX_OK;

  4574. failed:

  4575.     BIO_free(bio);
  4576.     X509_free(cert);

  4577.     return NGX_ERROR;
  4578. }


  4579. ngx_int_t
  4580. ‌ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4581. {
  4582.     u_char      *p;
  4583.     size_t       len;
  4584.     ngx_uint_t   i;
  4585.     ngx_str_t    cert;

  4586.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  4587.         return NGX_ERROR;
  4588.     }

  4589.     if (cert.len == 0) {
  4590.         s->len = 0;
  4591.         return NGX_OK;
  4592.     }

  4593.     len = cert.len - 1;

  4594.     for (i = 0; i < cert.len - 1; i++) {
  4595.         if (cert.data[i] == LF) {
  4596.             len++;
  4597.         }
  4598.     }

  4599.     s->len = len;
  4600.     s->data = ngx_pnalloc(pool, len);
  4601.     if (s->data == NULL) {
  4602.         return NGX_ERROR;
  4603.     }

  4604.     p = s->data;

  4605.     for (i = 0; i < cert.len - 1; i++) {
  4606.         *p++ = cert.data[i];
  4607.         if (cert.data[i] == LF) {
  4608.             *p++ = '\t';
  4609.         }
  4610.     }

  4611.     return NGX_OK;
  4612. }


  4613. ngx_int_t
  4614. ‌ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool,
  4615.     ngx_str_t *s)
  4616. {
  4617.     ngx_str_t  cert;
  4618.     uintptr_t  n;

  4619.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  4620.         return NGX_ERROR;
  4621.     }

  4622.     if (cert.len == 0) {
  4623.         s->len = 0;
  4624.         return NGX_OK;
  4625.     }

  4626.     n = ngx_escape_uri(NULL, cert.data, cert.len, NGX_ESCAPE_URI_COMPONENT);

  4627.     s->len = cert.len + n * 2;
  4628.     s->data = ngx_pnalloc(pool, s->len);
  4629.     if (s->data == NULL) {
  4630.         return NGX_ERROR;
  4631.     }

  4632.     ngx_escape_uri(s->data, cert.data, cert.len, NGX_ESCAPE_URI_COMPONENT);

  4633.     return NGX_OK;
  4634. }


  4635. ngx_int_t
  4636. ‌ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4637. {
  4638.     BIO        *bio;
  4639.     X509       *cert;
  4640. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4641.     const
  4642. #endif
  4643.     X509_NAME  *name;

  4644.     s->len = 0;

  4645.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4646.     if (cert == NULL) {
  4647.         return NGX_OK;
  4648.     }

  4649.     name = X509_get_subject_name(cert);
  4650.     if (name == NULL) {
  4651.         X509_free(cert);
  4652.         return NGX_ERROR;
  4653.     }

  4654.     bio = BIO_new(BIO_s_mem());
  4655.     if (bio == NULL) {
  4656.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4657.         X509_free(cert);
  4658.         return NGX_ERROR;
  4659.     }

  4660.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4661.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4662.         goto failed;
  4663.     }

  4664.     s->len = BIO_pending(bio);
  4665.     s->data = ngx_pnalloc(pool, s->len);
  4666.     if (s->data == NULL) {
  4667.         goto failed;
  4668.     }

  4669.     BIO_read(bio, s->data, s->len);

  4670.     BIO_free(bio);
  4671.     X509_free(cert);

  4672.     return NGX_OK;

  4673. failed:

  4674.     BIO_free(bio);
  4675.     X509_free(cert);

  4676.     return NGX_ERROR;
  4677. }


  4678. ngx_int_t
  4679. ‌ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4680. {
  4681.     BIO        *bio;
  4682.     X509       *cert;
  4683. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4684.     const
  4685. #endif
  4686.     X509_NAME  *name;

  4687.     s->len = 0;

  4688.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4689.     if (cert == NULL) {
  4690.         return NGX_OK;
  4691.     }

  4692.     name = X509_get_issuer_name(cert);
  4693.     if (name == NULL) {
  4694.         X509_free(cert);
  4695.         return NGX_ERROR;
  4696.     }

  4697.     bio = BIO_new(BIO_s_mem());
  4698.     if (bio == NULL) {
  4699.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4700.         X509_free(cert);
  4701.         return NGX_ERROR;
  4702.     }

  4703.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4704.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4705.         goto failed;
  4706.     }

  4707.     s->len = BIO_pending(bio);
  4708.     s->data = ngx_pnalloc(pool, s->len);
  4709.     if (s->data == NULL) {
  4710.         goto failed;
  4711.     }

  4712.     BIO_read(bio, s->data, s->len);

  4713.     BIO_free(bio);
  4714.     X509_free(cert);

  4715.     return NGX_OK;

  4716. failed:

  4717.     BIO_free(bio);
  4718.     X509_free(cert);

  4719.     return NGX_ERROR;
  4720. }


  4721. ngx_int_t
  4722. ‌ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4723.     ngx_str_t *s)
  4724. {
  4725.     char       *p;
  4726.     size_t      len;
  4727.     X509       *cert;
  4728. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4729.     const
  4730. #endif
  4731.     X509_NAME  *name;

  4732.     s->len = 0;

  4733.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4734.     if (cert == NULL) {
  4735.         return NGX_OK;
  4736.     }

  4737.     name = X509_get_subject_name(cert);
  4738.     if (name == NULL) {
  4739.         X509_free(cert);
  4740.         return NGX_ERROR;
  4741.     }

  4742.     p = X509_NAME_oneline(name, NULL, 0);
  4743.     if (p == NULL) {
  4744.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4745.         X509_free(cert);
  4746.         return NGX_ERROR;
  4747.     }

  4748.     for (len = 0; p[len]; len++) { /* void */ }

  4749.     s->len = len;
  4750.     s->data = ngx_pnalloc(pool, len);
  4751.     if (s->data == NULL) {
  4752.         OPENSSL_free(p);
  4753.         X509_free(cert);
  4754.         return NGX_ERROR;
  4755.     }

  4756.     ngx_memcpy(s->data, p, len);

  4757.     OPENSSL_free(p);
  4758.     X509_free(cert);

  4759.     return NGX_OK;
  4760. }


  4761. ngx_int_t
  4762. ‌ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4763.     ngx_str_t *s)
  4764. {
  4765.     char       *p;
  4766.     size_t      len;
  4767.     X509       *cert;
  4768. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4769.     const
  4770. #endif
  4771.     X509_NAME  *name;

  4772.     s->len = 0;

  4773.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4774.     if (cert == NULL) {
  4775.         return NGX_OK;
  4776.     }

  4777.     name = X509_get_issuer_name(cert);
  4778.     if (name == NULL) {
  4779.         X509_free(cert);
  4780.         return NGX_ERROR;
  4781.     }

  4782.     p = X509_NAME_oneline(name, NULL, 0);
  4783.     if (p == NULL) {
  4784.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4785.         X509_free(cert);
  4786.         return NGX_ERROR;
  4787.     }

  4788.     for (len = 0; p[len]; len++) { /* void */ }

  4789.     s->len = len;
  4790.     s->data = ngx_pnalloc(pool, len);
  4791.     if (s->data == NULL) {
  4792.         OPENSSL_free(p);
  4793.         X509_free(cert);
  4794.         return NGX_ERROR;
  4795.     }

  4796.     ngx_memcpy(s->data, p, len);

  4797.     OPENSSL_free(p);
  4798.     X509_free(cert);

  4799.     return NGX_OK;
  4800. }


  4801. ngx_int_t
  4802. ‌ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4803. {
  4804.     size_t   len;
  4805.     X509    *cert;
  4806.     BIO     *bio;

  4807.     s->len = 0;

  4808.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4809.     if (cert == NULL) {
  4810.         return NGX_OK;
  4811.     }

  4812.     bio = BIO_new(BIO_s_mem());
  4813.     if (bio == NULL) {
  4814.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4815.         X509_free(cert);
  4816.         return NGX_ERROR;
  4817.     }

  4818.     i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
  4819.     len = BIO_pending(bio);

  4820.     s->len = len;
  4821.     s->data = ngx_pnalloc(pool, len);
  4822.     if (s->data == NULL) {
  4823.         BIO_free(bio);
  4824.         X509_free(cert);
  4825.         return NGX_ERROR;
  4826.     }

  4827.     BIO_read(bio, s->data, len);
  4828.     BIO_free(bio);
  4829.     X509_free(cert);

  4830.     return NGX_OK;
  4831. }


  4832. ngx_int_t
  4833. ‌ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4834. {
  4835.     X509          *cert;
  4836.     unsigned int   len;
  4837.     u_char         buf[EVP_MAX_MD_SIZE];

  4838.     s->len = 0;

  4839.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4840.     if (cert == NULL) {
  4841.         return NGX_OK;
  4842.     }

  4843.     if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
  4844.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed");
  4845.         X509_free(cert);
  4846.         return NGX_ERROR;
  4847.     }

  4848.     s->len = 2 * len;
  4849.     s->data = ngx_pnalloc(pool, 2 * len);
  4850.     if (s->data == NULL) {
  4851.         X509_free(cert);
  4852.         return NGX_ERROR;
  4853.     }

  4854.     ngx_hex_dump(s->data, buf, len);

  4855.     X509_free(cert);

  4856.     return NGX_OK;
  4857. }


  4858. ngx_int_t
  4859. ‌ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4860. {
  4861.     X509        *cert;
  4862.     long         rc;
  4863.     const char  *str;

  4864.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4865.     if (cert == NULL) {
  4866.         ngx_str_set(s, "NONE");
  4867.         return NGX_OK;
  4868.     }

  4869.     X509_free(cert);

  4870.     rc = SSL_get_verify_result(c->ssl->connection);

  4871.     if (rc == X509_V_OK) {
  4872.         if (ngx_ssl_ocsp_get_status(c, &str) == NGX_OK) {
  4873.             ngx_str_set(s, "SUCCESS");
  4874.             return NGX_OK;
  4875.         }

  4876.     } else {
  4877.         str = X509_verify_cert_error_string(rc);
  4878.     }

  4879.     s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str));
  4880.     if (s->data == NULL) {
  4881.         return NGX_ERROR;
  4882.     }

  4883.     s->len = ngx_sprintf(s->data, "FAILED:%s", str) - s->data;

  4884.     return NGX_OK;
  4885. }


  4886. ngx_int_t
  4887. ‌ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4888. {
  4889.     BIO     *bio;
  4890.     X509    *cert;
  4891.     size_t   len;

  4892.     s->len = 0;

  4893.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4894.     if (cert == NULL) {
  4895.         return NGX_OK;
  4896.     }

  4897.     bio = BIO_new(BIO_s_mem());
  4898.     if (bio == NULL) {
  4899.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4900.         X509_free(cert);
  4901.         return NGX_ERROR;
  4902.     }

  4903. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4904.     ASN1_TIME_print(bio, X509_get0_notBefore(cert));
  4905. #else
  4906.     ASN1_TIME_print(bio, X509_get_notBefore(cert));
  4907. #endif

  4908.     len = BIO_pending(bio);

  4909.     s->len = len;
  4910.     s->data = ngx_pnalloc(pool, len);
  4911.     if (s->data == NULL) {
  4912.         BIO_free(bio);
  4913.         X509_free(cert);
  4914.         return NGX_ERROR;
  4915.     }

  4916.     BIO_read(bio, s->data, len);
  4917.     BIO_free(bio);
  4918.     X509_free(cert);

  4919.     return NGX_OK;
  4920. }


  4921. ngx_int_t
  4922. ‌ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4923. {
  4924.     BIO     *bio;
  4925.     X509    *cert;
  4926.     size_t   len;

  4927.     s->len = 0;

  4928.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4929.     if (cert == NULL) {
  4930.         return NGX_OK;
  4931.     }

  4932.     bio = BIO_new(BIO_s_mem());
  4933.     if (bio == NULL) {
  4934.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4935.         X509_free(cert);
  4936.         return NGX_ERROR;
  4937.     }

  4938. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4939.     ASN1_TIME_print(bio, X509_get0_notAfter(cert));
  4940. #else
  4941.     ASN1_TIME_print(bio, X509_get_notAfter(cert));
  4942. #endif

  4943.     len = BIO_pending(bio);

  4944.     s->len = len;
  4945.     s->data = ngx_pnalloc(pool, len);
  4946.     if (s->data == NULL) {
  4947.         BIO_free(bio);
  4948.         X509_free(cert);
  4949.         return NGX_ERROR;
  4950.     }

  4951.     BIO_read(bio, s->data, len);
  4952.     BIO_free(bio);
  4953.     X509_free(cert);

  4954.     return NGX_OK;
  4955. }


  4956. ngx_int_t
  4957. ‌ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4958. {
  4959.     X509    *cert;
  4960.     time_t   now, end;

  4961.     s->len = 0;

  4962.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4963.     if (cert == NULL) {
  4964.         return NGX_OK;
  4965.     }

  4966. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4967.     end = ngx_ssl_parse_time(X509_get0_notAfter(cert), c->log);
  4968. #else
  4969.     end = ngx_ssl_parse_time(X509_get_notAfter(cert), c->log);
  4970. #endif

  4971.     if (end == (time_t) NGX_ERROR) {
  4972.         X509_free(cert);
  4973.         return NGX_OK;
  4974.     }

  4975.     now = ngx_time();

  4976.     if (end < now + 86400) {
  4977.         ngx_str_set(s, "0");
  4978.         X509_free(cert);
  4979.         return NGX_OK;
  4980.     }

  4981.     s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN);
  4982.     if (s->data == NULL) {
  4983.         X509_free(cert);
  4984.         return NGX_ERROR;
  4985.     }

  4986.     s->len = ngx_sprintf(s->data, "%T", (end - now) / 86400) - s->data;

  4987.     X509_free(cert);

  4988.     return NGX_OK;
  4989. }


  4990. static time_t
  4991. ‌ngx_ssl_parse_time(
  4992. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4993.     const
  4994. #endif
  4995.     ASN1_TIME *asn1time, ngx_log_t *log)
  4996. {
  4997.     BIO     *bio;
  4998.     char    *value;
  4999.     size_t   len;
  5000.     time_t   time;

  5001.     /*
  5002.      * OpenSSL doesn't provide a way to convert ASN1_TIME
  5003.      * into time_t.  To do this, we use ASN1_TIME_print(),
  5004.      * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g.,
  5005.      * "Feb  3 00:55:52 2015 GMT"), and parse the result.
  5006.      */

  5007.     bio = BIO_new(BIO_s_mem());
  5008.     if (bio == NULL) {
  5009.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "BIO_new() failed");
  5010.         return NGX_ERROR;
  5011.     }

  5012.     /* fake weekday prepended to match C asctime() format */

  5013.     BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
  5014.     ASN1_TIME_print(bio, asn1time);
  5015.     len = BIO_get_mem_data(bio, &value);

  5016.     time = ngx_parse_http_time((u_char *) value, len);

  5017.     BIO_free(bio);

  5018.     return time;
  5019. }


  5020. ngx_int_t
  5021. ‌ngx_ssl_get_client_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  5022. {
  5023. #ifdef SSL_get0_peer_signature_name

  5024.     const char  *name;

  5025.     if (SSL_get0_peer_signature_name(c->ssl->connection, &name)) {
  5026.         s->len = ngx_strlen(name);
  5027.         s->data = ngx_pnalloc(pool, s->len);
  5028.         if (s->data == NULL) {
  5029.             return NGX_ERROR;
  5030.         }

  5031.         ngx_memcpy(s->data, name, s->len);

  5032.         return NGX_OK;
  5033.     }

  5034. #endif

  5035.     s->len = 0;
  5036.     return NGX_OK;
  5037. }


  5038. static void *
  5039. ‌ngx_openssl_create_conf(ngx_cycle_t *cycle)
  5040. {
  5041.     ngx_openssl_conf_t  *oscf;

  5042.     oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
  5043.     if (oscf == NULL) {
  5044.         return NULL;
  5045.     }

  5046.     /*
  5047.      * set by ngx_pcalloc():
  5048.      *
  5049.      *     oscf->engine = 0;
  5050.      */

  5051.     return oscf;
  5052. }


  5053. static char *
  5054. ‌ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  5055. {
  5056. #ifndef OPENSSL_NO_ENGINE

  5057.     ngx_openssl_conf_t *oscf = conf;

  5058.     ENGINE     *engine;
  5059.     ngx_str_t  *value;

  5060.     if (oscf->engine) {
  5061.         return "is duplicate";
  5062.     }

  5063.     oscf->engine = 1;

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

  5065.     engine = ENGINE_by_id((char *) value[1].data);

  5066.     if (engine == NULL) {
  5067.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  5068.                       "ENGINE_by_id(\"%V\") failed", &value[1]);
  5069.         return NGX_CONF_ERROR;
  5070.     }

  5071.     if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
  5072.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  5073.                       "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",
  5074.                       &value[1]);

  5075.         ENGINE_free(engine);

  5076.         return NGX_CONF_ERROR;
  5077.     }

  5078.     ENGINE_free(engine);

  5079.     return NGX_CONF_OK;

  5080. #else

  5081.     return "is not supported";

  5082. #endif
  5083. }


  5084. static void
  5085. ‌ngx_openssl_exit(ngx_cycle_t *cycle)
  5086. {
  5087. #if OPENSSL_VERSION_NUMBER < 0x10100003L

  5088.     EVP_cleanup();
  5089. #ifndef OPENSSL_NO_ENGINE
  5090.     ENGINE_cleanup();
  5091. #endif

  5092. #endif
  5093. }