src/event/ngx_event_openssl_stapling.c - nginx source code

Data types defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Maxim Dounin
  3. * Copyright (C) Nginx, Inc.
  4. */


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


  9. #if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)


  10. typedef struct {
  11.     ngx_rbtree_node_t            node;

  12.     ngx_str_t                    staple;
  13.     ngx_msec_t                   timeout;

  14.     ngx_resolver_t              *resolver;
  15.     ngx_msec_t                   resolver_timeout;

  16.     ngx_addr_t                  *addrs;
  17.     ngx_uint_t                   naddrs;
  18.     ngx_str_t                    host;
  19.     ngx_str_t                    uri;
  20.     in_port_t                    port;

  21.     SSL_CTX                     *ssl_ctx;

  22.     X509                        *cert;
  23.     X509                        *issuer;
  24.     STACK_OF(X509)              *chain;

  25.     u_char                      *name;

  26.     time_t                       valid;
  27.     time_t                       refresh;

  28.     unsigned                     verify:1;
  29.     unsigned                     loading:1;
  30. } ngx_ssl_stapling_t;


  31. typedef struct {
  32.     ngx_addr_t                  *addrs;
  33.     ngx_uint_t                   naddrs;

  34.     ngx_str_t                    host;
  35.     ngx_str_t                    uri;
  36.     in_port_t                    port;
  37.     ngx_uint_t                   depth;

  38.     ngx_shm_zone_t              *shm_zone;

  39.     ngx_resolver_t              *resolver;
  40.     ngx_msec_t                   resolver_timeout;
  41. } ngx_ssl_ocsp_conf_t;


  42. typedef struct {
  43.     ngx_rbtree_t                 rbtree;
  44.     ngx_rbtree_node_t            sentinel;
  45.     ngx_queue_t                  expire_queue;
  46. } ngx_ssl_ocsp_cache_t;


  47. typedef struct {
  48.     ngx_str_node_t               node;
  49.     ngx_queue_t                  queue;
  50.     int                          status;
  51.     time_t                       valid;
  52. } ngx_ssl_ocsp_cache_node_t;


  53. typedef struct ngx_ssl_ocsp_ctx_s  ngx_ssl_ocsp_ctx_t;


  54. struct ngx_ssl_ocsp_s {
  55.     STACK_OF(X509)              *certs;
  56.     ngx_uint_t                   ncert;

  57.     int                          cert_status;
  58.     ngx_int_t                    status;

  59.     ngx_ssl_ocsp_conf_t         *conf;
  60.     ngx_ssl_ocsp_ctx_t          *ctx;
  61. };


  62. struct ngx_ssl_ocsp_ctx_s {
  63.     SSL_CTX                     *ssl_ctx;

  64.     X509                        *cert;
  65.     X509                        *issuer;
  66.     STACK_OF(X509)              *chain;

  67.     int                          status;
  68.     time_t                       valid;

  69.     u_char                      *name;

  70.     ngx_uint_t                   naddrs;
  71.     ngx_uint_t                   naddr;

  72.     ngx_addr_t                  *addrs;
  73.     ngx_str_t                    host;
  74.     ngx_str_t                    uri;
  75.     in_port_t                    port;

  76.     ngx_resolver_t              *resolver;
  77.     ngx_msec_t                   resolver_timeout;

  78.     ngx_msec_t                   timeout;

  79.     void                       (*handler)(ngx_ssl_ocsp_ctx_t *ctx);
  80.     void                        *data;

  81.     ngx_str_t                    key;
  82.     ngx_buf_t                   *request;
  83.     ngx_buf_t                   *response;
  84.     ngx_peer_connection_t        peer;

  85.     ngx_shm_zone_t              *shm_zone;

  86.     ngx_int_t                  (*process)(ngx_ssl_ocsp_ctx_t *ctx);

  87.     ngx_uint_t                   state;

  88.     ngx_uint_t                   code;
  89.     ngx_uint_t                   count;
  90.     ngx_uint_t                   flags;
  91.     ngx_uint_t                   done;

  92.     u_char                      *header_name_start;
  93.     u_char                      *header_name_end;
  94.     u_char                      *header_start;
  95.     u_char                      *header_end;

  96.     ngx_pool_t                  *pool;
  97.     ngx_log_t                   *log;
  98. };


  99. static ngx_int_t ngx_ssl_stapling_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
  100.     X509 *cert, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify);
  101. static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl,
  102.     ngx_ssl_stapling_t *staple, ngx_str_t *file);
  103. static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl,
  104.     ngx_ssl_stapling_t *staple);
  105. static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl,
  106.     ngx_ssl_stapling_t *staple, ngx_str_t *responder);

  107. static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn,
  108.     void *data);
  109. static ngx_ssl_stapling_t *ngx_ssl_stapling_lookup(ngx_ssl_t *ssl, X509 *cert);
  110. static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
  111. static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);

  112. static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time);

  113. static void ngx_ssl_stapling_cleanup(void *data);

  114. static void ngx_ssl_ocsp_validate_next(ngx_connection_t *c);
  115. static void ngx_ssl_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
  116. static ngx_int_t ngx_ssl_ocsp_responder(ngx_connection_t *c,
  117.     ngx_ssl_ocsp_ctx_t *ctx);

  118. static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(ngx_log_t *log);
  119. static void ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx);
  120. static void ngx_ssl_ocsp_next(ngx_ssl_ocsp_ctx_t *ctx);
  121. static void ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx);
  122. static void ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve);
  123. static void ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx);
  124. static void ngx_ssl_ocsp_write_handler(ngx_event_t *wev);
  125. static void ngx_ssl_ocsp_read_handler(ngx_event_t *rev);
  126. static void ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev);

  127. static ngx_int_t ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx);
  128. static ngx_int_t ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx);
  129. static ngx_int_t ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx);
  130. static ngx_int_t ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx);
  131. static ngx_int_t ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx);
  132. static ngx_int_t ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx);
  133. static ngx_int_t ngx_ssl_ocsp_verify(ngx_ssl_ocsp_ctx_t *ctx);

  134. static ngx_int_t ngx_ssl_ocsp_cache_lookup(ngx_ssl_ocsp_ctx_t *ctx);
  135. static ngx_int_t ngx_ssl_ocsp_cache_store(ngx_ssl_ocsp_ctx_t *ctx);
  136. static ngx_int_t ngx_ssl_ocsp_create_key(ngx_ssl_ocsp_ctx_t *ctx);

  137. static u_char *ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len);


  138. ngx_int_t
  139. ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
  140.     ngx_str_t *responder, ngx_uint_t verify)
  141. {
  142.     X509        *cert;
  143.     ngx_uint_t   k;

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

  146.         if (ngx_ssl_stapling_certificate(cf, ssl, cert, file, responder, verify)
  147.             != NGX_OK)
  148.         {
  149.             return NGX_ERROR;
  150.         }
  151.     }

  152.     SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback);

  153.     return NGX_OK;
  154. }


  155. static ngx_int_t
  156. ngx_ssl_stapling_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, X509 *cert,
  157.     ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify)
  158. {
  159.     ngx_int_t            rc;
  160.     ngx_pool_cleanup_t  *cln;
  161.     ngx_ssl_stapling_t  *staple;

  162.     staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t));
  163.     if (staple == NULL) {
  164.         return NGX_ERROR;
  165.     }

  166.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  167.     if (cln == NULL) {
  168.         return NGX_ERROR;
  169.     }

  170.     cln->handler = ngx_ssl_stapling_cleanup;
  171.     cln->data = staple;

  172.     staple->node.key = (ngx_rbtree_key_t) cert;

  173.     ngx_rbtree_insert(&ssl->staple_rbtree, &staple->node);

  174. #ifdef SSL_CTRL_SELECT_CURRENT_CERT
  175.     /* OpenSSL 1.0.2+ */
  176.     SSL_CTX_select_current_cert(ssl->ctx, cert);
  177. #endif

  178. #ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
  179.     /* OpenSSL 1.0.1+ */
  180.     SSL_CTX_get_extra_chain_certs(ssl->ctx, &staple->chain);
  181. #else
  182.     staple->chain = ssl->ctx->extra_certs;
  183. #endif

  184.     staple->ssl_ctx = ssl->ctx;
  185.     staple->timeout = 60000;
  186.     staple->verify = verify;
  187.     staple->cert = cert;
  188.     staple->name = X509_get_ex_data(staple->cert,
  189.                                     ngx_ssl_certificate_name_index);

  190.     if (file->len) {
  191.         /* use OCSP response from the file */

  192.         if (ngx_ssl_stapling_file(cf, ssl, staple, file) != NGX_OK) {
  193.             return NGX_ERROR;
  194.         }

  195.         return NGX_OK;
  196.     }

  197.     rc = ngx_ssl_stapling_issuer(cf, ssl, staple);

  198.     if (rc == NGX_DECLINED) {
  199.         return NGX_OK;
  200.     }

  201.     if (rc != NGX_OK) {
  202.         return NGX_ERROR;
  203.     }

  204.     rc = ngx_ssl_stapling_responder(cf, ssl, staple, responder);

  205.     if (rc == NGX_DECLINED) {
  206.         return NGX_OK;
  207.     }

  208.     if (rc != NGX_OK) {
  209.         return NGX_ERROR;
  210.     }

  211.     return NGX_OK;
  212. }


  213. static ngx_int_t
  214. ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl,
  215.     ngx_ssl_stapling_t *staple, ngx_str_t *file)
  216. {
  217.     BIO            *bio;
  218.     int             len;
  219.     u_char         *p, *buf;
  220.     OCSP_RESPONSE  *response;

  221.     if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
  222.         return NGX_ERROR;
  223.     }

  224.     bio = BIO_new_file((char *) file->data, "rb");
  225.     if (bio == NULL) {
  226.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  227.                       "BIO_new_file(\"%s\") failed", file->data);
  228.         return NGX_ERROR;
  229.     }

  230.     response = d2i_OCSP_RESPONSE_bio(bio, NULL);
  231.     if (response == NULL) {
  232.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  233.                       "d2i_OCSP_RESPONSE_bio(\"%s\") failed", file->data);
  234.         BIO_free(bio);
  235.         return NGX_ERROR;
  236.     }

  237.     len = i2d_OCSP_RESPONSE(response, NULL);
  238.     if (len <= 0) {
  239.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  240.                       "i2d_OCSP_RESPONSE(\"%s\") failed", file->data);
  241.         goto failed;
  242.     }

  243.     buf = ngx_alloc(len, ssl->log);
  244.     if (buf == NULL) {
  245.         goto failed;
  246.     }

  247.     p = buf;
  248.     len = i2d_OCSP_RESPONSE(response, &p);
  249.     if (len <= 0) {
  250.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  251.                       "i2d_OCSP_RESPONSE(\"%s\") failed", file->data);
  252.         ngx_free(buf);
  253.         goto failed;
  254.     }

  255.     OCSP_RESPONSE_free(response);
  256.     BIO_free(bio);

  257.     staple->staple.data = buf;
  258.     staple->staple.len = len;
  259.     staple->valid = NGX_MAX_TIME_T_VALUE;

  260.     return NGX_OK;

  261. failed:

  262.     OCSP_RESPONSE_free(response);
  263.     BIO_free(bio);

  264.     return NGX_ERROR;
  265. }


  266. static ngx_int_t
  267. ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl,
  268.     ngx_ssl_stapling_t *staple)
  269. {
  270.     int              i, n, rc;
  271.     X509            *cert, *issuer;
  272.     X509_STORE      *store;
  273.     X509_STORE_CTX  *store_ctx;

  274.     cert = staple->cert;

  275.     n = sk_X509_num(staple->chain);

  276.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
  277.                    "SSL get issuer: %d extra certs", n);

  278.     for (i = 0; i < n; i++) {
  279.         issuer = sk_X509_value(staple->chain, i);
  280.         if (X509_check_issued(issuer, cert) == X509_V_OK) {
  281. #if OPENSSL_VERSION_NUMBER >= 0x10100001L
  282.             X509_up_ref(issuer);
  283. #else
  284.             CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509);
  285. #endif

  286.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
  287.                            "SSL get issuer: found %p in extra certs", issuer);

  288.             staple->issuer = issuer;

  289.             return NGX_OK;
  290.         }
  291.     }

  292.     store = SSL_CTX_get_cert_store(ssl->ctx);
  293.     if (store == NULL) {
  294.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  295.                       "SSL_CTX_get_cert_store() failed");
  296.         return NGX_ERROR;
  297.     }

  298.     store_ctx = X509_STORE_CTX_new();
  299.     if (store_ctx == NULL) {
  300.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  301.                       "X509_STORE_CTX_new() failed");
  302.         return NGX_ERROR;
  303.     }

  304.     if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) {
  305.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  306.                       "X509_STORE_CTX_init() failed");
  307.         X509_STORE_CTX_free(store_ctx);
  308.         return NGX_ERROR;
  309.     }

  310.     rc = X509_STORE_CTX_get1_issuer(&issuer, store_ctx, cert);

  311.     if (rc == -1) {
  312.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  313.                       "X509_STORE_CTX_get1_issuer() failed");
  314.         X509_STORE_CTX_free(store_ctx);
  315.         return NGX_ERROR;
  316.     }

  317.     if (rc == 0) {
  318.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  319.                       "\"ssl_stapling\" ignored, "
  320.                       "issuer certificate not found for certificate \"%s\"",
  321.                       staple->name);
  322.         X509_STORE_CTX_free(store_ctx);
  323.         return NGX_DECLINED;
  324.     }

  325.     X509_STORE_CTX_free(store_ctx);

  326.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
  327.                    "SSL get issuer: found %p in cert store", issuer);

  328.     staple->issuer = issuer;

  329.     return NGX_OK;
  330. }


  331. static ngx_int_t
  332. ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl,
  333.     ngx_ssl_stapling_t *staple, ngx_str_t *responder)
  334. {
  335.     char                      *s;
  336.     ngx_str_t                  rsp;
  337.     ngx_url_t                  u;
  338.     STACK_OF(OPENSSL_STRING)  *aia;

  339.     if (responder->len == 0) {

  340.         /* extract OCSP responder URL from certificate */

  341.         aia = X509_get1_ocsp(staple->cert);
  342.         if (aia == NULL) {
  343.             ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  344.                           "\"ssl_stapling\" ignored, "
  345.                           "no OCSP responder URL in the certificate \"%s\"",
  346.                           staple->name);
  347.             return NGX_DECLINED;
  348.         }

  349. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  350.         s = sk_OPENSSL_STRING_value(aia, 0);
  351. #else
  352.         s = sk_value(aia, 0);
  353. #endif
  354.         if (s == NULL) {
  355.             ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  356.                           "\"ssl_stapling\" ignored, "
  357.                           "no OCSP responder URL in the certificate \"%s\"",
  358.                           staple->name);
  359.             X509_email_free(aia);
  360.             return NGX_DECLINED;
  361.         }

  362.         responder = &rsp;

  363.         responder->len = ngx_strlen(s);
  364.         responder->data = ngx_palloc(cf->pool, responder->len);
  365.         if (responder->data == NULL) {
  366.             X509_email_free(aia);
  367.             return NGX_ERROR;
  368.         }

  369.         ngx_memcpy(responder->data, s, responder->len);
  370.         X509_email_free(aia);
  371.     }

  372.     ngx_memzero(&u, sizeof(ngx_url_t));

  373.     u.url = *responder;
  374.     u.default_port = 80;
  375.     u.uri_part = 1;

  376.     if (u.url.len > 7
  377.         && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0)
  378.     {
  379.         u.url.len -= 7;
  380.         u.url.data += 7;

  381.     } else {
  382.         ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  383.                       "\"ssl_stapling\" ignored, "
  384.                       "invalid URL prefix in OCSP responder \"%V\" "
  385.                       "in the certificate \"%s\"",
  386.                       &u.url, staple->name);
  387.         return NGX_DECLINED;
  388.     }

  389.     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
  390.         if (u.err) {
  391.             ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  392.                           "\"ssl_stapling\" ignored, "
  393.                           "%s in OCSP responder \"%V\" "
  394.                           "in the certificate \"%s\"",
  395.                           u.err, &u.url, staple->name);
  396.             return NGX_DECLINED;
  397.         }

  398.         return NGX_ERROR;
  399.     }

  400.     staple->addrs = u.addrs;
  401.     staple->naddrs = u.naddrs;
  402.     staple->host = u.host;
  403.     staple->uri = u.uri;
  404.     staple->port = u.port;

  405.     if (staple->uri.len == 0) {
  406.         ngx_str_set(&staple->uri, "/");
  407.     }

  408.     return NGX_OK;
  409. }


  410. ngx_int_t
  411. ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
  412.     ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
  413. {
  414.     ngx_rbtree_t        *tree;
  415.     ngx_rbtree_node_t   *node;
  416.     ngx_ssl_stapling_t  *staple;

  417.     tree = &ssl->staple_rbtree;

  418.     if (tree->root == tree->sentinel) {
  419.         return NGX_OK;
  420.     }

  421.     for (node = ngx_rbtree_min(tree->root, tree->sentinel);
  422.          node;
  423.          node = ngx_rbtree_next(tree, node))
  424.     {
  425.         staple = ngx_rbtree_data(node, ngx_ssl_stapling_t, node);
  426.         staple->resolver = resolver;
  427.         staple->resolver_timeout = resolver_timeout;
  428.     }

  429.     return NGX_OK;
  430. }


  431. static int
  432. ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data)
  433. {
  434.     int                  rc;
  435.     X509                *cert;
  436.     u_char              *p;
  437.     SSL_CTX             *ssl_ctx;
  438.     ngx_ssl_t           *ssl;
  439.     ngx_connection_t    *c;
  440.     ngx_ssl_stapling_t  *staple;

  441.     c = ngx_ssl_get_connection(ssl_conn);

  442.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  443.                    "SSL certificate status callback");

  444.     rc = SSL_TLSEXT_ERR_NOACK;

  445.     cert = SSL_get_certificate(ssl_conn);

  446.     if (cert == NULL) {
  447.         return rc;
  448.     }

  449.     ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
  450.     ssl = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_index);

  451.     staple = ngx_ssl_stapling_lookup(ssl, cert);

  452.     if (staple == NULL) {
  453.         return rc;
  454.     }

  455.     if (staple->staple.len
  456.         && staple->valid >= ngx_time())
  457.     {
  458.         /* we have to copy ocsp response as OpenSSL will free it by itself */

  459.         p = OPENSSL_malloc(staple->staple.len);
  460.         if (p == NULL) {
  461.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed");
  462.             return SSL_TLSEXT_ERR_NOACK;
  463.         }

  464.         ngx_memcpy(p, staple->staple.data, staple->staple.len);

  465.         SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len);

  466.         rc = SSL_TLSEXT_ERR_OK;
  467.     }

  468.     ngx_ssl_stapling_update(staple);

  469.     return rc;
  470. }


  471. static ngx_ssl_stapling_t *
  472. ngx_ssl_stapling_lookup(ngx_ssl_t *ssl, X509 *cert)
  473. {
  474.     ngx_rbtree_key_t    key;
  475.     ngx_rbtree_node_t  *node, *sentinel;

  476.     node = ssl->staple_rbtree.root;
  477.     sentinel = ssl->staple_rbtree.sentinel;
  478.     key = (ngx_rbtree_key_t) cert;

  479.     while (node != sentinel) {

  480.         if (key != node->key) {
  481.             node = (key < node->key) ? node->left : node->right;
  482.             continue;
  483.         }

  484.         return ngx_rbtree_data(node, ngx_ssl_stapling_t, node);
  485.     }

  486.     return NULL;
  487. }


  488. static void
  489. ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple)
  490. {
  491.     ngx_ssl_ocsp_ctx_t  *ctx;

  492.     if (staple->host.len == 0
  493.         || staple->loading || staple->refresh >= ngx_time())
  494.     {
  495.         return;
  496.     }

  497.     staple->loading = 1;

  498.     ctx = ngx_ssl_ocsp_start(ngx_cycle->log);
  499.     if (ctx == NULL) {
  500.         return;
  501.     }

  502.     ctx->ssl_ctx = staple->ssl_ctx;
  503.     ctx->cert = staple->cert;
  504.     ctx->issuer = staple->issuer;
  505.     ctx->chain = staple->chain;
  506.     ctx->name = staple->name;
  507.     ctx->flags = (staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY);

  508.     ctx->addrs = staple->addrs;
  509.     ctx->naddrs = staple->naddrs;
  510.     ctx->host = staple->host;
  511.     ctx->uri = staple->uri;
  512.     ctx->port = staple->port;
  513.     ctx->timeout = staple->timeout;

  514.     ctx->resolver = staple->resolver;
  515.     ctx->resolver_timeout = staple->resolver_timeout;

  516.     ctx->handler = ngx_ssl_stapling_ocsp_handler;
  517.     ctx->data = staple;

  518.     ngx_ssl_ocsp_request(ctx);

  519.     return;
  520. }


  521. static void
  522. ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
  523. {
  524.     time_t               now;
  525.     ngx_str_t            response;
  526.     ngx_ssl_stapling_t  *staple;

  527.     staple = ctx->data;
  528.     now = ngx_time();

  529.     if (ngx_ssl_ocsp_verify(ctx) != NGX_OK) {
  530.         goto error;
  531.     }

  532.     if (ctx->status != V_OCSP_CERTSTATUS_GOOD) {
  533.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  534.                       "certificate status \"%s\" in the OCSP response",
  535.                       OCSP_cert_status_str(ctx->status));
  536.         goto error;
  537.     }

  538.     /* copy the response to memory not in ctx->pool */

  539.     response.len = ctx->response->last - ctx->response->pos;
  540.     response.data = ngx_alloc(response.len, ctx->log);

  541.     if (response.data == NULL) {
  542.         goto error;
  543.     }

  544.     ngx_memcpy(response.data, ctx->response->pos, response.len);

  545.     if (staple->staple.data) {
  546.         ngx_free(staple->staple.data);
  547.     }

  548.     staple->staple = response;
  549.     staple->valid = ctx->valid;

  550.     /*
  551.      * refresh before the response expires,
  552.      * but not earlier than in 5 minutes, and at least in an hour
  553.      */

  554.     staple->loading = 0;
  555.     staple->refresh = ngx_max(ngx_min(ctx->valid - 300, now + 3600), now + 300);

  556.     ngx_ssl_ocsp_done(ctx);
  557.     return;

  558. error:

  559.     staple->loading = 0;
  560.     staple->refresh = now + 300;

  561.     ngx_ssl_ocsp_done(ctx);
  562. }


  563. static time_t
  564. ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time)
  565. {
  566.     BIO     *bio;
  567.     char    *value;
  568.     size_t   len;
  569.     time_t   time;

  570.     /*
  571.      * OpenSSL doesn't provide a way to convert ASN1_GENERALIZEDTIME
  572.      * into time_t.  To do this, we use ASN1_GENERALIZEDTIME_print(),
  573.      * which uses the "MMM DD HH:MM:SS YYYY [GMT]" format (e.g.,
  574.      * "Feb  3 00:55:52 2015 GMT"), and parse the result.
  575.      */

  576.     bio = BIO_new(BIO_s_mem());
  577.     if (bio == NULL) {
  578.         return NGX_ERROR;
  579.     }

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

  581.     BIO_write(bio, "Tue ", sizeof("Tue ") - 1);
  582.     ASN1_GENERALIZEDTIME_print(bio, asn1time);
  583.     len = BIO_get_mem_data(bio, &value);

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

  585.     BIO_free(bio);

  586.     return time;
  587. }


  588. static void
  589. ngx_ssl_stapling_cleanup(void *data)
  590. {
  591.     ngx_ssl_stapling_t  *staple = data;

  592.     if (staple->issuer) {
  593.         X509_free(staple->issuer);
  594.     }

  595.     if (staple->staple.data) {
  596.         ngx_free(staple->staple.data);
  597.     }
  598. }


  599. ngx_int_t
  600. ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
  601.     ngx_uint_t depth, ngx_shm_zone_t *shm_zone)
  602. {
  603.     ngx_url_t             u;
  604.     ngx_ssl_ocsp_conf_t  *ocf;

  605.     ocf = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_ocsp_conf_t));
  606.     if (ocf == NULL) {
  607.         return NGX_ERROR;
  608.     }

  609.     ocf->depth = depth;
  610.     ocf->shm_zone = shm_zone;

  611.     if (responder->len) {
  612.         ngx_memzero(&u, sizeof(ngx_url_t));

  613.         u.url = *responder;
  614.         u.default_port = 80;
  615.         u.uri_part = 1;

  616.         if (u.url.len > 7
  617.             && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0)
  618.         {
  619.             u.url.len -= 7;
  620.             u.url.data += 7;

  621.         } else {
  622.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  623.                           "invalid URL prefix in OCSP responder \"%V\" "
  624.                           "in \"ssl_ocsp_responder\"", &u.url);
  625.             return NGX_ERROR;
  626.         }

  627.         if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
  628.             if (u.err) {
  629.                 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  630.                               "%s in OCSP responder \"%V\" "
  631.                               "in \"ssl_ocsp_responder\"", u.err, &u.url);
  632.             }

  633.             return NGX_ERROR;
  634.         }

  635.         ocf->addrs = u.addrs;
  636.         ocf->naddrs = u.naddrs;
  637.         ocf->host = u.host;
  638.         ocf->uri = u.uri;
  639.         ocf->port = u.port;
  640.     }

  641.     if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ocsp_index, ocf) == 0) {
  642.         ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
  643.                       "SSL_CTX_set_ex_data() failed");
  644.         return NGX_ERROR;
  645.     }

  646.     return NGX_OK;
  647. }


  648. ngx_int_t
  649. ngx_ssl_ocsp_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
  650.     ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
  651. {
  652.     ngx_ssl_ocsp_conf_t  *ocf;

  653.     ocf = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_ocsp_index);
  654.     ocf->resolver = resolver;
  655.     ocf->resolver_timeout = resolver_timeout;

  656.     return NGX_OK;
  657. }


  658. ngx_int_t
  659. ngx_ssl_ocsp_validate(ngx_connection_t *c)
  660. {
  661.     X509                 *cert;
  662.     SSL_CTX              *ssl_ctx;
  663.     ngx_int_t             rc;
  664.     X509_STORE           *store;
  665.     X509_STORE_CTX       *store_ctx;
  666.     STACK_OF(X509)       *chain;
  667.     ngx_ssl_ocsp_t       *ocsp;
  668.     ngx_ssl_ocsp_conf_t  *ocf;

  669.     if (c->ssl->in_ocsp) {
  670.         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  671.             return NGX_ERROR;
  672.         }

  673.         if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
  674.             return NGX_ERROR;
  675.         }

  676.         return NGX_AGAIN;
  677.     }

  678.     ssl_ctx = SSL_get_SSL_CTX(c->ssl->connection);

  679.     ocf = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_ocsp_index);
  680.     if (ocf == NULL) {
  681.         return NGX_OK;
  682.     }

  683.     if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
  684.         return NGX_OK;
  685.     }

  686.     cert = SSL_get_peer_certificate(c->ssl->connection);
  687.     if (cert == NULL) {
  688.         return NGX_OK;
  689.     }

  690.     ocsp = ngx_pcalloc(c->pool, sizeof(ngx_ssl_ocsp_t));
  691.     if (ocsp == NULL) {
  692.         X509_free(cert);
  693.         return NGX_ERROR;
  694.     }

  695.     c->ssl->ocsp = ocsp;

  696.     ocsp->status = NGX_AGAIN;
  697.     ocsp->cert_status = V_OCSP_CERTSTATUS_GOOD;
  698.     ocsp->conf = ocf;

  699. #if OPENSSL_VERSION_NUMBER >= 0x10100000L

  700.     ocsp->certs = SSL_get0_verified_chain(c->ssl->connection);

  701.     if (ocsp->certs) {
  702.         ocsp->certs = X509_chain_up_ref(ocsp->certs);
  703.         if (ocsp->certs == NULL) {
  704.             X509_free(cert);
  705.             return NGX_ERROR;
  706.         }
  707.     }

  708. #endif

  709.     if (ocsp->certs == NULL) {
  710.         store = SSL_CTX_get_cert_store(ssl_ctx);
  711.         if (store == NULL) {
  712.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  713.                           "SSL_CTX_get_cert_store() failed");
  714.             X509_free(cert);
  715.             return NGX_ERROR;
  716.         }

  717.         store_ctx = X509_STORE_CTX_new();
  718.         if (store_ctx == NULL) {
  719.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  720.                           "X509_STORE_CTX_new() failed");
  721.             X509_free(cert);
  722.             return NGX_ERROR;
  723.         }

  724.         chain = SSL_get_peer_cert_chain(c->ssl->connection);

  725.         if (X509_STORE_CTX_init(store_ctx, store, cert, chain) == 0) {
  726.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  727.                           "X509_STORE_CTX_init() failed");
  728.             X509_STORE_CTX_free(store_ctx);
  729.             X509_free(cert);
  730.             return NGX_ERROR;
  731.         }

  732.         rc = X509_verify_cert(store_ctx);
  733.         if (rc <= 0) {
  734.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "X509_verify_cert() failed");
  735.             X509_STORE_CTX_free(store_ctx);
  736.             X509_free(cert);
  737.             return NGX_ERROR;
  738.         }

  739.         ocsp->certs = X509_STORE_CTX_get1_chain(store_ctx);
  740.         if (ocsp->certs == NULL) {
  741.             ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
  742.                           "X509_STORE_CTX_get1_chain() failed");
  743.             X509_STORE_CTX_free(store_ctx);
  744.             X509_free(cert);
  745.             return NGX_ERROR;
  746.         }

  747.         X509_STORE_CTX_free(store_ctx);
  748.     }

  749.     X509_free(cert);

  750.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  751.                    "ssl ocsp validate, certs:%d", sk_X509_num(ocsp->certs));

  752.     ngx_ssl_ocsp_validate_next(c);

  753.     if (ocsp->status == NGX_AGAIN) {
  754.         c->ssl->in_ocsp = 1;
  755.         return NGX_AGAIN;
  756.     }

  757.     return NGX_OK;
  758. }


  759. static void
  760. ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
  761. {
  762.     ngx_int_t             rc;
  763.     ngx_uint_t            n;
  764.     ngx_ssl_ocsp_t       *ocsp;
  765.     ngx_ssl_ocsp_ctx_t   *ctx;
  766.     ngx_ssl_ocsp_conf_t  *ocf;

  767.     ocsp = c->ssl->ocsp;
  768.     ocf = ocsp->conf;

  769.     n = sk_X509_num(ocsp->certs);

  770.     for ( ;; ) {

  771.         if (ocsp->ncert == n - 1 || (ocf->depth == 2 && ocsp->ncert == 1)) {
  772.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  773.                            "ssl ocsp validated, certs:%ui", ocsp->ncert);
  774.             rc = NGX_OK;
  775.             goto done;
  776.         }

  777.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  778.                        "ssl ocsp validate cert:%ui", ocsp->ncert);

  779.         ctx = ngx_ssl_ocsp_start(c->log);
  780.         if (ctx == NULL) {
  781.             rc = NGX_ERROR;
  782.             goto done;
  783.         }

  784.         ocsp->ctx = ctx;

  785.         ctx->ssl_ctx = SSL_get_SSL_CTX(c->ssl->connection);
  786.         ctx->cert = sk_X509_value(ocsp->certs, ocsp->ncert);
  787.         ctx->issuer = sk_X509_value(ocsp->certs, ocsp->ncert + 1);
  788.         ctx->chain = ocsp->certs;

  789.         ctx->resolver = ocf->resolver;
  790.         ctx->resolver_timeout = ocf->resolver_timeout;

  791.         ctx->handler = ngx_ssl_ocsp_handler;
  792.         ctx->data = c;

  793.         ctx->shm_zone = ocf->shm_zone;

  794.         ctx->addrs = ocf->addrs;
  795.         ctx->naddrs = ocf->naddrs;
  796.         ctx->host = ocf->host;
  797.         ctx->uri = ocf->uri;
  798.         ctx->port = ocf->port;

  799.         rc = ngx_ssl_ocsp_responder(c, ctx);
  800.         if (rc != NGX_OK) {
  801.             goto done;
  802.         }

  803.         if (ctx->uri.len == 0) {
  804.             ngx_str_set(&ctx->uri, "/");
  805.         }

  806.         ocsp->ncert++;

  807.         rc = ngx_ssl_ocsp_cache_lookup(ctx);

  808.         if (rc == NGX_ERROR) {
  809.             goto done;
  810.         }

  811.         if (rc == NGX_DECLINED) {
  812.             break;
  813.         }

  814.         /* rc == NGX_OK */

  815.         if (ctx->status != V_OCSP_CERTSTATUS_GOOD) {
  816.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  817.                            "ssl ocsp cached status \"%s\"",
  818.                            OCSP_cert_status_str(ctx->status));
  819.             ocsp->cert_status = ctx->status;
  820.             goto done;
  821.         }

  822.         ocsp->ctx = NULL;
  823.         ngx_ssl_ocsp_done(ctx);
  824.     }

  825.     ngx_ssl_ocsp_request(ctx);
  826.     return;

  827. done:

  828.     ocsp->status = rc;

  829.     if (c->ssl->in_ocsp) {
  830.         c->ssl->handshaked = 1;
  831.         c->ssl->handler(c);
  832.     }
  833. }


  834. static void
  835. ngx_ssl_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
  836. {
  837.     ngx_int_t          rc;
  838.     ngx_ssl_ocsp_t    *ocsp;
  839.     ngx_connection_t  *c;

  840.     c = ctx->data;
  841.     ocsp = c->ssl->ocsp;
  842.     ocsp->ctx = NULL;

  843.     rc = ngx_ssl_ocsp_verify(ctx);
  844.     if (rc != NGX_OK) {
  845.         goto done;
  846.     }

  847.     rc = ngx_ssl_ocsp_cache_store(ctx);
  848.     if (rc != NGX_OK) {
  849.         goto done;
  850.     }

  851.     if (ctx->status != V_OCSP_CERTSTATUS_GOOD) {
  852.         ocsp->cert_status = ctx->status;
  853.         goto done;
  854.     }

  855.     ngx_ssl_ocsp_done(ctx);

  856.     ngx_ssl_ocsp_validate_next(c);

  857.     return;

  858. done:

  859.     ocsp->status = rc;
  860.     ngx_ssl_ocsp_done(ctx);

  861.     if (c->ssl->in_ocsp) {
  862.         c->ssl->handshaked = 1;
  863.         c->ssl->handler(c);
  864.     }
  865. }


  866. static ngx_int_t
  867. ngx_ssl_ocsp_responder(ngx_connection_t *c, ngx_ssl_ocsp_ctx_t *ctx)
  868. {
  869.     char                      *s;
  870.     ngx_str_t                  responder;
  871.     ngx_url_t                  u;
  872.     STACK_OF(OPENSSL_STRING)  *aia;

  873.     if (ctx->host.len) {
  874.         return NGX_OK;
  875.     }

  876.     /* extract OCSP responder URL from certificate */

  877.     aia = X509_get1_ocsp(ctx->cert);
  878.     if (aia == NULL) {
  879.         ngx_log_error(NGX_LOG_ERR, c->log, 0,
  880.                       "no OCSP responder URL in certificate");
  881.         return NGX_ERROR;
  882.     }

  883. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  884.     s = sk_OPENSSL_STRING_value(aia, 0);
  885. #else
  886.     s = sk_value(aia, 0);
  887. #endif
  888.     if (s == NULL) {
  889.         ngx_log_error(NGX_LOG_ERR, c->log, 0,
  890.                       "no OCSP responder URL in certificate");
  891.         X509_email_free(aia);
  892.         return NGX_ERROR;
  893.     }

  894.     responder.len = ngx_strlen(s);
  895.     responder.data = ngx_palloc(ctx->pool, responder.len);
  896.     if (responder.data == NULL) {
  897.         X509_email_free(aia);
  898.         return NGX_ERROR;
  899.     }

  900.     ngx_memcpy(responder.data, s, responder.len);
  901.     X509_email_free(aia);

  902.     ngx_memzero(&u, sizeof(ngx_url_t));

  903.     u.url = responder;
  904.     u.default_port = 80;
  905.     u.uri_part = 1;
  906.     u.no_resolve = 1;

  907.     if (u.url.len > 7
  908.         && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0)
  909.     {
  910.         u.url.len -= 7;
  911.         u.url.data += 7;

  912.     } else {
  913.         ngx_log_error(NGX_LOG_ERR, c->log, 0,
  914.                       "invalid URL prefix in OCSP responder \"%V\" "
  915.                       "in certificate", &u.url);
  916.         return NGX_ERROR;
  917.     }

  918.     if (ngx_parse_url(ctx->pool, &u) != NGX_OK) {
  919.         if (u.err) {
  920.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  921.                           "%s in OCSP responder \"%V\" in certificate",
  922.                           u.err, &u.url);
  923.         }

  924.         return NGX_ERROR;
  925.     }

  926.     if (u.host.len == 0) {
  927.         ngx_log_error(NGX_LOG_ERR, c->log, 0,
  928.                       "empty host in OCSP responder in certificate");
  929.         return NGX_ERROR;
  930.     }

  931.     ctx->addrs = u.addrs;
  932.     ctx->naddrs = u.naddrs;
  933.     ctx->host = u.host;
  934.     ctx->uri = u.uri;
  935.     ctx->port = u.port;

  936.     return NGX_OK;
  937. }


  938. ngx_int_t
  939. ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s)
  940. {
  941.     ngx_ssl_ocsp_t  *ocsp;

  942.     ocsp = c->ssl->ocsp;
  943.     if (ocsp == NULL) {
  944.         return NGX_OK;
  945.     }

  946.     if (ocsp->status == NGX_ERROR) {
  947.         *s = "certificate status request failed";
  948.         return NGX_DECLINED;
  949.     }

  950.     switch (ocsp->cert_status) {

  951.     case V_OCSP_CERTSTATUS_GOOD:
  952.         return NGX_OK;

  953.     case V_OCSP_CERTSTATUS_REVOKED:
  954.         *s = "certificate revoked";
  955.         break;

  956.     default: /* V_OCSP_CERTSTATUS_UNKNOWN */
  957.         *s = "certificate status unknown";
  958.     }

  959.     return NGX_DECLINED;
  960. }


  961. void
  962. ngx_ssl_ocsp_cleanup(ngx_connection_t *c)
  963. {
  964.     ngx_ssl_ocsp_t  *ocsp;

  965.     ocsp = c->ssl->ocsp;
  966.     if (ocsp == NULL) {
  967.         return;
  968.     }

  969.     if (ocsp->ctx) {
  970.         ngx_ssl_ocsp_done(ocsp->ctx);
  971.         ocsp->ctx = NULL;
  972.     }

  973.     if (ocsp->certs) {
  974.         sk_X509_pop_free(ocsp->certs, X509_free);
  975.         ocsp->certs = NULL;
  976.     }
  977. }


  978. static ngx_ssl_ocsp_ctx_t *
  979. ngx_ssl_ocsp_start(ngx_log_t *log)
  980. {
  981.     ngx_pool_t          *pool;
  982.     ngx_ssl_ocsp_ctx_t  *ctx;

  983.     pool = ngx_create_pool(2048, log);
  984.     if (pool == NULL) {
  985.         return NULL;
  986.     }

  987.     ctx = ngx_pcalloc(pool, sizeof(ngx_ssl_ocsp_ctx_t));
  988.     if (ctx == NULL) {
  989.         ngx_destroy_pool(pool);
  990.         return NULL;
  991.     }

  992.     log = ngx_palloc(pool, sizeof(ngx_log_t));
  993.     if (log == NULL) {
  994.         ngx_destroy_pool(pool);
  995.         return NULL;
  996.     }

  997.     ctx->pool = pool;

  998.     *log = *ctx->pool->log;

  999.     ctx->pool->log = log;
  1000.     ctx->log = log;

  1001.     log->handler = ngx_ssl_ocsp_log_error;
  1002.     log->data = ctx;
  1003.     log->action = "requesting certificate status";

  1004.     return ctx;
  1005. }


  1006. static void
  1007. ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx)
  1008. {
  1009.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1010.                    "ssl ocsp done");

  1011.     if (ctx->peer.connection) {
  1012.         ngx_close_connection(ctx->peer.connection);
  1013.     }

  1014.     ngx_destroy_pool(ctx->pool);
  1015. }


  1016. static void
  1017. ngx_ssl_ocsp_error(ngx_ssl_ocsp_ctx_t *ctx)
  1018. {
  1019.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1020.                    "ssl ocsp error");

  1021.     ctx->code = 0;
  1022.     ctx->handler(ctx);
  1023. }


  1024. static void
  1025. ngx_ssl_ocsp_next(ngx_ssl_ocsp_ctx_t *ctx)
  1026. {
  1027.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1028.                    "ssl ocsp next");

  1029.     if (++ctx->naddr >= ctx->naddrs) {
  1030.         ngx_ssl_ocsp_error(ctx);
  1031.         return;
  1032.     }

  1033.     ctx->request->pos = ctx->request->start;

  1034.     if (ctx->response) {
  1035.         ctx->response->last = ctx->response->pos;
  1036.     }

  1037.     if (ctx->peer.connection) {
  1038.         ngx_close_connection(ctx->peer.connection);
  1039.         ctx->peer.connection = NULL;
  1040.     }

  1041.     ctx->state = 0;
  1042.     ctx->count = 0;
  1043.     ctx->done = 0;

  1044.     ngx_ssl_ocsp_connect(ctx);
  1045. }


  1046. static void
  1047. ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx)
  1048. {
  1049.     ngx_resolver_ctx_t  *resolve, temp;

  1050.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1051.                    "ssl ocsp request");

  1052.     if (ngx_ssl_ocsp_create_request(ctx) != NGX_OK) {
  1053.         ngx_ssl_ocsp_error(ctx);
  1054.         return;
  1055.     }

  1056.     if (ctx->resolver) {
  1057.         /* resolve OCSP responder hostname */

  1058.         temp.name = ctx->host;

  1059.         resolve = ngx_resolve_start(ctx->resolver, &temp);
  1060.         if (resolve == NULL) {
  1061.             ngx_ssl_ocsp_error(ctx);
  1062.             return;
  1063.         }

  1064.         if (resolve == NGX_NO_RESOLVER) {
  1065.             if (ctx->naddrs == 0) {
  1066.                 ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1067.                               "no resolver defined to resolve %V", &ctx->host);

  1068.                 ngx_ssl_ocsp_error(ctx);
  1069.                 return;
  1070.             }

  1071.             ngx_log_error(NGX_LOG_WARN, ctx->log, 0,
  1072.                           "no resolver defined to resolve %V", &ctx->host);
  1073.             goto connect;
  1074.         }

  1075.         resolve->name = ctx->host;
  1076.         resolve->handler = ngx_ssl_ocsp_resolve_handler;
  1077.         resolve->data = ctx;
  1078.         resolve->timeout = ctx->resolver_timeout;

  1079.         if (ngx_resolve_name(resolve) != NGX_OK) {
  1080.             ngx_ssl_ocsp_error(ctx);
  1081.             return;
  1082.         }

  1083.         return;
  1084.     }

  1085. connect:

  1086.     ngx_ssl_ocsp_connect(ctx);
  1087. }


  1088. static void
  1089. ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
  1090. {
  1091.     ngx_ssl_ocsp_ctx_t *ctx = resolve->data;

  1092.     u_char           *p;
  1093.     size_t            len;
  1094.     socklen_t         socklen;
  1095.     ngx_uint_t        i;
  1096.     struct sockaddr  *sockaddr;

  1097.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1098.                    "ssl ocsp resolve handler");

  1099.     if (resolve->state) {
  1100.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1101.                       "%V could not be resolved (%i: %s)",
  1102.                       &resolve->name, resolve->state,
  1103.                       ngx_resolver_strerror(resolve->state));
  1104.         goto failed;
  1105.     }

  1106. #if (NGX_DEBUG)
  1107.     {
  1108.     u_char     text[NGX_SOCKADDR_STRLEN];
  1109.     ngx_str_t  addr;

  1110.     addr.data = text;

  1111.     for (i = 0; i < resolve->naddrs; i++) {
  1112.         addr.len = ngx_sock_ntop(resolve->addrs[i].sockaddr,
  1113.                                  resolve->addrs[i].socklen,
  1114.                                  text, NGX_SOCKADDR_STRLEN, 0);

  1115.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1116.                        "name was resolved to %V", &addr);

  1117.     }
  1118.     }
  1119. #endif

  1120.     ctx->naddrs = resolve->naddrs;
  1121.     ctx->addrs = ngx_pcalloc(ctx->pool, ctx->naddrs * sizeof(ngx_addr_t));

  1122.     if (ctx->addrs == NULL) {
  1123.         goto failed;
  1124.     }

  1125.     for (i = 0; i < resolve->naddrs; i++) {

  1126.         socklen = resolve->addrs[i].socklen;

  1127.         sockaddr = ngx_palloc(ctx->pool, socklen);
  1128.         if (sockaddr == NULL) {
  1129.             goto failed;
  1130.         }

  1131.         ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen);
  1132.         ngx_inet_set_port(sockaddr, ctx->port);

  1133.         ctx->addrs[i].sockaddr = sockaddr;
  1134.         ctx->addrs[i].socklen = socklen;

  1135.         p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN);
  1136.         if (p == NULL) {
  1137.             goto failed;
  1138.         }

  1139.         len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);

  1140.         ctx->addrs[i].name.len = len;
  1141.         ctx->addrs[i].name.data = p;
  1142.     }

  1143.     ngx_resolve_name_done(resolve);

  1144.     ngx_ssl_ocsp_connect(ctx);
  1145.     return;

  1146. failed:

  1147.     ngx_resolve_name_done(resolve);
  1148.     ngx_ssl_ocsp_error(ctx);
  1149. }


  1150. static void
  1151. ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx)
  1152. {
  1153.     ngx_int_t    rc;
  1154.     ngx_addr_t  *addr;

  1155.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1156.                    "ssl ocsp connect %ui/%ui", ctx->naddr, ctx->naddrs);

  1157.     addr = &ctx->addrs[ctx->naddr];

  1158.     ctx->peer.sockaddr = addr->sockaddr;
  1159.     ctx->peer.socklen = addr->socklen;
  1160.     ctx->peer.name = &addr->name;
  1161.     ctx->peer.get = ngx_event_get_peer;
  1162.     ctx->peer.log = ctx->log;
  1163.     ctx->peer.log_error = NGX_ERROR_ERR;

  1164.     rc = ngx_event_connect_peer(&ctx->peer);

  1165.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1166.                    "ssl ocsp connect peer done");

  1167.     if (rc == NGX_ERROR) {
  1168.         ngx_ssl_ocsp_error(ctx);
  1169.         return;
  1170.     }

  1171.     if (rc == NGX_BUSY || rc == NGX_DECLINED) {
  1172.         ngx_ssl_ocsp_next(ctx);
  1173.         return;
  1174.     }

  1175.     ctx->peer.connection->data = ctx;
  1176.     ctx->peer.connection->pool = ctx->pool;

  1177.     ctx->peer.connection->read->handler = ngx_ssl_ocsp_read_handler;
  1178.     ctx->peer.connection->write->handler = ngx_ssl_ocsp_write_handler;

  1179.     ctx->process = ngx_ssl_ocsp_process_status_line;

  1180.     if (ctx->timeout) {
  1181.         ngx_add_timer(ctx->peer.connection->read, ctx->timeout);
  1182.         ngx_add_timer(ctx->peer.connection->write, ctx->timeout);
  1183.     }

  1184.     if (rc == NGX_OK) {
  1185.         ngx_ssl_ocsp_write_handler(ctx->peer.connection->write);
  1186.         return;
  1187.     }
  1188. }


  1189. static void
  1190. ngx_ssl_ocsp_write_handler(ngx_event_t *wev)
  1191. {
  1192.     ssize_t              n, size;
  1193.     ngx_connection_t    *c;
  1194.     ngx_ssl_ocsp_ctx_t  *ctx;

  1195.     c = wev->data;
  1196.     ctx = c->data;

  1197.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, wev->log, 0,
  1198.                    "ssl ocsp write handler");

  1199.     if (wev->timedout) {
  1200.         ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
  1201.                       "OCSP responder timed out");
  1202.         ngx_ssl_ocsp_next(ctx);
  1203.         return;
  1204.     }

  1205.     size = ctx->request->last - ctx->request->pos;

  1206.     n = ngx_send(c, ctx->request->pos, size);

  1207.     if (n == NGX_ERROR) {
  1208.         ngx_ssl_ocsp_next(ctx);
  1209.         return;
  1210.     }

  1211.     if (n > 0) {
  1212.         ctx->request->pos += n;

  1213.         if (n == size) {
  1214.             wev->handler = ngx_ssl_ocsp_dummy_handler;

  1215.             if (wev->timer_set) {
  1216.                 ngx_del_timer(wev);
  1217.             }

  1218.             if (ngx_handle_write_event(wev, 0) != NGX_OK) {
  1219.                 ngx_ssl_ocsp_error(ctx);
  1220.             }

  1221.             return;
  1222.         }
  1223.     }

  1224.     if (!wev->timer_set && ctx->timeout) {
  1225.         ngx_add_timer(wev, ctx->timeout);
  1226.     }
  1227. }


  1228. static void
  1229. ngx_ssl_ocsp_read_handler(ngx_event_t *rev)
  1230. {
  1231.     ssize_t              n, size;
  1232.     ngx_int_t            rc;
  1233.     ngx_connection_t    *c;
  1234.     ngx_ssl_ocsp_ctx_t  *ctx;

  1235.     c = rev->data;
  1236.     ctx = c->data;

  1237.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0,
  1238.                    "ssl ocsp read handler");

  1239.     if (rev->timedout) {
  1240.         ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
  1241.                       "OCSP responder timed out");
  1242.         ngx_ssl_ocsp_next(ctx);
  1243.         return;
  1244.     }

  1245.     if (ctx->response == NULL) {
  1246.         ctx->response = ngx_create_temp_buf(ctx->pool, 16384);
  1247.         if (ctx->response == NULL) {
  1248.             ngx_ssl_ocsp_error(ctx);
  1249.             return;
  1250.         }
  1251.     }

  1252.     for ( ;; ) {

  1253.         size = ctx->response->end - ctx->response->last;

  1254.         n = ngx_recv(c, ctx->response->last, size);

  1255.         if (n > 0) {
  1256.             ctx->response->last += n;

  1257.             rc = ctx->process(ctx);

  1258.             if (rc == NGX_ERROR) {
  1259.                 ngx_ssl_ocsp_next(ctx);
  1260.                 return;
  1261.             }

  1262.             continue;
  1263.         }

  1264.         if (n == NGX_AGAIN) {

  1265.             if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  1266.                 ngx_ssl_ocsp_error(ctx);
  1267.             }

  1268.             return;
  1269.         }

  1270.         break;
  1271.     }

  1272.     ctx->done = 1;

  1273.     rc = ctx->process(ctx);

  1274.     if (rc == NGX_DONE) {
  1275.         /* ctx->handler() was called */
  1276.         return;
  1277.     }

  1278.     ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1279.                   "OCSP responder prematurely closed connection");

  1280.     ngx_ssl_ocsp_next(ctx);
  1281. }


  1282. static void
  1283. ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev)
  1284. {
  1285.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
  1286.                    "ssl ocsp dummy handler");
  1287. }


  1288. static ngx_int_t
  1289. ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
  1290. {
  1291.     int            len;
  1292.     u_char        *p;
  1293.     uintptr_t      escape;
  1294.     ngx_str_t      binary, base64;
  1295.     ngx_buf_t     *b;
  1296.     OCSP_CERTID   *id;
  1297.     OCSP_REQUEST  *ocsp;

  1298.     ocsp = OCSP_REQUEST_new();
  1299.     if (ocsp == NULL) {
  1300.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1301.                       "OCSP_REQUEST_new() failed");
  1302.         return NGX_ERROR;
  1303.     }

  1304.     id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
  1305.     if (id == NULL) {
  1306.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1307.                       "OCSP_cert_to_id() failed");
  1308.         goto failed;
  1309.     }

  1310.     if (OCSP_request_add0_id(ocsp, id) == NULL) {
  1311.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1312.                       "OCSP_request_add0_id() failed");
  1313.         OCSP_CERTID_free(id);
  1314.         goto failed;
  1315.     }

  1316.     len = i2d_OCSP_REQUEST(ocsp, NULL);
  1317.     if (len <= 0) {
  1318.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1319.                       "i2d_OCSP_REQUEST() failed");
  1320.         goto failed;
  1321.     }

  1322.     binary.len = len;
  1323.     binary.data = ngx_palloc(ctx->pool, len);
  1324.     if (binary.data == NULL) {
  1325.         goto failed;
  1326.     }

  1327.     p = binary.data;
  1328.     len = i2d_OCSP_REQUEST(ocsp, &p);
  1329.     if (len <= 0) {
  1330.         ngx_ssl_error(NGX_LOG_EMERG, ctx->log, 0,
  1331.                       "i2d_OCSP_REQUEST() failed");
  1332.         goto failed;
  1333.     }

  1334.     base64.len = ngx_base64_encoded_length(binary.len);
  1335.     base64.data = ngx_palloc(ctx->pool, base64.len);
  1336.     if (base64.data == NULL) {
  1337.         goto failed;
  1338.     }

  1339.     ngx_encode_base64(&base64, &binary);

  1340.     escape = ngx_escape_uri(NULL, base64.data, base64.len,
  1341.                             NGX_ESCAPE_URI_COMPONENT);

  1342.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1343.                    "ssl ocsp request length %z, escape %d",
  1344.                    base64.len, (int) escape);

  1345.     len = sizeof("GET ") - 1 + ctx->uri.len + sizeof("/") - 1
  1346.           + base64.len + 2 * escape + sizeof(" HTTP/1.0" CRLF) - 1
  1347.           + sizeof("Host: ") - 1 + ctx->host.len + sizeof(CRLF) - 1
  1348.           + sizeof(CRLF) - 1;

  1349.     b = ngx_create_temp_buf(ctx->pool, len);
  1350.     if (b == NULL) {
  1351.         goto failed;
  1352.     }

  1353.     p = b->last;

  1354.     p = ngx_cpymem(p, "GET ", sizeof("GET ") - 1);
  1355.     p = ngx_cpymem(p, ctx->uri.data, ctx->uri.len);

  1356.     if (ctx->uri.data[ctx->uri.len - 1] != '/') {
  1357.         *p++ = '/';
  1358.     }

  1359.     if (escape == 0) {
  1360.         p = ngx_cpymem(p, base64.data, base64.len);

  1361.     } else {
  1362.         p = (u_char *) ngx_escape_uri(p, base64.data, base64.len,
  1363.                                       NGX_ESCAPE_URI_COMPONENT);
  1364.     }

  1365.     p = ngx_cpymem(p, " HTTP/1.0" CRLF, sizeof(" HTTP/1.0" CRLF) - 1);
  1366.     p = ngx_cpymem(p, "Host: ", sizeof("Host: ") - 1);
  1367.     p = ngx_cpymem(p, ctx->host.data, ctx->host.len);
  1368.     *p++ = CR; *p++ = LF;

  1369.     /* add "\r\n" at the header end */
  1370.     *p++ = CR; *p++ = LF;

  1371.     b->last = p;
  1372.     ctx->request = b;

  1373.     OCSP_REQUEST_free(ocsp);

  1374.     return NGX_OK;

  1375. failed:

  1376.     OCSP_REQUEST_free(ocsp);

  1377.     return NGX_ERROR;
  1378. }


  1379. static ngx_int_t
  1380. ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx)
  1381. {
  1382.     ngx_int_t  rc;

  1383.     rc = ngx_ssl_ocsp_parse_status_line(ctx);

  1384.     if (rc == NGX_OK) {
  1385.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1386.                        "ssl ocsp status %ui \"%*s\"",
  1387.                        ctx->code,
  1388.                        ctx->header_end - ctx->header_start,
  1389.                        ctx->header_start);

  1390.         ctx->process = ngx_ssl_ocsp_process_headers;
  1391.         return ctx->process(ctx);
  1392.     }

  1393.     if (rc == NGX_AGAIN) {
  1394.         return NGX_AGAIN;
  1395.     }

  1396.     /* rc == NGX_ERROR */

  1397.     ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1398.                   "OCSP responder sent invalid response");

  1399.     return NGX_ERROR;
  1400. }


  1401. static ngx_int_t
  1402. ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx)
  1403. {
  1404.     u_char      ch;
  1405.     u_char     *p;
  1406.     ngx_buf_t  *b;
  1407.     enum {
  1408.         sw_start = 0,
  1409.         sw_H,
  1410.         sw_HT,
  1411.         sw_HTT,
  1412.         sw_HTTP,
  1413.         sw_first_major_digit,
  1414.         sw_major_digit,
  1415.         sw_first_minor_digit,
  1416.         sw_minor_digit,
  1417.         sw_status,
  1418.         sw_space_after_status,
  1419.         sw_status_text,
  1420.         sw_almost_done
  1421.     } state;

  1422.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1423.                    "ssl ocsp process status line");

  1424.     state = ctx->state;
  1425.     b = ctx->response;

  1426.     for (p = b->pos; p < b->last; p++) {
  1427.         ch = *p;

  1428.         switch (state) {

  1429.         /* "HTTP/" */
  1430.         case sw_start:
  1431.             switch (ch) {
  1432.             case 'H':
  1433.                 state = sw_H;
  1434.                 break;
  1435.             default:
  1436.                 return NGX_ERROR;
  1437.             }
  1438.             break;

  1439.         case sw_H:
  1440.             switch (ch) {
  1441.             case 'T':
  1442.                 state = sw_HT;
  1443.                 break;
  1444.             default:
  1445.                 return NGX_ERROR;
  1446.             }
  1447.             break;

  1448.         case sw_HT:
  1449.             switch (ch) {
  1450.             case 'T':
  1451.                 state = sw_HTT;
  1452.                 break;
  1453.             default:
  1454.                 return NGX_ERROR;
  1455.             }
  1456.             break;

  1457.         case sw_HTT:
  1458.             switch (ch) {
  1459.             case 'P':
  1460.                 state = sw_HTTP;
  1461.                 break;
  1462.             default:
  1463.                 return NGX_ERROR;
  1464.             }
  1465.             break;

  1466.         case sw_HTTP:
  1467.             switch (ch) {
  1468.             case '/':
  1469.                 state = sw_first_major_digit;
  1470.                 break;
  1471.             default:
  1472.                 return NGX_ERROR;
  1473.             }
  1474.             break;

  1475.         /* the first digit of major HTTP version */
  1476.         case sw_first_major_digit:
  1477.             if (ch < '1' || ch > '9') {
  1478.                 return NGX_ERROR;
  1479.             }

  1480.             state = sw_major_digit;
  1481.             break;

  1482.         /* the major HTTP version or dot */
  1483.         case sw_major_digit:
  1484.             if (ch == '.') {
  1485.                 state = sw_first_minor_digit;
  1486.                 break;
  1487.             }

  1488.             if (ch < '0' || ch > '9') {
  1489.                 return NGX_ERROR;
  1490.             }

  1491.             break;

  1492.         /* the first digit of minor HTTP version */
  1493.         case sw_first_minor_digit:
  1494.             if (ch < '0' || ch > '9') {
  1495.                 return NGX_ERROR;
  1496.             }

  1497.             state = sw_minor_digit;
  1498.             break;

  1499.         /* the minor HTTP version or the end of the request line */
  1500.         case sw_minor_digit:
  1501.             if (ch == ' ') {
  1502.                 state = sw_status;
  1503.                 break;
  1504.             }

  1505.             if (ch < '0' || ch > '9') {
  1506.                 return NGX_ERROR;
  1507.             }

  1508.             break;

  1509.         /* HTTP status code */
  1510.         case sw_status:
  1511.             if (ch == ' ') {
  1512.                 break;
  1513.             }

  1514.             if (ch < '0' || ch > '9') {
  1515.                 return NGX_ERROR;
  1516.             }

  1517.             ctx->code = ctx->code * 10 + (ch - '0');

  1518.             if (++ctx->count == 3) {
  1519.                 state = sw_space_after_status;
  1520.                 ctx->header_start = p - 2;
  1521.             }

  1522.             break;

  1523.         /* space or end of line */
  1524.         case sw_space_after_status:
  1525.             switch (ch) {
  1526.             case ' ':
  1527.                 state = sw_status_text;
  1528.                 break;
  1529.             case '.':                    /* IIS may send 403.1, 403.2, etc */
  1530.                 state = sw_status_text;
  1531.                 break;
  1532.             case CR:
  1533.                 state = sw_almost_done;
  1534.                 break;
  1535.             case LF:
  1536.                 ctx->header_end = p;
  1537.                 goto done;
  1538.             default:
  1539.                 return NGX_ERROR;
  1540.             }
  1541.             break;

  1542.         /* any text until end of line */
  1543.         case sw_status_text:
  1544.             switch (ch) {
  1545.             case CR:
  1546.                 state = sw_almost_done;
  1547.                 break;
  1548.             case LF:
  1549.                 ctx->header_end = p;
  1550.                 goto done;
  1551.             }
  1552.             break;

  1553.         /* end of status line */
  1554.         case sw_almost_done:
  1555.             switch (ch) {
  1556.             case LF:
  1557.                 ctx->header_end = p - 1;
  1558.                 goto done;
  1559.             default:
  1560.                 return NGX_ERROR;
  1561.             }
  1562.         }
  1563.     }

  1564.     b->pos = p;
  1565.     ctx->state = state;

  1566.     return NGX_AGAIN;

  1567. done:

  1568.     b->pos = p + 1;
  1569.     ctx->state = sw_start;

  1570.     return NGX_OK;
  1571. }


  1572. static ngx_int_t
  1573. ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx)
  1574. {
  1575.     size_t     len;
  1576.     ngx_int_t  rc;

  1577.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1578.                    "ssl ocsp process headers");

  1579.     for ( ;; ) {
  1580.         rc = ngx_ssl_ocsp_parse_header_line(ctx);

  1581.         if (rc == NGX_OK) {

  1582.             ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1583.                            "ssl ocsp header \"%*s: %*s\"",
  1584.                            ctx->header_name_end - ctx->header_name_start,
  1585.                            ctx->header_name_start,
  1586.                            ctx->header_end - ctx->header_start,
  1587.                            ctx->header_start);

  1588.             len = ctx->header_name_end - ctx->header_name_start;

  1589.             if (len == sizeof("Content-Type") - 1
  1590.                 && ngx_strncasecmp(ctx->header_name_start,
  1591.                                    (u_char *) "Content-Type",
  1592.                                    sizeof("Content-Type") - 1)
  1593.                    == 0)
  1594.             {
  1595.                 len = ctx->header_end - ctx->header_start;

  1596.                 if (len != sizeof("application/ocsp-response") - 1
  1597.                     || ngx_strncasecmp(ctx->header_start,
  1598.                                        (u_char *) "application/ocsp-response",
  1599.                                        sizeof("application/ocsp-response") - 1)
  1600.                        != 0)
  1601.                 {
  1602.                     ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1603.                                   "OCSP responder sent invalid "
  1604.                                   "\"Content-Type\" header: \"%*s\"",
  1605.                                   ctx->header_end - ctx->header_start,
  1606.                                   ctx->header_start);
  1607.                     return NGX_ERROR;
  1608.                 }

  1609.                 continue;
  1610.             }

  1611.             /* TODO: honor Content-Length */

  1612.             continue;
  1613.         }

  1614.         if (rc == NGX_DONE) {
  1615.             break;
  1616.         }

  1617.         if (rc == NGX_AGAIN) {
  1618.             return NGX_AGAIN;
  1619.         }

  1620.         /* rc == NGX_ERROR */

  1621.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1622.                       "OCSP responder sent invalid response");

  1623.         return NGX_ERROR;
  1624.     }

  1625.     ctx->process = ngx_ssl_ocsp_process_body;
  1626.     return ctx->process(ctx);
  1627. }


  1628. static ngx_int_t
  1629. ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx)
  1630. {
  1631.     u_char  c, ch, *p;
  1632.     enum {
  1633.         sw_start = 0,
  1634.         sw_name,
  1635.         sw_space_before_value,
  1636.         sw_value,
  1637.         sw_space_after_value,
  1638.         sw_almost_done,
  1639.         sw_header_almost_done
  1640.     } state;

  1641.     state = ctx->state;

  1642.     for (p = ctx->response->pos; p < ctx->response->last; p++) {
  1643.         ch = *p;

  1644. #if 0
  1645.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1646.                        "s:%d in:'%02Xd:%c'", state, ch, ch);
  1647. #endif

  1648.         switch (state) {

  1649.         /* first char */
  1650.         case sw_start:

  1651.             switch (ch) {
  1652.             case CR:
  1653.                 ctx->header_end = p;
  1654.                 state = sw_header_almost_done;
  1655.                 break;
  1656.             case LF:
  1657.                 ctx->header_end = p;
  1658.                 goto header_done;
  1659.             default:
  1660.                 state = sw_name;
  1661.                 ctx->header_name_start = p;

  1662.                 c = (u_char) (ch | 0x20);
  1663.                 if (c >= 'a' && c <= 'z') {
  1664.                     break;
  1665.                 }

  1666.                 if (ch >= '0' && ch <= '9') {
  1667.                     break;
  1668.                 }

  1669.                 return NGX_ERROR;
  1670.             }
  1671.             break;

  1672.         /* header name */
  1673.         case sw_name:
  1674.             c = (u_char) (ch | 0x20);
  1675.             if (c >= 'a' && c <= 'z') {
  1676.                 break;
  1677.             }

  1678.             if (ch == ':') {
  1679.                 ctx->header_name_end = p;
  1680.                 state = sw_space_before_value;
  1681.                 break;
  1682.             }

  1683.             if (ch == '-') {
  1684.                 break;
  1685.             }

  1686.             if (ch >= '0' && ch <= '9') {
  1687.                 break;
  1688.             }

  1689.             if (ch == CR) {
  1690.                 ctx->header_name_end = p;
  1691.                 ctx->header_start = p;
  1692.                 ctx->header_end = p;
  1693.                 state = sw_almost_done;
  1694.                 break;
  1695.             }

  1696.             if (ch == LF) {
  1697.                 ctx->header_name_end = p;
  1698.                 ctx->header_start = p;
  1699.                 ctx->header_end = p;
  1700.                 goto done;
  1701.             }

  1702.             return NGX_ERROR;

  1703.         /* space* before header value */
  1704.         case sw_space_before_value:
  1705.             switch (ch) {
  1706.             case ' ':
  1707.                 break;
  1708.             case CR:
  1709.                 ctx->header_start = p;
  1710.                 ctx->header_end = p;
  1711.                 state = sw_almost_done;
  1712.                 break;
  1713.             case LF:
  1714.                 ctx->header_start = p;
  1715.                 ctx->header_end = p;
  1716.                 goto done;
  1717.             default:
  1718.                 ctx->header_start = p;
  1719.                 state = sw_value;
  1720.                 break;
  1721.             }
  1722.             break;

  1723.         /* header value */
  1724.         case sw_value:
  1725.             switch (ch) {
  1726.             case ' ':
  1727.                 ctx->header_end = p;
  1728.                 state = sw_space_after_value;
  1729.                 break;
  1730.             case CR:
  1731.                 ctx->header_end = p;
  1732.                 state = sw_almost_done;
  1733.                 break;
  1734.             case LF:
  1735.                 ctx->header_end = p;
  1736.                 goto done;
  1737.             }
  1738.             break;

  1739.         /* space* before end of header line */
  1740.         case sw_space_after_value:
  1741.             switch (ch) {
  1742.             case ' ':
  1743.                 break;
  1744.             case CR:
  1745.                 state = sw_almost_done;
  1746.                 break;
  1747.             case LF:
  1748.                 goto done;
  1749.             default:
  1750.                 state = sw_value;
  1751.                 break;
  1752.             }
  1753.             break;

  1754.         /* end of header line */
  1755.         case sw_almost_done:
  1756.             switch (ch) {
  1757.             case LF:
  1758.                 goto done;
  1759.             default:
  1760.                 return NGX_ERROR;
  1761.             }

  1762.         /* end of header */
  1763.         case sw_header_almost_done:
  1764.             switch (ch) {
  1765.             case LF:
  1766.                 goto header_done;
  1767.             default:
  1768.                 return NGX_ERROR;
  1769.             }
  1770.         }
  1771.     }

  1772.     ctx->response->pos = p;
  1773.     ctx->state = state;

  1774.     return NGX_AGAIN;

  1775. done:

  1776.     ctx->response->pos = p + 1;
  1777.     ctx->state = sw_start;

  1778.     return NGX_OK;

  1779. header_done:

  1780.     ctx->response->pos = p + 1;
  1781.     ctx->state = sw_start;

  1782.     return NGX_DONE;
  1783. }


  1784. static ngx_int_t
  1785. ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx)
  1786. {
  1787.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1788.                    "ssl ocsp process body");

  1789.     if (ctx->done) {
  1790.         ctx->handler(ctx);
  1791.         return NGX_DONE;
  1792.     }

  1793.     return NGX_AGAIN;
  1794. }


  1795. static ngx_int_t
  1796. ngx_ssl_ocsp_verify(ngx_ssl_ocsp_ctx_t *ctx)
  1797. {
  1798.     int                    n;
  1799.     size_t                 len;
  1800.     X509_STORE            *store;
  1801.     const u_char          *p;
  1802.     OCSP_CERTID           *id;
  1803.     OCSP_RESPONSE         *ocsp;
  1804.     OCSP_BASICRESP        *basic;
  1805.     ASN1_GENERALIZEDTIME  *thisupdate, *nextupdate;

  1806.     ocsp = NULL;
  1807.     basic = NULL;
  1808.     id = NULL;

  1809.     if (ctx->code != 200) {
  1810.         goto error;
  1811.     }

  1812.     /* check the response */

  1813.     len = ctx->response->last - ctx->response->pos;
  1814.     p = ctx->response->pos;

  1815.     ocsp = d2i_OCSP_RESPONSE(NULL, &p, len);
  1816.     if (ocsp == NULL) {
  1817.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1818.                       "d2i_OCSP_RESPONSE() failed");
  1819.         goto error;
  1820.     }

  1821.     n = OCSP_response_status(ocsp);

  1822.     if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
  1823.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1824.                       "OCSP response not successful (%d: %s)",
  1825.                       n, OCSP_response_status_str(n));
  1826.         goto error;
  1827.     }

  1828.     basic = OCSP_response_get1_basic(ocsp);
  1829.     if (basic == NULL) {
  1830.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1831.                       "OCSP_response_get1_basic() failed");
  1832.         goto error;
  1833.     }

  1834.     store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
  1835.     if (store == NULL) {
  1836.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1837.                       "SSL_CTX_get_cert_store() failed");
  1838.         goto error;
  1839.     }

  1840.     if (OCSP_basic_verify(basic, ctx->chain, store, ctx->flags) != 1) {
  1841.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1842.                       "OCSP_basic_verify() failed");
  1843.         goto error;
  1844.     }

  1845.     id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
  1846.     if (id == NULL) {
  1847.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1848.                       "OCSP_cert_to_id() failed");
  1849.         goto error;
  1850.     }

  1851.     if (OCSP_resp_find_status(basic, id, &ctx->status, NULL, NULL,
  1852.                               &thisupdate, &nextupdate)
  1853.         != 1)
  1854.     {
  1855.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1856.                       "certificate status not found in the OCSP response");
  1857.         goto error;
  1858.     }

  1859.     if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
  1860.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1861.                       "OCSP_check_validity() failed");
  1862.         goto error;
  1863.     }

  1864.     if (nextupdate) {
  1865.         ctx->valid = ngx_ssl_stapling_time(nextupdate);
  1866.         if (ctx->valid == (time_t) NGX_ERROR) {
  1867.             ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1868.                           "invalid nextUpdate time in certificate status");
  1869.             goto error;
  1870.         }

  1871.     } else {
  1872.         ctx->valid = NGX_MAX_TIME_T_VALUE;
  1873.     }

  1874.     OCSP_CERTID_free(id);
  1875.     OCSP_BASICRESP_free(basic);
  1876.     OCSP_RESPONSE_free(ocsp);

  1877.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1878.                    "ssl ocsp response, %s, %uz",
  1879.                    OCSP_cert_status_str(ctx->status), len);

  1880.     return NGX_OK;

  1881. error:

  1882.     if (id) {
  1883.         OCSP_CERTID_free(id);
  1884.     }

  1885.     if (basic) {
  1886.         OCSP_BASICRESP_free(basic);
  1887.     }

  1888.     if (ocsp) {
  1889.         OCSP_RESPONSE_free(ocsp);
  1890.     }

  1891.     return NGX_ERROR;
  1892. }


  1893. ngx_int_t
  1894. ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  1895. {
  1896.     size_t                 len;
  1897.     ngx_slab_pool_t       *shpool;
  1898.     ngx_ssl_ocsp_cache_t  *cache;

  1899.     if (data) {
  1900.         shm_zone->data = data;
  1901.         return NGX_OK;
  1902.     }

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

  1904.     if (shm_zone->shm.exists) {
  1905.         shm_zone->data = shpool->data;
  1906.         return NGX_OK;
  1907.     }

  1908.     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_ocsp_cache_t));
  1909.     if (cache == NULL) {
  1910.         return NGX_ERROR;
  1911.     }

  1912.     shpool->data = cache;
  1913.     shm_zone->data = cache;

  1914.     ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
  1915.                     ngx_str_rbtree_insert_value);

  1916.     ngx_queue_init(&cache->expire_queue);

  1917.     len = sizeof(" in OCSP cache \"\"") + shm_zone->shm.name.len;

  1918.     shpool->log_ctx = ngx_slab_alloc(shpool, len);
  1919.     if (shpool->log_ctx == NULL) {
  1920.         return NGX_ERROR;
  1921.     }

  1922.     ngx_sprintf(shpool->log_ctx, " in OCSP cache \"%V\"%Z",
  1923.                 &shm_zone->shm.name);

  1924.     shpool->log_nomem = 0;

  1925.     return NGX_OK;
  1926. }


  1927. static ngx_int_t
  1928. ngx_ssl_ocsp_cache_lookup(ngx_ssl_ocsp_ctx_t *ctx)
  1929. {
  1930.     uint32_t                    hash;
  1931.     ngx_shm_zone_t             *shm_zone;
  1932.     ngx_slab_pool_t            *shpool;
  1933.     ngx_ssl_ocsp_cache_t       *cache;
  1934.     ngx_ssl_ocsp_cache_node_t  *node;

  1935.     shm_zone = ctx->shm_zone;

  1936.     if (shm_zone == NULL) {
  1937.         return NGX_DECLINED;
  1938.     }

  1939.     if (ngx_ssl_ocsp_create_key(ctx) != NGX_OK) {
  1940.         return NGX_ERROR;
  1941.     }

  1942.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "ssl ocsp cache lookup");

  1943.     cache = shm_zone->data;
  1944.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
  1945.     hash = ngx_hash_key(ctx->key.data, ctx->key.len);

  1946.     ngx_shmtx_lock(&shpool->mutex);

  1947.     node = (ngx_ssl_ocsp_cache_node_t *)
  1948.                ngx_str_rbtree_lookup(&cache->rbtree, &ctx->key, hash);

  1949.     if (node) {
  1950.         if (node->valid > ngx_time()) {
  1951.             ctx->status = node->status;
  1952.             ngx_shmtx_unlock(&shpool->mutex);

  1953.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1954.                            "ssl ocsp cache hit, %s",
  1955.                            OCSP_cert_status_str(ctx->status));

  1956.             return NGX_OK;
  1957.         }

  1958.         ngx_queue_remove(&node->queue);
  1959.         ngx_rbtree_delete(&cache->rbtree, &node->node.node);
  1960.         ngx_slab_free_locked(shpool, node);

  1961.         ngx_shmtx_unlock(&shpool->mutex);

  1962.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1963.                        "ssl ocsp cache expired");

  1964.         return NGX_DECLINED;
  1965.     }

  1966.     ngx_shmtx_unlock(&shpool->mutex);

  1967.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0, "ssl ocsp cache miss");

  1968.     return NGX_DECLINED;
  1969. }


  1970. static ngx_int_t
  1971. ngx_ssl_ocsp_cache_store(ngx_ssl_ocsp_ctx_t *ctx)
  1972. {
  1973.     time_t                      now, valid;
  1974.     uint32_t                    hash;
  1975.     ngx_queue_t                *q;
  1976.     ngx_shm_zone_t             *shm_zone;
  1977.     ngx_slab_pool_t            *shpool;
  1978.     ngx_ssl_ocsp_cache_t       *cache;
  1979.     ngx_ssl_ocsp_cache_node_t  *node;

  1980.     shm_zone = ctx->shm_zone;

  1981.     if (shm_zone == NULL) {
  1982.         return NGX_OK;
  1983.     }

  1984.     valid = ctx->valid;

  1985.     now = ngx_time();

  1986.     if (valid < now) {
  1987.         return NGX_OK;
  1988.     }

  1989.     if (valid == NGX_MAX_TIME_T_VALUE) {
  1990.         valid = now + 3600;
  1991.     }

  1992.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1993.                    "ssl ocsp cache store, valid:%T", valid - now);

  1994.     cache = shm_zone->data;
  1995.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
  1996.     hash = ngx_hash_key(ctx->key.data, ctx->key.len);

  1997.     ngx_shmtx_lock(&shpool->mutex);

  1998.     node = ngx_slab_calloc_locked(shpool,
  1999.                              sizeof(ngx_ssl_ocsp_cache_node_t) + ctx->key.len);
  2000.     if (node == NULL) {

  2001.         if (!ngx_queue_empty(&cache->expire_queue)) {
  2002.             q = ngx_queue_last(&cache->expire_queue);
  2003.             node = ngx_queue_data(q, ngx_ssl_ocsp_cache_node_t, queue);

  2004.             ngx_rbtree_delete(&cache->rbtree, &node->node.node);
  2005.             ngx_queue_remove(q);
  2006.             ngx_slab_free_locked(shpool, node);

  2007.             node = ngx_slab_alloc_locked(shpool,
  2008.                              sizeof(ngx_ssl_ocsp_cache_node_t) + ctx->key.len);
  2009.         }

  2010.         if (node == NULL) {
  2011.             ngx_shmtx_unlock(&shpool->mutex);
  2012.             ngx_log_error(NGX_LOG_ALERT, ctx->log, 0,
  2013.                           "could not allocate new entry%s", shpool->log_ctx);
  2014.             return NGX_ERROR;
  2015.         }
  2016.     }

  2017.     node->node.str.len = ctx->key.len;
  2018.     node->node.str.data = (u_char *) node + sizeof(ngx_ssl_ocsp_cache_node_t);
  2019.     ngx_memcpy(node->node.str.data, ctx->key.data, ctx->key.len);
  2020.     node->node.node.key = hash;
  2021.     node->status = ctx->status;
  2022.     node->valid = valid;

  2023.     ngx_rbtree_insert(&cache->rbtree, &node->node.node);
  2024.     ngx_queue_insert_head(&cache->expire_queue, &node->queue);

  2025.     ngx_shmtx_unlock(&shpool->mutex);

  2026.     return NGX_OK;
  2027. }


  2028. static ngx_int_t
  2029. ngx_ssl_ocsp_create_key(ngx_ssl_ocsp_ctx_t *ctx)
  2030. {
  2031.     u_char        *p;
  2032.     X509_NAME     *name;
  2033.     ASN1_INTEGER  *serial;

  2034.     p = ngx_pnalloc(ctx->pool, 60);
  2035.     if (p == NULL) {
  2036.         return NGX_ERROR;
  2037.     }

  2038.     ctx->key.data = p;
  2039.     ctx->key.len = 60;

  2040.     name = X509_get_subject_name(ctx->issuer);
  2041.     if (X509_NAME_digest(name, EVP_sha1(), p, NULL) == 0) {
  2042.         return NGX_ERROR;
  2043.     }

  2044.     p += 20;

  2045.     if (X509_pubkey_digest(ctx->issuer, EVP_sha1(), p, NULL) == 0) {
  2046.         return NGX_ERROR;
  2047.     }

  2048.     p += 20;

  2049.     serial = X509_get_serialNumber(ctx->cert);
  2050.     if (serial->length > 20) {
  2051.         return NGX_ERROR;
  2052.     }

  2053.     p = ngx_cpymem(p, serial->data, serial->length);
  2054.     ngx_memzero(p, 20 - serial->length);

  2055.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  2056.                    "ssl ocsp key %xV", &ctx->key);

  2057.     return NGX_OK;
  2058. }


  2059. static u_char *
  2060. ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len)
  2061. {
  2062.     u_char              *p;
  2063.     ngx_ssl_ocsp_ctx_t  *ctx;

  2064.     p = buf;

  2065.     if (log->action) {
  2066.         p = ngx_snprintf(buf, len, " while %s", log->action);
  2067.         len -= p - buf;
  2068.         buf = p;
  2069.     }

  2070.     ctx = log->data;

  2071.     if (ctx) {
  2072.         p = ngx_snprintf(buf, len, ", responder: %V", &ctx->host);
  2073.         len -= p - buf;
  2074.         buf = p;
  2075.     }

  2076.     if (ctx && ctx->peer.name) {
  2077.         p = ngx_snprintf(buf, len, ", peer: %V", ctx->peer.name);
  2078.         len -= p - buf;
  2079.         buf = p;
  2080.     }

  2081.     if (ctx && ctx->name) {
  2082.         p = ngx_snprintf(buf, len, ", certificate: \"%s\"", ctx->name);
  2083.         len -= p - buf;
  2084.         buf = p;
  2085.     }

  2086.     return p;
  2087. }


  2088. #else


  2089. ngx_int_t
  2090. ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
  2091.     ngx_str_t *responder, ngx_uint_t verify)
  2092. {
  2093.     ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  2094.                   "\"ssl_stapling\" ignored, not supported");

  2095.     return NGX_OK;
  2096. }


  2097. ngx_int_t
  2098. ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
  2099.     ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
  2100. {
  2101.     return NGX_OK;
  2102. }


  2103. ngx_int_t
  2104. ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
  2105.     ngx_uint_t depth, ngx_shm_zone_t *shm_zone)
  2106. {
  2107.     ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,
  2108.                   "\"ssl_ocsp\" is not supported on this platform");

  2109.     return NGX_ERROR;
  2110. }


  2111. ngx_int_t
  2112. ngx_ssl_ocsp_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
  2113.     ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
  2114. {
  2115.     return NGX_OK;
  2116. }


  2117. ngx_int_t
  2118. ngx_ssl_ocsp_validate(ngx_connection_t *c)
  2119. {
  2120.     return NGX_OK;
  2121. }


  2122. ngx_int_t
  2123. ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s)
  2124. {
  2125.     return NGX_OK;
  2126. }


  2127. void
  2128. ngx_ssl_ocsp_cleanup(ngx_connection_t *c)
  2129. {
  2130. }


  2131. ngx_int_t
  2132. ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  2133. {
  2134.     return NGX_OK;
  2135. }


  2136. #endif