src/event/ngx_event_openssl.c - nginx source code

Global variables defined

Data types defined

Functions defined

Macros defined

Source code


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


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


  8. #define NGX_SSL_PASSWORD_BUFFER_SIZE  4096


  9. typedef struct {
  10.     ngx_uint_t  engine;   /* unsigned  engine:1; */
  11. } ngx_openssl_conf_t;


  12. static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void);
  13. static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
  14. static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
  15.     int ret);
  16. static int ngx_ssl_cmp_x509_name(const X509_NAME *const *a,
  17.     const X509_NAME *const *b);
  18. static void ngx_ssl_passwords_cleanup(void *data);
  19. static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn,
  20.     ngx_ssl_session_t *sess);
  21. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  22. static ngx_int_t ngx_ssl_try_early_data(ngx_connection_t *c);
  23. #endif
  24. static void ngx_ssl_handshake_handler(ngx_event_t *ev);
  25. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  26. static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
  27.     size_t size);
  28. #endif
  29. static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
  30. static void ngx_ssl_write_handler(ngx_event_t *wev);
  31. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  32. static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
  33.     size_t size);
  34. #endif
  35. static ssize_t ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file,
  36.     size_t size);
  37. static void ngx_ssl_read_handler(ngx_event_t *rev);
  38. static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
  39. static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
  40.     ngx_err_t err, char *text);
  41. static void ngx_ssl_clear_error(ngx_log_t *log);

  42. static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl,
  43.     ngx_str_t *sess_ctx, ngx_array_t *certificates);
  44. static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
  45.     ngx_ssl_session_t *sess);
  46. static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
  47. #if OPENSSL_VERSION_NUMBER >= 0x10100003L
  48.     const
  49. #endif
  50.     u_char *id, int len, int *copy);
  51. static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
  52. static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
  53.     ngx_slab_pool_t *shpool, ngx_uint_t n);
  54. static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
  55.     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

  56. #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
  57. static int ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
  58.     unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
  59.     HMAC_CTX *hctx, int enc);
  60. static ngx_int_t ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log);
  61. static void ngx_ssl_ticket_keys_cleanup(void *data);
  62. #endif

  63. #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT
  64. static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str);
  65. #endif

  66. static time_t ngx_ssl_parse_time(
  67. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  68.     const
  69. #endif
  70.     ASN1_TIME *asn1time, ngx_log_t *log);

  71. static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
  72. static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  73. static void ngx_openssl_exit(ngx_cycle_t *cycle);


  74. static ngx_command_t  ngx_openssl_commands[] = {

  75.     { ngx_string("ssl_engine"),
  76.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
  77.       ngx_openssl_engine,
  78.       0,
  79.       0,
  80.       NULL },

  81.       ngx_null_command
  82. };


  83. static ngx_core_module_t  ngx_openssl_module_ctx = {
  84.     ngx_string("openssl"),
  85.     ngx_openssl_create_conf,
  86.     NULL
  87. };


  88. ngx_module_t  ngx_openssl_module = {
  89.     NGX_MODULE_V1,
  90.     &ngx_openssl_module_ctx,               /* module context */
  91.     ngx_openssl_commands,                  /* module directives */
  92.     NGX_CORE_MODULE,                       /* module type */
  93.     NULL,                                  /* init master */
  94.     NULL,                                  /* init module */
  95.     NULL,                                  /* init process */
  96.     NULL,                                  /* init thread */
  97.     NULL,                                  /* exit thread */
  98.     NULL,                                  /* exit process */
  99.     ngx_openssl_exit,                      /* exit master */
  100.     NGX_MODULE_V1_PADDING
  101. };


  102. int  ngx_ssl_connection_index;
  103. int  ngx_ssl_server_conf_index;
  104. int  ngx_ssl_session_cache_index;
  105. int  ngx_ssl_ticket_keys_index;
  106. int  ngx_ssl_ocsp_index;
  107. int  ngx_ssl_index;
  108. int  ngx_ssl_certificate_name_index;


  109. ngx_int_t
  110. ngx_ssl_init(ngx_log_t *log)
  111. {
  112. #if (OPENSSL_INIT_LOAD_CONFIG && !defined LIBRESSL_VERSION_NUMBER)

  113.     uint64_t                opts;
  114.     OPENSSL_INIT_SETTINGS  *init;

  115.     opts = OPENSSL_INIT_LOAD_CONFIG;

  116. #if (NGX_OPENSSL_NO_CONFIG)

  117.     if (getenv("OPENSSL_CONF") == NULL) {
  118.         opts = OPENSSL_INIT_NO_LOAD_CONFIG;
  119.     }

  120. #endif

  121.     init = OPENSSL_INIT_new();
  122.     if (init == NULL) {
  123.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_INIT_new() failed");
  124.         return NGX_ERROR;
  125.     }

  126. #ifndef OPENSSL_NO_STDIO
  127.     if (OPENSSL_INIT_set_config_appname(init, "nginx") == 0) {
  128.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  129.                       "OPENSSL_INIT_set_config_appname() failed");
  130.         return NGX_ERROR;
  131.     }
  132. #endif

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

  137.     OPENSSL_INIT_free(init);

  138.     /*
  139.      * OPENSSL_init_ssl() may leave errors in the error queue
  140.      * while returning success
  141.      */

  142.     ERR_clear_error();

  143. #else

  144. #if (NGX_OPENSSL_NO_CONFIG)

  145.     if (getenv("OPENSSL_CONF") == NULL) {
  146.         OPENSSL_no_config();
  147.     }

  148. #endif

  149.     OPENSSL_config("nginx");

  150.     SSL_library_init();
  151.     SSL_load_error_strings();

  152.     OpenSSL_add_all_algorithms();

  153. #endif

  154. #ifndef SSL_OP_NO_COMPRESSION
  155.     {
  156.     /*
  157.      * Disable gzip compression in OpenSSL prior to 1.0.0 version,
  158.      * this saves about 522K per connection.
  159.      */
  160.     int                  n;
  161.     STACK_OF(SSL_COMP)  *ssl_comp_methods;

  162.     ssl_comp_methods = SSL_COMP_get_compression_methods();
  163.     n = sk_SSL_COMP_num(ssl_comp_methods);

  164.     while (n--) {
  165.         (void) sk_SSL_COMP_pop(ssl_comp_methods);
  166.     }
  167.     }
  168. #endif

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

  170.     if (ngx_ssl_connection_index == -1) {
  171.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed");
  172.         return NGX_ERROR;
  173.     }

  174.     ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
  175.                                                          NULL);
  176.     if (ngx_ssl_server_conf_index == -1) {
  177.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  178.                       "SSL_CTX_get_ex_new_index() failed");
  179.         return NGX_ERROR;
  180.     }

  181.     ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
  182.                                                            NULL);
  183.     if (ngx_ssl_session_cache_index == -1) {
  184.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  185.                       "SSL_CTX_get_ex_new_index() failed");
  186.         return NGX_ERROR;
  187.     }

  188.     ngx_ssl_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
  189.                                                          NULL);
  190.     if (ngx_ssl_ticket_keys_index == -1) {
  191.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  192.                       "SSL_CTX_get_ex_new_index() failed");
  193.         return NGX_ERROR;
  194.     }

  195.     ngx_ssl_ocsp_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
  196.     if (ngx_ssl_ocsp_index == -1) {
  197.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  198.                       "SSL_CTX_get_ex_new_index() failed");
  199.         return NGX_ERROR;
  200.     }

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

  202.     if (ngx_ssl_index == -1) {
  203.         ngx_ssl_error(NGX_LOG_ALERT, log, 0,
  204.                       "SSL_CTX_get_ex_new_index() failed");
  205.         return NGX_ERROR;
  206.     }

  207.     ngx_ssl_certificate_name_index = X509_get_ex_new_index(0, NULL, NULL, NULL,
  208.                                                            NULL);

  209.     if (ngx_ssl_certificate_name_index == -1) {
  210.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "X509_get_ex_new_index() failed");
  211.         return NGX_ERROR;
  212.     }

  213.     return NGX_OK;
  214. }


  215. ngx_int_t
  216. ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
  217. {
  218.     ssl->ctx = SSL_CTX_new(SSLv23_method());

  219.     if (ssl->ctx == NULL) {
  220.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed");
  221.         return NGX_ERROR;
  222.     }

  223.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) {
  224.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  225.                       "SSL_CTX_set_ex_data() failed");
  226.         return NGX_ERROR;
  227.     }

  228.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_index, ssl) == 0) {
  229.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  230.                       "SSL_CTX_set_ex_data() failed");
  231.         return NGX_ERROR;
  232.     }

  233.     ngx_rbtree_init(&ssl->staple_rbtree, &ssl->staple_sentinel,
  234.                     ngx_rbtree_insert_value);

  235.     ssl->buffer_size = NGX_SSL_BUFSIZE;

  236.     /* client side options */

  237. #ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
  238.     SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
  239. #endif

  240. #ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
  241.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
  242. #endif

  243.     /* server side options */

  244. #ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
  245.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
  246. #endif

  247. #ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
  248.     SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
  249. #endif

  250. #ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
  251.     SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
  252. #endif

  253. #ifdef SSL_OP_TLS_D5_BUG
  254.     SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
  255. #endif

  256. #ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
  257.     SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
  258. #endif

  259. #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
  260.     SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
  261. #endif

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

  263. #if OPENSSL_VERSION_NUMBER >= 0x009080dfL
  264.     /* only in 0.9.8m+ */
  265.     SSL_CTX_clear_options(ssl->ctx,
  266.                           SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1);
  267. #endif

  268.     if (!(protocols & NGX_SSL_SSLv2)) {
  269.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2);
  270.     }
  271.     if (!(protocols & NGX_SSL_SSLv3)) {
  272.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv3);
  273.     }
  274.     if (!(protocols & NGX_SSL_TLSv1)) {
  275.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1);
  276.     }
  277. #ifdef SSL_OP_NO_TLSv1_1
  278.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_1);
  279.     if (!(protocols & NGX_SSL_TLSv1_1)) {
  280.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_1);
  281.     }
  282. #endif
  283. #ifdef SSL_OP_NO_TLSv1_2
  284.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
  285.     if (!(protocols & NGX_SSL_TLSv1_2)) {
  286.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
  287.     }
  288. #endif
  289. #ifdef SSL_OP_NO_TLSv1_3
  290.     SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_3);
  291.     if (!(protocols & NGX_SSL_TLSv1_3)) {
  292.         SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_3);
  293.     }
  294. #endif

  295. #ifdef SSL_CTX_set_min_proto_version
  296.     SSL_CTX_set_min_proto_version(ssl->ctx, 0);
  297.     SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_2_VERSION);
  298. #endif

  299. #ifdef TLS1_3_VERSION
  300.     SSL_CTX_set_min_proto_version(ssl->ctx, 0);
  301.     SSL_CTX_set_max_proto_version(ssl->ctx, TLS1_3_VERSION);
  302. #endif

  303. #ifdef SSL_OP_NO_COMPRESSION
  304.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
  305. #endif

  306. #ifdef SSL_OP_NO_ANTI_REPLAY
  307.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY);
  308. #endif

  309. #ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
  310.     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
  311. #endif

  312. #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
  313.     SSL_CTX_set_options(ssl->ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
  314. #endif

  315. #ifdef SSL_MODE_RELEASE_BUFFERS
  316.     SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
  317. #endif

  318. #ifdef SSL_MODE_NO_AUTO_CHAIN
  319.     SSL_CTX_set_mode(ssl->ctx, SSL_MODE_NO_AUTO_CHAIN);
  320. #endif

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

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

  323.     return NGX_OK;
  324. }


  325. ngx_int_t
  326. ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs,
  327.     ngx_array_t *keys, ngx_array_t *passwords)
  328. {
  329.     ngx_str_t   *cert, *key;
  330.     ngx_uint_t   i;

  331.     cert = certs->elts;
  332.     key = keys->elts;

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

  334.         if (ngx_ssl_certificate(cf, ssl, &cert[i], &key[i], passwords)
  335.             != NGX_OK)
  336.         {
  337.             return NGX_ERROR;
  338.         }
  339.     }

  340.     return NGX_OK;
  341. }


  342. ngx_int_t
  343. ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
  344.     ngx_str_t *key, ngx_array_t *passwords)
  345. {
  346.     char            *err;
  347.     X509            *x509, **elm;
  348.     EVP_PKEY        *pkey;
  349.     STACK_OF(X509)  *chain;

  350.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT, &err, cert, NULL);
  351.     if (chain == NULL) {
  352.         if (err != NULL) {
  353.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  354.                           "cannot load certificate \"%s\": %s",
  355.                           cert->data, err);
  356.         }

  357.         return NGX_ERROR;
  358.     }

  359.     x509 = sk_X509_shift(chain);

  360.     if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) {
  361.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  362.                       "SSL_CTX_use_certificate(\"%s\") failed", cert->data);
  363.         X509_free(x509);
  364.         sk_X509_pop_free(chain, X509_free);
  365.         return NGX_ERROR;
  366.     }

  367.     if (X509_set_ex_data(x509, ngx_ssl_certificate_name_index, cert->data)
  368.         == 0)
  369.     {
  370.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_set_ex_data() failed");
  371.         X509_free(x509);
  372.         sk_X509_pop_free(chain, X509_free);
  373.         return NGX_ERROR;
  374.     }

  375.     if (ssl->certs.elts == NULL) {
  376.         if (ngx_array_init(&ssl->certs, cf->pool, 1, sizeof(X509 *))
  377.             != NGX_OK)
  378.         {
  379.             X509_free(x509);
  380.             sk_X509_pop_free(chain, X509_free);
  381.             return NGX_ERROR;
  382.         }
  383.     }

  384.     elm = ngx_array_push(&ssl->certs);
  385.     if (elm == NULL) {
  386.         X509_free(x509);
  387.         sk_X509_pop_free(chain, X509_free);
  388.         return NGX_ERROR;
  389.     }

  390.     *elm = x509;

  391.     /*
  392.      * Note that x509 is not freed here, but will be instead freed in
  393.      * ngx_ssl_cleanup_ctx().  This is because we need to preserve all
  394.      * certificates to be able to iterate all of them through ssl->certs,
  395.      * while OpenSSL can free a certificate if it is replaced with another
  396.      * certificate of the same type.
  397.      */

  398. #ifdef SSL_CTX_set0_chain

  399.     if (SSL_CTX_set0_chain(ssl->ctx, chain) == 0) {
  400.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  401.                       "SSL_CTX_set0_chain(\"%s\") failed", cert->data);
  402.         sk_X509_pop_free(chain, X509_free);
  403.         return NGX_ERROR;
  404.     }

  405. #else
  406.     {
  407.     int  n;

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

  409.     n = sk_X509_num(chain);

  410.     while (n--) {
  411.         x509 = sk_X509_shift(chain);

  412.         if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
  413.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  414.                           "SSL_CTX_add_extra_chain_cert(\"%s\") failed",
  415.                           cert->data);
  416.             sk_X509_pop_free(chain, X509_free);
  417.             return NGX_ERROR;
  418.         }
  419.     }

  420.     sk_X509_free(chain);
  421.     }
  422. #endif

  423.     pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY, &err, key, passwords);
  424.     if (pkey == NULL) {
  425.         if (err != NULL) {
  426.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  427.                           "cannot load certificate key \"%s\": %s",
  428.                           key->data, err);
  429.         }

  430.         return NGX_ERROR;
  431.     }

  432.     if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
  433.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  434.                       "SSL_CTX_use_PrivateKey(\"%s\") failed", key->data);
  435.         EVP_PKEY_free(pkey);
  436.         return NGX_ERROR;
  437.     }

  438.     EVP_PKEY_free(pkey);

  439.     return NGX_OK;
  440. }


  441. ngx_int_t
  442. ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
  443.     ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords)
  444. {
  445.     char            *err;
  446.     X509            *x509;
  447.     EVP_PKEY        *pkey;
  448.     STACK_OF(X509)  *chain;

  449.     chain = ngx_ssl_cache_connection_fetch(pool, NGX_SSL_CACHE_CERT, &err,
  450.                                            cert, NULL);
  451.     if (chain == NULL) {
  452.         if (err != NULL) {
  453.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  454.                           "cannot load certificate \"%s\": %s",
  455.                           cert->data, err);
  456.         }

  457.         return NGX_ERROR;
  458.     }

  459.     x509 = sk_X509_shift(chain);

  460.     if (SSL_use_certificate(c->ssl->connection, x509) == 0) {
  461.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  462.                       "SSL_use_certificate(\"%s\") failed", cert->data);
  463.         X509_free(x509);
  464.         sk_X509_pop_free(chain, X509_free);
  465.         return NGX_ERROR;
  466.     }

  467.     X509_free(x509);

  468. #ifdef SSL_set0_chain

  469.     /*
  470.      * SSL_set0_chain() is only available in OpenSSL 1.0.2+,
  471.      * but this function is only called via certificate callback,
  472.      * which is only available in OpenSSL 1.0.2+ as well
  473.      */

  474.     if (SSL_set0_chain(c->ssl->connection, chain) == 0) {
  475.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  476.                       "SSL_set0_chain(\"%s\") failed", cert->data);
  477.         sk_X509_pop_free(chain, X509_free);
  478.         return NGX_ERROR;
  479.     }

  480. #endif

  481.     pkey = ngx_ssl_cache_connection_fetch(pool, NGX_SSL_CACHE_PKEY, &err,
  482.                                           key, passwords);
  483.     if (pkey == NULL) {
  484.         if (err != NULL) {
  485.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  486.                           "cannot load certificate key \"%s\": %s",
  487.                           key->data, err);
  488.         }

  489.         return NGX_ERROR;
  490.     }

  491.     if (SSL_use_PrivateKey(c->ssl->connection, pkey) == 0) {
  492.         ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  493.                       "SSL_use_PrivateKey(\"%s\") failed", key->data);
  494.         EVP_PKEY_free(pkey);
  495.         return NGX_ERROR;
  496.     }

  497.     EVP_PKEY_free(pkey);

  498.     return NGX_OK;
  499. }


  500. ngx_int_t
  501. ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
  502.     ngx_uint_t prefer_server_ciphers)
  503. {
  504.     if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) {
  505.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  506.                       "SSL_CTX_set_cipher_list(\"%V\") failed",
  507.                       ciphers);
  508.         return NGX_ERROR;
  509.     }

  510.     if (prefer_server_ciphers) {
  511.         SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
  512.     }

  513.     return NGX_OK;
  514. }


  515. ngx_int_t
  516. ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
  517.     ngx_int_t depth)
  518. {
  519.     int                   n, i;
  520.     char                 *err;
  521.     X509                 *x509;
  522.     X509_NAME            *name;
  523.     X509_STORE           *store;
  524.     STACK_OF(X509)       *chain;
  525.     STACK_OF(X509_NAME)  *list;

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

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

  528.     if (cert->len == 0) {
  529.         return NGX_OK;
  530.     }

  531.     list = sk_X509_NAME_new(ngx_ssl_cmp_x509_name);
  532.     if (list == NULL) {
  533.         return NGX_ERROR;
  534.     }

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

  536.     if (store == NULL) {
  537.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  538.                       "SSL_CTX_get_cert_store() failed");
  539.         return NGX_ERROR;
  540.     }

  541.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL);
  542.     if (chain == NULL) {
  543.         if (err != NULL) {
  544.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  545.                           "cannot load certificate \"%s\": %s",
  546.                           cert->data, err);
  547.         }

  548.         sk_X509_NAME_pop_free(list, X509_NAME_free);
  549.         return NGX_ERROR;
  550.     }

  551.     n = sk_X509_num(chain);

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

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

  555.             if (ngx_ssl_cert_already_in_hash()) {
  556.                 continue;
  557.             }

  558.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  559.                           "X509_STORE_add_cert(\"%s\") failed", cert->data);
  560.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  561.             sk_X509_pop_free(chain, X509_free);
  562.             return NGX_ERROR;
  563.         }

  564.         name = X509_get_subject_name(x509);
  565.         if (name == NULL) {
  566.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  567.                           "X509_get_subject_name(\"%s\") failed", cert->data);
  568.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  569.             sk_X509_pop_free(chain, X509_free);
  570.             return NGX_ERROR;
  571.         }

  572.         name = X509_NAME_dup(name);
  573.         if (name == NULL) {
  574.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  575.             sk_X509_pop_free(chain, X509_free);
  576.             return NGX_ERROR;
  577.         }

  578. #ifdef OPENSSL_IS_BORINGSSL
  579.         if (sk_X509_NAME_find(list, NULL, name) > 0) {
  580. #else
  581.         if (sk_X509_NAME_find(list, name) >= 0) {
  582. #endif
  583.             X509_NAME_free(name);
  584.             continue;
  585.         }

  586.         if (sk_X509_NAME_push(list, name) == 0) {
  587.             sk_X509_NAME_pop_free(list, X509_NAME_free);
  588.             sk_X509_pop_free(chain, X509_free);
  589.             X509_NAME_free(name);
  590.             return NGX_ERROR;
  591.         }
  592.     }

  593.     sk_X509_pop_free(chain, X509_free);

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

  595.     return NGX_OK;
  596. }


  597. ngx_int_t
  598. ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
  599.     ngx_int_t depth)
  600. {
  601.     int              i, n;
  602.     char            *err;
  603.     X509            *x509;
  604.     X509_STORE      *store;
  605.     STACK_OF(X509)  *chain;

  606.     SSL_CTX_set_verify(ssl->ctx, SSL_CTX_get_verify_mode(ssl->ctx),
  607.                        ngx_ssl_verify_callback);

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

  609.     if (cert->len == 0) {
  610.         return NGX_OK;
  611.     }

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

  613.     if (store == NULL) {
  614.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  615.                       "SSL_CTX_get_cert_store() failed");
  616.         return NGX_ERROR;
  617.     }

  618.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL);
  619.     if (chain == NULL) {
  620.         if (err != NULL) {
  621.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  622.                           "cannot load certificate \"%s\": %s",
  623.                           cert->data, err);
  624.         }

  625.         return NGX_ERROR;
  626.     }

  627.     n = sk_X509_num(chain);

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

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

  631.             if (ngx_ssl_cert_already_in_hash()) {
  632.                 continue;
  633.             }

  634.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  635.                           "X509_STORE_add_cert(\"%s\") failed", cert->data);
  636.             sk_X509_pop_free(chain, X509_free);
  637.             return NGX_ERROR;
  638.         }
  639.     }

  640.     sk_X509_pop_free(chain, X509_free);

  641.     return NGX_OK;
  642. }


  643. ngx_int_t
  644. ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
  645. {
  646.     int                  n, i;
  647.     char                *err;
  648.     X509_CRL            *x509;
  649.     X509_STORE          *store;
  650.     STACK_OF(X509_CRL)  *chain;

  651.     if (crl->len == 0) {
  652.         return NGX_OK;
  653.     }

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

  655.     if (store == NULL) {
  656.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  657.                       "SSL_CTX_get_cert_store() failed");
  658.         return NGX_ERROR;
  659.     }

  660.     chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CRL, &err, crl, NULL);
  661.     if (chain == NULL) {
  662.         if (err != NULL) {
  663.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  664.                           "cannot load CRL \"%s\": %s", crl->data, err);
  665.         }

  666.         return NGX_ERROR;
  667.     }

  668.     n = sk_X509_CRL_num(chain);

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

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

  672.             if (ngx_ssl_cert_already_in_hash()) {
  673.                 continue;
  674.             }

  675.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  676.                           "X509_STORE_add_crl(\"%s\") failed", crl->data);
  677.             sk_X509_CRL_pop_free(chain, X509_CRL_free);
  678.             return NGX_ERROR;
  679.         }
  680.     }

  681.     sk_X509_CRL_pop_free(chain, X509_CRL_free);

  682.     X509_STORE_set_flags(store,
  683.                          X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);

  684.     return NGX_OK;
  685. }


  686. static ngx_inline ngx_int_t
  687. ngx_ssl_cert_already_in_hash(void)
  688. {
  689. #if !(OPENSSL_VERSION_NUMBER >= 0x1010009fL \
  690.       || LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
  691.     u_long  error;

  692.     /*
  693.      * OpenSSL prior to 1.1.0i doesn't ignore duplicate certificate entries,
  694.      * see https://github.com/openssl/openssl/commit/c0452248
  695.      */

  696.     error = ERR_peek_last_error();

  697.     if (ERR_GET_LIB(error) == ERR_LIB_X509
  698.         && ERR_GET_REASON(error) == X509_R_CERT_ALREADY_IN_HASH_TABLE)
  699.     {
  700.         ERR_clear_error();
  701.         return 1;
  702.     }
  703. #endif

  704.     return 0;
  705. }


  706. static int
  707. ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
  708. {
  709. #if (NGX_DEBUG)
  710.     char              *subject, *issuer;
  711.     int                err, depth;
  712.     X509              *cert;
  713.     X509_NAME         *sname, *iname;
  714.     ngx_connection_t  *c;
  715.     ngx_ssl_conn_t    *ssl_conn;

  716.     ssl_conn = X509_STORE_CTX_get_ex_data(x509_store,
  717.                                           SSL_get_ex_data_X509_STORE_CTX_idx());

  718.     c = ngx_ssl_get_connection(ssl_conn);

  719.     if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
  720.         return 1;
  721.     }

  722.     cert = X509_STORE_CTX_get_current_cert(x509_store);
  723.     err = X509_STORE_CTX_get_error(x509_store);
  724.     depth = X509_STORE_CTX_get_error_depth(x509_store);

  725.     sname = X509_get_subject_name(cert);

  726.     if (sname) {
  727.         subject = X509_NAME_oneline(sname, NULL, 0);
  728.         if (subject == NULL) {
  729.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  730.                           "X509_NAME_oneline() failed");
  731.         }

  732.     } else {
  733.         subject = NULL;
  734.     }

  735.     iname = X509_get_issuer_name(cert);

  736.     if (iname) {
  737.         issuer = X509_NAME_oneline(iname, NULL, 0);
  738.         if (issuer == NULL) {
  739.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  740.                           "X509_NAME_oneline() failed");
  741.         }

  742.     } else {
  743.         issuer = NULL;
  744.     }

  745.     ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
  746.                    "verify:%d, error:%d, depth:%d, "
  747.                    "subject:\"%s\", issuer:\"%s\"",
  748.                    ok, err, depth,
  749.                    subject ? subject : "(none)",
  750.                    issuer ? issuer : "(none)");

  751.     if (subject) {
  752.         OPENSSL_free(subject);
  753.     }

  754.     if (issuer) {
  755.         OPENSSL_free(issuer);
  756.     }
  757. #endif

  758.     return 1;
  759. }


  760. static void
  761. ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
  762. {
  763.     BIO               *rbio, *wbio;
  764.     ngx_connection_t  *c;

  765. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  766.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

  767.     if ((where & SSL_CB_HANDSHAKE_START)
  768.         && SSL_is_server((ngx_ssl_conn_t *) ssl_conn))
  769.     {
  770.         c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);

  771.         if (c->ssl->handshaked) {
  772.             c->ssl->renegotiation = 1;
  773.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation");
  774.         }
  775.     }

  776. #endif

  777. #ifdef TLS1_3_VERSION

  778.     if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP
  779.         && SSL_version(ssl_conn) == TLS1_3_VERSION)
  780.     {
  781.         time_t        now, time, timeout, conf_timeout;
  782.         SSL_SESSION  *sess;

  783.         /*
  784.          * OpenSSL with TLSv1.3 updates the session creation time on
  785.          * session resumption and keeps the session timeout unmodified,
  786.          * making it possible to maintain the session forever, bypassing
  787.          * client certificate expiration and revocation.  To make sure
  788.          * session timeouts are actually used, we now update the session
  789.          * creation time and reduce the session timeout accordingly.
  790.          *
  791.          * BoringSSL with TLSv1.3 ignores configured session timeouts
  792.          * and uses a hardcoded timeout instead, 7 days.  So we update
  793.          * session timeout to the configured value as soon as a session
  794.          * is created.
  795.          */

  796.         c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
  797.         sess = SSL_get0_session(ssl_conn);

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

  800.             now = ngx_time();
  801.             time = SSL_SESSION_get_time(sess);
  802.             timeout = SSL_SESSION_get_timeout(sess);
  803.             conf_timeout = SSL_CTX_get_timeout(c->ssl->session_ctx);

  804.             timeout = ngx_min(timeout, conf_timeout);

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

  807.             } else {
  808.                 SSL_SESSION_set_time(sess, now);
  809.                 SSL_SESSION_set_timeout(sess, timeout - (now - time));
  810.             }
  811.         }
  812.     }

  813. #endif

  814.     if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
  815.         c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);

  816.         if (!c->ssl->handshake_buffer_set) {
  817.             /*
  818.              * By default OpenSSL uses 4k buffer during a handshake,
  819.              * which is too low for long certificate chains and might
  820.              * result in extra round-trips.
  821.              *
  822.              * To adjust a buffer size we detect that buffering was added
  823.              * to write side of the connection by comparing rbio and wbio.
  824.              * If they are different, we assume that it's due to buffering
  825.              * added to wbio, and set buffer size.
  826.              */

  827.             rbio = SSL_get_rbio(ssl_conn);
  828.             wbio = SSL_get_wbio(ssl_conn);

  829.             if (rbio != wbio) {
  830.                 (void) BIO_set_write_buffer_size(wbio, NGX_SSL_BUFSIZE);
  831.                 c->ssl->handshake_buffer_set = 1;
  832.             }
  833.         }
  834.     }
  835. }


  836. static int
  837. ngx_ssl_cmp_x509_name(const X509_NAME *const *a, const X509_NAME *const *b)
  838. {
  839.     return (X509_NAME_cmp(*a, *b));
  840. }


  841. ngx_array_t *
  842. ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file)
  843. {
  844.     u_char              *p, *last, *end;
  845.     size_t               len;
  846.     ssize_t              n;
  847.     ngx_fd_t             fd;
  848.     ngx_str_t           *pwd;
  849.     ngx_array_t         *passwords;
  850.     ngx_pool_cleanup_t  *cln;
  851.     u_char               buf[NGX_SSL_PASSWORD_BUFFER_SIZE];

  852.     if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
  853.         return NULL;
  854.     }

  855.     passwords = ngx_array_create(cf->temp_pool, 4, sizeof(ngx_str_t));
  856.     if (passwords == NULL) {
  857.         return NULL;
  858.     }

  859.     cln = ngx_pool_cleanup_add(cf->temp_pool, 0);
  860.     if (cln == NULL) {
  861.         return NULL;
  862.     }

  863.     cln->handler = ngx_ssl_passwords_cleanup;
  864.     cln->data = passwords;

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

  866.     if (fd == NGX_INVALID_FILE) {
  867.         ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  868.                            ngx_open_file_n " \"%s\" failed", file->data);
  869.         return NULL;
  870.     }

  871.     len = 0;
  872.     last = buf;

  873.     do {
  874.         n = ngx_read_fd(fd, last, NGX_SSL_PASSWORD_BUFFER_SIZE - len);

  875.         if (n == -1) {
  876.             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  877.                                ngx_read_fd_n " \"%s\" failed", file->data);
  878.             passwords = NULL;
  879.             goto cleanup;
  880.         }

  881.         end = last + n;

  882.         if (len && n == 0) {
  883.             *end++ = LF;
  884.         }

  885.         p = buf;

  886.         for ( ;; ) {
  887.             last = ngx_strlchr(last, end, LF);

  888.             if (last == NULL) {
  889.                 break;
  890.             }

  891.             len = last++ - p;

  892.             if (len && p[len - 1] == CR) {
  893.                 len--;
  894.             }

  895.             if (len) {
  896.                 pwd = ngx_array_push(passwords);
  897.                 if (pwd == NULL) {
  898.                     passwords = NULL;
  899.                     goto cleanup;
  900.                 }

  901.                 pwd->len = len;
  902.                 pwd->data = ngx_pnalloc(cf->temp_pool, len);

  903.                 if (pwd->data == NULL) {
  904.                     passwords->nelts--;
  905.                     passwords = NULL;
  906.                     goto cleanup;
  907.                 }

  908.                 ngx_memcpy(pwd->data, p, len);
  909.             }

  910.             p = last;
  911.         }

  912.         len = end - p;

  913.         if (len == NGX_SSL_PASSWORD_BUFFER_SIZE) {
  914.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  915.                                "too long line in \"%s\"", file->data);
  916.             passwords = NULL;
  917.             goto cleanup;
  918.         }

  919.         ngx_memmove(buf, p, len);
  920.         last = buf + len;

  921.     } while (n != 0);

  922.     if (passwords->nelts == 0) {
  923.         pwd = ngx_array_push(passwords);
  924.         if (pwd == NULL) {
  925.             passwords = NULL;
  926.             goto cleanup;
  927.         }

  928.         ngx_memzero(pwd, sizeof(ngx_str_t));
  929.     }

  930. cleanup:

  931.     if (ngx_close_file(fd) == NGX_FILE_ERROR) {
  932.         ngx_conf_log_error(NGX_LOG_ALERT, cf, ngx_errno,
  933.                            ngx_close_file_n " \"%s\" failed", file->data);
  934.     }

  935.     ngx_explicit_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE);

  936.     return passwords;
  937. }


  938. ngx_array_t *
  939. ngx_ssl_preserve_passwords(ngx_conf_t *cf, ngx_array_t *passwords)
  940. {
  941.     ngx_str_t           *opwd, *pwd;
  942.     ngx_uint_t           i;
  943.     ngx_array_t         *pwds;
  944.     ngx_pool_cleanup_t  *cln;
  945.     static ngx_array_t   empty_passwords;

  946.     if (passwords == NULL) {

  947.         /*
  948.          * If there are no passwords, an empty array is used
  949.          * to make sure OpenSSL's default password callback
  950.          * won't block on reading from stdin.
  951.          */

  952.         return &empty_passwords;
  953.     }

  954.     /*
  955.      * Passwords are normally allocated from the temporary pool
  956.      * and cleared after parsing configuration.  To be used at
  957.      * runtime they have to be copied to the configuration pool.
  958.      */

  959.     pwds = ngx_array_create(cf->pool, passwords->nelts, sizeof(ngx_str_t));
  960.     if (pwds == NULL) {
  961.         return NULL;
  962.     }

  963.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  964.     if (cln == NULL) {
  965.         return NULL;
  966.     }

  967.     cln->handler = ngx_ssl_passwords_cleanup;
  968.     cln->data = pwds;

  969.     opwd = passwords->elts;

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

  971.         pwd = ngx_array_push(pwds);
  972.         if (pwd == NULL) {
  973.             return NULL;
  974.         }

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

  977.         if (pwd->data == NULL) {
  978.             pwds->nelts--;
  979.             return NULL;
  980.         }

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

  983.     return pwds;
  984. }


  985. static void
  986. ngx_ssl_passwords_cleanup(void *data)
  987. {
  988.     ngx_array_t *passwords = data;

  989.     ngx_str_t   *pwd;
  990.     ngx_uint_t   i;

  991.     pwd = passwords->elts;

  992.     for (i = 0; i < passwords->nelts; i++) {
  993.         ngx_explicit_memzero(pwd[i].data, pwd[i].len);
  994.     }
  995. }


  996. ngx_int_t
  997. ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
  998. {
  999.     BIO  *bio;

  1000.     if (file->len == 0) {
  1001.         return NGX_OK;
  1002.     }

  1003.     if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
  1004.         return NGX_ERROR;
  1005.     }

  1006.     bio = BIO_new_file((char *) file->data, "r");
  1007.     if (bio == NULL) {
  1008.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1009.                       "BIO_new_file(\"%s\") failed", file->data);
  1010.         return NGX_ERROR;
  1011.     }

  1012. #ifdef SSL_CTX_set_tmp_dh
  1013.     {
  1014.     DH  *dh;

  1015.     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
  1016.     if (dh == NULL) {
  1017.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1018.                       "PEM_read_bio_DHparams(\"%s\") failed", file->data);
  1019.         BIO_free(bio);
  1020.         return NGX_ERROR;
  1021.     }

  1022.     if (SSL_CTX_set_tmp_dh(ssl->ctx, dh) != 1) {
  1023.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1024.                       "SSL_CTX_set_tmp_dh(\"%s\") failed", file->data);
  1025.         DH_free(dh);
  1026.         BIO_free(bio);
  1027.         return NGX_ERROR;
  1028.     }

  1029.     DH_free(dh);
  1030.     }
  1031. #else
  1032.     {
  1033.     EVP_PKEY  *dh;

  1034.     /*
  1035.      * PEM_read_bio_DHparams() and SSL_CTX_set_tmp_dh()
  1036.      * are deprecated in OpenSSL 3.0
  1037.      */

  1038.     dh = PEM_read_bio_Parameters(bio, NULL);
  1039.     if (dh == NULL) {
  1040.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1041.                       "PEM_read_bio_Parameters(\"%s\") failed", file->data);
  1042.         BIO_free(bio);
  1043.         return NGX_ERROR;
  1044.     }

  1045.     if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
  1046.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1047.                       "SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed", file->data);
  1048. #if (OPENSSL_VERSION_NUMBER >= 0x3000001fL)
  1049.         EVP_PKEY_free(dh);
  1050. #endif
  1051.         BIO_free(bio);
  1052.         return NGX_ERROR;
  1053.     }
  1054.     }
  1055. #endif

  1056.     BIO_free(bio);

  1057.     return NGX_OK;
  1058. }


  1059. ngx_int_t
  1060. ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
  1061. {
  1062. #ifndef OPENSSL_NO_ECDH

  1063.     /*
  1064.      * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
  1065.      * from RFC 4492 section 5.1.1, or explicitly described curves over
  1066.      * binary fields.  OpenSSL only supports the "named curves", which provide
  1067.      * maximum interoperability.
  1068.      */

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

  1070.     /*
  1071.      * OpenSSL 1.0.2+ allows configuring a curve list instead of a single
  1072.      * curve previously supported.  By default an internal list is used,
  1073.      * with prime256v1 being preferred by server in OpenSSL 1.0.2b+
  1074.      * and X25519 in OpenSSL 1.1.0+.
  1075.      *
  1076.      * By default a curve preferred by the client will be used for
  1077.      * key exchange.  The SSL_OP_CIPHER_SERVER_PREFERENCE option can
  1078.      * be used to prefer server curves instead, similar to what it
  1079.      * does for ciphers.
  1080.      */

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

  1082. #ifdef SSL_CTRL_SET_ECDH_AUTO
  1083.     /* not needed in OpenSSL 1.1.0+ */
  1084.     (void) SSL_CTX_set_ecdh_auto(ssl->ctx, 1);
  1085. #endif

  1086.     if (ngx_strcmp(name->data, "auto") == 0) {
  1087.         return NGX_OK;
  1088.     }

  1089.     if (SSL_CTX_set1_curves_list(ssl->ctx, (char *) name->data) == 0) {
  1090.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1091.                       "SSL_CTX_set1_curves_list(\"%s\") failed", name->data);
  1092.         return NGX_ERROR;
  1093.     }

  1094. #else

  1095.     int      nid;
  1096.     char    *curve;
  1097.     EC_KEY  *ecdh;

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

  1100.     } else {
  1101.         curve = (char *) name->data;
  1102.     }

  1103.     nid = OBJ_sn2nid(curve);
  1104.     if (nid == 0) {
  1105.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1106.                       "OBJ_sn2nid(\"%s\") failed: unknown curve", curve);
  1107.         return NGX_ERROR;
  1108.     }

  1109.     ecdh = EC_KEY_new_by_curve_name(nid);
  1110.     if (ecdh == NULL) {
  1111.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1112.                       "EC_KEY_new_by_curve_name(\"%s\") failed", curve);
  1113.         return NGX_ERROR;
  1114.     }

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

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

  1117.     EC_KEY_free(ecdh);
  1118. #endif
  1119. #endif

  1120.     return NGX_OK;
  1121. }


  1122. ngx_int_t
  1123. ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
  1124. {
  1125.     if (!enable) {
  1126.         return NGX_OK;
  1127.     }

  1128. #ifdef SSL_ERROR_EARLY_DATA_REJECTED

  1129.     /* BoringSSL */

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

  1131. #elif defined SSL_READ_EARLY_DATA_SUCCESS

  1132.     /* OpenSSL */

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

  1134. #else
  1135.     ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  1136.                   "\"ssl_early_data\" is not supported on this platform, "
  1137.                   "ignored");
  1138. #endif

  1139.     return NGX_OK;
  1140. }


  1141. ngx_int_t
  1142. ngx_ssl_conf_commands(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *commands)
  1143. {
  1144.     if (commands == NULL) {
  1145.         return NGX_OK;
  1146.     }

  1147. #ifdef SSL_CONF_FLAG_FILE
  1148.     {
  1149.     int            type;
  1150.     u_char        *key, *value;
  1151.     ngx_uint_t     i;
  1152.     ngx_keyval_t  *cmd;
  1153.     SSL_CONF_CTX  *cctx;

  1154.     cctx = SSL_CONF_CTX_new();
  1155.     if (cctx == NULL) {
  1156.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1157.                       "SSL_CONF_CTX_new() failed");
  1158.         return NGX_ERROR;
  1159.     }

  1160.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
  1161.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
  1162.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
  1163.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
  1164.     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS);

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

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

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

  1170.         if (type == SSL_CONF_TYPE_FILE || type == SSL_CONF_TYPE_DIR) {
  1171.             if (ngx_conf_full_name(cf->cycle, &cmd[i].value, 1) != NGX_OK) {
  1172.                 SSL_CONF_CTX_free(cctx);
  1173.                 return NGX_ERROR;
  1174.             }
  1175.         }

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

  1177.         if (SSL_CONF_cmd(cctx, (char *) key, (char *) value) <= 0) {
  1178.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1179.                           "SSL_CONF_cmd(\"%s\", \"%s\") failed", key, value);
  1180.             SSL_CONF_CTX_free(cctx);
  1181.             return NGX_ERROR;
  1182.         }
  1183.     }

  1184.     if (SSL_CONF_CTX_finish(cctx) != 1) {
  1185.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  1186.                       "SSL_CONF_finish() failed");
  1187.         SSL_CONF_CTX_free(cctx);
  1188.         return NGX_ERROR;
  1189.     }

  1190.     SSL_CONF_CTX_free(cctx);

  1191.     return NGX_OK;
  1192.     }
  1193. #else
  1194.     ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,
  1195.                   "SSL_CONF_cmd() is not available on this platform");
  1196.     return NGX_ERROR;
  1197. #endif
  1198. }


  1199. ngx_int_t
  1200. ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable)
  1201. {
  1202.     if (!enable) {
  1203.         return NGX_OK;
  1204.     }

  1205.     SSL_CTX_set_session_cache_mode(ssl->ctx,
  1206.                                    SSL_SESS_CACHE_CLIENT
  1207.                                    |SSL_SESS_CACHE_NO_INTERNAL);

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

  1209.     return NGX_OK;
  1210. }


  1211. static int
  1212. ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
  1213. {
  1214.     ngx_connection_t  *c;

  1215.     c = ngx_ssl_get_connection(ssl_conn);

  1216.     if (c->ssl->save_session) {
  1217.         c->ssl->session = sess;

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

  1219.         c->ssl->session = NULL;
  1220.     }

  1221.     return 0;
  1222. }


  1223. ngx_int_t
  1224. ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
  1225. {
  1226.     ngx_ssl_connection_t  *sc;

  1227.     sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t));
  1228.     if (sc == NULL) {
  1229.         return NGX_ERROR;
  1230.     }

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

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

  1234. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  1235.     if (SSL_CTX_get_max_early_data(ssl->ctx)) {
  1236.         sc->try_early_data = 1;
  1237.     }
  1238. #endif

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

  1240.     if (sc->connection == NULL) {
  1241.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed");
  1242.         return NGX_ERROR;
  1243.     }

  1244.     if (SSL_set_fd(sc->connection, c->fd) == 0) {
  1245.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");
  1246.         return NGX_ERROR;
  1247.     }

  1248.     if (flags & NGX_SSL_CLIENT) {
  1249.         SSL_set_connect_state(sc->connection);

  1250.     } else {
  1251.         SSL_set_accept_state(sc->connection);

  1252. #ifdef SSL_OP_NO_RENEGOTIATION
  1253.         SSL_set_options(sc->connection, SSL_OP_NO_RENEGOTIATION);
  1254. #endif
  1255.     }

  1256.     if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) {
  1257.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
  1258.         return NGX_ERROR;
  1259.     }

  1260.     c->ssl = sc;

  1261.     return NGX_OK;
  1262. }


  1263. ngx_ssl_session_t *
  1264. ngx_ssl_get_session(ngx_connection_t *c)
  1265. {
  1266. #ifdef TLS1_3_VERSION
  1267.     if (c->ssl->session) {
  1268.         SSL_SESSION_up_ref(c->ssl->session);
  1269.         return c->ssl->session;
  1270.     }
  1271. #endif

  1272.     return SSL_get1_session(c->ssl->connection);
  1273. }


  1274. ngx_ssl_session_t *
  1275. ngx_ssl_get0_session(ngx_connection_t *c)
  1276. {
  1277.     if (c->ssl->session) {
  1278.         return c->ssl->session;
  1279.     }

  1280.     return SSL_get0_session(c->ssl->connection);
  1281. }


  1282. ngx_int_t
  1283. ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
  1284. {
  1285.     if (session) {
  1286.         if (SSL_set_session(c->ssl->connection, session) == 0) {
  1287.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed");
  1288.             return NGX_ERROR;
  1289.         }
  1290.     }

  1291.     return NGX_OK;
  1292. }


  1293. ngx_int_t
  1294. ngx_ssl_handshake(ngx_connection_t *c)
  1295. {
  1296.     int        n, sslerr;
  1297.     ngx_err_t  err;
  1298.     ngx_int_t  rc;

  1299. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  1300.     if (c->ssl->try_early_data) {
  1301.         return ngx_ssl_try_early_data(c);
  1302.     }
  1303. #endif

  1304.     if (c->ssl->in_ocsp) {
  1305.         return ngx_ssl_ocsp_validate(c);
  1306.     }

  1307.     ngx_ssl_clear_error(c->log);

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

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

  1310.     if (n == 1) {

  1311.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1312.             return NGX_ERROR;
  1313.         }

  1314.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1315.             return NGX_ERROR;
  1316.         }

  1317. #if (NGX_DEBUG)
  1318.         ngx_ssl_handshake_log(c);
  1319. #endif

  1320.         c->recv = ngx_ssl_recv;
  1321.         c->send = ngx_ssl_write;
  1322.         c->recv_chain = ngx_ssl_recv_chain;
  1323.         c->send_chain = ngx_ssl_send_chain;

  1324.         c->read->ready = 1;
  1325.         c->write->ready = 1;

  1326. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  1327.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION                               \
  1328.      && defined SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS                             \
  1329.      && OPENSSL_VERSION_NUMBER < 0x10100000L)

  1330.         /* initial handshake done, disable renegotiation (CVE-2009-3555) */
  1331.         if (c->ssl->connection->s3 && SSL_is_server(c->ssl->connection)) {
  1332.             c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
  1333.         }

  1334. #endif

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

  1336.         if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
  1337.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1338.                            "BIO_get_ktls_send(): 1");
  1339.             c->ssl->sendfile = 1;
  1340.         }

  1341. #endif

  1342.         rc = ngx_ssl_ocsp_validate(c);

  1343.         if (rc == NGX_ERROR) {
  1344.             return NGX_ERROR;
  1345.         }

  1346.         if (rc == NGX_AGAIN) {
  1347.             c->read->handler = ngx_ssl_handshake_handler;
  1348.             c->write->handler = ngx_ssl_handshake_handler;
  1349.             return NGX_AGAIN;
  1350.         }

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

  1352.         return NGX_OK;
  1353.     }

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

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

  1356.     if (sslerr == SSL_ERROR_WANT_READ) {
  1357.         c->read->ready = 0;
  1358.         c->read->handler = ngx_ssl_handshake_handler;
  1359.         c->write->handler = ngx_ssl_handshake_handler;

  1360.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1361.             return NGX_ERROR;
  1362.         }

  1363.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1364.             return NGX_ERROR;
  1365.         }

  1366.         return NGX_AGAIN;
  1367.     }

  1368.     if (sslerr == SSL_ERROR_WANT_WRITE) {
  1369.         c->write->ready = 0;
  1370.         c->read->handler = ngx_ssl_handshake_handler;
  1371.         c->write->handler = ngx_ssl_handshake_handler;

  1372.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1373.             return NGX_ERROR;
  1374.         }

  1375.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1376.             return NGX_ERROR;
  1377.         }

  1378.         return NGX_AGAIN;
  1379.     }

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

  1381.     c->ssl->no_wait_shutdown = 1;
  1382.     c->ssl->no_send_shutdown = 1;
  1383.     c->read->eof = 1;

  1384.     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  1385.         ngx_connection_error(c, err,
  1386.                              "peer closed connection in SSL handshake");

  1387.         return NGX_ERROR;
  1388.     }

  1389.     if (c->ssl->handshake_rejected) {
  1390.         ngx_connection_error(c, err, "handshake rejected");
  1391.         ERR_clear_error();

  1392.         return NGX_ERROR;
  1393.     }

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

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

  1396.     return NGX_ERROR;
  1397. }


  1398. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  1399. static ngx_int_t
  1400. ngx_ssl_try_early_data(ngx_connection_t *c)
  1401. {
  1402.     int        n, sslerr;
  1403.     u_char     buf;
  1404.     size_t     readbytes;
  1405.     ngx_err_t  err;
  1406.     ngx_int_t  rc;

  1407.     ngx_ssl_clear_error(c->log);

  1408.     readbytes = 0;

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

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

  1412.     if (n == SSL_READ_EARLY_DATA_FINISH) {
  1413.         c->ssl->try_early_data = 0;
  1414.         return ngx_ssl_handshake(c);
  1415.     }

  1416.     if (n == SSL_READ_EARLY_DATA_SUCCESS) {

  1417.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1418.             return NGX_ERROR;
  1419.         }

  1420.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1421.             return NGX_ERROR;
  1422.         }

  1423. #if (NGX_DEBUG)
  1424.         ngx_ssl_handshake_log(c);
  1425. #endif

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

  1427.         c->ssl->early_buf = buf;
  1428.         c->ssl->early_preread = 1;

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

  1430.         c->recv = ngx_ssl_recv;
  1431.         c->send = ngx_ssl_write;
  1432.         c->recv_chain = ngx_ssl_recv_chain;
  1433.         c->send_chain = ngx_ssl_send_chain;

  1434.         c->read->ready = 1;
  1435.         c->write->ready = 1;

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

  1437.         if (BIO_get_ktls_send(SSL_get_wbio(c->ssl->connection)) == 1) {
  1438.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1439.                            "BIO_get_ktls_send(): 1");
  1440.             c->ssl->sendfile = 1;
  1441.         }

  1442. #endif

  1443.         rc = ngx_ssl_ocsp_validate(c);

  1444.         if (rc == NGX_ERROR) {
  1445.             return NGX_ERROR;
  1446.         }

  1447.         if (rc == NGX_AGAIN) {
  1448.             c->read->handler = ngx_ssl_handshake_handler;
  1449.             c->write->handler = ngx_ssl_handshake_handler;
  1450.             return NGX_AGAIN;
  1451.         }

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

  1453.         return NGX_OK;
  1454.     }

  1455.     /* SSL_READ_EARLY_DATA_ERROR */

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

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

  1458.     if (sslerr == SSL_ERROR_WANT_READ) {
  1459.         c->read->ready = 0;
  1460.         c->read->handler = ngx_ssl_handshake_handler;
  1461.         c->write->handler = ngx_ssl_handshake_handler;

  1462.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1463.             return NGX_ERROR;
  1464.         }

  1465.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1466.             return NGX_ERROR;
  1467.         }

  1468.         return NGX_AGAIN;
  1469.     }

  1470.     if (sslerr == SSL_ERROR_WANT_WRITE) {
  1471.         c->write->ready = 0;
  1472.         c->read->handler = ngx_ssl_handshake_handler;
  1473.         c->write->handler = ngx_ssl_handshake_handler;

  1474.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  1475.             return NGX_ERROR;
  1476.         }

  1477.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1478.             return NGX_ERROR;
  1479.         }

  1480.         return NGX_AGAIN;
  1481.     }

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

  1483.     c->ssl->no_wait_shutdown = 1;
  1484.     c->ssl->no_send_shutdown = 1;
  1485.     c->read->eof = 1;

  1486.     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  1487.         ngx_connection_error(c, err,
  1488.                              "peer closed connection in SSL handshake");

  1489.         return NGX_ERROR;
  1490.     }

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

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

  1493.     return NGX_ERROR;
  1494. }

  1495. #endif


  1496. #if (NGX_DEBUG)

  1497. void
  1498. ngx_ssl_handshake_log(ngx_connection_t *c)
  1499. {
  1500.     char         buf[129], *s, *d;
  1501. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  1502.     const
  1503. #endif
  1504.     SSL_CIPHER  *cipher;

  1505.     if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
  1506.         return;
  1507.     }

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

  1509.     if (cipher) {
  1510.         SSL_CIPHER_description(cipher, &buf[1], 128);

  1511.         for (s = &buf[1], d = buf; *s; s++) {
  1512.             if (*s == ' ' && *d == ' ') {
  1513.                 continue;
  1514.             }

  1515.             if (*s == LF || *s == CR) {
  1516.                 continue;
  1517.             }

  1518.             *++d = *s;
  1519.         }

  1520.         if (*d != ' ') {
  1521.             d++;
  1522.         }

  1523.         *d = '\0';

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

  1527.         if (SSL_session_reused(c->ssl->connection)) {
  1528.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1529.                            "SSL reused session");
  1530.         }

  1531.     } else {
  1532.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1533.                        "SSL no shared ciphers");
  1534.     }
  1535. }

  1536. #endif


  1537. static void
  1538. ngx_ssl_handshake_handler(ngx_event_t *ev)
  1539. {
  1540.     ngx_connection_t  *c;

  1541.     c = ev->data;

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

  1544.     if (ev->timedout) {
  1545.         c->ssl->handler(c);
  1546.         return;
  1547.     }

  1548.     if (ngx_ssl_handshake(c) == NGX_AGAIN) {
  1549.         return;
  1550.     }

  1551.     c->ssl->handler(c);
  1552. }


  1553. ssize_t
  1554. ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl, off_t limit)
  1555. {
  1556.     u_char     *last;
  1557.     ssize_t     n, bytes, size;
  1558.     ngx_buf_t  *b;

  1559.     bytes = 0;

  1560.     b = cl->buf;
  1561.     last = b->last;

  1562.     for ( ;; ) {
  1563.         size = b->end - last;

  1564.         if (limit) {
  1565.             if (bytes >= limit) {
  1566.                 return bytes;
  1567.             }

  1568.             if (bytes + size > limit) {
  1569.                 size = (ssize_t) (limit - bytes);
  1570.             }
  1571.         }

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

  1573.         if (n > 0) {
  1574.             last += n;
  1575.             bytes += n;

  1576.             if (!c->read->ready) {
  1577.                 return bytes;
  1578.             }

  1579.             if (last == b->end) {
  1580.                 cl = cl->next;

  1581.                 if (cl == NULL) {
  1582.                     return bytes;
  1583.                 }

  1584.                 b = cl->buf;
  1585.                 last = b->last;
  1586.             }

  1587.             continue;
  1588.         }

  1589.         if (bytes) {

  1590.             if (n == 0 || n == NGX_ERROR) {
  1591.                 c->read->ready = 1;
  1592.             }

  1593.             return bytes;
  1594.         }

  1595.         return n;
  1596.     }
  1597. }


  1598. ssize_t
  1599. ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
  1600. {
  1601.     int  n, bytes;

  1602. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  1603.     if (c->ssl->in_early) {
  1604.         return ngx_ssl_recv_early(c, buf, size);
  1605.     }
  1606. #endif

  1607.     if (c->ssl->last == NGX_ERROR) {
  1608.         c->read->ready = 0;
  1609.         c->read->error = 1;
  1610.         return NGX_ERROR;
  1611.     }

  1612.     if (c->ssl->last == NGX_DONE) {
  1613.         c->read->ready = 0;
  1614.         c->read->eof = 1;
  1615.         return 0;
  1616.     }

  1617.     bytes = 0;

  1618.     ngx_ssl_clear_error(c->log);

  1619.     /*
  1620.      * SSL_read() may return data in parts, so try to read
  1621.      * until SSL_read() would return no data
  1622.      */

  1623.     for ( ;; ) {

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

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

  1626.         if (n > 0) {
  1627.             bytes += n;
  1628.         }

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

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

  1631.             size -= n;

  1632.             if (size == 0) {
  1633.                 c->read->ready = 1;

  1634.                 if (c->read->available >= 0) {
  1635.                     c->read->available -= bytes;

  1636.                     /*
  1637.                      * there can be data buffered at SSL layer,
  1638.                      * so we post an event to continue reading on the next
  1639.                      * iteration of the event loop
  1640.                      */

  1641.                     if (c->read->available < 0) {
  1642.                         c->read->available = 0;
  1643.                         c->read->ready = 0;

  1644.                         if (c->read->posted) {
  1645.                             ngx_delete_posted_event(c->read);
  1646.                         }

  1647.                         ngx_post_event(c->read, &ngx_posted_next_events);
  1648.                     }

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

  1651.                 } else {

  1652. #if (NGX_HAVE_FIONREAD)

  1653.                     if (ngx_socket_nread(c->fd, &c->read->available) == -1) {
  1654.                         c->read->ready = 0;
  1655.                         c->read->error = 1;
  1656.                         ngx_connection_error(c, ngx_socket_errno,
  1657.                                              ngx_socket_nread_n " failed");
  1658.                         return NGX_ERROR;
  1659.                     }

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

  1662. #endif
  1663.                 }

  1664.                 return bytes;
  1665.             }

  1666.             buf += n;

  1667.             continue;
  1668.         }

  1669.         if (bytes) {
  1670.             if (c->ssl->last != NGX_AGAIN) {
  1671.                 c->read->ready = 1;
  1672.             }

  1673.             return bytes;
  1674.         }

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

  1676.         case NGX_DONE:
  1677.             c->read->ready = 0;
  1678.             c->read->eof = 1;
  1679.             return 0;

  1680.         case NGX_ERROR:
  1681.             c->read->ready = 0;
  1682.             c->read->error = 1;

  1683.             /* fall through */

  1684.         case NGX_AGAIN:
  1685.             return c->ssl->last;
  1686.         }
  1687.     }
  1688. }


  1689. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  1690. static ssize_t
  1691. ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size)
  1692. {
  1693.     int        n, bytes;
  1694.     size_t     readbytes;

  1695.     if (c->ssl->last == NGX_ERROR) {
  1696.         c->read->ready = 0;
  1697.         c->read->error = 1;
  1698.         return NGX_ERROR;
  1699.     }

  1700.     if (c->ssl->last == NGX_DONE) {
  1701.         c->read->ready = 0;
  1702.         c->read->eof = 1;
  1703.         return 0;
  1704.     }

  1705.     bytes = 0;

  1706.     ngx_ssl_clear_error(c->log);

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

  1708.         if (size == 0) {
  1709.             c->read->ready = 0;
  1710.             c->read->eof = 1;
  1711.             return 0;
  1712.         }

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

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

  1715.         bytes = 1;
  1716.         size -= 1;
  1717.         buf += 1;
  1718.     }

  1719.     if (c->ssl->write_blocked) {
  1720.         return NGX_AGAIN;
  1721.     }

  1722.     /*
  1723.      * SSL_read_early_data() may return data in parts, so try to read
  1724.      * until SSL_read_early_data() would return no data
  1725.      */

  1726.     for ( ;; ) {

  1727.         readbytes = 0;

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

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

  1731.         if (n == SSL_READ_EARLY_DATA_SUCCESS) {

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

  1733.             bytes += readbytes;
  1734.             size -= readbytes;

  1735.             if (size == 0) {
  1736.                 c->read->ready = 1;
  1737.                 return bytes;
  1738.             }

  1739.             buf += readbytes;

  1740.             continue;
  1741.         }

  1742.         if (n == SSL_READ_EARLY_DATA_FINISH) {

  1743.             c->ssl->last = ngx_ssl_handle_recv(c, 1);
  1744.             c->ssl->in_early = 0;

  1745.             if (bytes) {
  1746.                 c->read->ready = 1;
  1747.                 return bytes;
  1748.             }

  1749.             return ngx_ssl_recv(c, buf, size);
  1750.         }

  1751.         /* SSL_READ_EARLY_DATA_ERROR */

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

  1753.         if (bytes) {
  1754.             if (c->ssl->last != NGX_AGAIN) {
  1755.                 c->read->ready = 1;
  1756.             }

  1757.             return bytes;
  1758.         }

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

  1760.         case NGX_DONE:
  1761.             c->read->ready = 0;
  1762.             c->read->eof = 1;
  1763.             return 0;

  1764.         case NGX_ERROR:
  1765.             c->read->ready = 0;
  1766.             c->read->error = 1;

  1767.             /* fall through */

  1768.         case NGX_AGAIN:
  1769.             return c->ssl->last;
  1770.         }
  1771.     }
  1772. }

  1773. #endif


  1774. static ngx_int_t
  1775. ngx_ssl_handle_recv(ngx_connection_t *c, int n)
  1776. {
  1777.     int        sslerr;
  1778.     ngx_err_t  err;

  1779. #if (!defined SSL_OP_NO_RENEGOTIATION                                         \
  1780.      && !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

  1781.     if (c->ssl->renegotiation) {
  1782.         /*
  1783.          * disable renegotiation (CVE-2009-3555):
  1784.          * OpenSSL (at least up to 0.9.8l) does not handle disabled
  1785.          * renegotiation gracefully, so drop connection here
  1786.          */

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

  1788.         while (ERR_peek_error()) {
  1789.             ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0,
  1790.                           "ignoring stale global SSL error");
  1791.         }

  1792.         ERR_clear_error();

  1793.         c->ssl->no_wait_shutdown = 1;
  1794.         c->ssl->no_send_shutdown = 1;

  1795.         return NGX_ERROR;
  1796.     }

  1797. #endif

  1798.     if (n > 0) {

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

  1800.             c->write->handler = c->ssl->saved_write_handler;
  1801.             c->ssl->saved_write_handler = NULL;
  1802.             c->write->ready = 1;

  1803.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1804.                 return NGX_ERROR;
  1805.             }

  1806.             ngx_post_event(c->write, &ngx_posted_events);
  1807.         }

  1808.         return NGX_OK;
  1809.     }

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

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

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

  1813.     if (sslerr == SSL_ERROR_WANT_READ) {

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

  1815.             c->write->handler = c->ssl->saved_write_handler;
  1816.             c->ssl->saved_write_handler = NULL;
  1817.             c->write->ready = 1;

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

  1821.             ngx_post_event(c->write, &ngx_posted_events);
  1822.         }

  1823.         c->read->ready = 0;
  1824.         return NGX_AGAIN;
  1825.     }

  1826.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

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

  1830.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  1831.             return NGX_ERROR;
  1832.         }

  1833.         /*
  1834.          * we do not set the timer because there is already the read event timer
  1835.          */

  1836.         if (c->ssl->saved_write_handler == NULL) {
  1837.             c->ssl->saved_write_handler = c->write->handler;
  1838.             c->write->handler = ngx_ssl_write_handler;
  1839.         }

  1840.         return NGX_AGAIN;
  1841.     }

  1842.     c->ssl->no_wait_shutdown = 1;
  1843.     c->ssl->no_send_shutdown = 1;

  1844.     if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  1845.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1846.                        "peer shutdown SSL cleanly");
  1847.         return NGX_DONE;
  1848.     }

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

  1850.     return NGX_ERROR;
  1851. }


  1852. static void
  1853. ngx_ssl_write_handler(ngx_event_t *wev)
  1854. {
  1855.     ngx_connection_t  *c;

  1856.     c = wev->data;

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

  1858.     c->read->handler(c->read);
  1859. }


  1860. /*
  1861. * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
  1862. * before the SSL_write() call to decrease a SSL overhead.
  1863. *
  1864. * Besides for protocols such as HTTP it is possible to always buffer
  1865. * the output to decrease a SSL overhead some more.
  1866. */

  1867. ngx_chain_t *
  1868. ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
  1869. {
  1870.     int           n;
  1871.     ngx_uint_t    flush;
  1872.     ssize_t       send, size, file_size;
  1873.     ngx_buf_t    *buf;
  1874.     ngx_chain_t  *cl;

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

  1876.         while (in) {
  1877.             if (ngx_buf_special(in->buf)) {
  1878.                 in = in->next;
  1879.                 continue;
  1880.             }

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

  1882.             if (n == NGX_ERROR) {
  1883.                 return NGX_CHAIN_ERROR;
  1884.             }

  1885.             if (n == NGX_AGAIN) {
  1886.                 return in;
  1887.             }

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

  1889.             if (in->buf->pos == in->buf->last) {
  1890.                 in = in->next;
  1891.             }
  1892.         }

  1893.         return in;
  1894.     }


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

  1896.     if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) {
  1897.         limit = NGX_MAX_INT32_VALUE - ngx_pagesize;
  1898.     }

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

  1900.     if (buf == NULL) {
  1901.         buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size);
  1902.         if (buf == NULL) {
  1903.             return NGX_CHAIN_ERROR;
  1904.         }

  1905.         c->ssl->buf = buf;
  1906.     }

  1907.     if (buf->start == NULL) {
  1908.         buf->start = ngx_palloc(c->pool, c->ssl->buffer_size);
  1909.         if (buf->start == NULL) {
  1910.             return NGX_CHAIN_ERROR;
  1911.         }

  1912.         buf->pos = buf->start;
  1913.         buf->last = buf->start;
  1914.         buf->end = buf->start + c->ssl->buffer_size;
  1915.     }

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

  1918.     for ( ;; ) {

  1919.         while (in && buf->last < buf->end && send < limit) {
  1920.             if (in->buf->last_buf || in->buf->flush) {
  1921.                 flush = 1;
  1922.             }

  1923.             if (ngx_buf_special(in->buf)) {
  1924.                 in = in->next;
  1925.                 continue;
  1926.             }

  1927.             if (in->buf->in_file && c->ssl->sendfile) {
  1928.                 flush = 1;
  1929.                 break;
  1930.             }

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

  1932.             if (size > buf->end - buf->last) {
  1933.                 size = buf->end - buf->last;
  1934.             }

  1935.             if (send + size > limit) {
  1936.                 size = (ssize_t) (limit - send);
  1937.             }

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

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

  1941.             buf->last += size;
  1942.             in->buf->pos += size;
  1943.             send += size;

  1944.             if (in->buf->pos == in->buf->last) {
  1945.                 in = in->next;
  1946.             }
  1947.         }

  1948.         if (!flush && send < limit && buf->last < buf->end) {
  1949.             break;
  1950.         }

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

  1952.         if (size == 0) {

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

  1954.                 /* coalesce the neighbouring file bufs */

  1955.                 cl = in;
  1956.                 file_size = (size_t) ngx_chain_coalesce_file(&cl, limit - send);

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

  1958.                 if (n == NGX_ERROR) {
  1959.                     return NGX_CHAIN_ERROR;
  1960.                 }

  1961.                 if (n == NGX_AGAIN) {
  1962.                     break;
  1963.                 }

  1964.                 in = ngx_chain_update_sent(in, n);

  1965.                 send += n;
  1966.                 flush = 0;

  1967.                 continue;
  1968.             }

  1969.             buf->flush = 0;
  1970.             c->buffered &= ~NGX_SSL_BUFFERED;

  1971.             return in;
  1972.         }

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

  1974.         if (n == NGX_ERROR) {
  1975.             return NGX_CHAIN_ERROR;
  1976.         }

  1977.         if (n == NGX_AGAIN) {
  1978.             break;
  1979.         }

  1980.         buf->pos += n;

  1981.         if (n < size) {
  1982.             break;
  1983.         }

  1984.         flush = 0;

  1985.         buf->pos = buf->start;
  1986.         buf->last = buf->start;

  1987.         if (in == NULL || send >= limit) {
  1988.             break;
  1989.         }
  1990.     }

  1991.     buf->flush = flush;

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

  1994.     } else {
  1995.         c->buffered &= ~NGX_SSL_BUFFERED;
  1996.     }

  1997.     return in;
  1998. }


  1999. ssize_t
  2000. ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
  2001. {
  2002.     int        n, sslerr;
  2003.     ngx_err_t  err;

  2004. #ifdef SSL_READ_EARLY_DATA_SUCCESS
  2005.     if (c->ssl->in_early) {
  2006.         return ngx_ssl_write_early(c, data, size);
  2007.     }
  2008. #endif

  2009.     ngx_ssl_clear_error(c->log);

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

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

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

  2013.     if (n > 0) {

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

  2015.             c->read->handler = c->ssl->saved_read_handler;
  2016.             c->ssl->saved_read_handler = NULL;
  2017.             c->read->ready = 1;

  2018.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2019.                 return NGX_ERROR;
  2020.             }

  2021.             ngx_post_event(c->read, &ngx_posted_events);
  2022.         }

  2023.         c->sent += n;

  2024.         return n;
  2025.     }

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

  2027.     if (sslerr == SSL_ERROR_ZERO_RETURN) {

  2028.         /*
  2029.          * OpenSSL 1.1.1 fails to return SSL_ERROR_SYSCALL if an error
  2030.          * happens during SSL_write() after close_notify alert from the
  2031.          * peer, and returns SSL_ERROR_ZERO_RETURN instead,
  2032.          * https://git.openssl.org/?p=openssl.git;a=commitdiff;h=8051ab2
  2033.          */

  2034.         sslerr = SSL_ERROR_SYSCALL;
  2035.     }

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

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

  2038.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

  2040.             c->read->handler = c->ssl->saved_read_handler;
  2041.             c->ssl->saved_read_handler = NULL;
  2042.             c->read->ready = 1;

  2043.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2044.                 return NGX_ERROR;
  2045.             }

  2046.             ngx_post_event(c->read, &ngx_posted_events);
  2047.         }

  2048.         c->write->ready = 0;
  2049.         return NGX_AGAIN;
  2050.     }

  2051.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

  2055.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2056.             return NGX_ERROR;
  2057.         }

  2058.         /*
  2059.          * we do not set the timer because there is already
  2060.          * the write event timer
  2061.          */

  2062.         if (c->ssl->saved_read_handler == NULL) {
  2063.             c->ssl->saved_read_handler = c->read->handler;
  2064.             c->read->handler = ngx_ssl_read_handler;
  2065.         }

  2066.         return NGX_AGAIN;
  2067.     }

  2068.     c->ssl->no_wait_shutdown = 1;
  2069.     c->ssl->no_send_shutdown = 1;
  2070.     c->write->error = 1;

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

  2072.     return NGX_ERROR;
  2073. }


  2074. #ifdef SSL_READ_EARLY_DATA_SUCCESS

  2075. static ssize_t
  2076. ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size)
  2077. {
  2078.     int        n, sslerr;
  2079.     size_t     written;
  2080.     ngx_err_t  err;

  2081.     ngx_ssl_clear_error(c->log);

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

  2083.     written = 0;

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

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

  2087.     if (n > 0) {

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

  2089.             c->read->handler = c->ssl->saved_read_handler;
  2090.             c->ssl->saved_read_handler = NULL;
  2091.             c->read->ready = 1;

  2092.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2093.                 return NGX_ERROR;
  2094.             }

  2095.             ngx_post_event(c->read, &ngx_posted_events);
  2096.         }

  2097.         if (c->ssl->write_blocked) {
  2098.             c->ssl->write_blocked = 0;
  2099.             ngx_post_event(c->read, &ngx_posted_events);
  2100.         }

  2101.         c->sent += written;

  2102.         return written;
  2103.     }

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

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

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

  2107.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

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

  2111.             c->read->handler = c->ssl->saved_read_handler;
  2112.             c->ssl->saved_read_handler = NULL;
  2113.             c->read->ready = 1;

  2114.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2115.                 return NGX_ERROR;
  2116.             }

  2117.             ngx_post_event(c->read, &ngx_posted_events);
  2118.         }

  2119.         /*
  2120.          * OpenSSL 1.1.1a fails to handle SSL_read_early_data()
  2121.          * if an SSL_write_early_data() call blocked on writing,
  2122.          * see https://github.com/openssl/openssl/issues/7757
  2123.          */

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

  2125.         c->write->ready = 0;
  2126.         return NGX_AGAIN;
  2127.     }

  2128.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

  2132.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2133.             return NGX_ERROR;
  2134.         }

  2135.         /*
  2136.          * we do not set the timer because there is already
  2137.          * the write event timer
  2138.          */

  2139.         if (c->ssl->saved_read_handler == NULL) {
  2140.             c->ssl->saved_read_handler = c->read->handler;
  2141.             c->read->handler = ngx_ssl_read_handler;
  2142.         }

  2143.         return NGX_AGAIN;
  2144.     }

  2145.     c->ssl->no_wait_shutdown = 1;
  2146.     c->ssl->no_send_shutdown = 1;
  2147.     c->write->error = 1;

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

  2149.     return NGX_ERROR;
  2150. }

  2151. #endif


  2152. static ssize_t
  2153. ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
  2154. {
  2155. #if (defined BIO_get_ktls_send && !NGX_WIN32)

  2156.     int        sslerr, flags;
  2157.     ssize_t    n;
  2158.     ngx_err_t  err;

  2159.     ngx_ssl_clear_error(c->log);

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

  2163.     ngx_set_errno(0);

  2164. #if (NGX_HAVE_SENDFILE_NODISKIO)

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

  2166.     if (file->file->directio) {
  2167.         flags |= SF_NOCACHE;
  2168.     }

  2169. #else
  2170.     flags = 0;
  2171. #endif

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

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

  2175.     if (n > 0) {

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

  2177.             c->read->handler = c->ssl->saved_read_handler;
  2178.             c->ssl->saved_read_handler = NULL;
  2179.             c->read->ready = 1;

  2180.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2181.                 return NGX_ERROR;
  2182.             }

  2183.             ngx_post_event(c->read, &ngx_posted_events);
  2184.         }

  2185. #if (NGX_HAVE_SENDFILE_NODISKIO)
  2186.         c->busy_count = 0;
  2187. #endif

  2188.         c->sent += n;

  2189.         return n;
  2190.     }

  2191.     if (n == 0) {

  2192.         /*
  2193.          * if sendfile returns zero, then someone has truncated the file,
  2194.          * so the offset became beyond the end of the file
  2195.          */

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

  2199.         return NGX_ERROR;
  2200.     }

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

  2202.     if (sslerr == SSL_ERROR_ZERO_RETURN) {

  2203.         /*
  2204.          * OpenSSL fails to return SSL_ERROR_SYSCALL if an error
  2205.          * happens during writing after close_notify alert from the
  2206.          * peer, and returns SSL_ERROR_ZERO_RETURN instead
  2207.          */

  2208.         sslerr = SSL_ERROR_SYSCALL;
  2209.     }

  2210.     if (sslerr == SSL_ERROR_SSL
  2211.         && ERR_GET_REASON(ERR_peek_error()) == SSL_R_UNINITIALIZED
  2212.         && ngx_errno != 0)
  2213.     {
  2214.         /*
  2215.          * OpenSSL fails to return SSL_ERROR_SYSCALL if an error
  2216.          * happens in sendfile(), and returns SSL_ERROR_SSL with
  2217.          * SSL_R_UNINITIALIZED reason instead
  2218.          */

  2219.         sslerr = SSL_ERROR_SYSCALL;
  2220.     }

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

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

  2223.     if (sslerr == SSL_ERROR_WANT_WRITE) {

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

  2225.             c->read->handler = c->ssl->saved_read_handler;
  2226.             c->ssl->saved_read_handler = NULL;
  2227.             c->read->ready = 1;

  2228.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2229.                 return NGX_ERROR;
  2230.             }

  2231.             ngx_post_event(c->read, &ngx_posted_events);
  2232.         }

  2233. #if (NGX_HAVE_SENDFILE_NODISKIO)

  2234.         if (ngx_errno == EBUSY) {
  2235.             c->busy_count++;

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

  2238.             if (c->write->posted) {
  2239.                 ngx_delete_posted_event(c->write);
  2240.             }

  2241.             ngx_post_event(c->write, &ngx_posted_next_events);
  2242.         }

  2243. #endif

  2244.         c->write->ready = 0;
  2245.         return NGX_AGAIN;
  2246.     }

  2247.     if (sslerr == SSL_ERROR_WANT_READ) {

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

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

  2251.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2252.             return NGX_ERROR;
  2253.         }

  2254.         /*
  2255.          * we do not set the timer because there is already
  2256.          * the write event timer
  2257.          */

  2258.         if (c->ssl->saved_read_handler == NULL) {
  2259.             c->ssl->saved_read_handler = c->read->handler;
  2260.             c->read->handler = ngx_ssl_read_handler;
  2261.         }

  2262.         return NGX_AGAIN;
  2263.     }

  2264.     c->ssl->no_wait_shutdown = 1;
  2265.     c->ssl->no_send_shutdown = 1;
  2266.     c->write->error = 1;

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

  2268. #else
  2269.     ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2270.                   "SSL_sendfile() not available");
  2271. #endif

  2272.     return NGX_ERROR;
  2273. }


  2274. static void
  2275. ngx_ssl_read_handler(ngx_event_t *rev)
  2276. {
  2277.     ngx_connection_t  *c;

  2278.     c = rev->data;

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

  2280.     c->write->handler(c->write);
  2281. }


  2282. void
  2283. ngx_ssl_free_buffer(ngx_connection_t *c)
  2284. {
  2285.     if (c->ssl->buf && c->ssl->buf->start) {
  2286.         if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
  2287.             c->ssl->buf->start = NULL;
  2288.         }
  2289.     }
  2290. }


  2291. ngx_int_t
  2292. ngx_ssl_shutdown(ngx_connection_t *c)
  2293. {
  2294.     int         n, sslerr, mode;
  2295.     ngx_int_t   rc;
  2296.     ngx_err_t   err;
  2297.     ngx_uint_t  tries;

  2298. #if (NGX_QUIC)
  2299.     if (c->quic) {
  2300.         /* QUIC streams inherit SSL object */
  2301.         return NGX_OK;
  2302.     }
  2303. #endif

  2304.     rc = NGX_OK;

  2305.     ngx_ssl_ocsp_cleanup(c);

  2306.     if (SSL_in_init(c->ssl->connection)) {
  2307.         /*
  2308.          * OpenSSL 1.0.2f complains if SSL_shutdown() is called during
  2309.          * an SSL handshake, while previous versions always return 0.
  2310.          * Avoid calling SSL_shutdown() if handshake wasn't completed.
  2311.          */

  2312.         goto done;
  2313.     }

  2314.     if (c->timedout || c->error || c->buffered) {
  2315.         mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
  2316.         SSL_set_quiet_shutdown(c->ssl->connection, 1);

  2317.     } else {
  2318.         mode = SSL_get_shutdown(c->ssl->connection);

  2319.         if (c->ssl->no_wait_shutdown) {
  2320.             mode |= SSL_RECEIVED_SHUTDOWN;
  2321.         }

  2322.         if (c->ssl->no_send_shutdown) {
  2323.             mode |= SSL_SENT_SHUTDOWN;
  2324.         }

  2325.         if (c->ssl->no_wait_shutdown && c->ssl->no_send_shutdown) {
  2326.             SSL_set_quiet_shutdown(c->ssl->connection, 1);
  2327.         }
  2328.     }

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

  2330.     ngx_ssl_clear_error(c->log);

  2331.     tries = 2;

  2332.     for ( ;; ) {

  2333.         /*
  2334.          * For bidirectional shutdown, SSL_shutdown() needs to be called
  2335.          * twice: first call sends the "close notify" alert and returns 0,
  2336.          * second call waits for the peer's "close notify" alert.
  2337.          */

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

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

  2340.         if (n == 1) {
  2341.             goto done;
  2342.         }

  2343.         if (n == 0 && tries-- > 1) {
  2344.             continue;
  2345.         }

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

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

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

  2350.         if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
  2351.             c->read->handler = ngx_ssl_shutdown_handler;
  2352.             c->write->handler = ngx_ssl_shutdown_handler;

  2353.             if (sslerr == SSL_ERROR_WANT_READ) {
  2354.                 c->read->ready = 0;

  2355.             } else {
  2356.                 c->write->ready = 0;
  2357.             }

  2358.             if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  2359.                 goto failed;
  2360.             }

  2361.             if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  2362.                 goto failed;
  2363.             }

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

  2365.             return NGX_AGAIN;
  2366.         }

  2367.         if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
  2368.             goto done;
  2369.         }

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

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

  2372.         break;
  2373.     }

  2374. failed:

  2375.     rc = NGX_ERROR;

  2376. done:

  2377.     if (c->ssl->shutdown_without_free) {
  2378.         c->ssl->shutdown_without_free = 0;
  2379.         c->recv = ngx_recv;
  2380.         return rc;
  2381.     }

  2382.     SSL_free(c->ssl->connection);
  2383.     c->ssl = NULL;
  2384.     c->recv = ngx_recv;

  2385.     return rc;
  2386. }


  2387. static void
  2388. ngx_ssl_shutdown_handler(ngx_event_t *ev)
  2389. {
  2390.     ngx_connection_t           *c;
  2391.     ngx_connection_handler_pt   handler;

  2392.     c = ev->data;
  2393.     handler = c->ssl->handler;

  2394.     if (ev->timedout) {
  2395.         c->timedout = 1;
  2396.     }

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

  2398.     if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2399.         return;
  2400.     }

  2401.     handler(c);
  2402. }


  2403. static void
  2404. ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
  2405.     char *text)
  2406. {
  2407.     int         n;
  2408.     ngx_uint_t  level;

  2409.     level = NGX_LOG_CRIT;

  2410.     if (sslerr == SSL_ERROR_SYSCALL) {

  2411.         if (err == NGX_ECONNRESET
  2412. #if (NGX_WIN32)
  2413.             || err == NGX_ECONNABORTED
  2414. #endif
  2415.             || err == NGX_EPIPE
  2416.             || err == NGX_ENOTCONN
  2417.             || err == NGX_ETIMEDOUT
  2418.             || err == NGX_ECONNREFUSED
  2419.             || err == NGX_ENETDOWN
  2420.             || err == NGX_ENETUNREACH
  2421.             || err == NGX_EHOSTDOWN
  2422.             || err == NGX_EHOSTUNREACH)
  2423.         {
  2424.             switch (c->log_error) {

  2425.             case NGX_ERROR_IGNORE_ECONNRESET:
  2426.             case NGX_ERROR_INFO:
  2427.                 level = NGX_LOG_INFO;
  2428.                 break;

  2429.             case NGX_ERROR_ERR:
  2430.                 level = NGX_LOG_ERR;
  2431.                 break;

  2432.             default:
  2433.                 break;
  2434.             }
  2435.         }

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

  2437.         n = ERR_GET_REASON(ERR_peek_last_error());

  2438.             /* handshake failures */
  2439.         if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC                        /*  103 */
  2440. #ifdef SSL_R_NO_SUITABLE_KEY_SHARE
  2441.             || n == SSL_R_NO_SUITABLE_KEY_SHARE                      /*  101 */
  2442. #endif
  2443. #ifdef SSL_R_BAD_ALERT
  2444.             || n == SSL_R_BAD_ALERT                                  /*  102 */
  2445. #endif
  2446. #ifdef SSL_R_BAD_KEY_SHARE
  2447.             || n == SSL_R_BAD_KEY_SHARE                              /*  108 */
  2448. #endif
  2449. #ifdef SSL_R_BAD_EXTENSION
  2450.             || n == SSL_R_BAD_EXTENSION                              /*  110 */
  2451. #endif
  2452.             || n == SSL_R_BAD_DIGEST_LENGTH                          /*  111 */
  2453. #ifdef SSL_R_MISSING_SIGALGS_EXTENSION
  2454.             || n == SSL_R_MISSING_SIGALGS_EXTENSION                  /*  112 */
  2455. #endif
  2456.             || n == SSL_R_BAD_PACKET_LENGTH                          /*  115 */
  2457. #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM
  2458.             || n == SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM            /*  118 */
  2459. #endif
  2460. #ifdef SSL_R_BAD_KEY_UPDATE
  2461.             || n == SSL_R_BAD_KEY_UPDATE                             /*  122 */
  2462. #endif
  2463.             || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  /*  129 */
  2464.             || n == SSL_R_CCS_RECEIVED_EARLY                         /*  133 */
  2465. #ifdef SSL_R_DECODE_ERROR
  2466.             || n == SSL_R_DECODE_ERROR                               /*  137 */
  2467. #endif
  2468. #ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED
  2469.             || n == SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              /*  145 */
  2470. #endif
  2471.             || n == SSL_R_DATA_LENGTH_TOO_LONG                       /*  146 */
  2472.             || n == SSL_R_DIGEST_CHECK_FAILED                        /*  149 */
  2473.             || n == SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  /*  150 */
  2474.             || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              /*  151 */
  2475.             || n == SSL_R_EXCESSIVE_MESSAGE_SIZE                     /*  152 */
  2476. #ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS
  2477.             || n == SSL_R_GOT_A_FIN_BEFORE_A_CCS                     /*  154 */
  2478. #endif
  2479.             || n == SSL_R_HTTPS_PROXY_REQUEST                        /*  155 */
  2480.             || n == SSL_R_HTTP_REQUEST                               /*  156 */
  2481.             || n == SSL_R_LENGTH_MISMATCH                            /*  159 */
  2482. #ifdef SSL_R_LENGTH_TOO_SHORT
  2483.             || n == SSL_R_LENGTH_TOO_SHORT                           /*  160 */
  2484. #endif
  2485. #ifdef SSL_R_NO_RENEGOTIATION
  2486.             || n == SSL_R_NO_RENEGOTIATION                           /*  182 */
  2487. #endif
  2488. #ifdef SSL_R_NO_CIPHERS_PASSED
  2489.             || n == SSL_R_NO_CIPHERS_PASSED                          /*  182 */
  2490. #endif
  2491.             || n == SSL_R_NO_CIPHERS_SPECIFIED                       /*  183 */
  2492. #ifdef SSL_R_BAD_CIPHER
  2493.             || n == SSL_R_BAD_CIPHER                                 /*  186 */
  2494. #endif
  2495.             || n == SSL_R_NO_COMPRESSION_SPECIFIED                   /*  187 */
  2496.             || n == SSL_R_NO_SHARED_CIPHER                           /*  193 */
  2497. #ifdef SSL_R_PACKET_LENGTH_TOO_LONG
  2498.             || n == SSL_R_PACKET_LENGTH_TOO_LONG                     /*  198 */
  2499. #endif
  2500.             || n == SSL_R_RECORD_LENGTH_MISMATCH                     /*  213 */
  2501. #ifdef SSL_R_TOO_MANY_WARNING_ALERTS
  2502.             || n == SSL_R_TOO_MANY_WARNING_ALERTS                    /*  220 */
  2503. #endif
  2504. #ifdef SSL_R_CLIENTHELLO_TLSEXT
  2505.             || n == SSL_R_CLIENTHELLO_TLSEXT                         /*  226 */
  2506. #endif
  2507. #ifdef SSL_R_PARSE_TLSEXT
  2508.             || n == SSL_R_PARSE_TLSEXT                               /*  227 */
  2509. #endif
  2510. #ifdef SSL_R_CALLBACK_FAILED
  2511.             || n == SSL_R_CALLBACK_FAILED                            /*  234 */
  2512. #endif
  2513. #ifdef SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
  2514.             || n == SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    /*  234 */
  2515. #endif
  2516. #ifdef SSL_R_NO_APPLICATION_PROTOCOL
  2517.             || n == SSL_R_NO_APPLICATION_PROTOCOL                    /*  235 */
  2518. #endif
  2519.             || n == SSL_R_UNEXPECTED_MESSAGE                         /*  244 */
  2520.             || n == SSL_R_UNEXPECTED_RECORD                          /*  245 */
  2521.             || n == SSL_R_UNKNOWN_ALERT_TYPE                         /*  246 */
  2522.             || n == SSL_R_UNKNOWN_PROTOCOL                           /*  252 */
  2523. #ifdef SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS
  2524.             || n == SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS             /*  253 */
  2525. #endif
  2526. #ifdef SSL_R_INVALID_COMPRESSION_LIST
  2527.             || n == SSL_R_INVALID_COMPRESSION_LIST                   /*  256 */
  2528. #endif
  2529. #ifdef SSL_R_MISSING_KEY_SHARE
  2530.             || n == SSL_R_MISSING_KEY_SHARE                          /*  258 */
  2531. #endif
  2532.             || n == SSL_R_UNSUPPORTED_PROTOCOL                       /*  258 */
  2533. #ifdef SSL_R_NO_SHARED_GROUP
  2534.             || n == SSL_R_NO_SHARED_GROUP                            /*  266 */
  2535. #endif
  2536.             || n == SSL_R_WRONG_VERSION_NUMBER                       /*  267 */
  2537. #ifdef SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA
  2538.             || n == SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA                /*  270 */
  2539. #endif
  2540.             || n == SSL_R_BAD_LENGTH                                 /*  271 */
  2541.             || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        /*  281 */
  2542. #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY
  2543.             || n == SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY        /*  291 */
  2544. #endif
  2545. #ifdef SSL_R_APPLICATION_DATA_ON_SHUTDOWN
  2546.             || n == SSL_R_APPLICATION_DATA_ON_SHUTDOWN               /*  291 */
  2547. #endif
  2548. #ifdef SSL_R_BAD_LEGACY_VERSION
  2549.             || n == SSL_R_BAD_LEGACY_VERSION                         /*  292 */
  2550. #endif
  2551. #ifdef SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA
  2552.             || n == SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA     /*  293 */
  2553. #endif
  2554. #ifdef SSL_R_RECORD_TOO_SMALL
  2555.             || n == SSL_R_RECORD_TOO_SMALL                           /*  298 */
  2556. #endif
  2557. #ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG
  2558.             || n == SSL_R_SSL3_SESSION_ID_TOO_LONG                   /*  300 */
  2559. #endif
  2560. #ifdef SSL_R_BAD_ECPOINT
  2561.             || n == SSL_R_BAD_ECPOINT                                /*  306 */
  2562. #endif
  2563. #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
  2564.             || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG                   /*  335 */
  2565.             || n == SSL_R_RENEGOTIATION_ENCODING_ERR                 /*  336 */
  2566.             || n == SSL_R_RENEGOTIATION_MISMATCH                     /*  337 */
  2567. #endif
  2568. #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
  2569.             || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       /*  338 */
  2570. #endif
  2571. #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
  2572.             || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           /*  345 */
  2573. #endif
  2574. #ifdef SSL_R_INAPPROPRIATE_FALLBACK
  2575.             || n == SSL_R_INAPPROPRIATE_FALLBACK                     /*  373 */
  2576. #endif
  2577. #ifdef SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS
  2578.             || n == SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS             /*  376 */
  2579. #endif
  2580. #ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS
  2581.             || n == SSL_R_NO_SHARED_SIGATURE_ALGORITHMS              /*  376 */
  2582. #endif
  2583. #ifdef SSL_R_CERT_CB_ERROR
  2584.             || n == SSL_R_CERT_CB_ERROR                              /*  377 */
  2585. #endif
  2586. #ifdef SSL_R_VERSION_TOO_LOW
  2587.             || n == SSL_R_VERSION_TOO_LOW                            /*  396 */
  2588. #endif
  2589. #ifdef SSL_R_TOO_MANY_WARN_ALERTS
  2590.             || n == SSL_R_TOO_MANY_WARN_ALERTS                       /*  409 */
  2591. #endif
  2592. #ifdef SSL_R_BAD_RECORD_TYPE
  2593.             || n == SSL_R_BAD_RECORD_TYPE                            /*  443 */
  2594. #endif
  2595.             || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
  2596. #ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE
  2597.             || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE             /* 1010 */
  2598.             || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC                 /* 1020 */
  2599.             || n == SSL_R_TLSV1_ALERT_DECRYPTION_FAILED              /* 1021 */
  2600.             || n == SSL_R_TLSV1_ALERT_RECORD_OVERFLOW                /* 1022 */
  2601.             || n == SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE          /* 1030 */
  2602.             || n == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE              /* 1040 */
  2603.             || n == SSL_R_SSLV3_ALERT_NO_CERTIFICATE                 /* 1041 */
  2604.             || n == SSL_R_SSLV3_ALERT_BAD_CERTIFICATE                /* 1042 */
  2605.             || n == SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE        /* 1043 */
  2606.             || n == SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED            /* 1044 */
  2607.             || n == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED            /* 1045 */
  2608.             || n == SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN            /* 1046 */
  2609.             || n == SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER              /* 1047 */
  2610.             || n == SSL_R_TLSV1_ALERT_UNKNOWN_CA                     /* 1048 */
  2611.             || n == SSL_R_TLSV1_ALERT_ACCESS_DENIED                  /* 1049 */
  2612.             || n == SSL_R_TLSV1_ALERT_DECODE_ERROR                   /* 1050 */
  2613.             || n == SSL_R_TLSV1_ALERT_DECRYPT_ERROR                  /* 1051 */
  2614.             || n == SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION             /* 1060 */
  2615.             || n == SSL_R_TLSV1_ALERT_PROTOCOL_VERSION               /* 1070 */
  2616.             || n == SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY          /* 1071 */
  2617.             || n == SSL_R_TLSV1_ALERT_INTERNAL_ERROR                 /* 1080 */
  2618.             || n == SSL_R_TLSV1_ALERT_USER_CANCELLED                 /* 1090 */
  2619.             || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION               /* 1100 */
  2620. #endif
  2621.             )
  2622.         {
  2623.             switch (c->log_error) {

  2624.             case NGX_ERROR_IGNORE_ECONNRESET:
  2625.             case NGX_ERROR_INFO:
  2626.                 level = NGX_LOG_INFO;
  2627.                 break;

  2628.             case NGX_ERROR_ERR:
  2629.                 level = NGX_LOG_ERR;
  2630.                 break;

  2631.             default:
  2632.                 break;
  2633.             }
  2634.         }
  2635.     }

  2636.     ngx_ssl_error(level, c->log, err, text);
  2637. }


  2638. static void
  2639. ngx_ssl_clear_error(ngx_log_t *log)
  2640. {
  2641.     while (ERR_peek_error()) {
  2642.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
  2643.     }

  2644.     ERR_clear_error();
  2645. }


  2646. void ngx_cdecl
  2647. ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
  2648. {
  2649.     int          flags;
  2650.     u_long       n;
  2651.     va_list      args;
  2652.     u_char      *p, *last;
  2653.     u_char       errstr[NGX_MAX_CONF_ERRSTR];
  2654.     const char  *data;

  2655.     last = errstr + NGX_MAX_CONF_ERRSTR;

  2656.     va_start(args, fmt);
  2657.     p = ngx_vslprintf(errstr, last - 1, fmt, args);
  2658.     va_end(args);

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

  2661.         for ( ;; ) {

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

  2663.             if (n == 0) {
  2664.                 break;
  2665.             }

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

  2667.             if (p >= last - 1) {
  2668.                 goto next;
  2669.             }

  2670.             *p++ = ' ';

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

  2672.             while (p < last && *p) {
  2673.                 p++;
  2674.             }

  2675.             if (p < last && *data && (flags & ERR_TXT_STRING)) {
  2676.                 *p++ = ':';
  2677.                 p = ngx_cpystrn(p, (u_char *) data, last - p);
  2678.             }

  2679.         next:

  2680.             (void) ERR_get_error();
  2681.         }

  2682.         if (p < last) {
  2683.             *p++ = ')';
  2684.         }
  2685.     }

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


  2688. ngx_int_t
  2689. ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  2690.     ngx_array_t *certificates, ssize_t builtin_session_cache,
  2691.     ngx_shm_zone_t *shm_zone, time_t timeout)
  2692. {
  2693.     long  cache_mode;

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

  2695.     if (ngx_ssl_session_id_context(ssl, sess_ctx, certificates) != NGX_OK) {
  2696.         return NGX_ERROR;
  2697.     }

  2698.     if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
  2699.         SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
  2700.         return NGX_OK;
  2701.     }

  2702.     if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {

  2703.         /*
  2704.          * If the server explicitly says that it does not support
  2705.          * session reuse (see SSL_SESS_CACHE_OFF above), then
  2706.          * Outlook Express fails to upload a sent email to
  2707.          * the Sent Items folder on the IMAP server via a separate IMAP
  2708.          * connection in the background.  Therefore we have a special
  2709.          * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
  2710.          * where the server pretends that it supports session reuse,
  2711.          * but it does not actually store any session.
  2712.          */

  2713.         SSL_CTX_set_session_cache_mode(ssl->ctx,
  2714.                                        SSL_SESS_CACHE_SERVER
  2715.                                        |SSL_SESS_CACHE_NO_AUTO_CLEAR
  2716.                                        |SSL_SESS_CACHE_NO_INTERNAL_STORE);

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

  2718.         return NGX_OK;
  2719.     }

  2720.     cache_mode = SSL_SESS_CACHE_SERVER;

  2721.     if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
  2722.         cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
  2723.     }

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

  2725.     if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {

  2726.         if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
  2727.             SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
  2728.         }
  2729.     }

  2730.     if (shm_zone) {
  2731.         SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
  2732.         SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
  2733.         SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);

  2734.         if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone)
  2735.             == 0)
  2736.         {
  2737.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2738.                           "SSL_CTX_set_ex_data() failed");
  2739.             return NGX_ERROR;
  2740.         }
  2741.     }

  2742.     return NGX_OK;
  2743. }


  2744. static ngx_int_t
  2745. ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
  2746.     ngx_array_t *certificates)
  2747. {
  2748.     int                   n, i;
  2749.     X509                 *cert;
  2750.     X509_NAME            *name;
  2751.     ngx_str_t            *certs;
  2752.     ngx_uint_t            k;
  2753.     EVP_MD_CTX           *md;
  2754.     unsigned int          len;
  2755.     STACK_OF(X509_NAME)  *list;
  2756.     u_char                buf[EVP_MAX_MD_SIZE];

  2757.     /*
  2758.      * Session ID context is set based on the string provided,
  2759.      * the server certificates, and the client CA list.
  2760.      */

  2761.     md = EVP_MD_CTX_create();
  2762.     if (md == NULL) {
  2763.         return NGX_ERROR;
  2764.     }

  2765.     if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) {
  2766.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2767.                       "EVP_DigestInit_ex() failed");
  2768.         goto failed;
  2769.     }

  2770.     if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) {
  2771.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2772.                       "EVP_DigestUpdate() failed");
  2773.         goto failed;
  2774.     }

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

  2777.         if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
  2778.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2779.                           "X509_digest() failed");
  2780.             goto failed;
  2781.         }

  2782.         if (EVP_DigestUpdate(md, buf, len) == 0) {
  2783.             ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2784.                           "EVP_DigestUpdate() failed");
  2785.             goto failed;
  2786.         }
  2787.     }

  2788.     if (ssl->certs.nelts == 0 && certificates != NULL) {
  2789.         /*
  2790.          * If certificates are loaded dynamically, we use certificate
  2791.          * names as specified in the configuration (with variables).
  2792.          */

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

  2795.             if (EVP_DigestUpdate(md, certs[k].data, certs[k].len) == 0) {
  2796.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2797.                               "EVP_DigestUpdate() failed");
  2798.                 goto failed;
  2799.             }
  2800.         }
  2801.     }

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

  2803.     if (list != NULL) {
  2804.         n = sk_X509_NAME_num(list);

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

  2807.             if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
  2808.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2809.                               "X509_NAME_digest() failed");
  2810.                 goto failed;
  2811.             }

  2812.             if (EVP_DigestUpdate(md, buf, len) == 0) {
  2813.                 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2814.                               "EVP_DigestUpdate() failed");
  2815.                 goto failed;
  2816.             }
  2817.         }
  2818.     }

  2819.     if (EVP_DigestFinal_ex(md, buf, &len) == 0) {
  2820.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2821.                       "EVP_DigestFinal_ex() failed");
  2822.         goto failed;
  2823.     }

  2824.     EVP_MD_CTX_destroy(md);

  2825.     if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
  2826.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  2827.                       "SSL_CTX_set_session_id_context() failed");
  2828.         return NGX_ERROR;
  2829.     }

  2830.     return NGX_OK;

  2831. failed:

  2832.     EVP_MD_CTX_destroy(md);

  2833.     return NGX_ERROR;
  2834. }


  2835. ngx_int_t
  2836. ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  2837. {
  2838.     size_t                    len;
  2839.     ngx_slab_pool_t          *shpool;
  2840.     ngx_ssl_session_cache_t  *cache;

  2841.     if (data) {
  2842.         shm_zone->data = data;
  2843.         return NGX_OK;
  2844.     }

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

  2846.     if (shm_zone->shm.exists) {
  2847.         shm_zone->data = shpool->data;
  2848.         return NGX_OK;
  2849.     }

  2850.     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
  2851.     if (cache == NULL) {
  2852.         return NGX_ERROR;
  2853.     }

  2854.     shpool->data = cache;
  2855.     shm_zone->data = cache;

  2856.     ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
  2857.                     ngx_ssl_session_rbtree_insert_value);

  2858.     ngx_queue_init(&cache->expire_queue);

  2859.     cache->ticket_keys[0].expire = 0;
  2860.     cache->ticket_keys[1].expire = 0;
  2861.     cache->ticket_keys[2].expire = 0;

  2862.     cache->fail_time = 0;

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

  2864.     shpool->log_ctx = ngx_slab_alloc(shpool, len);
  2865.     if (shpool->log_ctx == NULL) {
  2866.         return NGX_ERROR;
  2867.     }

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

  2870.     shpool->log_nomem = 0;

  2871.     return NGX_OK;
  2872. }


  2873. /*
  2874. * The length of the session id is 16 bytes for SSLv2 sessions and
  2875. * between 1 and 32 bytes for SSLv3 and TLS, typically 32 bytes.
  2876. * Typical length of the external ASN1 representation of a session
  2877. * is about 150 bytes plus SNI server name.
  2878. *
  2879. * On 32-bit platforms we allocate an rbtree node, a session id, and
  2880. * an ASN1 representation in a single allocation, it typically takes
  2881. * 256 bytes.
  2882. *
  2883. * On 64-bit platforms we allocate separately an rbtree node + session_id,
  2884. * and an ASN1 representation, they take accordingly 128 and 256 bytes.
  2885. *
  2886. * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
  2887. * so they are outside the code locked by shared pool mutex
  2888. */

  2889. static int
  2890. ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
  2891. {
  2892.     int                       len;
  2893.     u_char                   *p, *session_id;
  2894.     size_t                    n;
  2895.     uint32_t                  hash;
  2896.     SSL_CTX                  *ssl_ctx;
  2897.     unsigned int              session_id_length;
  2898.     ngx_shm_zone_t           *shm_zone;
  2899.     ngx_connection_t         *c;
  2900.     ngx_slab_pool_t          *shpool;
  2901.     ngx_ssl_sess_id_t        *sess_id;
  2902.     ngx_ssl_session_cache_t  *cache;
  2903.     u_char                    buf[NGX_SSL_MAX_SESSION_SIZE];

  2904. #ifdef TLS1_3_VERSION

  2905.     /*
  2906.      * OpenSSL tries to save TLSv1.3 sessions into session cache
  2907.      * even when using tickets for stateless session resumption,
  2908.      * "because some applications just want to know about the creation
  2909.      * of a session"; do not cache such sessions
  2910.      */

  2911.     if (SSL_version(ssl_conn) == TLS1_3_VERSION
  2912.         && (SSL_get_options(ssl_conn) & SSL_OP_NO_TICKET) == 0)
  2913.     {
  2914.         return 0;
  2915.     }

  2916. #endif

  2917.     len = i2d_SSL_SESSION(sess, NULL);

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

  2919.     if (len > NGX_SSL_MAX_SESSION_SIZE) {
  2920.         return 0;
  2921.     }

  2922.     p = buf;
  2923.     i2d_SSL_SESSION(sess, &p);

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

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

  2926.     if (session_id_length > 32) {
  2927.         return 0;
  2928.     }

  2929.     c = ngx_ssl_get_connection(ssl_conn);

  2930.     ssl_ctx = c->ssl->session_ctx;
  2931.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  2932.     cache = shm_zone->data;
  2933.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  2934.     ngx_shmtx_lock(&shpool->mutex);

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

  2937. #if (NGX_PTR_SIZE == 8)
  2938.     n = sizeof(ngx_ssl_sess_id_t);
  2939. #else
  2940.     n = offsetof(ngx_ssl_sess_id_t, session) + len;
  2941. #endif

  2942.     sess_id = ngx_slab_alloc_locked(shpool, n);

  2943.     if (sess_id == NULL) {

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

  2945.         ngx_ssl_expire_sessions(cache, shpool, 0);

  2946.         sess_id = ngx_slab_alloc_locked(shpool, n);

  2947.         if (sess_id == NULL) {
  2948.             goto failed;
  2949.         }
  2950.     }

  2951. #if (NGX_PTR_SIZE == 8)

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

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

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

  2955.         ngx_ssl_expire_sessions(cache, shpool, 0);

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

  2957.         if (sess_id->session == NULL) {
  2958.             goto failed;
  2959.         }
  2960.     }

  2961. #endif

  2962.     ngx_memcpy(sess_id->session, buf, len);
  2963.     ngx_memcpy(sess_id->id, session_id, session_id_length);

  2964.     hash = ngx_crc32_short(session_id, session_id_length);

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

  2968.     sess_id->node.key = hash;
  2969.     sess_id->node.data = (u_char) session_id_length;
  2970.     sess_id->len = len;

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

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

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

  2974.     ngx_shmtx_unlock(&shpool->mutex);

  2975.     return 0;

  2976. failed:

  2977.     if (sess_id) {
  2978.         ngx_slab_free_locked(shpool, sess_id);
  2979.     }

  2980.     ngx_shmtx_unlock(&shpool->mutex);

  2981.     if (cache->fail_time != ngx_time()) {
  2982.         cache->fail_time = ngx_time();
  2983.         ngx_log_error(NGX_LOG_WARN, c->log, 0,
  2984.                       "could not allocate new session%s", shpool->log_ctx);
  2985.     }

  2986.     return 0;
  2987. }


  2988. static ngx_ssl_session_t *
  2989. ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
  2990. #if OPENSSL_VERSION_NUMBER >= 0x10100003L
  2991.     const
  2992. #endif
  2993.     u_char *id, int len, int *copy)
  2994. {
  2995.     size_t                    slen;
  2996.     uint32_t                  hash;
  2997.     ngx_int_t                 rc;
  2998.     const u_char             *p;
  2999.     ngx_shm_zone_t           *shm_zone;
  3000.     ngx_slab_pool_t          *shpool;
  3001.     ngx_rbtree_node_t        *node, *sentinel;
  3002.     ngx_ssl_session_t        *sess;
  3003.     ngx_ssl_sess_id_t        *sess_id;
  3004.     ngx_ssl_session_cache_t  *cache;
  3005.     u_char                    buf[NGX_SSL_MAX_SESSION_SIZE];
  3006.     ngx_connection_t         *c;

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

  3009.     c = ngx_ssl_get_connection(ssl_conn);

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

  3012.     shm_zone = SSL_CTX_get_ex_data(c->ssl->session_ctx,
  3013.                                    ngx_ssl_session_cache_index);

  3014.     cache = shm_zone->data;

  3015.     sess = NULL;

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

  3017.     ngx_shmtx_lock(&shpool->mutex);

  3018.     node = cache->session_rbtree.root;
  3019.     sentinel = cache->session_rbtree.sentinel;

  3020.     while (node != sentinel) {

  3021.         if (hash < node->key) {
  3022.             node = node->left;
  3023.             continue;
  3024.         }

  3025.         if (hash > node->key) {
  3026.             node = node->right;
  3027.             continue;
  3028.         }

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

  3030.         sess_id = (ngx_ssl_sess_id_t *) node;

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

  3033.         if (rc == 0) {

  3034.             if (sess_id->expire > ngx_time()) {
  3035.                 slen = sess_id->len;

  3036.                 ngx_memcpy(buf, sess_id->session, slen);

  3037.                 ngx_shmtx_unlock(&shpool->mutex);

  3038.                 p = buf;
  3039.                 sess = d2i_SSL_SESSION(NULL, &p, slen);

  3040.                 return sess;
  3041.             }

  3042.             ngx_queue_remove(&sess_id->queue);

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

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

  3045. #if (NGX_PTR_SIZE == 8)
  3046.             ngx_slab_free_locked(shpool, sess_id->session);
  3047. #endif
  3048.             ngx_slab_free_locked(shpool, sess_id);

  3049.             sess = NULL;

  3050.             goto done;
  3051.         }

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

  3054. done:

  3055.     ngx_shmtx_unlock(&shpool->mutex);

  3056.     return sess;
  3057. }


  3058. void
  3059. ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3060. {
  3061.     SSL_CTX_remove_session(ssl, sess);

  3062.     ngx_ssl_remove_session(ssl, sess);
  3063. }


  3064. static void
  3065. ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
  3066. {
  3067.     u_char                   *id;
  3068.     uint32_t                  hash;
  3069.     ngx_int_t                 rc;
  3070.     unsigned int              len;
  3071.     ngx_shm_zone_t           *shm_zone;
  3072.     ngx_slab_pool_t          *shpool;
  3073.     ngx_rbtree_node_t        *node, *sentinel;
  3074.     ngx_ssl_sess_id_t        *sess_id;
  3075.     ngx_ssl_session_cache_t  *cache;

  3076.     shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);

  3077.     if (shm_zone == NULL) {
  3078.         return;
  3079.     }

  3080.     cache = shm_zone->data;

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

  3082.     hash = ngx_crc32_short(id, len);

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

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

  3086.     ngx_shmtx_lock(&shpool->mutex);

  3087.     node = cache->session_rbtree.root;
  3088.     sentinel = cache->session_rbtree.sentinel;

  3089.     while (node != sentinel) {

  3090.         if (hash < node->key) {
  3091.             node = node->left;
  3092.             continue;
  3093.         }

  3094.         if (hash > node->key) {
  3095.             node = node->right;
  3096.             continue;
  3097.         }

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

  3099.         sess_id = (ngx_ssl_sess_id_t *) node;

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

  3101.         if (rc == 0) {

  3102.             ngx_queue_remove(&sess_id->queue);

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

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

  3105. #if (NGX_PTR_SIZE == 8)
  3106.             ngx_slab_free_locked(shpool, sess_id->session);
  3107. #endif
  3108.             ngx_slab_free_locked(shpool, sess_id);

  3109.             goto done;
  3110.         }

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

  3113. done:

  3114.     ngx_shmtx_unlock(&shpool->mutex);
  3115. }


  3116. static void
  3117. ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
  3118.     ngx_slab_pool_t *shpool, ngx_uint_t n)
  3119. {
  3120.     time_t              now;
  3121.     ngx_queue_t        *q;
  3122.     ngx_ssl_sess_id_t  *sess_id;

  3123.     now = ngx_time();

  3124.     while (n < 3) {

  3125.         if (ngx_queue_empty(&cache->expire_queue)) {
  3126.             return;
  3127.         }

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

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

  3130.         if (n++ != 0 && sess_id->expire > now) {
  3131.             return;
  3132.         }

  3133.         ngx_queue_remove(q);

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

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

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

  3138. #if (NGX_PTR_SIZE == 8)
  3139.         ngx_slab_free_locked(shpool, sess_id->session);
  3140. #endif
  3141.         ngx_slab_free_locked(shpool, sess_id);
  3142.     }
  3143. }


  3144. static void
  3145. ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
  3146.     ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
  3147. {
  3148.     ngx_rbtree_node_t  **p;
  3149.     ngx_ssl_sess_id_t   *sess_id, *sess_id_temp;

  3150.     for ( ;; ) {

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

  3152.             p = &temp->left;

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

  3154.             p = &temp->right;

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

  3156.             sess_id = (ngx_ssl_sess_id_t *) node;
  3157.             sess_id_temp = (ngx_ssl_sess_id_t *) temp;

  3158.             p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
  3159.                               (size_t) node->data, (size_t) temp->data)
  3160.                  < 0) ? &temp->left : &temp->right;
  3161.         }

  3162.         if (*p == sentinel) {
  3163.             break;
  3164.         }

  3165.         temp = *p;
  3166.     }

  3167.     *p = node;
  3168.     node->parent = temp;
  3169.     node->left = sentinel;
  3170.     node->right = sentinel;
  3171.     ngx_rbt_red(node);
  3172. }


  3173. #ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB

  3174. ngx_int_t
  3175. ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3176. {
  3177.     u_char                 buf[80];
  3178.     size_t                 size;
  3179.     ssize_t                n;
  3180.     ngx_str_t             *path;
  3181.     ngx_file_t             file;
  3182.     ngx_uint_t             i;
  3183.     ngx_array_t           *keys;
  3184.     ngx_file_info_t        fi;
  3185.     ngx_pool_cleanup_t    *cln;
  3186.     ngx_ssl_ticket_key_t  *key;

  3187.     if (paths == NULL
  3188.         && SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_session_cache_index) == NULL)
  3189.     {
  3190.         return NGX_OK;
  3191.     }

  3192.     keys = ngx_array_create(cf->pool, paths ? paths->nelts : 3,
  3193.                             sizeof(ngx_ssl_ticket_key_t));
  3194.     if (keys == NULL) {
  3195.         return NGX_ERROR;
  3196.     }

  3197.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  3198.     if (cln == NULL) {
  3199.         return NGX_ERROR;
  3200.     }

  3201.     cln->handler = ngx_ssl_ticket_keys_cleanup;
  3202.     cln->data = keys;

  3203.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ticket_keys_index, keys) == 0) {
  3204.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  3205.                       "SSL_CTX_set_ex_data() failed");
  3206.         return NGX_ERROR;
  3207.     }

  3208.     if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx, ngx_ssl_ticket_key_callback)
  3209.         == 0)
  3210.     {
  3211.         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
  3212.                       "nginx was built with Session Tickets support, however, "
  3213.                       "now it is linked dynamically to an OpenSSL library "
  3214.                       "which has no tlsext support, therefore Session Tickets "
  3215.                       "are not available");
  3216.         return NGX_OK;
  3217.     }

  3218.     if (paths == NULL) {

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

  3220.         key = ngx_array_push_n(keys, 3);
  3221.         key[0].shared = 1;
  3222.         key[0].expire = 0;
  3223.         key[1].shared = 1;
  3224.         key[1].expire = 0;
  3225.         key[2].shared = 1;
  3226.         key[2].expire = 0;

  3227.         return NGX_OK;
  3228.     }

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

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

  3234.         ngx_memzero(&file, sizeof(ngx_file_t));
  3235.         file.name = path[i];
  3236.         file.log = cf->log;

  3237.         file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
  3238.                                 NGX_FILE_OPEN, 0);

  3239.         if (file.fd == NGX_INVALID_FILE) {
  3240.             ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
  3241.                                ngx_open_file_n " \"%V\" failed", &file.name);
  3242.             return NGX_ERROR;
  3243.         }

  3244.         if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
  3245.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3246.                                ngx_fd_info_n " \"%V\" failed", &file.name);
  3247.             goto failed;
  3248.         }

  3249.         size = ngx_file_size(&fi);

  3250.         if (size != 48 && size != 80) {
  3251.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3252.                                "\"%V\" must be 48 or 80 bytes", &file.name);
  3253.             goto failed;
  3254.         }

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

  3256.         if (n == NGX_ERROR) {
  3257.             ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
  3258.                                ngx_read_file_n " \"%V\" failed", &file.name);
  3259.             goto failed;
  3260.         }

  3261.         if ((size_t) n != size) {
  3262.             ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
  3263.                                ngx_read_file_n " \"%V\" returned only "
  3264.                                "%z bytes instead of %uz", &file.name, n, size);
  3265.             goto failed;
  3266.         }

  3267.         key = ngx_array_push(keys);
  3268.         if (key == NULL) {
  3269.             goto failed;
  3270.         }

  3271.         key->shared = 0;
  3272.         key->expire = 1;

  3273.         if (size == 48) {
  3274.             key->size = 48;
  3275.             ngx_memcpy(key->name, buf, 16);
  3276.             ngx_memcpy(key->aes_key, buf + 16, 16);
  3277.             ngx_memcpy(key->hmac_key, buf + 32, 16);

  3278.         } else {
  3279.             key->size = 80;
  3280.             ngx_memcpy(key->name, buf, 16);
  3281.             ngx_memcpy(key->hmac_key, buf + 16, 32);
  3282.             ngx_memcpy(key->aes_key, buf + 48, 32);
  3283.         }

  3284.         if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3285.             ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3286.                           ngx_close_file_n " \"%V\" failed", &file.name);
  3287.         }

  3288.         ngx_explicit_memzero(&buf, 80);
  3289.     }

  3290.     return NGX_OK;

  3291. failed:

  3292.     if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
  3293.         ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
  3294.                       ngx_close_file_n " \"%V\" failed", &file.name);
  3295.     }

  3296.     ngx_explicit_memzero(&buf, 80);

  3297.     return NGX_ERROR;
  3298. }


  3299. static int
  3300. ngx_ssl_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
  3301.     unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
  3302.     HMAC_CTX *hctx, int enc)
  3303. {
  3304.     size_t                 size;
  3305.     SSL_CTX               *ssl_ctx;
  3306.     ngx_uint_t             i;
  3307.     ngx_array_t           *keys;
  3308.     ngx_connection_t      *c;
  3309.     ngx_ssl_ticket_key_t  *key;
  3310.     const EVP_MD          *digest;
  3311.     const EVP_CIPHER      *cipher;

  3312.     c = ngx_ssl_get_connection(ssl_conn);
  3313.     ssl_ctx = c->ssl->session_ctx;

  3314.     if (ngx_ssl_rotate_ticket_keys(ssl_ctx, c->log) != NGX_OK) {
  3315.         return -1;
  3316.     }

  3317. #ifdef OPENSSL_NO_SHA256
  3318.     digest = EVP_sha1();
  3319. #else
  3320.     digest = EVP_sha256();
  3321. #endif

  3322.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3323.     if (keys == NULL) {
  3324.         return -1;
  3325.     }

  3326.     key = keys->elts;

  3327.     if (enc == 1) {
  3328.         /* encrypt session ticket */

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

  3333.         if (key[0].size == 48) {
  3334.             cipher = EVP_aes_128_cbc();
  3335.             size = 16;

  3336.         } else {
  3337.             cipher = EVP_aes_256_cbc();
  3338.             size = 32;
  3339.         }

  3340.         if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
  3341.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "RAND_bytes() failed");
  3342.             return -1;
  3343.         }

  3344.         if (EVP_EncryptInit_ex(ectx, cipher, NULL, key[0].aes_key, iv) != 1) {
  3345.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3346.                           "EVP_EncryptInit_ex() failed");
  3347.             return -1;
  3348.         }

  3349. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3350.         if (HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL) != 1) {
  3351.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3352.             return -1;
  3353.         }
  3354. #else
  3355.         HMAC_Init_ex(hctx, key[0].hmac_key, size, digest, NULL);
  3356. #endif

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

  3358.         return 1;

  3359.     } else {
  3360.         /* decrypt session ticket */

  3361.         for (i = 0; i < keys->nelts; i++) {
  3362.             if (ngx_memcmp(name, key[i].name, 16) == 0) {
  3363.                 goto found;
  3364.             }
  3365.         }

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

  3369.         return 0;

  3370.     found:

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

  3374.         if (key[i].size == 48) {
  3375.             cipher = EVP_aes_128_cbc();
  3376.             size = 16;

  3377.         } else {
  3378.             cipher = EVP_aes_256_cbc();
  3379.             size = 32;
  3380.         }

  3381. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  3382.         if (HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL) != 1) {
  3383.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "HMAC_Init_ex() failed");
  3384.             return -1;
  3385.         }
  3386. #else
  3387.         HMAC_Init_ex(hctx, key[i].hmac_key, size, digest, NULL);
  3388. #endif

  3389.         if (EVP_DecryptInit_ex(ectx, cipher, NULL, key[i].aes_key, iv) != 1) {
  3390.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  3391.                           "EVP_DecryptInit_ex() failed");
  3392.             return -1;
  3393.         }

  3394.         /* renew if TLSv1.3 */

  3395. #ifdef TLS1_3_VERSION
  3396.         if (SSL_version(ssl_conn) == TLS1_3_VERSION) {
  3397.             return 2;
  3398.         }
  3399. #endif

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

  3401.         if (i != 0 && key[i].expire) {
  3402.             return 2;
  3403.         }

  3404.         return 1;
  3405.     }
  3406. }


  3407. static ngx_int_t
  3408. ngx_ssl_rotate_ticket_keys(SSL_CTX *ssl_ctx, ngx_log_t *log)
  3409. {
  3410.     time_t                    now, expire;
  3411.     ngx_array_t              *keys;
  3412.     ngx_shm_zone_t           *shm_zone;
  3413.     ngx_slab_pool_t          *shpool;
  3414.     ngx_ssl_ticket_key_t     *key;
  3415.     ngx_ssl_session_cache_t  *cache;
  3416.     u_char                    buf[80];

  3417.     keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ticket_keys_index);
  3418.     if (keys == NULL) {
  3419.         return NGX_OK;
  3420.     }

  3421.     key = keys->elts;

  3422.     if (!key[0].shared) {
  3423.         return NGX_OK;
  3424.     }

  3425.     /*
  3426.      * if we don't need to update expiration of the current key
  3427.      * and the previous key is still needed, don't sync with shared
  3428.      * memory to save some work; in the worst case other worker process
  3429.      * will switch to the next key, but this process will still be able
  3430.      * to decrypt tickets encrypted with it
  3431.      */

  3432.     now = ngx_time();
  3433.     expire = now + SSL_CTX_get_timeout(ssl_ctx);

  3434.     if (key[0].expire >= expire && key[1].expire >= now) {
  3435.         return NGX_OK;
  3436.     }

  3437.     shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);

  3438.     cache = shm_zone->data;
  3439.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

  3440.     ngx_shmtx_lock(&shpool->mutex);

  3441.     key = cache->ticket_keys;

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

  3443.         /* initialize the current key */

  3444.         if (RAND_bytes(buf, 80) != 1) {
  3445.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3446.             ngx_shmtx_unlock(&shpool->mutex);
  3447.             return NGX_ERROR;
  3448.         }

  3449.         key[0].shared = 1;
  3450.         key[0].expire = expire;
  3451.         key[0].size = 80;
  3452.         ngx_memcpy(key[0].name, buf, 16);
  3453.         ngx_memcpy(key[0].hmac_key, buf + 16, 32);
  3454.         ngx_memcpy(key[0].aes_key, buf + 48, 32);

  3455.         ngx_explicit_memzero(&buf, 80);

  3456.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3457.                        "ssl ticket key: \"%*xs\"",
  3458.                        (size_t) 16, key[0].name);

  3459.         /*
  3460.          * copy the current key to the next key, as initialization of
  3461.          * the previous key will replace the current key with the next
  3462.          * key
  3463.          */

  3464.         key[2] = key[0];
  3465.     }

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

  3467.         /*
  3468.          * if the previous key is no longer needed (or not initialized),
  3469.          * replace it with the current key, replace the current key with
  3470.          * the next key, and generate new next key
  3471.          */

  3472.         key[1] = key[0];
  3473.         key[0] = key[2];

  3474.         if (RAND_bytes(buf, 80) != 1) {
  3475.             ngx_ssl_error(NGX_LOG_ALERT, log, 0, "RAND_bytes() failed");
  3476.             ngx_shmtx_unlock(&shpool->mutex);
  3477.             return NGX_ERROR;
  3478.         }

  3479.         key[2].shared = 1;
  3480.         key[2].expire = 0;
  3481.         key[2].size = 80;
  3482.         ngx_memcpy(key[2].name, buf, 16);
  3483.         ngx_memcpy(key[2].hmac_key, buf + 16, 32);
  3484.         ngx_memcpy(key[2].aes_key, buf + 48, 32);

  3485.         ngx_explicit_memzero(&buf, 80);

  3486.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  3487.                        "ssl ticket key: \"%*xs\"",
  3488.                        (size_t) 16, key[2].name);
  3489.     }

  3490.     /*
  3491.      * update expiration of the current key: it is going to be needed
  3492.      * at least till the session being created expires
  3493.      */

  3494.     if (expire > key[0].expire) {
  3495.         key[0].expire = expire;
  3496.     }

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

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

  3500.     ngx_shmtx_unlock(&shpool->mutex);

  3501.     return NGX_OK;
  3502. }


  3503. static void
  3504. ngx_ssl_ticket_keys_cleanup(void *data)
  3505. {
  3506.     ngx_array_t  *keys = data;

  3507.     ngx_explicit_memzero(keys->elts,
  3508.                          keys->nelts * sizeof(ngx_ssl_ticket_key_t));
  3509. }

  3510. #else

  3511. ngx_int_t
  3512. ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
  3513. {
  3514.     if (paths) {
  3515.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  3516.                       "\"ssl_session_ticket_key\" ignored, not supported");
  3517.     }

  3518.     return NGX_OK;
  3519. }

  3520. #endif


  3521. void
  3522. ngx_ssl_cleanup_ctx(void *data)
  3523. {
  3524.     ngx_ssl_t  *ssl = data;

  3525.     X509        *cert;
  3526.     ngx_uint_t   i;

  3527.     for (i = 0; i < ssl->certs.nelts; i++) {
  3528.         cert = ((X509 **) ssl->certs.elts)[i];
  3529.         X509_free(cert);
  3530.     }

  3531.     SSL_CTX_free(ssl->ctx);
  3532. }


  3533. ngx_int_t
  3534. ngx_ssl_check_host(ngx_connection_t *c, ngx_str_t *name)
  3535. {
  3536.     X509   *cert;

  3537.     cert = SSL_get_peer_certificate(c->ssl->connection);
  3538.     if (cert == NULL) {
  3539.         return NGX_ERROR;
  3540.     }

  3541. #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

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

  3543.     if (name->len == 0) {
  3544.         goto failed;
  3545.     }

  3546.     if (X509_check_host(cert, (char *) name->data, name->len, 0, NULL) != 1) {
  3547.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3548.                        "X509_check_host(): no match");
  3549.         goto failed;
  3550.     }

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

  3553.     goto found;

  3554. #else
  3555.     {
  3556.     int                      n, i;
  3557.     X509_NAME               *sname;
  3558.     ASN1_STRING             *str;
  3559.     X509_NAME_ENTRY         *entry;
  3560.     GENERAL_NAME            *altname;
  3561.     STACK_OF(GENERAL_NAME)  *altnames;

  3562.     /*
  3563.      * As per RFC6125 and RFC2818, we check subjectAltName extension,
  3564.      * and if it's not present - commonName in Subject is checked.
  3565.      */

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

  3567.     if (altnames) {
  3568.         n = sk_GENERAL_NAME_num(altnames);

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

  3571.             if (altname->type != GEN_DNS) {
  3572.                 continue;
  3573.             }

  3574.             str = altname->d.dNSName;

  3575.             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3576.                            "SSL subjectAltName: \"%*s\"",
  3577.                            ASN1_STRING_length(str), ASN1_STRING_data(str));

  3578.             if (ngx_ssl_check_name(name, str) == NGX_OK) {
  3579.                 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3580.                                "SSL subjectAltName: match");
  3581.                 GENERAL_NAMES_free(altnames);
  3582.                 goto found;
  3583.             }
  3584.         }

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

  3587.         GENERAL_NAMES_free(altnames);
  3588.         goto failed;
  3589.     }

  3590.     /*
  3591.      * If there is no subjectAltName extension, check commonName
  3592.      * in Subject.  While RFC2818 requires to only check "most specific"
  3593.      * CN, both Apache and OpenSSL check all CNs, and so do we.
  3594.      */

  3595.     sname = X509_get_subject_name(cert);

  3596.     if (sname == NULL) {
  3597.         goto failed;
  3598.     }

  3599.     i = -1;
  3600.     for ( ;; ) {
  3601.         i = X509_NAME_get_index_by_NID(sname, NID_commonName, i);

  3602.         if (i < 0) {
  3603.             break;
  3604.         }

  3605.         entry = X509_NAME_get_entry(sname, i);
  3606.         str = X509_NAME_ENTRY_get_data(entry);

  3607.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3608.                        "SSL commonName: \"%*s\"",
  3609.                        ASN1_STRING_length(str), ASN1_STRING_data(str));

  3610.         if (ngx_ssl_check_name(name, str) == NGX_OK) {
  3611.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3612.                            "SSL commonName: match");
  3613.             goto found;
  3614.         }
  3615.     }

  3616.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  3617.                    "SSL commonName: no match");
  3618.     }
  3619. #endif

  3620. failed:

  3621.     X509_free(cert);
  3622.     return NGX_ERROR;

  3623. found:

  3624.     X509_free(cert);
  3625.     return NGX_OK;
  3626. }


  3627. #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT

  3628. static ngx_int_t
  3629. ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern)
  3630. {
  3631.     u_char  *s, *p, *end;
  3632.     size_t   slen, plen;

  3633.     s = name->data;
  3634.     slen = name->len;

  3635.     p = ASN1_STRING_data(pattern);
  3636.     plen = ASN1_STRING_length(pattern);

  3637.     if (slen == plen && ngx_strncasecmp(s, p, plen) == 0) {
  3638.         return NGX_OK;
  3639.     }

  3640.     if (plen > 2 && p[0] == '*' && p[1] == '.') {
  3641.         plen -= 1;
  3642.         p += 1;

  3643.         end = s + slen;
  3644.         s = ngx_strlchr(s, end, '.');

  3645.         if (s == NULL) {
  3646.             return NGX_ERROR;
  3647.         }

  3648.         slen = end - s;

  3649.         if (plen == slen && ngx_strncasecmp(s, p, plen) == 0) {
  3650.             return NGX_OK;
  3651.         }
  3652.     }

  3653.     return NGX_ERROR;
  3654. }

  3655. #endif


  3656. ngx_int_t
  3657. ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3658. {
  3659.     s->data = (u_char *) SSL_get_version(c->ssl->connection);
  3660.     return NGX_OK;
  3661. }


  3662. ngx_int_t
  3663. ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3664. {
  3665.     s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);
  3666.     return NGX_OK;
  3667. }


  3668. ngx_int_t
  3669. ngx_ssl_get_ciphers(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3670. {
  3671. #ifdef SSL_CTRL_GET_RAW_CIPHERLIST

  3672.     int                n, i, bytes;
  3673.     size_t             len;
  3674.     u_char            *ciphers, *p;
  3675.     const SSL_CIPHER  *cipher;

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

  3678.     if (n <= 0) {
  3679.         s->len = 0;
  3680.         return NGX_OK;
  3681.     }

  3682.     len = 0;
  3683.     n /= bytes;

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

  3686.         if (cipher) {
  3687.             len += ngx_strlen(SSL_CIPHER_get_name(cipher));

  3688.         } else {
  3689.             len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1);
  3690.         }

  3691.         len += sizeof(":") - 1;
  3692.     }

  3693.     s->data = ngx_pnalloc(pool, len);
  3694.     if (s->data == NULL) {
  3695.         return NGX_ERROR;
  3696.     }

  3697.     p = s->data;

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

  3700.         if (cipher) {
  3701.             p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher));

  3702.         } else {
  3703.             p = ngx_sprintf(p, "0x");
  3704.             p = ngx_hex_dump(p, ciphers + i * bytes, bytes);
  3705.         }

  3706.         *p++ = ':';
  3707.     }

  3708.     p--;

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

  3710. #else

  3711.     u_char  buf[4096];

  3712.     if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096)
  3713.         == NULL)
  3714.     {
  3715.         s->len = 0;
  3716.         return NGX_OK;
  3717.     }

  3718.     s->len = ngx_strlen(buf);
  3719.     s->data = ngx_pnalloc(pool, s->len);
  3720.     if (s->data == NULL) {
  3721.         return NGX_ERROR;
  3722.     }

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

  3724. #endif

  3725.     return NGX_OK;
  3726. }


  3727. ngx_int_t
  3728. ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3729. {
  3730. #ifdef SSL_get_negotiated_group

  3731.     int  nid;

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

  3733.     if (nid != NID_undef) {

  3734.         if ((nid & TLSEXT_nid_unknown) == 0) {
  3735.             s->len = ngx_strlen(OBJ_nid2sn(nid));
  3736.             s->data = (u_char *) OBJ_nid2sn(nid);
  3737.             return NGX_OK;
  3738.         }

  3739.         s->len = sizeof("0x0000") - 1;

  3740.         s->data = ngx_pnalloc(pool, s->len);
  3741.         if (s->data == NULL) {
  3742.             return NGX_ERROR;
  3743.         }

  3744.         ngx_sprintf(s->data, "0x%04xd", nid & 0xffff);

  3745.         return NGX_OK;
  3746.     }

  3747. #endif

  3748.     s->len = 0;
  3749.     return NGX_OK;
  3750. }


  3751. ngx_int_t
  3752. ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3753. {
  3754. #ifdef SSL_CTRL_GET_CURVES

  3755.     int         *curves, n, i, nid;
  3756.     u_char      *p;
  3757.     size_t       len;

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

  3759.     if (n <= 0) {
  3760.         s->len = 0;
  3761.         return NGX_OK;
  3762.     }

  3763.     curves = ngx_palloc(pool, n * sizeof(int));
  3764.     if (curves == NULL) {
  3765.         return NGX_ERROR;
  3766.     }

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

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

  3771.         if (nid & TLSEXT_nid_unknown) {
  3772.             len += sizeof("0x0000") - 1;

  3773.         } else {
  3774.             len += ngx_strlen(OBJ_nid2sn(nid));
  3775.         }

  3776.         len += sizeof(":") - 1;
  3777.     }

  3778.     s->data = ngx_pnalloc(pool, len);
  3779.     if (s->data == NULL) {
  3780.         return NGX_ERROR;
  3781.     }

  3782.     p = s->data;

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

  3785.         if (nid & TLSEXT_nid_unknown) {
  3786.             p = ngx_sprintf(p, "0x%04xd", nid & 0xffff);

  3787.         } else {
  3788.             p = ngx_sprintf(p, "%s", OBJ_nid2sn(nid));
  3789.         }

  3790.         *p++ = ':';
  3791.     }

  3792.     p--;

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

  3794. #else

  3795.     s->len = 0;

  3796. #endif

  3797.     return NGX_OK;
  3798. }


  3799. ngx_int_t
  3800. ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3801. {
  3802.     u_char        *buf;
  3803.     SSL_SESSION   *sess;
  3804.     unsigned int   len;

  3805.     sess = SSL_get0_session(c->ssl->connection);
  3806.     if (sess == NULL) {
  3807.         s->len = 0;
  3808.         return NGX_OK;
  3809.     }

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

  3811.     s->len = 2 * len;
  3812.     s->data = ngx_pnalloc(pool, 2 * len);
  3813.     if (s->data == NULL) {
  3814.         return NGX_ERROR;
  3815.     }

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

  3817.     return NGX_OK;
  3818. }


  3819. ngx_int_t
  3820. ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3821. {
  3822.     if (SSL_session_reused(c->ssl->connection)) {
  3823.         ngx_str_set(s, "r");

  3824.     } else {
  3825.         ngx_str_set(s, ".");
  3826.     }

  3827.     return NGX_OK;
  3828. }


  3829. ngx_int_t
  3830. ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3831. {
  3832.     s->len = 0;

  3833. #ifdef SSL_ERROR_EARLY_DATA_REJECTED

  3834.     /* BoringSSL */

  3835.     if (SSL_in_early_data(c->ssl->connection)) {
  3836.         ngx_str_set(s, "1");
  3837.     }

  3838. #elif defined SSL_READ_EARLY_DATA_SUCCESS

  3839.     /* OpenSSL */

  3840.     if (!SSL_is_init_finished(c->ssl->connection)) {
  3841.         ngx_str_set(s, "1");
  3842.     }

  3843. #endif

  3844.     return NGX_OK;
  3845. }


  3846. ngx_int_t
  3847. ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3848. {
  3849. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  3850.     size_t       len;
  3851.     const char  *name;

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

  3853.     if (name) {
  3854.         len = ngx_strlen(name);

  3855.         s->len = len;
  3856.         s->data = ngx_pnalloc(pool, len);
  3857.         if (s->data == NULL) {
  3858.             return NGX_ERROR;
  3859.         }

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

  3861.         return NGX_OK;
  3862.     }

  3863. #endif

  3864.     s->len = 0;
  3865.     return NGX_OK;
  3866. }


  3867. ngx_int_t
  3868. ngx_ssl_get_alpn_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3869. {
  3870. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation

  3871.     unsigned int          len;
  3872.     const unsigned char  *data;

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

  3874.     if (len > 0) {

  3875.         s->data = ngx_pnalloc(pool, len);
  3876.         if (s->data == NULL) {
  3877.             return NGX_ERROR;
  3878.         }

  3879.         ngx_memcpy(s->data, data, len);
  3880.         s->len = len;

  3881.         return NGX_OK;
  3882.     }

  3883. #endif

  3884.     s->len = 0;
  3885.     return NGX_OK;
  3886. }


  3887. ngx_int_t
  3888. ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3889. {
  3890.     size_t   len;
  3891.     BIO     *bio;
  3892.     X509    *cert;

  3893.     s->len = 0;

  3894.     cert = SSL_get_peer_certificate(c->ssl->connection);
  3895.     if (cert == NULL) {
  3896.         return NGX_OK;
  3897.     }

  3898.     bio = BIO_new(BIO_s_mem());
  3899.     if (bio == NULL) {
  3900.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  3901.         X509_free(cert);
  3902.         return NGX_ERROR;
  3903.     }

  3904.     if (PEM_write_bio_X509(bio, cert) == 0) {
  3905.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
  3906.         goto failed;
  3907.     }

  3908.     len = BIO_pending(bio);
  3909.     s->len = len;

  3910.     s->data = ngx_pnalloc(pool, len);
  3911.     if (s->data == NULL) {
  3912.         goto failed;
  3913.     }

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

  3915.     BIO_free(bio);
  3916.     X509_free(cert);

  3917.     return NGX_OK;

  3918. failed:

  3919.     BIO_free(bio);
  3920.     X509_free(cert);

  3921.     return NGX_ERROR;
  3922. }


  3923. ngx_int_t
  3924. ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3925. {
  3926.     u_char      *p;
  3927.     size_t       len;
  3928.     ngx_uint_t   i;
  3929.     ngx_str_t    cert;

  3930.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  3931.         return NGX_ERROR;
  3932.     }

  3933.     if (cert.len == 0) {
  3934.         s->len = 0;
  3935.         return NGX_OK;
  3936.     }

  3937.     len = cert.len - 1;

  3938.     for (i = 0; i < cert.len - 1; i++) {
  3939.         if (cert.data[i] == LF) {
  3940.             len++;
  3941.         }
  3942.     }

  3943.     s->len = len;
  3944.     s->data = ngx_pnalloc(pool, len);
  3945.     if (s->data == NULL) {
  3946.         return NGX_ERROR;
  3947.     }

  3948.     p = s->data;

  3949.     for (i = 0; i < cert.len - 1; i++) {
  3950.         *p++ = cert.data[i];
  3951.         if (cert.data[i] == LF) {
  3952.             *p++ = '\t';
  3953.         }
  3954.     }

  3955.     return NGX_OK;
  3956. }


  3957. ngx_int_t
  3958. ngx_ssl_get_escaped_certificate(ngx_connection_t *c, ngx_pool_t *pool,
  3959.     ngx_str_t *s)
  3960. {
  3961.     ngx_str_t  cert;
  3962.     uintptr_t  n;

  3963.     if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
  3964.         return NGX_ERROR;
  3965.     }

  3966.     if (cert.len == 0) {
  3967.         s->len = 0;
  3968.         return NGX_OK;
  3969.     }

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

  3971.     s->len = cert.len + n * 2;
  3972.     s->data = ngx_pnalloc(pool, s->len);
  3973.     if (s->data == NULL) {
  3974.         return NGX_ERROR;
  3975.     }

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

  3977.     return NGX_OK;
  3978. }


  3979. ngx_int_t
  3980. ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  3981. {
  3982.     BIO        *bio;
  3983.     X509       *cert;
  3984.     X509_NAME  *name;

  3985.     s->len = 0;

  3986.     cert = SSL_get_peer_certificate(c->ssl->connection);
  3987.     if (cert == NULL) {
  3988.         return NGX_OK;
  3989.     }

  3990.     name = X509_get_subject_name(cert);
  3991.     if (name == NULL) {
  3992.         X509_free(cert);
  3993.         return NGX_ERROR;
  3994.     }

  3995.     bio = BIO_new(BIO_s_mem());
  3996.     if (bio == NULL) {
  3997.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  3998.         X509_free(cert);
  3999.         return NGX_ERROR;
  4000.     }

  4001.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4002.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4003.         goto failed;
  4004.     }

  4005.     s->len = BIO_pending(bio);
  4006.     s->data = ngx_pnalloc(pool, s->len);
  4007.     if (s->data == NULL) {
  4008.         goto failed;
  4009.     }

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

  4011.     BIO_free(bio);
  4012.     X509_free(cert);

  4013.     return NGX_OK;

  4014. failed:

  4015.     BIO_free(bio);
  4016.     X509_free(cert);

  4017.     return NGX_ERROR;
  4018. }


  4019. ngx_int_t
  4020. ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4021. {
  4022.     BIO        *bio;
  4023.     X509       *cert;
  4024.     X509_NAME  *name;

  4025.     s->len = 0;

  4026.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4027.     if (cert == NULL) {
  4028.         return NGX_OK;
  4029.     }

  4030.     name = X509_get_issuer_name(cert);
  4031.     if (name == NULL) {
  4032.         X509_free(cert);
  4033.         return NGX_ERROR;
  4034.     }

  4035.     bio = BIO_new(BIO_s_mem());
  4036.     if (bio == NULL) {
  4037.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4038.         X509_free(cert);
  4039.         return NGX_ERROR;
  4040.     }

  4041.     if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
  4042.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
  4043.         goto failed;
  4044.     }

  4045.     s->len = BIO_pending(bio);
  4046.     s->data = ngx_pnalloc(pool, s->len);
  4047.     if (s->data == NULL) {
  4048.         goto failed;
  4049.     }

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

  4051.     BIO_free(bio);
  4052.     X509_free(cert);

  4053.     return NGX_OK;

  4054. failed:

  4055.     BIO_free(bio);
  4056.     X509_free(cert);

  4057.     return NGX_ERROR;
  4058. }


  4059. ngx_int_t
  4060. ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4061.     ngx_str_t *s)
  4062. {
  4063.     char       *p;
  4064.     size_t      len;
  4065.     X509       *cert;
  4066.     X509_NAME  *name;

  4067.     s->len = 0;

  4068.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4069.     if (cert == NULL) {
  4070.         return NGX_OK;
  4071.     }

  4072.     name = X509_get_subject_name(cert);
  4073.     if (name == NULL) {
  4074.         X509_free(cert);
  4075.         return NGX_ERROR;
  4076.     }

  4077.     p = X509_NAME_oneline(name, NULL, 0);
  4078.     if (p == NULL) {
  4079.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4080.         X509_free(cert);
  4081.         return NGX_ERROR;
  4082.     }

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

  4084.     s->len = len;
  4085.     s->data = ngx_pnalloc(pool, len);
  4086.     if (s->data == NULL) {
  4087.         OPENSSL_free(p);
  4088.         X509_free(cert);
  4089.         return NGX_ERROR;
  4090.     }

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

  4092.     OPENSSL_free(p);
  4093.     X509_free(cert);

  4094.     return NGX_OK;
  4095. }


  4096. ngx_int_t
  4097. ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
  4098.     ngx_str_t *s)
  4099. {
  4100.     char       *p;
  4101.     size_t      len;
  4102.     X509       *cert;
  4103.     X509_NAME  *name;

  4104.     s->len = 0;

  4105.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4106.     if (cert == NULL) {
  4107.         return NGX_OK;
  4108.     }

  4109.     name = X509_get_issuer_name(cert);
  4110.     if (name == NULL) {
  4111.         X509_free(cert);
  4112.         return NGX_ERROR;
  4113.     }

  4114.     p = X509_NAME_oneline(name, NULL, 0);
  4115.     if (p == NULL) {
  4116.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
  4117.         X509_free(cert);
  4118.         return NGX_ERROR;
  4119.     }

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

  4121.     s->len = len;
  4122.     s->data = ngx_pnalloc(pool, len);
  4123.     if (s->data == NULL) {
  4124.         OPENSSL_free(p);
  4125.         X509_free(cert);
  4126.         return NGX_ERROR;
  4127.     }

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

  4129.     OPENSSL_free(p);
  4130.     X509_free(cert);

  4131.     return NGX_OK;
  4132. }


  4133. ngx_int_t
  4134. ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4135. {
  4136.     size_t   len;
  4137.     X509    *cert;
  4138.     BIO     *bio;

  4139.     s->len = 0;

  4140.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4141.     if (cert == NULL) {
  4142.         return NGX_OK;
  4143.     }

  4144.     bio = BIO_new(BIO_s_mem());
  4145.     if (bio == NULL) {
  4146.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4147.         X509_free(cert);
  4148.         return NGX_ERROR;
  4149.     }

  4150.     i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
  4151.     len = BIO_pending(bio);

  4152.     s->len = len;
  4153.     s->data = ngx_pnalloc(pool, len);
  4154.     if (s->data == NULL) {
  4155.         BIO_free(bio);
  4156.         X509_free(cert);
  4157.         return NGX_ERROR;
  4158.     }

  4159.     BIO_read(bio, s->data, len);
  4160.     BIO_free(bio);
  4161.     X509_free(cert);

  4162.     return NGX_OK;
  4163. }


  4164. ngx_int_t
  4165. ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4166. {
  4167.     X509          *cert;
  4168.     unsigned int   len;
  4169.     u_char         buf[EVP_MAX_MD_SIZE];

  4170.     s->len = 0;

  4171.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4172.     if (cert == NULL) {
  4173.         return NGX_OK;
  4174.     }

  4175.     if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
  4176.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed");
  4177.         X509_free(cert);
  4178.         return NGX_ERROR;
  4179.     }

  4180.     s->len = 2 * len;
  4181.     s->data = ngx_pnalloc(pool, 2 * len);
  4182.     if (s->data == NULL) {
  4183.         X509_free(cert);
  4184.         return NGX_ERROR;
  4185.     }

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

  4187.     X509_free(cert);

  4188.     return NGX_OK;
  4189. }


  4190. ngx_int_t
  4191. ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4192. {
  4193.     X509        *cert;
  4194.     long         rc;
  4195.     const char  *str;

  4196.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4197.     if (cert == NULL) {
  4198.         ngx_str_set(s, "NONE");
  4199.         return NGX_OK;
  4200.     }

  4201.     X509_free(cert);

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

  4203.     if (rc == X509_V_OK) {
  4204.         if (ngx_ssl_ocsp_get_status(c, &str) == NGX_OK) {
  4205.             ngx_str_set(s, "SUCCESS");
  4206.             return NGX_OK;
  4207.         }

  4208.     } else {
  4209.         str = X509_verify_cert_error_string(rc);
  4210.     }

  4211.     s->data = ngx_pnalloc(pool, sizeof("FAILED:") - 1 + ngx_strlen(str));
  4212.     if (s->data == NULL) {
  4213.         return NGX_ERROR;
  4214.     }

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

  4216.     return NGX_OK;
  4217. }


  4218. ngx_int_t
  4219. ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4220. {
  4221.     BIO     *bio;
  4222.     X509    *cert;
  4223.     size_t   len;

  4224.     s->len = 0;

  4225.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4226.     if (cert == NULL) {
  4227.         return NGX_OK;
  4228.     }

  4229.     bio = BIO_new(BIO_s_mem());
  4230.     if (bio == NULL) {
  4231.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4232.         X509_free(cert);
  4233.         return NGX_ERROR;
  4234.     }

  4235. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4236.     ASN1_TIME_print(bio, X509_get0_notBefore(cert));
  4237. #else
  4238.     ASN1_TIME_print(bio, X509_get_notBefore(cert));
  4239. #endif

  4240.     len = BIO_pending(bio);

  4241.     s->len = len;
  4242.     s->data = ngx_pnalloc(pool, len);
  4243.     if (s->data == NULL) {
  4244.         BIO_free(bio);
  4245.         X509_free(cert);
  4246.         return NGX_ERROR;
  4247.     }

  4248.     BIO_read(bio, s->data, len);
  4249.     BIO_free(bio);
  4250.     X509_free(cert);

  4251.     return NGX_OK;
  4252. }


  4253. ngx_int_t
  4254. ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4255. {
  4256.     BIO     *bio;
  4257.     X509    *cert;
  4258.     size_t   len;

  4259.     s->len = 0;

  4260.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4261.     if (cert == NULL) {
  4262.         return NGX_OK;
  4263.     }

  4264.     bio = BIO_new(BIO_s_mem());
  4265.     if (bio == NULL) {
  4266.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
  4267.         X509_free(cert);
  4268.         return NGX_ERROR;
  4269.     }

  4270. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4271.     ASN1_TIME_print(bio, X509_get0_notAfter(cert));
  4272. #else
  4273.     ASN1_TIME_print(bio, X509_get_notAfter(cert));
  4274. #endif

  4275.     len = BIO_pending(bio);

  4276.     s->len = len;
  4277.     s->data = ngx_pnalloc(pool, len);
  4278.     if (s->data == NULL) {
  4279.         BIO_free(bio);
  4280.         X509_free(cert);
  4281.         return NGX_ERROR;
  4282.     }

  4283.     BIO_read(bio, s->data, len);
  4284.     BIO_free(bio);
  4285.     X509_free(cert);

  4286.     return NGX_OK;
  4287. }


  4288. ngx_int_t
  4289. ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
  4290. {
  4291.     X509    *cert;
  4292.     time_t   now, end;

  4293.     s->len = 0;

  4294.     cert = SSL_get_peer_certificate(c->ssl->connection);
  4295.     if (cert == NULL) {
  4296.         return NGX_OK;
  4297.     }

  4298. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4299.     end = ngx_ssl_parse_time(X509_get0_notAfter(cert), c->log);
  4300. #else
  4301.     end = ngx_ssl_parse_time(X509_get_notAfter(cert), c->log);
  4302. #endif

  4303.     if (end == (time_t) NGX_ERROR) {
  4304.         X509_free(cert);
  4305.         return NGX_OK;
  4306.     }

  4307.     now = ngx_time();

  4308.     if (end < now + 86400) {
  4309.         ngx_str_set(s, "0");
  4310.         X509_free(cert);
  4311.         return NGX_OK;
  4312.     }

  4313.     s->data = ngx_pnalloc(pool, NGX_TIME_T_LEN);
  4314.     if (s->data == NULL) {
  4315.         X509_free(cert);
  4316.         return NGX_ERROR;
  4317.     }

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

  4319.     X509_free(cert);

  4320.     return NGX_OK;
  4321. }


  4322. static time_t
  4323. ngx_ssl_parse_time(
  4324. #if OPENSSL_VERSION_NUMBER > 0x10100000L
  4325.     const
  4326. #endif
  4327.     ASN1_TIME *asn1time, ngx_log_t *log)
  4328. {
  4329.     BIO     *bio;
  4330.     char    *value;
  4331.     size_t   len;
  4332.     time_t   time;

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

  4339.     bio = BIO_new(BIO_s_mem());
  4340.     if (bio == NULL) {
  4341.         ngx_ssl_error(NGX_LOG_ALERT, log, 0, "BIO_new() failed");
  4342.         return NGX_ERROR;
  4343.     }

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

  4345.     BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
  4346.     ASN1_TIME_print(bio, asn1time);
  4347.     len = BIO_get_mem_data(bio, &value);

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

  4349.     BIO_free(bio);

  4350.     return time;
  4351. }


  4352. static void *
  4353. ngx_openssl_create_conf(ngx_cycle_t *cycle)
  4354. {
  4355.     ngx_openssl_conf_t  *oscf;

  4356.     oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
  4357.     if (oscf == NULL) {
  4358.         return NULL;
  4359.     }

  4360.     /*
  4361.      * set by ngx_pcalloc():
  4362.      *
  4363.      *     oscf->engine = 0;
  4364.      */

  4365.     return oscf;
  4366. }


  4367. static char *
  4368. ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4369. {
  4370. #ifndef OPENSSL_NO_ENGINE

  4371.     ngx_openssl_conf_t *oscf = conf;

  4372.     ENGINE     *engine;
  4373.     ngx_str_t  *value;

  4374.     if (oscf->engine) {
  4375.         return "is duplicate";
  4376.     }

  4377.     oscf->engine = 1;

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

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

  4380.     if (engine == NULL) {
  4381.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  4382.                       "ENGINE_by_id(\"%V\") failed", &value[1]);
  4383.         return NGX_CONF_ERROR;
  4384.     }

  4385.     if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
  4386.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  4387.                       "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",
  4388.                       &value[1]);

  4389.         ENGINE_free(engine);

  4390.         return NGX_CONF_ERROR;
  4391.     }

  4392.     ENGINE_free(engine);

  4393.     return NGX_CONF_OK;

  4394. #else

  4395.     return "is not supported";

  4396. #endif
  4397. }


  4398. static void
  4399. ngx_openssl_exit(ngx_cycle_t *cycle)
  4400. {
  4401. #if OPENSSL_VERSION_NUMBER < 0x10100003L

  4402.     EVP_cleanup();
  4403. #ifndef OPENSSL_NO_ENGINE
  4404.     ENGINE_cleanup();
  4405. #endif

  4406. #endif
  4407. }