src/event/ngx_event_openssl.c - nginx-1.31.3 nginx/ @ 42f8df65b

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(%s) 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.     c->ssl->no_wait_shutdown = 1;
  1773.     c->ssl->no_send_shutdown = 1;
  1774.     c->read->eof = 1;

  1775.     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  1776.         ngx_connection_error(c, err,
  1777.                              "peer closed connection in SSL handshake");

  1778.         return NGX_ERROR;
  1779.     }

  1780.     if (c->ssl->handshake_rejected) {
  1781.         ngx_connection_error(c, err, "handshake rejected");
  1782.         ERR_clear_error();

  1783.         return NGX_ERROR;
  1784.     }

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

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

  1787.     return NGX_ERROR;
  1788. }


  1789. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  1790. static ngx_int_t
  1791. ngx_ssl_try_early_data(ngx_connection_t *c)
  1792. {
  1793.     int        n, sslerr;
  1794.     u_char     buf;
  1795.     size_t     readbytes;
  1796.     ngx_err_t  err;
  1797.     ngx_int_t  rc;

  1798.     ngx_ssl_clear_error(c->log);

  1799.     readbytes = 0;

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

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

  1803.     if (n == SSL_READ_EARLY_DATA_FINISH) {
  1804.         c->ssl->try_early_data = 0;
  1805.         return ngx_ssl_handshake(c);
  1806.     }

  1807.     if (n == SSL_READ_EARLY_DATA_SUCCESS) {

  1808.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1809.             return NGX_ERROR;
  1810.         }

  1811.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1812.             return NGX_ERROR;
  1813.         }

  1814. #if (NGX_DEBUG)
  1815.         ngx_ssl_handshake_log(c);
  1816. #endif

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

  1818.         c->ssl->early_buf = buf;
  1819.         c->ssl->early_preread = 1;

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

  1821.         c->recv = ngx_ssl_recv;
  1822.         c->send = ngx_ssl_write;
  1823.         c->recv_chain = ngx_ssl_recv_chain;
  1824.         c->send_chain = ngx_ssl_send_chain;

  1825.         c->read->ready = 1;
  1826.         c->write->ready = 1;

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

  1828.         if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
  1829.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1830.                            "BIO_get_ktls_send(): 1");
  1831.             c->ssl->sendfile = 1;
  1832.         }

  1833. #endif

  1834.         rc = ngx_ssl_ocsp_validate(c);

  1835.         if (rc == NGX_ERROR) {
  1836.             return NGX_ERROR;
  1837.         }

  1838.         if (rc == NGX_AGAIN) {
  1839.             c->read->handler = ngx_ssl_handshake_handler;
  1840.             c->write->handler = ngx_ssl_handshake_handler;
  1841.             return NGX_AGAIN;
  1842.         }

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

  1844.         return NGX_OK;
  1845.     }

  1846.     /* SSL_READ_EARLY_DATA_ERROR */

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

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

  1849.     if (sslerr == SSL_ERROR_WANT_READ) {
  1850.         c->read->ready = 0;
  1851.         c->read->handler = ngx_ssl_handshake_handler;
  1852.         c->write->handler = ngx_ssl_handshake_handler;

  1853.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1854.             return NGX_ERROR;
  1855.         }

  1856.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1857.             return NGX_ERROR;
  1858.         }

  1859.         return NGX_AGAIN;
  1860.     }

  1861.     if (sslerr == SSL_ERROR_WANT_WRITE) {
  1862.         c->write->ready = 0;
  1863.         c->read->handler = ngx_ssl_handshake_handler;
  1864.         c->write->handler = ngx_ssl_handshake_handler;

  1865.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1866.             return NGX_ERROR;
  1867.         }

  1868.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1869.             return NGX_ERROR;
  1870.         }

  1871.         return NGX_AGAIN;
  1872.     }

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

  1874.     c->ssl->no_wait_shutdown = 1;
  1875.     c->ssl->no_send_shutdown = 1;
  1876.     c->read->eof = 1;

  1877.     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  1878.         ngx_connection_error(c, err,
  1879.                              "peer closed connection in SSL handshake");

  1880.         return NGX_ERROR;
  1881.     }

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

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

  1884.     return NGX_ERROR;
  1885. }

  1886. #endif


  1887. #if (NGX_DEBUG)

  1888. void
  1889. ngx_ssl_handshake_log(ngx_connection_t *c)
  1890. {
  1891.     char         buf[129], *s, *d;
  1892. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  1893.     const
  1894. #endif
  1895.     SSL_CIPHER  *cipher;

  1896.     if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
  1897.         return;
  1898.     }

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

  1900.     if (cipher) {
  1901.         SSL_CIPHER_description(cipher, &buf[1], 128);

  1902.         for (s = &buf[1], d = buf; *s; s++) {
  1903.             if (*s == ' ' && *d == ' ') {
  1904.                 continue;
  1905.             }

  1906.             if (*s == LF || *s == CR) {
  1907.                 continue;
  1908.             }

  1909.             *++d = *s;
  1910.         }

  1911.         if (*d != ' ') {
  1912.             d++;
  1913.         }

  1914.         *d = '\0';

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

  1918.         if (SSL_session_reused(c->ssl->connection)) {
  1919.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1920.                            "SSL reused session");
  1921.         }

  1922.     } else {
  1923.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1924.                        "SSL no shared ciphers");
  1925.     }
  1926. }

  1927. #endif


  1928. static void
  1929. ngx_ssl_handshake_handler(ngx_event_t *ev)
  1930. {
  1931.     ngx_connection_t  *c;

  1932.     c = ev->data;

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

  1935.     if (ev->timedout) {
  1936.         c->ssl->handler(c);
  1937.         return;
  1938.     }

  1939.     if (ngx_ssl_handshake(c) == NGX_AGAIN) {
  1940.         return;
  1941.     }

  1942.     c->ssl->handler(c);
  1943. }


  1944. ssize_t
  1945. ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl, off_t limit)
  1946. {
  1947.     u_char     *last;
  1948.     ssize_t     n, bytes, size;
  1949.     ngx_buf_t  *b;

  1950.     bytes = 0;

  1951.     b = cl->buf;
  1952.     last = b->last;

  1953.     for ( ;; ) {
  1954.         size = b->end - last;

  1955.         if (limit) {
  1956.             if (bytes >= limit) {
  1957.                 return bytes;
  1958.             }

  1959.             if (bytes + size > limit) {
  1960.                 size = (ssize_t) (limit - bytes);
  1961.             }
  1962.         }

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

  1964.         if (n > 0) {
  1965.             last += n;
  1966.             bytes += n;

  1967.             if (!c->read->ready) {
  1968.                 return bytes;
  1969.             }

  1970.             if (last == b->end) {
  1971.                 cl = cl->next;

  1972.                 if (cl == NULL) {
  1973.                     return bytes;
  1974.                 }

  1975.                 b = cl->buf;
  1976.                 last = b->last;
  1977.             }

  1978.             continue;
  1979.         }

  1980.         if (bytes) {

  1981.             if (n == 0 || n == NGX_ERROR) {
  1982.                 c->read->ready = 1;
  1983.             }

  1984.             return bytes;
  1985.         }

  1986.         return n;
  1987.     }
  1988. }


  1989. ssize_t
  1990. ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
  1991. {
  1992.     int  n, bytes;

  1993. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  1994.     if (c->ssl->in_early) {
  1995.         return ngx_ssl_recv_early(c, buf, size);
  1996.     }
  1997. #endif

  1998.     if (c->ssl->last == NGX_ERROR) {
  1999.         c->read->ready = 0;
  2000.         c->read->error = 1;
  2001.         return NGX_ERROR;
  2002.     }

  2003.     if (c->ssl->last == NGX_DONE) {
  2004.         c->read->ready = 0;
  2005.         c->read->eof = 1;
  2006.         return 0;
  2007.     }

  2008.     bytes = 0;

  2009.     ngx_ssl_clear_error(c->log);

  2010.     /*
  2011.      * SSL_read() may return data in parts, so try to read
  2012.      * until SSL_read() would return no data
  2013.      */

  2014.     for ( ;; ) {

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

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

  2017.         if (n > 0) {
  2018.             bytes += n;
  2019.         }

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

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

  2022.             size -= n;

  2023.             if (size == 0) {
  2024.                 c->read->ready = 1;

  2025.                 if (c->read->available >= 0) {
  2026.                     c->read->available -= bytes;

  2027.                     /*
  2028.                      * there can be data buffered at SSL layer,
  2029.                      * so we post an event to continue reading on the next
  2030.                      * iteration of the event loop
  2031.                      */

  2032.                     if (c->read->available < 0) {
  2033.                         c->read->available = 0;
  2034.                         c->read->ready = 0;

  2035.                         if (c->read->posted) {
  2036.                             ngx_delete_posted_event(c->read);
  2037.                         }

  2038.                         ngx_post_event(c->read, &ngx_posted_next_events);
  2039.                     }

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

  2042.                 } else {

  2043. #if (NGX_HAVE_FIONREAD)

  2044.                     if (ngx_socket_nread(c->fd, &c->read->available) == -1) {
  2045.                         c->read->ready = 0;
  2046.                         c->read->error = 1;
  2047.                         ngx_connection_error(c, ngx_socket_errno,
  2048.                                              ngx_socket_nread_n " failed");
  2049.                         return NGX_ERROR;
  2050.                     }

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

  2053. #endif
  2054.                 }

  2055.                 return bytes;
  2056.             }

  2057.             buf += n;

  2058.             continue;
  2059.         }

  2060.         if (bytes) {
  2061.             if (c->ssl->last != NGX_AGAIN) {
  2062.                 c->read->ready = 1;
  2063.             }

  2064.             return bytes;
  2065.         }

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

  2067.         case NGX_DONE:
  2068.             c->read->ready = 0;
  2069.             c->read->eof = 1;
  2070.             return 0;

  2071.         case NGX_ERROR:
  2072.             c->read->ready = 0;
  2073.             c->read->error = 1;

  2074.             /* fall through */

  2075.         case NGX_AGAIN:
  2076.             return c->ssl->last;
  2077.         }
  2078.     }
  2079. }


  2080. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  2081. static ssize_t
  2082. ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size)
  2083. {
  2084.     int        n, bytes;
  2085.     size_t     readbytes;

  2086.     if (c->ssl->last == NGX_ERROR) {
  2087.         c->read->ready = 0;
  2088.         c->read->error = 1;
  2089.         return NGX_ERROR;
  2090.     }

  2091.     if (c->ssl->last == NGX_DONE) {
  2092.         c->read->ready = 0;
  2093.         c->read->eof = 1;
  2094.         return 0;
  2095.     }

  2096.     bytes = 0;

  2097.     ngx_ssl_clear_error(c->log);

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

  2099.         if (size == 0) {
  2100.             c->read->ready = 0;
  2101.             c->read->eof = 1;
  2102.             return 0;
  2103.         }

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

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

  2106.         bytes = 1;
  2107.         size -= 1;
  2108.         buf += 1;
  2109.     }

  2110.     if (c->ssl->write_blocked) {
  2111.         return NGX_AGAIN;
  2112.     }

  2113.     /*
  2114.      * SSL_read_early_data() may return data in parts, so try to read
  2115.      * until SSL_read_early_data() would return no data
  2116.      */

  2117.     for ( ;; ) {

  2118.         readbytes = 0;

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

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

  2122.         if (n == SSL_READ_EARLY_DATA_SUCCESS) {

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

  2124.             bytes += readbytes;
  2125.             size -= readbytes;

  2126.             if (size == 0) {
  2127.                 c->read->ready = 1;
  2128.                 return bytes;
  2129.             }

  2130.             buf += readbytes;

  2131.             continue;
  2132.         }

  2133.         if (n == SSL_READ_EARLY_DATA_FINISH) {

  2134.             c->ssl->last = ngx_ssl_handle_recv(c, 1);
  2135.             c->ssl->in_early = 0;

  2136.             if (bytes) {
  2137.                 c->read->ready = 1;
  2138.                 return bytes;
  2139.             }

  2140.             return ngx_ssl_recv(c, buf, size);
  2141.         }

  2142.         /* SSL_READ_EARLY_DATA_ERROR */

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

  2144.         if (bytes) {
  2145.             if (c->ssl->last != NGX_AGAIN) {
  2146.                 c->read->ready = 1;
  2147.             }

  2148.             return bytes;
  2149.         }

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

  2151.         case NGX_DONE:
  2152.             c->read->ready = 0;
  2153.             c->read->eof = 1;
  2154.             return 0;

  2155.         case NGX_ERROR:
  2156.             c->read->ready = 0;
  2157.             c->read->error = 1;

  2158.             /* fall through */

  2159.         case NGX_AGAIN:
  2160.             return c->ssl->last;
  2161.         }
  2162.     }
  2163. }

  2164. #endif


  2165. static ngx_int_t
  2166. ngx_ssl_handle_recv(ngx_connection_t *c, int n)
  2167. {
  2168.     int        sslerr;
  2169.     ngx_err_t  err;

  2170. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  2171.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

  2172.     if (c->ssl->renegotiation) {
  2173.         /*
  2174.          * disable renegotiation (CVE-2009-3555):
  2175.          * OpenSSL (at least up to 0.9.8l) does not handle disabled
  2176.          * renegotiation gracefully, so drop connection here
  2177.          */

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

  2179.         while (ERR_peek_error()) {
  2180.             ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0,
  2181.                           "ignoring stale global SSL error");
  2182.         }

  2183.         ERR_clear_error();

  2184.         c->ssl->no_wait_shutdown = 1;
  2185.         c->ssl->no_send_shutdown = 1;

  2186.         return NGX_ERROR;
  2187.     }

  2188. #endif

  2189.     if (n > 0) {

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

  2191.             c->write->handler = c->ssl->saved_write_handler;
  2192.             c->ssl->saved_write_handler = NULL;
  2193.             c->write->ready = 1;

  2194.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2195.                 return NGX_ERROR;
  2196.             }

  2197.             ngx_post_event(c->write, &ngx_posted_events);
  2198.         }

  2199.         return NGX_OK;
  2200.     }

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

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

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

  2204.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

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

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

  2214.         c->read->ready = 0;
  2215.         return NGX_AGAIN;
  2216.     }

  2217.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

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

  2221.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2222.             return NGX_ERROR;
  2223.         }

  2224.         /*
  2225.          * we do not set the timer because there is already the read event timer
  2226.          */

  2227.         if (c->ssl->saved_write_handler == NULL) {
  2228.             c->ssl->saved_write_handler = c->write->handler;
  2229.             c->write->handler = ngx_ssl_write_handler;
  2230.         }

  2231.         return NGX_AGAIN;
  2232.     }

  2233.     c->ssl->no_wait_shutdown = 1;
  2234.     c->ssl->no_send_shutdown = 1;

  2235.     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  2236.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  2237.                        "peer shutdown SSL cleanly");
  2238.         return NGX_DONE;
  2239.     }

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

  2241.     return NGX_ERROR;
  2242. }


  2243. static void
  2244. ngx_ssl_write_handler(ngx_event_t *wev)
  2245. {
  2246.     ngx_connection_t  *c;

  2247.     c = wev->data;

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

  2249.     c->read->handler(c->read);
  2250. }


  2251. /*
  2252. * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
  2253. * before the SSL_write() call to decrease a SSL overhead.
  2254. *
  2255. * Besides for protocols such as HTTP it is possible to always buffer
  2256. * the output to decrease a SSL overhead some more.
  2257. */

  2258. ngx_chain_t *
  2259. ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
  2260. {
  2261.     int           n;
  2262.     ngx_uint_t    flush;
  2263.     ssize_t       send, size, file_size;
  2264.     ngx_buf_t    *buf;
  2265.     ngx_chain_t  *cl;

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

  2267.         while (in) {
  2268.             if (ngx_buf_special(in->buf)) {
  2269.                 in = in->next;
  2270.                 continue;
  2271.             }

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

  2273.             if (n == NGX_ERROR) {
  2274.                 return NGX_CHAIN_ERROR;
  2275.             }

  2276.             if (n == NGX_AGAIN) {
  2277.                 return in;
  2278.             }

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

  2280.             if (in->buf->pos == in->buf->last) {
  2281.                 in = in->next;
  2282.             }
  2283.         }

  2284.         return in;
  2285.     }


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

  2287.     if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) {
  2288.         limit = NGX_MAX_INT32_VALUE - ngx_pagesize;
  2289.     }

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

  2291.     if (buf == NULL) {
  2292.         buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size);
  2293.         if (buf == NULL) {
  2294.             return NGX_CHAIN_ERROR;
  2295.         }

  2296.         c->ssl->buf = buf;
  2297.     }

  2298.     if (buf->start == NULL) {
  2299.         buf->start = ngx_palloc(c->pool, c->ssl->buffer_size);
  2300.         if (buf->start == NULL) {
  2301.             return NGX_CHAIN_ERROR;
  2302.         }

  2303.         buf->pos = buf->start;
  2304.         buf->last = buf->start;
  2305.         buf->end = buf->start + c->ssl->buffer_size;
  2306.     }

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

  2309.     for ( ;; ) {

  2310.         while (in && buf->last < buf->end && send < limit) {
  2311.             if (in->buf->last_buf || in->buf->flush) {
  2312.                 flush = 1;
  2313.             }

  2314.             if (ngx_buf_special(in->buf)) {
  2315.                 in = in->next;
  2316.                 continue;
  2317.             }

  2318.             if (in->buf->in_file && c->ssl->sendfile) {
  2319.                 flush = 1;
  2320.                 break;
  2321.             }

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

  2323.             if (size > buf->end - buf->last) {
  2324.                 size = buf->end - buf->last;
  2325.             }

  2326.             if (send + size > limit) {
  2327.                 size = (ssize_t) (limit - send);
  2328.             }

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

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

  2332.             buf->last += size;
  2333.             in->buf->pos += size;
  2334.             send += size;

  2335.             if (in->buf->pos == in->buf->last) {
  2336.                 in = in->next;
  2337.             }
  2338.         }

  2339.         if (!flush && send < limit && buf->last < buf->end) {
  2340.             break;
  2341.         }

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

  2343.         if (size == 0) {

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

  2345.                 /* coalesce the neighbouring file bufs */

  2346.                 cl = in;
  2347.                 file_size = (size_t) ngx_chain_coalesce_file(&cl, limit - send);

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

  2349.                 if (n == NGX_ERROR) {
  2350.                     return NGX_CHAIN_ERROR;
  2351.                 }

  2352.                 if (n == NGX_AGAIN) {
  2353.                     break;
  2354.                 }

  2355.                 in = ngx_chain_update_sent(in, n);

  2356.                 send += n;
  2357.                 flush = 0;

  2358.                 continue;
  2359.             }

  2360.             buf->flush = 0;
  2361.             c->buffered &= ~NGX_SSL_BUFFERED;

  2362.             return in;
  2363.         }

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

  2365.         if (n == NGX_ERROR) {
  2366.             return NGX_CHAIN_ERROR;
  2367.         }

  2368.         if (n == NGX_AGAIN) {
  2369.             break;
  2370.         }

  2371.         buf->pos += n;

  2372.         if (n < size) {
  2373.             break;
  2374.         }

  2375.         flush = 0;

  2376.         buf->pos = buf->start;
  2377.         buf->last = buf->start;

  2378.         if (in == NULL || send >= limit) {
  2379.             break;
  2380.         }
  2381.     }

  2382.     buf->flush = flush;

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

  2385.     } else {
  2386.         c->buffered &= ~NGX_SSL_BUFFERED;
  2387.     }

  2388.     return in;
  2389. }


  2390. ssize_t
  2391. ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
  2392. {
  2393.     int        n, sslerr;
  2394.     ngx_err_t  err;

  2395. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  2396.     if (c->ssl->in_early) {
  2397.         return ngx_ssl_write_early(c, data, size);
  2398.     }
  2399. #endif

  2400.     ngx_ssl_clear_error(c->log);

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

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

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

  2404.     if (n > 0) {

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

  2406.             c->read->handler = c->ssl->saved_read_handler;
  2407.             c->ssl->saved_read_handler = NULL;
  2408.             c->read->ready = 1;

  2409.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2410.                 return NGX_ERROR;
  2411.             }

  2412.             ngx_post_event(c->read, &ngx_posted_events);
  2413.         }

  2414.         c->sent += n;

  2415.         return n;
  2416.     }

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

  2418.     if (sslerr == SSL_ERROR_ZERO_RETURN) {

  2419.         /*
  2420.          * OpenSSL 1.1.1 fails to return SSL_ERROR_SYSCALL if an error
  2421.          * happens during SSL_write() after close_notify alert from the
  2422.          * peer, and returns SSL_ERROR_ZERO_RETURN instead,
  2423.          * see https://github.com/openssl/openssl/commit/8051ab2
  2424.          */

  2425.         sslerr = SSL_ERROR_SYSCALL;
  2426.     }

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

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

  2429.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

  2431.             c->read->handler = c->ssl->saved_read_handler;
  2432.             c->ssl->saved_read_handler = NULL;
  2433.             c->read->ready = 1;

  2434.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2435.                 return NGX_ERROR;
  2436.             }

  2437.             ngx_post_event(c->read, &ngx_posted_events);
  2438.         }

  2439.         c->write->ready = 0;
  2440.         return NGX_AGAIN;
  2441.     }

  2442.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

  2446.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2447.             return NGX_ERROR;
  2448.         }

  2449.         /*
  2450.          * we do not set the timer because there is already
  2451.          * the write event timer
  2452.          */

  2453.         if (c->ssl->saved_read_handler == NULL) {
  2454.             c->ssl->saved_read_handler = c->read->handler;
  2455.             c->read->handler = ngx_ssl_read_handler;
  2456.         }

  2457.         return NGX_AGAIN;
  2458.     }

  2459.     c->ssl->no_wait_shutdown = 1;
  2460.     c->ssl->no_send_shutdown = 1;
  2461.     c->write->error = 1;

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

  2463.     return NGX_ERROR;
  2464. }


  2465. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  2466. static ssize_t
  2467. ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size)
  2468. {
  2469.     int        n, sslerr;
  2470.     size_t     written;
  2471.     ngx_err_t  err;

  2472.     ngx_ssl_clear_error(c->log);

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

  2474.     written = 0;

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

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

  2478.     if (n > 0) {

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

  2480.             c->read->handler = c->ssl->saved_read_handler;
  2481.             c->ssl->saved_read_handler = NULL;
  2482.             c->read->ready = 1;

  2483.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2484.                 return NGX_ERROR;
  2485.             }

  2486.             ngx_post_event(c->read, &ngx_posted_events);
  2487.         }

  2488.         if (c->ssl->write_blocked) {
  2489.             c->ssl->write_blocked = 0;
  2490.             ngx_post_event(c->read, &ngx_posted_events);
  2491.         }

  2492.         c->sent += written;

  2493.         return written;
  2494.     }

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

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

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

  2498.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

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

  2502.             c->read->handler = c->ssl->saved_read_handler;
  2503.             c->ssl->saved_read_handler = NULL;
  2504.             c->read->ready = 1;

  2505.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2506.                 return NGX_ERROR;
  2507.             }

  2508.             ngx_post_event(c->read, &ngx_posted_events);
  2509.         }

  2510.         /*
  2511.          * OpenSSL 1.1.1a fails to handle SSL_read_early_data()
  2512.          * if an SSL_write_early_data() call blocked on writing,
  2513.          * see https://github.com/openssl/openssl/issues/7757
  2514.          */

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

  2516.         c->write->ready = 0;
  2517.         return NGX_AGAIN;
  2518.     }

  2519.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

  2523.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2524.             return NGX_ERROR;
  2525.         }

  2526.         /*
  2527.          * we do not set the timer because there is already
  2528.          * the write event timer
  2529.          */

  2530.         if (c->ssl->saved_read_handler == NULL) {
  2531.             c->ssl->saved_read_handler = c->read->handler;
  2532.             c->read->handler = ngx_ssl_read_handler;
  2533.         }

  2534.         return NGX_AGAIN;
  2535.     }

  2536.     c->ssl->no_wait_shutdown = 1;
  2537.     c->ssl->no_send_shutdown = 1;
  2538.     c->write->error = 1;

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

  2540.     return NGX_ERROR;
  2541. }

  2542. #endif


  2543. static ssize_t
  2544. ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
  2545. {
  2546. #if (defined BIO_get_ktls_send && !NGX_WIN32)

  2547.     int        sslerr, flags;
  2548.     ssize_t    n;
  2549.     ngx_err_t  err;

  2550.     ngx_ssl_clear_error(c->log);

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

  2554.     ngx_set_errno(0);

  2555. #if (NGX_HAVE_SENDFILE_NODISKIO)

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

  2557.     if (file->file->directio) {
  2558.         flags |= SF_NOCACHE;
  2559.     }

  2560. #else
  2561.     flags = 0;
  2562. #endif

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

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

  2566.     if (n > 0) {

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

  2568.             c->read->handler = c->ssl->saved_read_handler;
  2569.             c->ssl->saved_read_handler = NULL;
  2570.             c->read->ready = 1;

  2571.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2572.                 return NGX_ERROR;
  2573.             }

  2574.             ngx_post_event(c->read, &ngx_posted_events);
  2575.         }

  2576. #if (NGX_HAVE_SENDFILE_NODISKIO)
  2577.         c->busy_count = 0;
  2578. #endif

  2579.         c->sent += n;

  2580.         return n;
  2581.     }

  2582.     if (n == 0) {

  2583.         /*
  2584.          * if sendfile returns zero, then someone has truncated the file,
  2585.          * so the offset became beyond the end of the file
  2586.          */

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

  2590.         return NGX_ERROR;
  2591.     }

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

  2593.     if (sslerr == SSL_ERROR_ZERO_RETURN) {

  2594.         /*
  2595.          * OpenSSL fails to return SSL_ERROR_SYSCALL if an error
  2596.          * happens during writing after close_notify alert from the
  2597.          * peer, and returns SSL_ERROR_ZERO_RETURN instead
  2598.          */

  2599.         sslerr = SSL_ERROR_SYSCALL;
  2600.     }

  2601.     if (sslerr == SSL_ERROR_SSL
  2602.         && ERR_GET_REASON(ERR_peek_error()) == SSL_R_UNINITIALIZED
  2603.         && ngx_errno != 0)
  2604.     {
  2605.         /*
  2606.          * OpenSSL fails to return SSL_ERROR_SYSCALL if an error
  2607.          * happens in sendfile(), and returns SSL_ERROR_SSL with
  2608.          * SSL_R_UNINITIALIZED reason instead
  2609.          */

  2610.         sslerr = SSL_ERROR_SYSCALL;
  2611.     }

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

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

  2614.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

  2616.             c->read->handler = c->ssl->saved_read_handler;
  2617.             c->ssl->saved_read_handler = NULL;
  2618.             c->read->ready = 1;

  2619.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2620.                 return NGX_ERROR;
  2621.             }

  2622.             ngx_post_event(c->read, &ngx_posted_events);
  2623.         }

  2624. #if (NGX_HAVE_SENDFILE_NODISKIO)

  2625.         if (ngx_errno == EBUSY) {
  2626.             c->busy_count++;

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

  2629.             if (c->write->posted) {
  2630.                 ngx_delete_posted_event(c->write);
  2631.             }

  2632.             ngx_post_event(c->write, &ngx_posted_next_events);
  2633.         }

  2634. #endif

  2635.         c->write->ready = 0;
  2636.         return NGX_AGAIN;
  2637.     }

  2638.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

  2642.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2643.             return NGX_ERROR;
  2644.         }

  2645.         /*
  2646.          * we do not set the timer because there is already
  2647.          * the write event timer
  2648.          */

  2649.         if (c->ssl->saved_read_handler == NULL) {
  2650.             c->ssl->saved_read_handler = c->read->handler;
  2651.             c->read->handler = ngx_ssl_read_handler;
  2652.         }

  2653.         return NGX_AGAIN;
  2654.     }

  2655.     c->ssl->no_wait_shutdown = 1;
  2656.     c->ssl->no_send_shutdown = 1;
  2657.     c->write->error = 1;

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

  2659. #else
  2660.     ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2661.                   "SSL_sendfile() not available");
  2662. #endif

  2663.     return NGX_ERROR;
  2664. }


  2665. static void
  2666. ngx_ssl_read_handler(ngx_event_t *rev)
  2667. {
  2668.     ngx_connection_t  *c;

  2669.     c = rev->data;

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

  2671.     c->write->handler(c->write);
  2672. }


  2673. void
  2674. ngx_ssl_free_buffer(ngx_connection_t *c)
  2675. {
  2676.     if (c->ssl->buf && c->ssl->buf->start) {
  2677.         if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
  2678.             c->ssl->buf->start = NULL;
  2679.         }
  2680.     }
  2681. }


  2682. ngx_int_t
  2683. ngx_ssl_shutdown(ngx_connection_t *c)
  2684. {
  2685.     int         n, sslerr, mode;
  2686.     ngx_int_t   rc;
  2687.     ngx_err_t   err;
  2688.     ngx_uint_t  tries;

  2689. #if (NGX_QUIC)
  2690.     if (c->quic) {
  2691.         /* QUIC streams inherit SSL object */
  2692.         return NGX_OK;
  2693.     }
  2694. #endif

  2695.     rc = NGX_OK;

  2696.     ngx_ssl_ocsp_cleanup(c);

  2697.     if (SSL_in_init(c->ssl->connection)) {
  2698.         /*
  2699.          * OpenSSL 1.0.2f complains if SSL_shutdown() is called during
  2700.          * an SSL handshake, while previous versions always return 0.
  2701.          * Avoid calling SSL_shutdown() if handshake wasn't completed.
  2702.          */

  2703.         goto done;
  2704.     }

  2705.     if (c->timedout || c->error || c->buffered) {
  2706.         mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
  2707.         SSL_set_quiet_shutdown(c->ssl->connection, 1);

  2708.     } else {
  2709.         mode = SSL_get_shutdown(c->ssl->connection);

  2710.         if (c->ssl->no_wait_shutdown) {
  2711.             mode |= SSL_RECEIVED_SHUTDOWN;
  2712.         }

  2713.         if (c->ssl->no_send_shutdown) {
  2714.             mode |= SSL_SENT_SHUTDOWN;
  2715.         }

  2716.         if (c->ssl->no_wait_shutdown && c->ssl->no_send_shutdown) {
  2717.             SSL_set_quiet_shutdown(c->ssl->connection, 1);
  2718.         }
  2719.     }

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

  2721.     ngx_ssl_clear_error(c->log);

  2722.     tries = 2;

  2723.     for ( ;; ) {

  2724.         /*
  2725.          * For bidirectional shutdown, SSL_shutdown() needs to be called
  2726.          * twice: first call sends the "close notify" alert and returns 0,
  2727.          * second call waits for the peer's "close notify" alert.
  2728.          */

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

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

  2731.         if (n == 1) {
  2732.             goto done;
  2733.         }

  2734.         if (n == 0 && tries-- > 1) {
  2735.             continue;
  2736.         }

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

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

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

  2741.         if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
  2742.             c->read->handler = ngx_ssl_shutdown_handler;
  2743.             c->write->handler = ngx_ssl_shutdown_handler;

  2744.             if (sslerr == SSL_ERROR_WANT_READ) {
  2745.                 c->read->ready = 0;

  2746.             } else {
  2747.                 c->write->ready = 0;
  2748.             }

  2749.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2750.                 goto failed;
  2751.             }

  2752.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2753.                 goto failed;
  2754.             }

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

  2756.             return NGX_AGAIN;
  2757.         }

  2758.         if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  2759.             goto done;
  2760.         }

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

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

  2763.         break;
  2764.     }

  2765. failed:

  2766.     rc = NGX_ERROR;

  2767. done:

  2768.     if (c->ssl->shutdown_without_free) {
  2769.         c->ssl->shutdown_without_free = 0;
  2770.         c->recv = ngx_recv;
  2771.         return rc;
  2772.     }

  2773.     SSL_free(c->ssl->connection);
  2774.     c->ssl = NULL;
  2775.     c->recv = ngx_recv;

  2776.     return rc;
  2777. }


  2778. static void
  2779. ngx_ssl_shutdown_handler(ngx_event_t *ev)
  2780. {
  2781.     ngx_connection_t           *c;
  2782.     ngx_connection_handler_pt   handler;

  2783.     c = ev->data;
  2784.     handler = c->ssl->handler;

  2785.     if (ev->timedout) {
  2786.         c->timedout = 1;
  2787.     }

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

  2789.     if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2790.         return;
  2791.     }

  2792.     handler(c);
  2793. }


  2794. void
  2795. ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
  2796.     char *text)
  2797. {
  2798.     int         n;
  2799.     ngx_uint_t  level;

  2800.     level = NGX_LOG_CRIT;

  2801.     if (sslerr == SSL_ERROR_SYSCALL) {

  2802.         if (err == NGX_ECONNRESET
  2803. #if (NGX_WIN32)
  2804.             || err == NGX_ECONNABORTED
  2805. #endif
  2806.             || err == NGX_EPIPE
  2807.             || err == NGX_ENOTCONN
  2808.             || err == NGX_ETIMEDOUT
  2809.             || err == NGX_ECONNREFUSED
  2810.             || err == NGX_ENETDOWN
  2811.             || err == NGX_ENETUNREACH
  2812.             || err == NGX_EHOSTDOWN
  2813.             || err == NGX_EHOSTUNREACH)
  2814.         {
  2815.             switch (c->log_error) {

  2816.             case NGX_ERROR_IGNORE_ECONNRESET:
  2817.             case NGX_ERROR_INFO:
  2818.                 level = NGX_LOG_INFO;
  2819.                 break;

  2820.             case NGX_ERROR_ERR:
  2821.                 level = NGX_LOG_ERR;
  2822.                 break;

  2823.             default:
  2824.                 break;
  2825.             }
  2826.         }

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

  2828.         n = ERR_GET_REASON(ERR_peek_last_error());

  2829.             /* handshake failures */
  2830.         if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC                        /*  103 */
  2831. #ifdef SSL_R_NO_SUITABLE_KEY_SHARE
  2832.             || n == SSL_R_NO_SUITABLE_KEY_SHARE                      /*  101 */
  2833. #endif
  2834. #ifdef SSL_R_BAD_ALERT
  2835.             || n == SSL_R_BAD_ALERT                                  /*  102 */
  2836. #endif
  2837. #ifdef SSL_R_BAD_KEY_SHARE
  2838.             || n == SSL_R_BAD_KEY_SHARE                              /*  108 */
  2839. #endif
  2840. #ifdef SSL_R_BAD_EXTENSION
  2841.             || n == SSL_R_BAD_EXTENSION                              /*  110 */
  2842. #endif
  2843.             || n == SSL_R_BAD_DIGEST_LENGTH                          /*  111 */
  2844. #ifdef SSL_R_MISSING_SIGALGS_EXTENSION
  2845.             || n == SSL_R_MISSING_SIGALGS_EXTENSION                  /*  112 */
  2846. #endif
  2847.             || n == SSL_R_BAD_PACKET_LENGTH                          /*  115 */
  2848. #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM
  2849.             || n == SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM            /*  118 */
  2850. #endif
  2851. #ifdef SSL_R_BAD_KEY_UPDATE
  2852.             || n == SSL_R_BAD_KEY_UPDATE                             /*  122 */
  2853. #endif
  2854.             || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */
  2855.             || n == SSL_R_CCS_RECEIVED_EARLY                         /*  133 */
  2856. #ifdef SSL_R_DECODE_ERROR
  2857.             || n == SSL_R_DECODE_ERROR                               /*  137 */
  2858. #endif
  2859. #ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED
  2860.             || n == SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              /*  145 */
  2861. #endif
  2862.             || n == SSL_R_DATA_LENGTH_TOO_LONG                       /*  146 */
  2863.             || n == SSL_R_DIGEST_CHECK_FAILED                        /*  149 */
  2864.             || n == SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  /*  150 */
  2865.             || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              /*  151 */
  2866.             || n == SSL_R_EXCESSIVE_MESSAGE_SIZE                     /*  152 */
  2867. #ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS
  2868.             || n == SSL_R_GOT_A_FIN_BEFORE_A_CCS                     /*  154 */
  2869. #endif
  2870.             || n == SSL_R_HTTPS_PROXY_REQUEST                        /*  155 */
  2871.             || n == SSL_R_HTTP_REQUEST                               /*  156 */
  2872.             || n == SSL_R_LENGTH_MISMATCH                            /*  159 */
  2873. #ifdef SSL_R_LENGTH_TOO_SHORT
  2874.             || n == SSL_R_LENGTH_TOO_SHORT                           /*  160 */
  2875. #endif
  2876. #ifdef SSL_R_NO_RENEGOTIATION
  2877.             || n == SSL_R_NO_RENEGOTIATION                           /*  182 */
  2878. #endif
  2879. #ifdef SSL_R_NO_CIPHERS_PASSED
  2880.             || n == SSL_R_NO_CIPHERS_PASSED                          /*  182 */
  2881. #endif
  2882.             || n == SSL_R_NO_CIPHERS_SPECIFIED                       /*  183 */
  2883. #ifdef SSL_R_BAD_CIPHER
  2884.             || n == SSL_R_BAD_CIPHER                                 /*  186 */
  2885. #endif
  2886.             || n == SSL_R_NO_COMPRESSION_SPECIFIED                   /*  187 */
  2887.             || n == SSL_R_NO_SHARED_CIPHER                           /*  193 */
  2888. #ifdef SSL_R_PACKET_LENGTH_TOO_LONG
  2889.             || n == SSL_R_PACKET_LENGTH_TOO_LONG                     /*  198 */
  2890. #endif
  2891. #ifdef SSL_R_INVALID_ALERT
  2892.             || n == SSL_R_INVALID_ALERT                              /*  205 */
  2893. #endif
  2894.             || n == SSL_R_RECORD_LENGTH_MISMATCH                     /*  213 */
  2895. #ifdef SSL_R_TOO_MANY_WARNING_ALERTS
  2896.             || n == SSL_R_TOO_MANY_WARNING_ALERTS                    /*  220 */
  2897. #endif
  2898. #ifdef SSL_R_CLIENTHELLO_TLSEXT
  2899.             || n == SSL_R_CLIENTHELLO_TLSEXT                         /*  226 */
  2900. #endif
  2901. #ifdef SSL_R_PARSE_TLSEXT
  2902.             || n == SSL_R_PARSE_TLSEXT                               /*  227 */
  2903. #endif
  2904. #ifdef SSL_R_CALLBACK_FAILED
  2905.             || n == SSL_R_CALLBACK_FAILED                            /*  234 */
  2906. #endif
  2907. #ifdef SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
  2908.             || n == SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    /*  234 */
  2909. #endif
  2910. #ifdef SSL_R_NO_APPLICATION_PROTOCOL
  2911.             || n == SSL_R_NO_APPLICATION_PROTOCOL                    /*  235 */
  2912. #endif
  2913.             || n == SSL_R_UNEXPECTED_MESSAGE                         /*  244 */
  2914.             || n == SSL_R_UNEXPECTED_RECORD                          /*  245 */
  2915.             || n == SSL_R_UNKNOWN_ALERT_TYPE                         /*  246 */
  2916.             || n == SSL_R_UNKNOWN_PROTOCOL                           /*  252 */
  2917. #ifdef SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS
  2918.             || n == SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS             /*  253 */
  2919. #endif
  2920. #ifdef SSL_R_INVALID_COMPRESSION_LIST
  2921.             || n == SSL_R_INVALID_COMPRESSION_LIST                   /*  256 */
  2922. #endif
  2923. #ifdef SSL_R_MISSING_KEY_SHARE
  2924.             || n == SSL_R_MISSING_KEY_SHARE                          /*  258 */
  2925. #endif
  2926.             || n == SSL_R_UNSUPPORTED_PROTOCOL                       /*  258 */
  2927. #ifdef SSL_R_NO_SHARED_GROUP
  2928.             || n == SSL_R_NO_SHARED_GROUP                            /*  266 */
  2929. #endif
  2930.             || n == SSL_R_WRONG_VERSION_NUMBER                       /*  267 */
  2931. #ifdef SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA
  2932.             || n == SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA                /*  270 */
  2933. #endif
  2934.             || n == SSL_R_BAD_LENGTH                                 /*  271 */
  2935.             || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        /*  281 */
  2936. #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY
  2937.             || n == SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY        /*  291 */
  2938. #endif
  2939. #ifdef SSL_R_APPLICATION_DATA_ON_SHUTDOWN
  2940.             || n == SSL_R_APPLICATION_DATA_ON_SHUTDOWN               /*  291 */
  2941. #endif
  2942. #ifdef SSL_R_BAD_LEGACY_VERSION
  2943.             || n == SSL_R_BAD_LEGACY_VERSION                         /*  292 */
  2944. #endif
  2945. #ifdef SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA
  2946.             || n == SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA     /*  293 */
  2947. #endif
  2948. #ifdef SSL_R_RECORD_TOO_SMALL
  2949.             || n == SSL_R_RECORD_TOO_SMALL                           /*  298 */
  2950. #endif
  2951. #ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG
  2952.             || n == SSL_R_SSL3_SESSION_ID_TOO_LONG                   /*  300 */
  2953. #elif (defined SSL_R_TLS_SESSION_ID_TOO_LONG)
  2954.             || n == SSL_R_TLS_SESSION_ID_TOO_LONG                    /*  300 */
  2955. #endif
  2956. #ifdef SSL_R_BAD_ECPOINT
  2957.             || n == SSL_R_BAD_ECPOINT                                /*  306 */
  2958. #endif
  2959. #ifdef SSL_R_RECORD_LAYER_FAILURE
  2960.             || n == SSL_R_RECORD_LAYER_FAILURE                       /*  313 */
  2961. #endif
  2962. #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
  2963.             || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG                   /*  335 */
  2964.             || n == SSL_R_RENEGOTIATION_ENCODING_ERR                 /*  336 */
  2965.             || n == SSL_R_RENEGOTIATION_MISMATCH                     /*  337 */
  2966. #endif
  2967. #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
  2968.             || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       /*  338 */
  2969. #endif
  2970. #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
  2971.             || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           /*  345 */
  2972. #endif
  2973. #ifdef SSL_R_INAPPROPRIATE_FALLBACK
  2974.             || n == SSL_R_INAPPROPRIATE_FALLBACK                     /*  373 */
  2975. #endif
  2976. #ifdef SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS
  2977.             || n == SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS             /*  376 */
  2978. #endif
  2979. #ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS
  2980.             || n == SSL_R_NO_SHARED_SIGATURE_ALGORITHMS              /*  376 */
  2981. #endif
  2982. #ifdef SSL_R_CERT_CB_ERROR
  2983.             || n == SSL_R_CERT_CB_ERROR                              /*  377 */
  2984. #endif
  2985. #ifdef SSL_R_VERSION_TOO_LOW
  2986.             || n == SSL_R_VERSION_TOO_LOW                            /*  396 */
  2987. #endif
  2988. #ifdef SSL_R_TOO_MANY_WARN_ALERTS
  2989.             || n == SSL_R_TOO_MANY_WARN_ALERTS                       /*  409 */
  2990. #endif
  2991. #ifdef SSL_R_BAD_RECORD_TYPE
  2992.             || n == SSL_R_BAD_RECORD_TYPE                            /*  443 */
  2993. #endif
  2994.             || (n >= SSL_AD_REASON_OFFSET                            /* 1000 */
  2995.                 && n <= SSL_AD_REASON_OFFSET + 255)
  2996.             )
  2997.         {
  2998.             switch (c->log_error) {

  2999.             case NGX_ERROR_IGNORE_ECONNRESET:
  3000.             case NGX_ERROR_INFO:
  3001.                 level = NGX_LOG_INFO;
  3002.                 break;

  3003.             case NGX_ERROR_ERR:
  3004.                 level = NGX_LOG_ERR;
  3005.                 break;

  3006.             default:
  3007.                 break;
  3008.             }
  3009.         }
  3010.     }

  3011.     ngx_ssl_error(level, c->log, err, text);
  3012. }


  3013. static void
  3014. ngx_ssl_clear_error(ngx_log_t *log)
  3015. {
  3016.     while (ERR_peek_error()) {
  3017.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
  3018.     }

  3019.     ERR_clear_error();
  3020. }


  3021. void ngx_cdecl
  3022. ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
  3023. {
  3024.     int          flags;
  3025.     u_long       n;
  3026.     va_list      args;
  3027.     u_char      *p, *last;
  3028.     u_char       errstr[NGX_MAX_CONF_ERRSTR];
  3029.     const char  *data;

  3030.     last = errstr + NGX_MAX_CONF_ERRSTR;

  3031.     va_start(args, fmt);
  3032.     p = ngx_vslprintf(errstr, last - 1, fmt, args);
  3033.     va_end(args);

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

  3036.         for ( ;; ) {

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

  3038.             if (n == 0) {
  3039.                 break;
  3040.             }

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

  3042.             if (p >= last - 1) {
  3043.                 goto next;
  3044.             }

  3045.             *p++ = ' ';

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

  3047.             while (p < last && *p) {
  3048.                 p++;
  3049.             }

  3050.             if (p < last && *data && (flags & ERR_TXT_STRING)) {
  3051.                 *p++ = ':';
  3052.                 p = ngx_cpystrn(p, (u_char *) data, last - p);
  3053.             }

  3054.         next:

  3055.             (void) ERR_get_error();
  3056.         }

  3057.         if (p < last) {
  3058.             *p++ = ')';
  3059.         }
  3060.     }

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


  3063. ngx_int_t
  3064. ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  3065.     ngx_array_t *certificates, ssize_t builtin_session_cache,
  3066.     ngx_shm_zone_t *shm_zone, time_t timeout)
  3067. {
  3068.     long  cache_mode;

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

  3070.     if (ngx_ssl_session_id_context(ssl, sess_ctx, certificates) != NGX_OK) {
  3071.         return NGX_ERROR;
  3072.     }

  3073.     if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
  3074.         SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
  3075.         return NGX_OK;
  3076.     }

  3077.     if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {

  3078.         /*
  3079.          * If the server explicitly says that it does not support
  3080.          * session reuse (see SSL_SESS_CACHE_OFF above), then
  3081.          * Outlook Express fails to upload a sent email to
  3082.          * the Sent Items folder on the IMAP server via a separate IMAP
  3083.          * connection in the background.  Therefore we have a special
  3084.          * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
  3085.          * where the server pretends that it supports session reuse,
  3086.          * but it does not actually store any session.
  3087.          */

  3088.         SSL_CTX_set_session_cache_mode(ssl->ctx,
  3089.                                        SSL_SESS_CACHE_SERVER
  3090.                                        |SSL_SESS_CACHE_NO_AUTO_CLEAR
  3091.                                        |SSL_SESS_CACHE_NO_INTERNAL_STORE);

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

  3093.         return NGX_OK;
  3094.     }

  3095.     cache_mode = SSL_SESS_CACHE_SERVER;

  3096.     if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
  3097.         cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
  3098.     }

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

  3100.     if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {

  3101.         if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
  3102.             SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
  3103.         }
  3104.     }

  3105.     if (shm_zone) {
  3106.         SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
  3107.         SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
  3108.         SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);

  3109.         if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone)
  3110.             == 0)
  3111.         {
  3112.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3113.                           "SSL_CTX_set_ex_data() failed");
  3114.             return NGX_ERROR;
  3115.         }
  3116.     }

  3117.     return NGX_OK;
  3118. }


  3119. static ngx_int_t
  3120. ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  3121.     ngx_array_t *certificates)
  3122. {
  3123.     int                   n, i;
  3124.     X509                 *cert;
  3125.     X509_NAME            *name;
  3126.     ngx_str_t            *certs;
  3127.     ngx_uint_t            k;
  3128.     EVP_MD_CTX           *md;
  3129.     unsigned int          len;
  3130.     STACK_OF(X509_NAME)  *list;
  3131.     u_char                buf[EVP_MAX_MD_SIZE];

  3132.     /*
  3133.      * Session ID context is set based on the string provided,
  3134.      * the server certificates, and the client CA list.
  3135.      */

  3136.     md = EVP_MD_CTX_create();
  3137.     if (md == NULL) {
  3138.         return NGX_ERROR;
  3139.     }

  3140.     if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) {
  3141.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3142.                       "EVP_DigestInit_ex() failed");
  3143.         goto failed;
  3144.     }

  3145.     if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) {
  3146.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3147.                       "EVP_DigestUpdate() failed");
  3148.         goto failed;
  3149.     }

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

  3152.         if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
  3153.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3154.                           "X509_digest() failed");
  3155.             goto failed;
  3156.         }

  3157.         if (EVP_DigestUpdate(md, buf, len) == 0) {
  3158.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3159.                           "EVP_DigestUpdate() failed");
  3160.             goto failed;
  3161.         }
  3162.     }

  3163.     if (ssl->certs.nelts == 0 && certificates != NULL) {
  3164.         /*
  3165.          * If certificates are loaded dynamically, we use certificate
  3166.          * names as specified in the configuration (with variables).
  3167.          */

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

  3170.             if (EVP_DigestUpdate(md, certs[k].data, certs[k].len) == 0) {
  3171.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3172.                               "EVP_DigestUpdate() failed");
  3173.                 goto failed;
  3174.             }
  3175.         }
  3176.     }

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

  3178.     if (list != NULL) {
  3179.         n = sk_X509_NAME_num(list);

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

  3182.             if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
  3183.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3184.                               "X509_NAME_digest() failed");
  3185.                 goto failed;
  3186.             }

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

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

  3199.     EVP_MD_CTX_destroy(md);

  3200.     if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
  3201.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3202.                       "SSL_CTX_set_session_id_context() failed");
  3203.         return NGX_ERROR;
  3204.     }

  3205.     return NGX_OK;

  3206. failed:

  3207.     EVP_MD_CTX_destroy(md);

  3208.     return NGX_ERROR;
  3209. }


  3210. ngx_int_t
  3211. ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  3212. {
  3213.     size_t                    len;
  3214.     ngx_slab_pool_t          *shpool;
  3215.     ngx_ssl_session_cache_t  *cache;

  3216.     if (data) {
  3217.         shm_zone->data = data;
  3218.         return NGX_OK;
  3219.     }

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

  3221.     if (shm_zone->shm.exists) {
  3222.         shm_zone->data = shpool->data;
  3223.         return NGX_OK;
  3224.     }

  3225.     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
  3226.     if (cache == NULL) {
  3227.         return NGX_ERROR;
  3228.     }

  3229.     shpool->data = cache;
  3230.     shm_zone->data = cache;

  3231.     ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
  3232.                     ngx_ssl_session_rbtree_insert_value);

  3233.     ngx_queue_init(&cache->expire_queue);

  3234.     cache->ticket_keys[0].expire = 0;
  3235.     cache->ticket_keys[1].expire = 0;
  3236.     cache->ticket_keys[2].expire = 0;

  3237.     cache->fail_time = 0;

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

  3239.     shpool->log_ctx = ngx_slab_alloc(shpool, len);
  3240.     if (shpool->log_ctx == NULL) {
  3241.         return NGX_ERROR;
  3242.     }

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

  3245.     shpool->log_nomem = 0;

  3246.     return NGX_OK;
  3247. }


  3248. /*
  3249. * The length of the session id is 16 bytes for SSLv2 sessions and
  3250. * between 1 and 32 bytes for SSLv3 and TLS, typically 32 bytes.
  3251. * Typical length of the external ASN1 representation of a session
  3252. * is about 150 bytes plus SNI server name.
  3253. *
  3254. * On 32-bit platforms we allocate an rbtree node, a session id, and
  3255. * an ASN1 representation in a single allocation, it typically takes
  3256. * 256 bytes.
  3257. *
  3258. * On 64-bit platforms we allocate separately an rbtree node + session_id,
  3259. * and an ASN1 representation, they take accordingly 128 and 256 bytes.
  3260. *
  3261. * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
  3262. * so they are outside the code locked by shared pool mutex
  3263. */

  3264. static int
  3265. ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
  3266. {
  3267.     int                       len;
  3268.     u_char                   *p, *session_id;
  3269.     size_t                    n;
  3270.     uint32_t                  hash;
  3271.     SSL_CTX                  *ssl_ctx;
  3272.     unsigned int              session_id_length;
  3273.     ngx_shm_zone_t           *shm_zone;
  3274.     ngx_connection_t         *c;
  3275.     ngx_slab_pool_t          *shpool;
  3276.     ngx_ssl_sess_id_t        *sess_id;
  3277.     ngx_ssl_session_cache_t  *cache;

  3278. #ifdef TLS1_3_VERSION

  3279.     /*
  3280.      * OpenSSL tries to save TLSv1.3 sessions into session cache
  3281.      * even when using tickets for stateless session resumption,
  3282.      * "because some applications just want to know about the creation
  3283.      * of a session"; do not cache such sessions
  3284.      */

  3285.     if (SSL_version(ssl_conn) == TLS1_3_VERSION
  3286.         && (SSL_get_options(ssl_conn) & SSL_OP_NO_TICKET) == 0)
  3287.     {
  3288.         return 0;
  3289.     }

  3290. #endif

  3291.     len = i2d_SSL_SESSION(sess, NULL);

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

  3293.     if (len > NGX_SSL_MAX_SESSION_SIZE) {
  3294.         return 0;
  3295.     }

  3296.     p = ngx_ssl_session_buffer;
  3297.     i2d_SSL_SESSION(sess, &p);

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

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

  3300.     if (session_id_length > 32) {
  3301.         return 0;
  3302.     }

  3303.     c = ngx_ssl_get_connection(ssl_conn);

  3304.     ssl_ctx = c->ssl->session_ctx;
  3305.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3306.     cache = shm_zone->data;
  3307.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3308.     ngx_shmtx_lock(&shpool->mutex);

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

  3311. #if (NGX_PTR_SIZE == 8)
  3312.     n = sizeof(ngx_ssl_sess_id_t);
  3313. #else
  3314.     n = offsetof(ngx_ssl_sess_id_t, session) + len;
  3315. #endif

  3316.     sess_id = ngx_slab_alloc_locked(shpool, n);

  3317.     if (sess_id == NULL) {

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

  3319.         ngx_ssl_expire_sessions(cache, shpool, 0);

  3320.         sess_id = ngx_slab_alloc_locked(shpool, n);

  3321.         if (sess_id == NULL) {
  3322.             goto failed;
  3323.         }
  3324.     }

  3325. #if (NGX_PTR_SIZE == 8)

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

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

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

  3329.         ngx_ssl_expire_sessions(cache, shpool, 0);

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

  3331.         if (sess_id->session == NULL) {
  3332.             goto failed;
  3333.         }
  3334.     }

  3335. #endif

  3336.     ngx_memcpy(sess_id->session, ngx_ssl_session_buffer, len);
  3337.     ngx_memcpy(sess_id->id, session_id, session_id_length);

  3338.     hash = ngx_crc32_short(session_id, session_id_length);

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

  3342.     sess_id->node.key = hash;
  3343.     sess_id->node.data = (u_char) session_id_length;
  3344.     sess_id->len = len;

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

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

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

  3348.     ngx_shmtx_unlock(&shpool->mutex);

  3349.     return 0;

  3350. failed:

  3351.     if (sess_id) {
  3352.         ngx_slab_free_locked(shpool, sess_id);
  3353.     }

  3354.     ngx_shmtx_unlock(&shpool->mutex);

  3355.     if (cache->fail_time != ngx_time()) {
  3356.         cache->fail_time = ngx_time();
  3357.         ngx_log_error(NGX_LOG_WARN, c->log, 0,
  3358.                       "could not allocate new session%s", shpool->log_ctx);
  3359.     }

  3360.     return 0;
  3361. }


  3362. static ngx_ssl_session_t *
  3363. ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
  3364. #if OPENSSL_VERSION_NUMBER >= 0x10100003L
  3365.     const
  3366. #endif
  3367.     u_char *id, int len, int *copy)
  3368. {
  3369.     size_t                    slen;
  3370.     uint32_t                  hash;
  3371.     ngx_int_t                 rc;
  3372.     const u_char             *p;
  3373.     ngx_shm_zone_t           *shm_zone;
  3374.     ngx_slab_pool_t          *shpool;
  3375.     ngx_connection_t         *c;
  3376.     ngx_rbtree_node_t        *node, *sentinel;
  3377.     ngx_ssl_session_t        *sess;
  3378.     ngx_ssl_sess_id_t        *sess_id;
  3379.     ngx_ssl_session_cache_t  *cache;

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

  3382.     c = ngx_ssl_get_connection(ssl_conn);

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

  3385.     shm_zone = SSL_CTX_get_ex_data(c->ssl->session_ctx,
  3386.                                    ngx_ssl_session_cache_index);

  3387.     cache = shm_zone->data;

  3388.     sess = NULL;

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

  3390.     ngx_shmtx_lock(&shpool->mutex);

  3391.     node = cache->session_rbtree.root;
  3392.     sentinel = cache->session_rbtree.sentinel;

  3393.     while (node != sentinel) {

  3394.         if (hash < node->key) {
  3395.             node = node->left;
  3396.             continue;
  3397.         }

  3398.         if (hash > node->key) {
  3399.             node = node->right;
  3400.             continue;
  3401.         }

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

  3403.         sess_id = (ngx_ssl_sess_id_t *) node;

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

  3406.         if (rc == 0) {

  3407.             if (sess_id->expire > ngx_time()) {
  3408.                 slen = sess_id->len;

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

  3410.                 ngx_shmtx_unlock(&shpool->mutex);

  3411.                 p = ngx_ssl_session_buffer;
  3412.                 sess = d2i_SSL_SESSION(NULL, &p, slen);

  3413.                 return sess;
  3414.             }

  3415.             ngx_queue_remove(&sess_id->queue);

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

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

  3418. #if (NGX_PTR_SIZE == 8)
  3419.             ngx_slab_free_locked(shpool, sess_id->session);
  3420. #endif
  3421.             ngx_slab_free_locked(shpool, sess_id);

  3422.             sess = NULL;

  3423.             goto done;
  3424.         }

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

  3427. done:

  3428.     ngx_shmtx_unlock(&shpool->mutex);

  3429.     return sess;
  3430. }


  3431. void
  3432. ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3433. {
  3434.     SSL_CTX_remove_session(ssl, sess);

  3435.     ngx_ssl_remove_session(ssl, sess);
  3436. }


  3437. static void
  3438. ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3439. {
  3440.     u_char                   *id;
  3441.     uint32_t                  hash;
  3442.     ngx_int_t                 rc;
  3443.     unsigned int              len;
  3444.     ngx_shm_zone_t           *shm_zone;
  3445.     ngx_slab_pool_t          *shpool;
  3446.     ngx_rbtree_node_t        *node, *sentinel;
  3447.     ngx_ssl_sess_id_t        *sess_id;
  3448.     ngx_ssl_session_cache_t  *cache;

  3449.     shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);

  3450.     if (shm_zone == NULL) {
  3451.         return;
  3452.     }

  3453.     cache = shm_zone->data;

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

  3455.     hash = ngx_crc32_short(id, len);

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

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

  3459.     ngx_shmtx_lock(&shpool->mutex);

  3460.     node = cache->session_rbtree.root;
  3461.     sentinel = cache->session_rbtree.sentinel;

  3462.     while (node != sentinel) {

  3463.         if (hash < node->key) {
  3464.             node = node->left;
  3465.             continue;
  3466.         }

  3467.         if (hash > node->key) {
  3468.             node = node->right;
  3469.             continue;
  3470.         }

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

  3472.         sess_id = (ngx_ssl_sess_id_t *) node;

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

  3474.         if (rc == 0) {

  3475.             ngx_queue_remove(&sess_id->queue);

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

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

  3478. #if (NGX_PTR_SIZE == 8)
  3479.             ngx_slab_free_locked(shpool, sess_id->session);
  3480. #endif
  3481.             ngx_slab_free_locked(shpool, sess_id);

  3482.             goto done;
  3483.         }

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

  3486. done:

  3487.     ngx_shmtx_unlock(&shpool->mutex);
  3488. }


  3489. static void
  3490. ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
  3491.     ngx_slab_pool_t *shpool, ngx_uint_t n)
  3492. {
  3493.     time_t              now;
  3494.     ngx_queue_t        *q;
  3495.     ngx_ssl_sess_id_t  *sess_id;

  3496.     now = ngx_time();

  3497.     while (n < 3) {

  3498.         if (ngx_queue_empty(&cache->expire_queue)) {
  3499.             return;
  3500.         }

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

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

  3503.         if (n++ != 0 && sess_id->expire > now) {
  3504.             return;
  3505.         }

  3506.         ngx_queue_remove(q);

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

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

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

  3511. #if (NGX_PTR_SIZE == 8)
  3512.         ngx_slab_free_locked(shpool, sess_id->session);
  3513. #endif
  3514.         ngx_slab_free_locked(shpool, sess_id);
  3515.     }
  3516. }


  3517. static void
  3518. ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
  3519.     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
  3520. {
  3521.     ngx_rbtree_node_t  **p;
  3522.     ngx_ssl_sess_id_t   *sess_id, *sess_id_temp;

  3523.     for ( ;; ) {

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

  3525.             p = &temp->left;

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

  3527.             p = &temp->right;

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

  3529.             sess_id = (ngx_ssl_sess_id_t *) node;
  3530.             sess_id_temp = (ngx_ssl_sess_id_t *) temp;

  3531.             p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
  3532.                               (size_t) node->data, (size_t) temp->data)
  3533.                  < 0) ? &temp->left : &temp->right;
  3534.         }

  3535.         if (*p == sentinel) {
  3536.             break;
  3537.         }

  3538.         temp = *p;
  3539.     }

  3540.     *p = node;
  3541.     node->parent = temp;
  3542.     node->left = sentinel;
  3543.     node->right = sentinel;
  3544.     ngx_rbt_red(node);
  3545. }


  3546. #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB

  3547. ngx_int_t
  3548. ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3549. {
  3550.     u_char                 buf[80];
  3551.     size_t                 size;
  3552.     ssize_t                n;
  3553.     ngx_str_t             *path;
  3554.     ngx_file_t             file;
  3555.     ngx_uint_t             i;
  3556.     ngx_array_t           *keys;
  3557.     ngx_file_info_t        fi;
  3558.     ngx_pool_cleanup_t    *cln;
  3559.     ngx_ssl_ticket_key_t  *key;

  3560.     if (paths == NULL
  3561.         && SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_session_cache_index) == NULL)
  3562.     {
  3563.         return NGX_OK;
  3564.     }

  3565.     keys = ngx_array_create(cf->pool, paths ? paths->nelts : 3,
  3566.                             sizeof(ngx_ssl_ticket_key_t));
  3567.     if (keys == NULL) {
  3568.         return NGX_ERROR;
  3569.     }

  3570.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  3571.     if (cln == NULL) {
  3572.         return NGX_ERROR;
  3573.     }

  3574.     cln->handler = ngx_ssl_ticket_keys_cleanup;
  3575.     cln->data = keys;

  3576.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ticket_keys_index, keys) == 0) {
  3577.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3578.                       "SSL_CTX_set_ex_data() failed");
  3579.         return NGX_ERROR;
  3580.     }

  3581.     if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx, ngx_ssl_ticket_key_callback)
  3582.         == 0)
  3583.     {
  3584.         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
  3585.                       "nginx was built with Session Tickets support, however, "
  3586.                       "now it is linked dynamically to an OpenSSL library "
  3587.                       "which has no tlsext support, therefore Session Tickets "
  3588.                       "are not available");
  3589.         return NGX_OK;
  3590.     }

  3591.     if (paths == NULL) {

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

  3593.         key = ngx_array_push_n(keys, 3);
  3594.         key[0].shared = 1;
  3595.         key[0].expire = 0;
  3596.         key[1].shared = 1;
  3597.         key[1].expire = 0;
  3598.         key[2].shared = 1;
  3599.         key[2].expire = 0;

  3600.         return NGX_OK;
  3601.     }

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

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

  3607.         ngx_memzero(&file, sizeof(ngx_file_t));
  3608.         file.name = path[i];
  3609.         file.log = cf->log;

  3610.         file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
  3611.                                 NGX_FILE_OPEN, 0);

  3612.         if (file.fd == NGX_INVALID_FILE) {
  3613.             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  3614.                                ngx_open_file_n " \"%V\" failed", &file.name);
  3615.             return NGX_ERROR;
  3616.         }

  3617.         if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
  3618.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3619.                                ngx_fd_info_n " \"%V\" failed", &file.name);
  3620.             goto failed;
  3621.         }

  3622.         size = ngx_file_size(&fi);

  3623.         if (size != 48 && size != 80) {
  3624.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3625.                                "\"%V\" must be 48 or 80 bytes", &file.name);
  3626.             goto failed;
  3627.         }

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

  3629.         if (n == NGX_ERROR) {
  3630.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3631.                                ngx_read_file_n " \"%V\" failed", &file.name);
  3632.             goto failed;
  3633.         }

  3634.         if ((size_t) n != size) {
  3635.             ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
  3636.                                ngx_read_file_n " \"%V\" returned only "
  3637.                                "%z bytes instead of %uz", &file.name, n, size);
  3638.             goto failed;
  3639.         }

  3640.         key = ngx_array_push(keys);
  3641.         if (key == NULL) {
  3642.             goto failed;
  3643.         }

  3644.         key->shared = 0;
  3645.         key->expire = 1;

  3646.         if (size == 48) {
  3647.             key->size = 48;
  3648.             ngx_memcpy(key->name, buf, 16);
  3649.             ngx_memcpy(key->aes_key, buf + 16, 16);
  3650.             ngx_memcpy(key->hmac_key, buf + 32, 16);

  3651.         } else {
  3652.             key->size = 80;
  3653.             ngx_memcpy(key->name, buf, 16);
  3654.             ngx_memcpy(key->hmac_key, buf + 16, 32);
  3655.             ngx_memcpy(key->aes_key, buf + 48, 32);
  3656.         }

  3657.         if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3658.             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3659.                           ngx_close_file_n " \"%V\" failed", &file.name);
  3660.         }

  3661.         ngx_explicit_memzero(&buf, 80);
  3662.     }

  3663.     return NGX_OK;

  3664. failed:

  3665.     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3666.         ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3667.                       ngx_close_file_n " \"%V\" failed", &file.name);
  3668.     }

  3669.     ngx_explicit_memzero(&buf, 80);

  3670.     return NGX_ERROR;
  3671. }


  3672. static int
  3673. ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
  3674.     unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
  3675.     HMAC_CTX *hctx, int enc)
  3676. {
  3677.     size_t                 size;
  3678.     SSL_CTX               *ssl_ctx;
  3679.     ngx_uint_t             i;
  3680.     ngx_array_t           *keys;
  3681.     ngx_connection_t      *c;
  3682.     ngx_ssl_ticket_key_t  *key;
  3683.     const EVP_MD          *digest;
  3684.     const EVP_CIPHER      *cipher;

  3685.     c = ngx_ssl_get_connection(ssl_conn);
  3686.     ssl_ctx = c->ssl->session_ctx;

  3687.     if (ngx_ssl_rotate_ticket_keys(ssl_ctx, c->log) != NGX_OK) {
  3688.         return -1;
  3689.     }

  3690. #ifdef OPENSSL_NO_SHA256
  3691.     digest = EVP_sha1();
  3692. #else
  3693.     digest = EVP_sha256();
  3694. #endif

  3695.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3696.     if (keys == NULL) {
  3697.         return -1;
  3698.     }

  3699.     key = keys->elts;

  3700.     if (enc == 1) {
  3701.         /* encrypt session ticket */

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

  3706.         if (key[0].size == 48) {
  3707.             cipher = EVP_aes_128_cbc();
  3708.             size = 16;

  3709.         } else {
  3710.             cipher = EVP_aes_256_cbc();
  3711.             size = 32;
  3712.         }

  3713.         if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
  3714.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed");
  3715.             return -1;
  3716.         }

  3717.         if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) {
  3718.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3719.                           "EVP_EncryptInit_ex() failed");
  3720.             return -1;
  3721.         }

  3722. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3723.         if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) {
  3724.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3725.             return -1;
  3726.         }
  3727. #else
  3728.         HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL);
  3729. #endif

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

  3731.         return 1;

  3732.     } else {
  3733.         /* decrypt session ticket */

  3734.         for (i = 0; i < keys->nelts; i++) {
  3735.             if (ngx_memcmp(name, key[i].name, 16) == 0) {
  3736.                 goto found;
  3737.             }
  3738.         }

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

  3742.         return 0;

  3743.     found:

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

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

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

  3754. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3755.         if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) {
  3756.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3757.             return -1;
  3758.         }
  3759. #else
  3760.         HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL);
  3761. #endif

  3762.         if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) {
  3763.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3764.                           "EVP_DecryptInit_ex() failed");
  3765.             return -1;
  3766.         }

  3767.         /* renew if TLSv1.3 */

  3768. #ifdef TLS1_3_VERSION
  3769.         if (SSL_version(ssl_conn) == TLS1_3_VERSION) {
  3770.             return 2;
  3771.         }
  3772. #endif

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

  3774.         if (i != 0 && key[i].expire) {
  3775.             return 2;
  3776.         }

  3777.         return 1;
  3778.     }
  3779. }


  3780. static ngx_int_t
  3781. ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
  3782. {
  3783.     time_t                    now, expire;
  3784.     ngx_array_t              *keys;
  3785.     ngx_shm_zone_t           *shm_zone;
  3786.     ngx_slab_pool_t          *shpool;
  3787.     ngx_ssl_ticket_key_t     *key;
  3788.     ngx_ssl_session_cache_t  *cache;
  3789.     u_char                    buf[80];

  3790.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3791.     if (keys == NULL) {
  3792.         return NGX_OK;
  3793.     }

  3794.     key = keys->elts;

  3795.     if (!key[0].shared) {
  3796.         return NGX_OK;
  3797.     }

  3798.     /*
  3799.      * if we don't need to update expiration of the current key
  3800.      * and the previous key is still needed, don't sync with shared
  3801.      * memory to save some work; in the worst case other worker process
  3802.      * will switch to the next key, but this process will still be able
  3803.      * to decrypt tickets encrypted with it
  3804.      */

  3805.     now = ngx_time();
  3806.     expire = now + SSL_CTX_get_timeout(ssl_ctx);

  3807.     if (key[0].expire >= expire && key[1].expire >= now) {
  3808.         return NGX_OK;
  3809.     }

  3810.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3811.     cache = shm_zone->data;
  3812.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3813.     ngx_shmtx_lock(&shpool->mutex);

  3814.     key = cache->ticket_keys;

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

  3816.         /* initialize the current key */

  3817.         if (RAND_bytes(buf, 80) != 1) {
  3818.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3819.             ngx_shmtx_unlock(&shpool->mutex);
  3820.             return NGX_ERROR;
  3821.         }

  3822.         key[0].shared = 1;
  3823.         key[0].expire = expire;
  3824.         key[0].size = 80;
  3825.         ngx_memcpy(key[0].name, buf, 16);
  3826.         ngx_memcpy(key[0].hmac_key, buf + 16, 32);
  3827.         ngx_memcpy(key[0].aes_key, buf + 48, 32);

  3828.         ngx_explicit_memzero(&buf, 80);

  3829.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3830.                        "ssl ticket key: \"%*xs\"",
  3831.                        (size_t) 16, key[0].name);

  3832.         /*
  3833.          * copy the current key to the next key, as initialization of
  3834.          * the previous key will replace the current key with the next
  3835.          * key
  3836.          */

  3837.         key[2] = key[0];
  3838.     }

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

  3840.         /*
  3841.          * if the previous key is no longer needed (or not initialized),
  3842.          * replace it with the current key, replace the current key with
  3843.          * the next key, and generate new next key
  3844.          */

  3845.         key[1] = key[0];
  3846.         key[0] = key[2];

  3847.         if (RAND_bytes(buf, 80) != 1) {
  3848.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3849.             ngx_shmtx_unlock(&shpool->mutex);
  3850.             return NGX_ERROR;
  3851.         }

  3852.         key[2].shared = 1;
  3853.         key[2].expire = 0;
  3854.         key[2].size = 80;
  3855.         ngx_memcpy(key[2].name, buf, 16);
  3856.         ngx_memcpy(key[2].hmac_key, buf + 16, 32);
  3857.         ngx_memcpy(key[2].aes_key, buf + 48, 32);

  3858.         ngx_explicit_memzero(&buf, 80);

  3859.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3860.                        "ssl ticket key: \"%*xs\"",
  3861.                        (size_t) 16, key[2].name);
  3862.     }

  3863.     /*
  3864.      * update expiration of the current key: it is going to be needed
  3865.      * at least till the session being created expires
  3866.      */

  3867.     if (expire > key[0].expire) {
  3868.         key[0].expire = expire;
  3869.     }

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

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

  3873.     ngx_shmtx_unlock(&shpool->mutex);

  3874.     return NGX_OK;
  3875. }


  3876. static void
  3877. ngx_ssl_ticket_keys_cleanup(void *data)
  3878. {
  3879.     ngx_array_t  *keys = data;

  3880.     ngx_explicit_memzero(keys->elts,
  3881.                          keys->nelts * sizeof(ngx_ssl_ticket_key_t));
  3882. }

  3883. #else

  3884. ngx_int_t
  3885. ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3886. {
  3887.     if (paths) {
  3888.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  3889.                       "\"ssl_session_ticket_key\" ignored, not supported");
  3890.     }

  3891.     return NGX_OK;
  3892. }

  3893. #endif


  3894. void
  3895. ngx_ssl_cleanup_ctx(void *data)
  3896. {
  3897.     ngx_ssl_t  *ssl = data;

  3898.     X509        *cert;
  3899.     u_char      *p;
  3900.     ngx_uint_t   i;

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

  3903.         p = X509_get_ex_data(cert, ngx_ssl_certificate_comp_index);

  3904.         if (p) {
  3905.             ngx_free(p);
  3906.             X509_set_ex_data(cert, ngx_ssl_certificate_comp_index, NULL);
  3907.         }

  3908.         X509_free(cert);
  3909.     }

  3910.     SSL_CTX_free(ssl->ctx);
  3911. }


  3912. ngx_int_t
  3913. ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
  3914. {
  3915.     X509   *cert;

  3916.     cert = SSL_get_peer_certificate(c->ssl->connection);
  3917.     if (cert == NULL) {
  3918.         return NGX_ERROR;
  3919.     }

  3920. #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

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

  3922.     if (name->len == 0) {
  3923.         goto failed;
  3924.     }

  3925.     if (X509_check_host(cert, (char *) name->data, name->len, 0, NULL) != 1) {
  3926.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3927.                        "X509_check_host(): no match");
  3928.         goto failed;
  3929.     }

  3930.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3931.                    "X509_check_host(): match");

  3932.     goto found;

  3933. #else
  3934.     {
  3935.     int                      n, i;
  3936.     X509_NAME               *sname;
  3937.     ASN1_STRING             *str;
  3938.     X509_NAME_ENTRY         *entry;
  3939.     GENERAL_NAME            *altname;
  3940.     STACK_OF(GENERAL_NAME)  *altnames;

  3941.     /*
  3942.      * As per RFC6125 and RFC2818, we check subjectAltName extension,
  3943.      * and if it's not present - commonName in Subject is checked.
  3944.      */

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

  3946.     if (altnames) {
  3947.         n = sk_GENERAL_NAME_num(altnames);

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

  3950.             if (altname->type != GEN_DNS) {
  3951.                 continue;
  3952.             }

  3953.             str = altname->d.dNSName;

  3954.             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3955.                            "SSL subjectAltName: \"%*s\"",
  3956.                            ASN1_STRING_length(str), ASN1_STRING_data(str));

  3957.             if (ngx_ssl_check_name(name, str) == NGX_OK) {
  3958.                 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3959.                                "SSL subjectAltName: match");
  3960.                 GENERAL_NAMES_free(altnames);
  3961.                 goto found;
  3962.             }
  3963.         }

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

  3966.         GENERAL_NAMES_free(altnames);
  3967.         goto failed;
  3968.     }

  3969.     /*
  3970.      * If there is no subjectAltName extension, check commonName
  3971.      * in Subject.  While RFC2818 requires to only check "most specific"
  3972.      * CN, both Apache and OpenSSL check all CNs, and so do we.
  3973.      */

  3974.     sname = X509_get_subject_name(cert);

  3975.     if (sname == NULL) {
  3976.         goto failed;
  3977.     }

  3978.     i = -1;
  3979.     for ( ;; ) {
  3980.         i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);

  3981.         if (i < 0) {
  3982.             break;
  3983.         }

  3984.         entry = X509_NAME_get_entry(sname, i);
  3985.         str = X509_NAME_ENTRY_get_data(entry);

  3986.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3987.                        "SSL commonName: \"%*s\"",
  3988.                        ASN1_STRING_length(str), ASN1_STRING_data(str));

  3989.         if (ngx_ssl_check_name(name, str) == NGX_OK) {
  3990.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3991.                            "SSL commonName: match");
  3992.             goto found;
  3993.         }
  3994.     }

  3995.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3996.                    "SSL commonName: no match");
  3997.     }
  3998. #endif

  3999. failed:

  4000.     X509_free(cert);
  4001.     return NGX_ERROR;

  4002. found:

  4003.     X509_free(cert);
  4004.     return NGX_OK;
  4005. }


  4006. #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

  4007. static ngx_int_t
  4008. ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern)
  4009. {
  4010.     u_char  *s, *p, *end;
  4011.     size_t   slen, plen;

  4012.     s = name->data;
  4013.     slen = name->len;

  4014.     p = ASN1_STRING_data(pattern);
  4015.     plen = ASN1_STRING_length(pattern);

  4016.     if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) {
  4017.         return NGX_OK;
  4018.     }

  4019.     if (plen > 2 && p[0] == '*' && p[1] == '.') {
  4020.         plen -= 1;
  4021.         p += 1;

  4022.         end = s + slen;
  4023.         s = ngx_strlchr(s, end, '.');

  4024.         if (s == NULL) {
  4025.             return NGX_ERROR;
  4026.         }

  4027.         slen = end - s;

  4028.         if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) {
  4029.             return NGX_OK;
  4030.         }
  4031.     }

  4032.     return NGX_ERROR;
  4033. }

  4034. #endif


  4035. ngx_int_t
  4036. ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4037. {
  4038.     s->data = (u_char *) SSL_get_version(c->ssl->connection);
  4039.     return NGX_OK;
  4040. }


  4041. ngx_int_t
  4042. ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4043. {
  4044.     s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);
  4045.     return NGX_OK;
  4046. }


  4047. ngx_int_t
  4048. ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4049. {
  4050. #ifdef SSL_CTRL_GET_RAW_CIPHERLIST

  4051.     int                n, i, bytes;
  4052.     size_t             len;
  4053.     u_char            *ciphers, *p;
  4054.     const SSL_CIPHER  *cipher;

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

  4057.     if (n <= 0) {
  4058.         s->len = 0;
  4059.         return NGX_OK;
  4060.     }

  4061.     len = 0;
  4062.     n /= bytes;

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

  4065.         if (cipher) {
  4066.             len += ngx_strlen(SSL_CIPHER_get_name(cipher));

  4067.         } else {
  4068.             len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1);
  4069.         }

  4070.         len += sizeof(":") - 1;
  4071.     }

  4072.     s->data = ngx_pnalloc(pool, len);
  4073.     if (s->data == NULL) {
  4074.         return NGX_ERROR;
  4075.     }

  4076.     p = s->data;

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

  4079.         if (cipher) {
  4080.             p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher));

  4081.         } else {
  4082.             p = ngx_sprintf(p, "0x");
  4083.             p = ngx_hex_dump(p, ciphers + i * bytes, bytes);
  4084.         }

  4085.         *p++ = ':';
  4086.     }

  4087.     p--;

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

  4089. #else

  4090.     u_char  buf[4096];

  4091.     if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096)
  4092.         == NULL)
  4093.     {
  4094.         s->len = 0;
  4095.         return NGX_OK;
  4096.     }

  4097.     s->len = ngx_strlen(buf);
  4098.     s->data = ngx_pnalloc(pool, s->len);
  4099.     if (s->data == NULL) {
  4100.         return NGX_ERROR;
  4101.     }

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

  4103. #endif

  4104.     return NGX_OK;
  4105. }


  4106. ngx_int_t
  4107. ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4108. {
  4109. #ifdef SSL_get_negotiated_group

  4110.     int          nid;
  4111.     const char  *name;

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

  4113.     if (nid != NID_undef) {

  4114.         if ((nid & TLSEXT_nid_unknown) == 0) {
  4115.             s->len = ngx_strlen(OBJ_nid2sn(nid));
  4116.             s->data = (u_char *) OBJ_nid2sn(nid);
  4117.             return NGX_OK;
  4118.         }

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

  4120.         s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
  4121.         s->data = ngx_pnalloc(pool, s->len);
  4122.         if (s->data == NULL) {
  4123.             return NGX_ERROR;
  4124.         }

  4125.         if (name) {
  4126.             ngx_memcpy(s->data, name, s->len);

  4127.         } else {
  4128.             ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);
  4129.         }

  4130.         return NGX_OK;
  4131.     }

  4132. #endif

  4133.     s->len = 0;
  4134.     return NGX_OK;
  4135. }


  4136. ngx_int_t
  4137. ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4138. {
  4139. #ifdef SSL_CTRL_GET_CURVES

  4140.     int         *curves, n, i, nid;
  4141.     u_char      *p;
  4142.     size_t       len;
  4143.     const char  *name;

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

  4145.     if (n <= 0) {
  4146.         s->len = 0;
  4147.         return NGX_OK;
  4148.     }

  4149.     curves = ngx_palloc(pool, n * sizeof(int));
  4150.     if (curves == NULL) {
  4151.         return NGX_ERROR;
  4152.     }

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

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

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

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

  4160.         } else {
  4161.             len += ngx_strlen(OBJ_nid2sn(nid));
  4162.         }

  4163.         len += sizeof(":") - 1;
  4164.     }

  4165.     s->data = ngx_pnalloc(pool, len);
  4166.     if (s->data == NULL) {
  4167.         return NGX_ERROR;
  4168.     }

  4169.     p = s->data;

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

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

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

  4176.         } else {
  4177.             p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));
  4178.         }

  4179.         *p++ = ':';
  4180.     }

  4181.     p--;

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

  4183. #else

  4184.     s->len = 0;

  4185. #endif

  4186.     return NGX_OK;
  4187. }


  4188. ngx_int_t
  4189. ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4190. {
  4191. #ifdef SSL_get0_signature_name

  4192.     const char  *name;

  4193.     if (SSL_get0_signature_name(c->ssl->connection, &name)) {
  4194.         s->len = ngx_strlen(name);
  4195.         s->data = ngx_pnalloc(pool, s->len);
  4196.         if (s->data == NULL) {
  4197.             return NGX_ERROR;
  4198.         }

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

  4200.         return NGX_OK;
  4201.     }

  4202. #endif

  4203.     s->len = 0;
  4204.     return NGX_OK;
  4205. }


  4206. ngx_int_t
  4207. ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4208. {
  4209. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)

  4210.     int            n, i;
  4211.     size_t         len;
  4212.     u_char        *p;
  4213.     const char    *name;
  4214.     unsigned int   codepoint;

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

  4216.     if (n <= 0) {
  4217.         s->len = 0;
  4218.         return NGX_OK;
  4219.     }

  4220.     len = 0;

  4221.     for (i = 0; i < n; i++) {
  4222.         SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name);
  4223.         len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
  4224.         len += sizeof(":") - 1;
  4225.     }

  4226.     s->data = ngx_pnalloc(pool, len);
  4227.     if (s->data == NULL) {
  4228.         return NGX_ERROR;
  4229.     }

  4230.     p = s->data;

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

  4233.         if (name) {
  4234.             p = ngx_cpymem(p, name, ngx_strlen(name));

  4235.         } else {
  4236.             p = ngx_sprintf(p, "0x%04xd", codepoint);
  4237.         }

  4238.         *p++ = ':';
  4239.     }

  4240.     p--;

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

  4242. #elif defined SSL_CTRL_SET_SIGALGS

  4243.     /*
  4244.      * SSL_get_sigalgs() is only available in OpenSSL 1.0.2+,
  4245.      * but uses a different naming, so emit raw codes
  4246.      */

  4247.     int             n, i;
  4248.     size_t          len;
  4249.     u_char         *p;
  4250.     unsigned char   rsig, rhash;

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

  4252.     if (n <= 0) {
  4253.         s->len = 0;
  4254.         return NGX_OK;
  4255.     }

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

  4257.     s->data = ngx_pnalloc(pool, len);
  4258.     if (s->data == NULL) {
  4259.         return NGX_ERROR;
  4260.     }

  4261.     p = s->data;

  4262.     for (i = 0; i < n; i++) {
  4263.         SSL_get_sigalgs(c->ssl->connection, i, NULL, NULL, NULL, &rsig, &rhash);
  4264.         p = ngx_sprintf(p, "0x%04xd", rhash << 8 | rsig);
  4265.         *p++ = ':';
  4266.     }

  4267.     p--;

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

  4269. #else

  4270.     s->len = 0;

  4271. #endif

  4272.     return NGX_OK;
  4273. }


  4274. ngx_int_t
  4275. ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4276. {
  4277.     u_char        *buf;
  4278.     SSL_SESSION   *sess;
  4279.     unsigned int   len;

  4280.     sess = SSL_get0_session(c->ssl->connection);
  4281.     if (sess == NULL) {
  4282.         s->len = 0;
  4283.         return NGX_OK;
  4284.     }

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

  4286.     s->len = 2 * len;
  4287.     s->data = ngx_pnalloc(pool, 2 * len);
  4288.     if (s->data == NULL) {
  4289.         return NGX_ERROR;
  4290.     }

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

  4292.     return NGX_OK;
  4293. }


  4294. ngx_int_t
  4295. ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4296. {
  4297.     if (SSL_session_reused(c->ssl->connection)) {
  4298.         ngx_str_set(s, "r");

  4299.     } else {
  4300.         ngx_str_set(s, ".");
  4301.     }

  4302.     return NGX_OK;
  4303. }


  4304. ngx_int_t
  4305. ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4306. {
  4307.     s->len = 0;

  4308. #ifdef SSL_ERROR_EARLY_DATA_REJECTED

  4309.     /* BoringSSL */

  4310.     if (SSL_in_early_data(c->ssl->connection)) {
  4311.         ngx_str_set(s, "1");
  4312.     }

  4313. #elif defined SSL_READ_EARLY_DATA_SUCCESS

  4314.     /* OpenSSL */

  4315.     if (!SSL_is_init_finished(c->ssl->connection)) {
  4316.         ngx_str_set(s, "1");
  4317.     }

  4318. #endif

  4319.     return NGX_OK;
  4320. }


  4321. ngx_int_t
  4322. ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4323. {
  4324. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  4325.     size_t       len;
  4326.     const char  *name;

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

  4328.     if (name) {
  4329.         len = ngx_strlen(name);

  4330.         s->len = len;
  4331.         s->data = ngx_pnalloc(pool, len);
  4332.         if (s->data == NULL) {
  4333.             return NGX_ERROR;
  4334.         }

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

  4336.         return NGX_OK;
  4337.     }

  4338. #endif

  4339.     s->len = 0;
  4340.     return NGX_OK;
  4341. }


  4342. ngx_int_t
  4343. ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4344. {
  4345. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  4346.     unsigned int          len;
  4347.     const unsigned char  *data;

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

  4349.     if (len > 0) {

  4350.         s->data = ngx_pnalloc(pool, len);
  4351.         if (s->data == NULL) {
  4352.             return NGX_ERROR;
  4353.         }

  4354.         ngx_memcpy(s->data, data, len);
  4355.         s->len = len;

  4356.         return NGX_OK;
  4357.     }

  4358. #endif

  4359.     s->len = 0;
  4360.     return NGX_OK;
  4361. }


  4362. ngx_int_t
  4363. ngx_ssl_get_ech_status(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4364. {
  4365. #ifdef SSL_OP_ECH_GREASE
  4366.     int    echrv;
  4367.     char  *inner_sni, *outer_sni;

  4368.     inner_sni = NULL;
  4369.     outer_sni = NULL;

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

  4371.     switch (echrv) {
  4372.     case SSL_ECH_STATUS_NOT_TRIED:
  4373.         ngx_str_set(s, "NOT_TRIED");
  4374.         break;
  4375.     case SSL_ECH_STATUS_SUCCESS:
  4376.         ngx_str_set(s, "SUCCESS");
  4377.         break;
  4378.     case SSL_ECH_STATUS_GREASE:
  4379.         ngx_str_set(s, "GREASE");
  4380.         break;
  4381.     case SSL_ECH_STATUS_BACKEND:
  4382.         ngx_str_set(s, "BACKEND");
  4383.         break;
  4384.     default:
  4385.         ngx_str_set(s, "FAILED");
  4386.         break;
  4387.     }

  4388.     OPENSSL_free(inner_sni);
  4389.     OPENSSL_free(outer_sni);
  4390. #else
  4391.     s->len = 0;
  4392. #endif
  4393.     return NGX_OK;
  4394. }


  4395. ngx_int_t
  4396. ngx_ssl_get_ech_outer_server_name(ngx_connection_t *c, ngx_pool_t *pool,
  4397.     ngx_str_t *s)
  4398. {
  4399. #if defined(SSL_OP_ECH_GREASE)
  4400.     int    echrv;
  4401.     char  *inner_sni, *outer_sni;

  4402.     inner_sni = NULL;
  4403.     outer_sni = NULL;

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

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

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

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

  4412.     } else {
  4413.         s->len = 0;
  4414.     }

  4415.     OPENSSL_free(inner_sni);
  4416.     OPENSSL_free(outer_sni);
  4417. #else
  4418.     s->len = 0;
  4419. #endif
  4420.     return NGX_OK;
  4421. }


  4422. ngx_int_t
  4423. ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4424. {
  4425.     size_t   len;
  4426.     BIO     *bio;
  4427.     X509    *cert;

  4428.     s->len = 0;

  4429.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4430.     if (cert == NULL) {
  4431.         return NGX_OK;
  4432.     }

  4433.     bio = BIO_new(BIO_s_mem());
  4434.     if (bio == NULL) {
  4435.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4436.         X509_free(cert);
  4437.         return NGX_ERROR;
  4438.     }

  4439.     if (PEM_write_bio_X509(bio, cert) == 0) {
  4440.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
  4441.         goto failed;
  4442.     }

  4443.     len = BIO_pending(bio);
  4444.     s->len = len;

  4445.     s->data = ngx_pnalloc(pool, len);
  4446.     if (s->data == NULL) {
  4447.         goto failed;
  4448.     }

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

  4450.     BIO_free(bio);
  4451.     X509_free(cert);

  4452.     return NGX_OK;

  4453. failed:

  4454.     BIO_free(bio);
  4455.     X509_free(cert);

  4456.     return NGX_ERROR;
  4457. }


  4458. ngx_int_t
  4459. ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4460. {
  4461.     u_char      *p;
  4462.     size_t       len;
  4463.     ngx_uint_t   i;
  4464.     ngx_str_t    cert;

  4465.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  4466.         return NGX_ERROR;
  4467.     }

  4468.     if (cert.len == 0) {
  4469.         s->len = 0;
  4470.         return NGX_OK;
  4471.     }

  4472.     len = cert.len - 1;

  4473.     for (i = 0; i < cert.len - 1; i++) {
  4474.         if (cert.data[i] == LF) {
  4475.             len++;
  4476.         }
  4477.     }

  4478.     s->len = len;
  4479.     s->data = ngx_pnalloc(pool, len);
  4480.     if (s->data == NULL) {
  4481.         return NGX_ERROR;
  4482.     }

  4483.     p = s->data;

  4484.     for (i = 0; i < cert.len - 1; i++) {
  4485.         *p++ = cert.data[i];
  4486.         if (cert.data[i] == LF) {
  4487.             *p++ = '\t';
  4488.         }
  4489.     }

  4490.     return NGX_OK;
  4491. }


  4492. ngx_int_t
  4493. ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool,
  4494.     ngx_str_t *s)
  4495. {
  4496.     ngx_str_t  cert;
  4497.     uintptr_t  n;

  4498.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  4499.         return NGX_ERROR;
  4500.     }

  4501.     if (cert.len == 0) {
  4502.         s->len = 0;
  4503.         return NGX_OK;
  4504.     }

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

  4506.     s->len = cert.len + n * 2;
  4507.     s->data = ngx_pnalloc(pool, s->len);
  4508.     if (s->data == NULL) {
  4509.         return NGX_ERROR;
  4510.     }

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

  4512.     return NGX_OK;
  4513. }


  4514. ngx_int_t
  4515. ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4516. {
  4517.     BIO        *bio;
  4518.     X509       *cert;
  4519. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4520.     const
  4521. #endif
  4522.     X509_NAME  *name;

  4523.     s->len = 0;

  4524.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4525.     if (cert == NULL) {
  4526.         return NGX_OK;
  4527.     }

  4528.     name = X509_get_subject_name(cert);
  4529.     if (name == NULL) {
  4530.         X509_free(cert);
  4531.         return NGX_ERROR;
  4532.     }

  4533.     bio = BIO_new(BIO_s_mem());
  4534.     if (bio == NULL) {
  4535.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4536.         X509_free(cert);
  4537.         return NGX_ERROR;
  4538.     }

  4539.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4540.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4541.         goto failed;
  4542.     }

  4543.     s->len = BIO_pending(bio);
  4544.     s->data = ngx_pnalloc(pool, s->len);
  4545.     if (s->data == NULL) {
  4546.         goto failed;
  4547.     }

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

  4549.     BIO_free(bio);
  4550.     X509_free(cert);

  4551.     return NGX_OK;

  4552. failed:

  4553.     BIO_free(bio);
  4554.     X509_free(cert);

  4555.     return NGX_ERROR;
  4556. }


  4557. ngx_int_t
  4558. ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4559. {
  4560.     BIO        *bio;
  4561.     X509       *cert;
  4562. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4563.     const
  4564. #endif
  4565.     X509_NAME  *name;

  4566.     s->len = 0;

  4567.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4568.     if (cert == NULL) {
  4569.         return NGX_OK;
  4570.     }

  4571.     name = X509_get_issuer_name(cert);
  4572.     if (name == NULL) {
  4573.         X509_free(cert);
  4574.         return NGX_ERROR;
  4575.     }

  4576.     bio = BIO_new(BIO_s_mem());
  4577.     if (bio == NULL) {
  4578.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4579.         X509_free(cert);
  4580.         return NGX_ERROR;
  4581.     }

  4582.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4583.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4584.         goto failed;
  4585.     }

  4586.     s->len = BIO_pending(bio);
  4587.     s->data = ngx_pnalloc(pool, s->len);
  4588.     if (s->data == NULL) {
  4589.         goto failed;
  4590.     }

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

  4592.     BIO_free(bio);
  4593.     X509_free(cert);

  4594.     return NGX_OK;

  4595. failed:

  4596.     BIO_free(bio);
  4597.     X509_free(cert);

  4598.     return NGX_ERROR;
  4599. }


  4600. ngx_int_t
  4601. ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4602.     ngx_str_t *s)
  4603. {
  4604.     char       *p;
  4605.     size_t      len;
  4606.     X509       *cert;
  4607. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4608.     const
  4609. #endif
  4610.     X509_NAME  *name;

  4611.     s->len = 0;

  4612.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4613.     if (cert == NULL) {
  4614.         return NGX_OK;
  4615.     }

  4616.     name = X509_get_subject_name(cert);
  4617.     if (name == NULL) {
  4618.         X509_free(cert);
  4619.         return NGX_ERROR;
  4620.     }

  4621.     p = X509_NAME_oneline(name, NULL, 0);
  4622.     if (p == NULL) {
  4623.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4624.         X509_free(cert);
  4625.         return NGX_ERROR;
  4626.     }

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

  4628.     s->len = len;
  4629.     s->data = ngx_pnalloc(pool, len);
  4630.     if (s->data == NULL) {
  4631.         OPENSSL_free(p);
  4632.         X509_free(cert);
  4633.         return NGX_ERROR;
  4634.     }

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

  4636.     OPENSSL_free(p);
  4637.     X509_free(cert);

  4638.     return NGX_OK;
  4639. }


  4640. ngx_int_t
  4641. ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4642.     ngx_str_t *s)
  4643. {
  4644.     char       *p;
  4645.     size_t      len;
  4646.     X509       *cert;
  4647. #if (OPENSSL_VERSION_NUMBER >= 0x40000000L)
  4648.     const
  4649. #endif
  4650.     X509_NAME  *name;

  4651.     s->len = 0;

  4652.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4653.     if (cert == NULL) {
  4654.         return NGX_OK;
  4655.     }

  4656.     name = X509_get_issuer_name(cert);
  4657.     if (name == NULL) {
  4658.         X509_free(cert);
  4659.         return NGX_ERROR;
  4660.     }

  4661.     p = X509_NAME_oneline(name, NULL, 0);
  4662.     if (p == NULL) {
  4663.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4664.         X509_free(cert);
  4665.         return NGX_ERROR;
  4666.     }

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

  4668.     s->len = len;
  4669.     s->data = ngx_pnalloc(pool, len);
  4670.     if (s->data == NULL) {
  4671.         OPENSSL_free(p);
  4672.         X509_free(cert);
  4673.         return NGX_ERROR;
  4674.     }

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

  4676.     OPENSSL_free(p);
  4677.     X509_free(cert);

  4678.     return NGX_OK;
  4679. }


  4680. ngx_int_t
  4681. ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4682. {
  4683.     size_t   len;
  4684.     X509    *cert;
  4685.     BIO     *bio;

  4686.     s->len = 0;

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

  4691.     bio = BIO_new(BIO_s_mem());
  4692.     if (bio == NULL) {
  4693.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4694.         X509_free(cert);
  4695.         return NGX_ERROR;
  4696.     }

  4697.     i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
  4698.     len = BIO_pending(bio);

  4699.     s->len = len;
  4700.     s->data = ngx_pnalloc(pool, len);
  4701.     if (s->data == NULL) {
  4702.         BIO_free(bio);
  4703.         X509_free(cert);
  4704.         return NGX_ERROR;
  4705.     }

  4706.     BIO_read(bio, s->data, len);
  4707.     BIO_free(bio);
  4708.     X509_free(cert);

  4709.     return NGX_OK;
  4710. }


  4711. ngx_int_t
  4712. ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4713. {
  4714.     X509          *cert;
  4715.     unsigned int   len;
  4716.     u_char         buf[EVP_MAX_MD_SIZE];

  4717.     s->len = 0;

  4718.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4719.     if (cert == NULL) {
  4720.         return NGX_OK;
  4721.     }

  4722.     if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
  4723.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed");
  4724.         X509_free(cert);
  4725.         return NGX_ERROR;
  4726.     }

  4727.     s->len = 2 * len;
  4728.     s->data = ngx_pnalloc(pool, 2 * len);
  4729.     if (s->data == NULL) {
  4730.         X509_free(cert);
  4731.         return NGX_ERROR;
  4732.     }

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

  4734.     X509_free(cert);

  4735.     return NGX_OK;
  4736. }


  4737. ngx_int_t
  4738. ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4739. {
  4740.     X509        *cert;
  4741.     long         rc;
  4742.     const char  *str;

  4743.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4744.     if (cert == NULL) {
  4745.         ngx_str_set(s, "NONE");
  4746.         return NGX_OK;
  4747.     }

  4748.     X509_free(cert);

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

  4750.     if (rc == X509_V_OK) {
  4751.         if (ngx_ssl_ocsp_get_status(c, &str) == NGX_OK) {
  4752.             ngx_str_set(s, "SUCCESS");
  4753.             return NGX_OK;
  4754.         }

  4755.     } else {
  4756.         str = X509_verify_cert_error_string(rc);
  4757.     }

  4758.     s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str));
  4759.     if (s->data == NULL) {
  4760.         return NGX_ERROR;
  4761.     }

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

  4763.     return NGX_OK;
  4764. }


  4765. ngx_int_t
  4766. ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4767. {
  4768.     BIO     *bio;
  4769.     X509    *cert;
  4770.     size_t   len;

  4771.     s->len = 0;

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

  4776.     bio = BIO_new(BIO_s_mem());
  4777.     if (bio == NULL) {
  4778.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4779.         X509_free(cert);
  4780.         return NGX_ERROR;
  4781.     }

  4782. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4783.     ASN1_TIME_print(bio, X509_get0_notBefore(cert));
  4784. #else
  4785.     ASN1_TIME_print(bio, X509_get_notBefore(cert));
  4786. #endif

  4787.     len = BIO_pending(bio);

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

  4795.     BIO_read(bio, s->data, len);
  4796.     BIO_free(bio);
  4797.     X509_free(cert);

  4798.     return NGX_OK;
  4799. }


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

  4806.     s->len = 0;

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

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

  4817. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4818.     ASN1_TIME_print(bio, X509_get0_notAfter(cert));
  4819. #else
  4820.     ASN1_TIME_print(bio, X509_get_notAfter(cert));
  4821. #endif

  4822.     len = BIO_pending(bio);

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

  4830.     BIO_read(bio, s->data, len);
  4831.     BIO_free(bio);
  4832.     X509_free(cert);

  4833.     return NGX_OK;
  4834. }


  4835. ngx_int_t
  4836. ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4837. {
  4838.     X509    *cert;
  4839.     time_t   now, end;

  4840.     s->len = 0;

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

  4845. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4846.     end = ngx_ssl_parse_time(X509_get0_notAfter(cert), c->log);
  4847. #else
  4848.     end = ngx_ssl_parse_time(X509_get_notAfter(cert), c->log);
  4849. #endif

  4850.     if (end == (time_t) NGX_ERROR) {
  4851.         X509_free(cert);
  4852.         return NGX_OK;
  4853.     }

  4854.     now = ngx_time();

  4855.     if (end < now + 86400) {
  4856.         ngx_str_set(s, "0");
  4857.         X509_free(cert);
  4858.         return NGX_OK;
  4859.     }

  4860.     s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN);
  4861.     if (s->data == NULL) {
  4862.         X509_free(cert);
  4863.         return NGX_ERROR;
  4864.     }

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

  4866.     X509_free(cert);

  4867.     return NGX_OK;
  4868. }


  4869. static time_t
  4870. ngx_ssl_parse_time(
  4871. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4872.     const
  4873. #endif
  4874.     ASN1_TIME *asn1time, ngx_log_t *log)
  4875. {
  4876.     BIO     *bio;
  4877.     char    *value;
  4878.     size_t   len;
  4879.     time_t   time;

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

  4886.     bio = BIO_new(BIO_s_mem());
  4887.     if (bio == NULL) {
  4888.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "BIO_new() failed");
  4889.         return NGX_ERROR;
  4890.     }

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

  4892.     BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
  4893.     ASN1_TIME_print(bio, asn1time);
  4894.     len = BIO_get_mem_data(bio, &value);

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

  4896.     BIO_free(bio);

  4897.     return time;
  4898. }


  4899. ngx_int_t
  4900. ngx_ssl_get_client_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4901. {
  4902. #ifdef SSL_get0_peer_signature_name

  4903.     const char  *name;

  4904.     if (SSL_get0_peer_signature_name(c->ssl->connection, &name)) {
  4905.         s->len = ngx_strlen(name);
  4906.         s->data = ngx_pnalloc(pool, s->len);
  4907.         if (s->data == NULL) {
  4908.             return NGX_ERROR;
  4909.         }

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

  4911.         return NGX_OK;
  4912.     }

  4913. #endif

  4914.     s->len = 0;
  4915.     return NGX_OK;
  4916. }


  4917. static void *
  4918. ngx_openssl_create_conf(ngx_cycle_t *cycle)
  4919. {
  4920.     ngx_openssl_conf_t  *oscf;

  4921.     oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
  4922.     if (oscf == NULL) {
  4923.         return NULL;
  4924.     }

  4925.     /*
  4926.      * set by ngx_pcalloc():
  4927.      *
  4928.      *     oscf->engine = 0;
  4929.      */

  4930.     return oscf;
  4931. }


  4932. static char *
  4933. ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4934. {
  4935. #ifndef OPENSSL_NO_ENGINE

  4936.     ngx_openssl_conf_t *oscf = conf;

  4937.     ENGINE     *engine;
  4938.     ngx_str_t  *value;

  4939.     if (oscf->engine) {
  4940.         return "is duplicate";
  4941.     }

  4942.     oscf->engine = 1;

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

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

  4945.     if (engine == NULL) {
  4946.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  4947.                       "ENGINE_by_id(\"%V\") failed", &value[1]);
  4948.         return NGX_CONF_ERROR;
  4949.     }

  4950.     if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
  4951.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  4952.                       "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",
  4953.                       &value[1]);

  4954.         ENGINE_free(engine);

  4955.         return NGX_CONF_ERROR;
  4956.     }

  4957.     ENGINE_free(engine);

  4958.     return NGX_CONF_OK;

  4959. #else

  4960.     return "is not supported";

  4961. #endif
  4962. }


  4963. static void
  4964. ngx_openssl_exit(ngx_cycle_t *cycle)
  4965. {
  4966. #if OPENSSL_VERSION_NUMBER < 0x10100003L

  4967.     EVP_cleanup();
  4968. #ifndef OPENSSL_NO_ENGINE
  4969.     ENGINE_cleanup();
  4970. #endif

  4971. #endif
  4972. }