src/event/ngx_event_openssl_stapling.c - nginx

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_resolver_ctx_t          *resolve;

  79.     ngx_msec_t                   timeout;

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

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

  86.     ngx_shm_zone_t              *shm_zone;

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

  88.     ngx_uint_t                   state;

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

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

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


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

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

  113. static time_t ngx_ssl_stapling_time(ASN1_GENERALIZEDTIME *asn1time);

  114. static void ngx_ssl_stapling_cleanup(void *data);

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

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

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

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

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


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

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

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

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

  154.     return NGX_OK;
  155. }


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

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

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

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

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

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

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

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

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

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

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

  196.         return NGX_OK;
  197.     }

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

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

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

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

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

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

  212.     return NGX_OK;
  213. }


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

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

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

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

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

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

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

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

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

  261.     return NGX_OK;

  262. failed:

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

  265.     return NGX_ERROR;
  266. }


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

  275.     cert = staple->cert;

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

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

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

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

  289.             staple->issuer = issuer;

  290.             return NGX_OK;
  291.         }
  292.     }

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

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

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

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

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

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

  326.     X509_STORE_CTX_free(store_ctx);

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

  329.     staple->issuer = issuer;

  330.     return NGX_OK;
  331. }


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

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

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

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

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

  363.         responder = &rsp;

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

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

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

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

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

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

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

  399.         return NGX_ERROR;
  400.     }

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

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

  409.     return NGX_OK;
  410. }


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

  418.     tree = &ssl->staple_rbtree;

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

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

  430.     return NGX_OK;
  431. }


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

  442.     c = ngx_ssl_get_connection(ssl_conn);

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

  445.     rc = SSL_TLSEXT_ERR_NOACK;

  446.     cert = SSL_get_certificate(ssl_conn);

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

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

  452.     staple = ngx_ssl_stapling_lookup(ssl, cert);

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

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

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

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

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

  467.         rc = SSL_TLSEXT_ERR_OK;
  468.     }

  469.     ngx_ssl_stapling_update(staple);

  470.     return rc;
  471. }


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

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

  480.     while (node != sentinel) {

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

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

  487.     return NULL;
  488. }


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

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

  498.     staple->loading = 1;

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

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

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

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

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

  519.     ngx_ssl_ocsp_request(ctx);

  520.     return;
  521. }


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

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

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

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

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

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

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

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

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

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

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

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

  557.     ngx_ssl_ocsp_done(ctx);
  558.     return;

  559. error:

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

  562.     ngx_ssl_ocsp_done(ctx);
  563. }


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

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

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

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

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

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

  586.     BIO_free(bio);

  587.     return time;
  588. }


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

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

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


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

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

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

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

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

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

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

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

  634.             return NGX_ERROR;
  635.         }

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

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

  647.     return NGX_OK;
  648. }


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

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

  657.     return NGX_OK;
  658. }


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

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

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

  677.         return NGX_AGAIN;
  678.     }

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

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

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

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

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

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

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

  700. #if OPENSSL_VERSION_NUMBER >= 0x10100000L

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

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

  709. #endif

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

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

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

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

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

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

  748.         X509_STORE_CTX_free(store_ctx);
  749.     }

  750.     X509_free(cert);

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

  753.     ngx_ssl_ocsp_validate_next(c);

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

  758.     return NGX_OK;
  759. }


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

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

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

  771.     for ( ;; ) {

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

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

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

  785.         ocsp->ctx = ctx;

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

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

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

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

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

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

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

  807.         ocsp->ncert++;

  808.         rc = ngx_ssl_ocsp_cache_lookup(ctx);

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

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

  815.         /* rc == NGX_OK */

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

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

  826.     ngx_ssl_ocsp_request(ctx);
  827.     return;

  828. done:

  829.     ocsp->status = rc;

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


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

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

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

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

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

  856.     ngx_ssl_ocsp_done(ctx);

  857.     ngx_ssl_ocsp_validate_next(c);

  858.     return;

  859. done:

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

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


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

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

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

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

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

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

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

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

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

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

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

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

  925.         return NGX_ERROR;
  926.     }

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

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

  937.     return NGX_OK;
  938. }


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

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

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

  951.     switch (ocsp->cert_status) {

  952.     case V_OCSP_CERTSTATUS_GOOD:
  953.         return NGX_OK;

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

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

  960.     return NGX_DECLINED;
  961. }


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

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

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

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


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

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

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

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

  998.     ctx->pool = pool;

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

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

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

  1005.     return ctx;
  1006. }


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

  1012.     if (ctx->resolve) {
  1013.         ngx_resolve_name_done(ctx->resolve);
  1014.     }

  1015.     if (ctx->peer.connection) {
  1016.         ngx_close_connection(ctx->peer.connection);
  1017.     }

  1018.     ngx_destroy_pool(ctx->pool);
  1019. }


  1020. static void
  1021. ngx_ssl_ocsp_error(ngx_ssl_ocsp_ctx_t *ctx)
  1022. {
  1023.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1024.                    "ssl ocsp error");

  1025.     ctx->code = 0;
  1026.     ctx->handler(ctx);
  1027. }


  1028. static void
  1029. ngx_ssl_ocsp_next(ngx_ssl_ocsp_ctx_t *ctx)
  1030. {
  1031.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1032.                    "ssl ocsp next");

  1033.     if (++ctx->naddr >= ctx->naddrs) {
  1034.         ngx_ssl_ocsp_error(ctx);
  1035.         return;
  1036.     }

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

  1038.     if (ctx->response) {
  1039.         ctx->response->last = ctx->response->pos;
  1040.     }

  1041.     if (ctx->peer.connection) {
  1042.         ngx_close_connection(ctx->peer.connection);
  1043.         ctx->peer.connection = NULL;
  1044.     }

  1045.     ctx->state = 0;
  1046.     ctx->count = 0;
  1047.     ctx->done = 0;

  1048.     ngx_ssl_ocsp_connect(ctx);
  1049. }


  1050. static void
  1051. ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx)
  1052. {
  1053.     ngx_resolver_ctx_t  *resolve, temp;

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

  1056.     if (ngx_ssl_ocsp_create_request(ctx) != NGX_OK) {
  1057.         ngx_ssl_ocsp_error(ctx);
  1058.         return;
  1059.     }

  1060.     if (ctx->resolver) {
  1061.         /* resolve OCSP responder hostname */

  1062.         temp.name = ctx->host;

  1063.         resolve = ngx_resolve_start(ctx->resolver, &temp);
  1064.         if (resolve == NULL) {
  1065.             ngx_ssl_ocsp_error(ctx);
  1066.             return;
  1067.         }

  1068.         if (resolve == NGX_NO_RESOLVER) {
  1069.             if (ctx->naddrs == 0) {
  1070.                 ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1071.                               "no resolver defined to resolve %V", &ctx->host);

  1072.                 ngx_ssl_ocsp_error(ctx);
  1073.                 return;
  1074.             }

  1075.             ngx_log_error(NGX_LOG_WARN, ctx->log, 0,
  1076.                           "no resolver defined to resolve %V", &ctx->host);
  1077.             goto connect;
  1078.         }

  1079.         resolve->name = ctx->host;
  1080.         resolve->handler = ngx_ssl_ocsp_resolve_handler;
  1081.         resolve->data = ctx;
  1082.         resolve->timeout = ctx->resolver_timeout;

  1083.         ctx->resolve = resolve;

  1084.         if (ngx_resolve_name(resolve) != NGX_OK) {
  1085.             ctx->resolve = NULL;
  1086.             ngx_ssl_ocsp_error(ctx);
  1087.             return;
  1088.         }

  1089.         return;
  1090.     }

  1091. connect:

  1092.     ngx_ssl_ocsp_connect(ctx);
  1093. }


  1094. static void
  1095. ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
  1096. {
  1097.     ngx_ssl_ocsp_ctx_t *ctx = resolve->data;

  1098.     u_char           *p;
  1099.     size_t            len;
  1100.     socklen_t         socklen;
  1101.     ngx_uint_t        i;
  1102.     struct sockaddr  *sockaddr;

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

  1105.     if (resolve->state) {
  1106.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1107.                       "%V could not be resolved (%i: %s)",
  1108.                       &resolve->name, resolve->state,
  1109.                       ngx_resolver_strerror(resolve->state));
  1110.         goto failed;
  1111.     }

  1112. #if (NGX_DEBUG)
  1113.     {
  1114.     u_char     text[NGX_SOCKADDR_STRLEN];
  1115.     ngx_str_t  addr;

  1116.     addr.data = text;

  1117.     for (i = 0; i < resolve->naddrs; i++) {
  1118.         addr.len = ngx_sock_ntop(resolve->addrs[i].sockaddr,
  1119.                                  resolve->addrs[i].socklen,
  1120.                                  text, NGX_SOCKADDR_STRLEN, 0);

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

  1123.     }
  1124.     }
  1125. #endif

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

  1128.     if (ctx->addrs == NULL) {
  1129.         goto failed;
  1130.     }

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

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

  1133.         sockaddr = ngx_palloc(ctx->pool, socklen);
  1134.         if (sockaddr == NULL) {
  1135.             goto failed;
  1136.         }

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

  1139.         ctx->addrs[i].sockaddr = sockaddr;
  1140.         ctx->addrs[i].socklen = socklen;

  1141.         p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN);
  1142.         if (p == NULL) {
  1143.             goto failed;
  1144.         }

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

  1146.         ctx->addrs[i].name.len = len;
  1147.         ctx->addrs[i].name.data = p;
  1148.     }

  1149.     ngx_resolve_name_done(resolve);
  1150.     ctx->resolve = NULL;

  1151.     ngx_ssl_ocsp_connect(ctx);
  1152.     return;

  1153. failed:

  1154.     ngx_resolve_name_done(resolve);
  1155.     ctx->resolve = NULL;

  1156.     ngx_ssl_ocsp_error(ctx);
  1157. }


  1158. static void
  1159. ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx)
  1160. {
  1161.     ngx_int_t    rc;
  1162.     ngx_addr_t  *addr;

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

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

  1166.     ctx->peer.sockaddr = addr->sockaddr;
  1167.     ctx->peer.socklen = addr->socklen;
  1168.     ctx->peer.name = &addr->name;
  1169.     ctx->peer.get = ngx_event_get_peer;
  1170.     ctx->peer.log = ctx->log;
  1171.     ctx->peer.log_error = NGX_ERROR_ERR;

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

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

  1175.     if (rc == NGX_ERROR) {
  1176.         ngx_ssl_ocsp_error(ctx);
  1177.         return;
  1178.     }

  1179.     if (rc == NGX_BUSY || rc == NGX_DECLINED) {
  1180.         ngx_ssl_ocsp_next(ctx);
  1181.         return;
  1182.     }

  1183.     ctx->peer.connection->data = ctx;
  1184.     ctx->peer.connection->pool = ctx->pool;

  1185.     ctx->peer.connection->read->handler = ngx_ssl_ocsp_read_handler;
  1186.     ctx->peer.connection->write->handler = ngx_ssl_ocsp_write_handler;

  1187.     ctx->process = ngx_ssl_ocsp_process_status_line;

  1188.     if (ctx->timeout) {
  1189.         ngx_add_timer(ctx->peer.connection->read, ctx->timeout);
  1190.         ngx_add_timer(ctx->peer.connection->write, ctx->timeout);
  1191.     }

  1192.     if (rc == NGX_OK) {
  1193.         ngx_ssl_ocsp_write_handler(ctx->peer.connection->write);
  1194.         return;
  1195.     }
  1196. }


  1197. static void
  1198. ngx_ssl_ocsp_write_handler(ngx_event_t *wev)
  1199. {
  1200.     ssize_t              n, size;
  1201.     ngx_connection_t    *c;
  1202.     ngx_ssl_ocsp_ctx_t  *ctx;

  1203.     c = wev->data;
  1204.     ctx = c->data;

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

  1207.     if (wev->timedout) {
  1208.         ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
  1209.                       "OCSP responder timed out");
  1210.         ngx_ssl_ocsp_next(ctx);
  1211.         return;
  1212.     }

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

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

  1215.     if (n == NGX_ERROR) {
  1216.         ngx_ssl_ocsp_next(ctx);
  1217.         return;
  1218.     }

  1219.     if (n > 0) {
  1220.         ctx->request->pos += n;

  1221.         if (n == size) {
  1222.             wev->handler = ngx_ssl_ocsp_dummy_handler;

  1223.             if (wev->timer_set) {
  1224.                 ngx_del_timer(wev);
  1225.             }

  1226.             if (ngx_handle_write_event(wev, 0) != NGX_OK) {
  1227.                 ngx_ssl_ocsp_error(ctx);
  1228.             }

  1229.             return;
  1230.         }
  1231.     }

  1232.     if (!wev->timer_set && ctx->timeout) {
  1233.         ngx_add_timer(wev, ctx->timeout);
  1234.     }
  1235. }


  1236. static void
  1237. ngx_ssl_ocsp_read_handler(ngx_event_t *rev)
  1238. {
  1239.     ssize_t              n, size;
  1240.     ngx_int_t            rc;
  1241.     ngx_connection_t    *c;
  1242.     ngx_ssl_ocsp_ctx_t  *ctx;

  1243.     c = rev->data;
  1244.     ctx = c->data;

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

  1247.     if (rev->timedout) {
  1248.         ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
  1249.                       "OCSP responder timed out");
  1250.         ngx_ssl_ocsp_next(ctx);
  1251.         return;
  1252.     }

  1253.     if (ctx->response == NULL) {
  1254.         ctx->response = ngx_create_temp_buf(ctx->pool, 16384);
  1255.         if (ctx->response == NULL) {
  1256.             ngx_ssl_ocsp_error(ctx);
  1257.             return;
  1258.         }
  1259.     }

  1260.     for ( ;; ) {

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

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

  1263.         if (n > 0) {
  1264.             ctx->response->last += n;

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

  1266.             if (rc == NGX_ERROR) {
  1267.                 ngx_ssl_ocsp_next(ctx);
  1268.                 return;
  1269.             }

  1270.             continue;
  1271.         }

  1272.         if (n == NGX_AGAIN) {

  1273.             if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  1274.                 ngx_ssl_ocsp_error(ctx);
  1275.             }

  1276.             return;
  1277.         }

  1278.         break;
  1279.     }

  1280.     ctx->done = 1;

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

  1282.     if (rc == NGX_DONE) {
  1283.         /* ctx->handler() was called */
  1284.         return;
  1285.     }

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

  1288.     ngx_ssl_ocsp_next(ctx);
  1289. }


  1290. static void
  1291. ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev)
  1292. {
  1293.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
  1294.                    "ssl ocsp dummy handler");
  1295. }


  1296. static ngx_int_t
  1297. ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
  1298. {
  1299.     int            len;
  1300.     u_char        *p;
  1301.     uintptr_t      escape;
  1302.     ngx_str_t      binary, base64;
  1303.     ngx_buf_t     *b;
  1304.     OCSP_CERTID   *id;
  1305.     OCSP_REQUEST  *ocsp;

  1306.     ocsp = OCSP_REQUEST_new();
  1307.     if (ocsp == NULL) {
  1308.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1309.                       "OCSP_REQUEST_new() failed");
  1310.         return NGX_ERROR;
  1311.     }

  1312.     id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
  1313.     if (id == NULL) {
  1314.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1315.                       "OCSP_cert_to_id() failed");
  1316.         goto failed;
  1317.     }

  1318.     if (OCSP_request_add0_id(ocsp, id) == NULL) {
  1319.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1320.                       "OCSP_request_add0_id() failed");
  1321.         OCSP_CERTID_free(id);
  1322.         goto failed;
  1323.     }

  1324.     len = i2d_OCSP_REQUEST(ocsp, NULL);
  1325.     if (len <= 0) {
  1326.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1327.                       "i2d_OCSP_REQUEST() failed");
  1328.         goto failed;
  1329.     }

  1330.     binary.len = len;
  1331.     binary.data = ngx_palloc(ctx->pool, len);
  1332.     if (binary.data == NULL) {
  1333.         goto failed;
  1334.     }

  1335.     p = binary.data;
  1336.     len = i2d_OCSP_REQUEST(ocsp, &p);
  1337.     if (len <= 0) {
  1338.         ngx_ssl_error(NGX_LOG_EMERG, ctx->log, 0,
  1339.                       "i2d_OCSP_REQUEST() failed");
  1340.         goto failed;
  1341.     }

  1342.     base64.len = ngx_base64_encoded_length(binary.len);
  1343.     base64.data = ngx_palloc(ctx->pool, base64.len);
  1344.     if (base64.data == NULL) {
  1345.         goto failed;
  1346.     }

  1347.     ngx_encode_base64(&base64, &binary);

  1348.     escape = ngx_escape_uri(NULL, base64.data, base64.len,
  1349.                             NGX_ESCAPE_URI_COMPONENT);

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

  1353.     len = sizeof("GET ") - 1 + ctx->uri.len + sizeof("/") - 1
  1354.           + base64.len + 2 * escape + sizeof(" HTTP/1.0" CRLF) - 1
  1355.           + sizeof("Host: ") - 1 + ctx->host.len + sizeof(CRLF) - 1
  1356.           + sizeof(CRLF) - 1;

  1357.     b = ngx_create_temp_buf(ctx->pool, len);
  1358.     if (b == NULL) {
  1359.         goto failed;
  1360.     }

  1361.     p = b->last;

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

  1364.     if (ctx->uri.data[ctx->uri.len - 1] != '/') {
  1365.         *p++ = '/';
  1366.     }

  1367.     if (escape == 0) {
  1368.         p = ngx_cpymem(p, base64.data, base64.len);

  1369.     } else {
  1370.         p = (u_char *) ngx_escape_uri(p, base64.data, base64.len,
  1371.                                       NGX_ESCAPE_URI_COMPONENT);
  1372.     }

  1373.     p = ngx_cpymem(p, " HTTP/1.0" CRLF, sizeof(" HTTP/1.0" CRLF) - 1);
  1374.     p = ngx_cpymem(p, "Host: ", sizeof("Host: ") - 1);
  1375.     p = ngx_cpymem(p, ctx->host.data, ctx->host.len);
  1376.     *p++ = CR; *p++ = LF;

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

  1379.     b->last = p;
  1380.     ctx->request = b;

  1381.     OCSP_REQUEST_free(ocsp);

  1382.     return NGX_OK;

  1383. failed:

  1384.     OCSP_REQUEST_free(ocsp);

  1385.     return NGX_ERROR;
  1386. }


  1387. static ngx_int_t
  1388. ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx)
  1389. {
  1390.     ngx_int_t  rc;

  1391.     rc = ngx_ssl_ocsp_parse_status_line(ctx);

  1392.     if (rc == NGX_OK) {
  1393.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1394.                        "ssl ocsp status %ui \"%*s\"",
  1395.                        ctx->code,
  1396.                        ctx->header_end - ctx->header_start,
  1397.                        ctx->header_start);

  1398.         ctx->process = ngx_ssl_ocsp_process_headers;
  1399.         return ctx->process(ctx);
  1400.     }

  1401.     if (rc == NGX_AGAIN) {
  1402.         return NGX_AGAIN;
  1403.     }

  1404.     /* rc == NGX_ERROR */

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

  1407.     return NGX_ERROR;
  1408. }


  1409. static ngx_int_t
  1410. ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx)
  1411. {
  1412.     u_char      ch;
  1413.     u_char     *p;
  1414.     ngx_buf_t  *b;
  1415.     enum {
  1416.         sw_start = 0,
  1417.         sw_H,
  1418.         sw_HT,
  1419.         sw_HTT,
  1420.         sw_HTTP,
  1421.         sw_first_major_digit,
  1422.         sw_major_digit,
  1423.         sw_first_minor_digit,
  1424.         sw_minor_digit,
  1425.         sw_status,
  1426.         sw_space_after_status,
  1427.         sw_status_text,
  1428.         sw_almost_done
  1429.     } state;

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

  1432.     state = ctx->state;
  1433.     b = ctx->response;

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

  1436.         switch (state) {

  1437.         /* "HTTP/" */
  1438.         case sw_start:
  1439.             switch (ch) {
  1440.             case 'H':
  1441.                 state = sw_H;
  1442.                 break;
  1443.             default:
  1444.                 return NGX_ERROR;
  1445.             }
  1446.             break;

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

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

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

  1474.         case sw_HTTP:
  1475.             switch (ch) {
  1476.             case '/':
  1477.                 state = sw_first_major_digit;
  1478.                 break;
  1479.             default:
  1480.                 return NGX_ERROR;
  1481.             }
  1482.             break;

  1483.         /* the first digit of major HTTP version */
  1484.         case sw_first_major_digit:
  1485.             if (ch < '1' || ch > '9') {
  1486.                 return NGX_ERROR;
  1487.             }

  1488.             state = sw_major_digit;
  1489.             break;

  1490.         /* the major HTTP version or dot */
  1491.         case sw_major_digit:
  1492.             if (ch == '.') {
  1493.                 state = sw_first_minor_digit;
  1494.                 break;
  1495.             }

  1496.             if (ch < '0' || ch > '9') {
  1497.                 return NGX_ERROR;
  1498.             }

  1499.             break;

  1500.         /* the first digit of minor HTTP version */
  1501.         case sw_first_minor_digit:
  1502.             if (ch < '0' || ch > '9') {
  1503.                 return NGX_ERROR;
  1504.             }

  1505.             state = sw_minor_digit;
  1506.             break;

  1507.         /* the minor HTTP version or the end of the request line */
  1508.         case sw_minor_digit:
  1509.             if (ch == ' ') {
  1510.                 state = sw_status;
  1511.                 break;
  1512.             }

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

  1516.             break;

  1517.         /* HTTP status code */
  1518.         case sw_status:
  1519.             if (ch == ' ') {
  1520.                 break;
  1521.             }

  1522.             if (ch < '0' || ch > '9') {
  1523.                 return NGX_ERROR;
  1524.             }

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

  1526.             if (++ctx->count == 3) {
  1527.                 state = sw_space_after_status;
  1528.                 ctx->header_start = p - 2;
  1529.             }

  1530.             break;

  1531.         /* space or end of line */
  1532.         case sw_space_after_status:
  1533.             switch (ch) {
  1534.             case ' ':
  1535.                 state = sw_status_text;
  1536.                 break;
  1537.             case '.':                    /* IIS may send 403.1, 403.2, etc */
  1538.                 state = sw_status_text;
  1539.                 break;
  1540.             case CR:
  1541.                 state = sw_almost_done;
  1542.                 break;
  1543.             case LF:
  1544.                 ctx->header_end = p;
  1545.                 goto done;
  1546.             default:
  1547.                 return NGX_ERROR;
  1548.             }
  1549.             break;

  1550.         /* any text until end of line */
  1551.         case sw_status_text:
  1552.             switch (ch) {
  1553.             case CR:
  1554.                 state = sw_almost_done;
  1555.                 break;
  1556.             case LF:
  1557.                 ctx->header_end = p;
  1558.                 goto done;
  1559.             }
  1560.             break;

  1561.         /* end of status line */
  1562.         case sw_almost_done:
  1563.             switch (ch) {
  1564.             case LF:
  1565.                 ctx->header_end = p - 1;
  1566.                 goto done;
  1567.             default:
  1568.                 return NGX_ERROR;
  1569.             }
  1570.         }
  1571.     }

  1572.     b->pos = p;
  1573.     ctx->state = state;

  1574.     return NGX_AGAIN;

  1575. done:

  1576.     b->pos = p + 1;
  1577.     ctx->state = sw_start;

  1578.     return NGX_OK;
  1579. }


  1580. static ngx_int_t
  1581. ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx)
  1582. {
  1583.     size_t     len;
  1584.     ngx_int_t  rc;

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

  1587.     for ( ;; ) {
  1588.         rc = ngx_ssl_ocsp_parse_header_line(ctx);

  1589.         if (rc == NGX_OK) {

  1590.             ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1591.                            "ssl ocsp header \"%*s: %*s\"",
  1592.                            ctx->header_name_end - ctx->header_name_start,
  1593.                            ctx->header_name_start,
  1594.                            ctx->header_end - ctx->header_start,
  1595.                            ctx->header_start);

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

  1597.             if (len == sizeof("Content-Type") - 1
  1598.                 && ngx_strncasecmp(ctx->header_name_start,
  1599.                                    (u_char *) "Content-Type",
  1600.                                    sizeof("Content-Type") - 1)
  1601.                    == 0)
  1602.             {
  1603.                 len = ctx->header_end - ctx->header_start;

  1604.                 if (len != sizeof("application/ocsp-response") - 1
  1605.                     || ngx_strncasecmp(ctx->header_start,
  1606.                                        (u_char *) "application/ocsp-response",
  1607.                                        sizeof("application/ocsp-response") - 1)
  1608.                        != 0)
  1609.                 {
  1610.                     ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1611.                                   "OCSP responder sent invalid "
  1612.                                   "\"Content-Type\" header: \"%*s\"",
  1613.                                   ctx->header_end - ctx->header_start,
  1614.                                   ctx->header_start);
  1615.                     return NGX_ERROR;
  1616.                 }

  1617.                 continue;
  1618.             }

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

  1620.             continue;
  1621.         }

  1622.         if (rc == NGX_DONE) {
  1623.             break;
  1624.         }

  1625.         if (rc == NGX_AGAIN) {
  1626.             return NGX_AGAIN;
  1627.         }

  1628.         /* rc == NGX_ERROR */

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

  1631.         return NGX_ERROR;
  1632.     }

  1633.     ctx->process = ngx_ssl_ocsp_process_body;
  1634.     return ctx->process(ctx);
  1635. }


  1636. static ngx_int_t
  1637. ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx)
  1638. {
  1639.     u_char  c, ch, *p;
  1640.     enum {
  1641.         sw_start = 0,
  1642.         sw_name,
  1643.         sw_space_before_value,
  1644.         sw_value,
  1645.         sw_space_after_value,
  1646.         sw_almost_done,
  1647.         sw_header_almost_done
  1648.     } state;

  1649.     state = ctx->state;

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

  1652. #if 0
  1653.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1654.                        "s:%d in:'%02Xd:%c'", state, ch, ch);
  1655. #endif

  1656.         switch (state) {

  1657.         /* first char */
  1658.         case sw_start:

  1659.             switch (ch) {
  1660.             case CR:
  1661.                 ctx->header_end = p;
  1662.                 state = sw_header_almost_done;
  1663.                 break;
  1664.             case LF:
  1665.                 ctx->header_end = p;
  1666.                 goto header_done;
  1667.             default:
  1668.                 state = sw_name;
  1669.                 ctx->header_name_start = p;

  1670.                 c = (u_char) (ch | 0x20);
  1671.                 if (c >= 'a' && c <= 'z') {
  1672.                     break;
  1673.                 }

  1674.                 if (ch >= '0' && ch <= '9') {
  1675.                     break;
  1676.                 }

  1677.                 return NGX_ERROR;
  1678.             }
  1679.             break;

  1680.         /* header name */
  1681.         case sw_name:
  1682.             c = (u_char) (ch | 0x20);
  1683.             if (c >= 'a' && c <= 'z') {
  1684.                 break;
  1685.             }

  1686.             if (ch == ':') {
  1687.                 ctx->header_name_end = p;
  1688.                 state = sw_space_before_value;
  1689.                 break;
  1690.             }

  1691.             if (ch == '-') {
  1692.                 break;
  1693.             }

  1694.             if (ch >= '0' && ch <= '9') {
  1695.                 break;
  1696.             }

  1697.             if (ch == CR) {
  1698.                 ctx->header_name_end = p;
  1699.                 ctx->header_start = p;
  1700.                 ctx->header_end = p;
  1701.                 state = sw_almost_done;
  1702.                 break;
  1703.             }

  1704.             if (ch == LF) {
  1705.                 ctx->header_name_end = p;
  1706.                 ctx->header_start = p;
  1707.                 ctx->header_end = p;
  1708.                 goto done;
  1709.             }

  1710.             return NGX_ERROR;

  1711.         /* space* before header value */
  1712.         case sw_space_before_value:
  1713.             switch (ch) {
  1714.             case ' ':
  1715.                 break;
  1716.             case CR:
  1717.                 ctx->header_start = p;
  1718.                 ctx->header_end = p;
  1719.                 state = sw_almost_done;
  1720.                 break;
  1721.             case LF:
  1722.                 ctx->header_start = p;
  1723.                 ctx->header_end = p;
  1724.                 goto done;
  1725.             default:
  1726.                 ctx->header_start = p;
  1727.                 state = sw_value;
  1728.                 break;
  1729.             }
  1730.             break;

  1731.         /* header value */
  1732.         case sw_value:
  1733.             switch (ch) {
  1734.             case ' ':
  1735.                 ctx->header_end = p;
  1736.                 state = sw_space_after_value;
  1737.                 break;
  1738.             case CR:
  1739.                 ctx->header_end = p;
  1740.                 state = sw_almost_done;
  1741.                 break;
  1742.             case LF:
  1743.                 ctx->header_end = p;
  1744.                 goto done;
  1745.             }
  1746.             break;

  1747.         /* space* before end of header line */
  1748.         case sw_space_after_value:
  1749.             switch (ch) {
  1750.             case ' ':
  1751.                 break;
  1752.             case CR:
  1753.                 state = sw_almost_done;
  1754.                 break;
  1755.             case LF:
  1756.                 goto done;
  1757.             default:
  1758.                 state = sw_value;
  1759.                 break;
  1760.             }
  1761.             break;

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

  1770.         /* end of header */
  1771.         case sw_header_almost_done:
  1772.             switch (ch) {
  1773.             case LF:
  1774.                 goto header_done;
  1775.             default:
  1776.                 return NGX_ERROR;
  1777.             }
  1778.         }
  1779.     }

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

  1782.     return NGX_AGAIN;

  1783. done:

  1784.     ctx->response->pos = p + 1;
  1785.     ctx->state = sw_start;

  1786.     return NGX_OK;

  1787. header_done:

  1788.     ctx->response->pos = p + 1;
  1789.     ctx->state = sw_start;

  1790.     return NGX_DONE;
  1791. }


  1792. static ngx_int_t
  1793. ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx)
  1794. {
  1795.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1796.                    "ssl ocsp process body");

  1797.     if (ctx->done) {
  1798.         ctx->handler(ctx);
  1799.         return NGX_DONE;
  1800.     }

  1801.     return NGX_AGAIN;
  1802. }


  1803. static ngx_int_t
  1804. ngx_ssl_ocsp_verify(ngx_ssl_ocsp_ctx_t *ctx)
  1805. {
  1806.     int                    n;
  1807.     size_t                 len;
  1808.     X509_STORE            *store;
  1809.     const u_char          *p;
  1810.     OCSP_CERTID           *id;
  1811.     OCSP_RESPONSE         *ocsp;
  1812.     OCSP_BASICRESP        *basic;
  1813.     ASN1_GENERALIZEDTIME  *thisupdate, *nextupdate;

  1814.     ocsp = NULL;
  1815.     basic = NULL;
  1816.     id = NULL;

  1817.     if (ctx->code != 200) {
  1818.         goto error;
  1819.     }

  1820.     /* check the response */

  1821.     len = ctx->response->last - ctx->response->pos;
  1822.     p = ctx->response->pos;

  1823.     ocsp = d2i_OCSP_RESPONSE(NULL, &p, len);
  1824.     if (ocsp == NULL) {
  1825.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1826.                       "d2i_OCSP_RESPONSE() failed");
  1827.         goto error;
  1828.     }

  1829.     n = OCSP_response_status(ocsp);

  1830.     if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
  1831.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1832.                       "OCSP response not successful (%d: %s)",
  1833.                       n, OCSP_response_status_str(n));
  1834.         goto error;
  1835.     }

  1836.     basic = OCSP_response_get1_basic(ocsp);
  1837.     if (basic == NULL) {
  1838.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1839.                       "OCSP_response_get1_basic() failed");
  1840.         goto error;
  1841.     }

  1842.     store = SSL_CTX_get_cert_store(ctx->ssl_ctx);
  1843.     if (store == NULL) {
  1844.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1845.                       "SSL_CTX_get_cert_store() failed");
  1846.         goto error;
  1847.     }

  1848.     if (OCSP_basic_verify(basic, ctx->chain, store, ctx->flags) != 1) {
  1849.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1850.                       "OCSP_basic_verify() failed");
  1851.         goto error;
  1852.     }

  1853.     id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
  1854.     if (id == NULL) {
  1855.         ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
  1856.                       "OCSP_cert_to_id() failed");
  1857.         goto error;
  1858.     }

  1859.     if (OCSP_resp_find_status(basic, id, &ctx->status, NULL, NULL,
  1860.                               &thisupdate, &nextupdate)
  1861.         != 1)
  1862.     {
  1863.         ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1864.                       "certificate status not found in the OCSP response");
  1865.         goto error;
  1866.     }

  1867.     if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
  1868.         ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
  1869.                       "OCSP_check_validity() failed");
  1870.         goto error;
  1871.     }

  1872.     if (nextupdate) {
  1873.         ctx->valid = ngx_ssl_stapling_time(nextupdate);
  1874.         if (ctx->valid == (time_t) NGX_ERROR) {
  1875.             ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
  1876.                           "invalid nextUpdate time in certificate status");
  1877.             goto error;
  1878.         }

  1879.     } else {
  1880.         ctx->valid = NGX_MAX_TIME_T_VALUE;
  1881.     }

  1882.     OCSP_CERTID_free(id);
  1883.     OCSP_BASICRESP_free(basic);
  1884.     OCSP_RESPONSE_free(ocsp);

  1885.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1886.                    "ssl ocsp response, %s, %uz",
  1887.                    OCSP_cert_status_str(ctx->status), len);

  1888.     return NGX_OK;

  1889. error:

  1890.     if (id) {
  1891.         OCSP_CERTID_free(id);
  1892.     }

  1893.     if (basic) {
  1894.         OCSP_BASICRESP_free(basic);
  1895.     }

  1896.     if (ocsp) {
  1897.         OCSP_RESPONSE_free(ocsp);
  1898.     }

  1899.     return NGX_ERROR;
  1900. }


  1901. ngx_int_t
  1902. ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  1903. {
  1904.     size_t                 len;
  1905.     ngx_slab_pool_t       *shpool;
  1906.     ngx_ssl_ocsp_cache_t  *cache;

  1907.     if (data) {
  1908.         shm_zone->data = data;
  1909.         return NGX_OK;
  1910.     }

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

  1912.     if (shm_zone->shm.exists) {
  1913.         shm_zone->data = shpool->data;
  1914.         return NGX_OK;
  1915.     }

  1916.     cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_ocsp_cache_t));
  1917.     if (cache == NULL) {
  1918.         return NGX_ERROR;
  1919.     }

  1920.     shpool->data = cache;
  1921.     shm_zone->data = cache;

  1922.     ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
  1923.                     ngx_str_rbtree_insert_value);

  1924.     ngx_queue_init(&cache->expire_queue);

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

  1926.     shpool->log_ctx = ngx_slab_alloc(shpool, len);
  1927.     if (shpool->log_ctx == NULL) {
  1928.         return NGX_ERROR;
  1929.     }

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

  1932.     shpool->log_nomem = 0;

  1933.     return NGX_OK;
  1934. }


  1935. static ngx_int_t
  1936. ngx_ssl_ocsp_cache_lookup(ngx_ssl_ocsp_ctx_t *ctx)
  1937. {
  1938.     uint32_t                    hash;
  1939.     ngx_shm_zone_t             *shm_zone;
  1940.     ngx_slab_pool_t            *shpool;
  1941.     ngx_ssl_ocsp_cache_t       *cache;
  1942.     ngx_ssl_ocsp_cache_node_t  *node;

  1943.     shm_zone = ctx->shm_zone;

  1944.     if (shm_zone == NULL) {
  1945.         return NGX_DECLINED;
  1946.     }

  1947.     if (ngx_ssl_ocsp_create_key(ctx) != NGX_OK) {
  1948.         return NGX_ERROR;
  1949.     }

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

  1951.     cache = shm_zone->data;
  1952.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
  1953.     hash = ngx_hash_key(ctx->key.data, ctx->key.len);

  1954.     ngx_shmtx_lock(&shpool->mutex);

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

  1957.     if (node) {
  1958.         if (node->valid > ngx_time()) {
  1959.             ctx->status = node->status;
  1960.             ngx_shmtx_unlock(&shpool->mutex);

  1961.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
  1962.                            "ssl ocsp cache hit, %s",
  1963.                            OCSP_cert_status_str(ctx->status));

  1964.             return NGX_OK;
  1965.         }

  1966.         ngx_queue_remove(&node->queue);
  1967.         ngx_rbtree_delete(&cache->rbtree, &node->node.node);
  1968.         ngx_slab_free_locked(shpool, node);

  1969.         ngx_shmtx_unlock(&shpool->mutex);

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

  1972.         return NGX_DECLINED;
  1973.     }

  1974.     ngx_shmtx_unlock(&shpool->mutex);

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

  1976.     return NGX_DECLINED;
  1977. }


  1978. static ngx_int_t
  1979. ngx_ssl_ocsp_cache_store(ngx_ssl_ocsp_ctx_t *ctx)
  1980. {
  1981.     time_t                      now, valid;
  1982.     uint32_t                    hash;
  1983.     ngx_queue_t                *q;
  1984.     ngx_shm_zone_t             *shm_zone;
  1985.     ngx_slab_pool_t            *shpool;
  1986.     ngx_ssl_ocsp_cache_t       *cache;
  1987.     ngx_ssl_ocsp_cache_node_t  *node;

  1988.     shm_zone = ctx->shm_zone;

  1989.     if (shm_zone == NULL) {
  1990.         return NGX_OK;
  1991.     }

  1992.     valid = ctx->valid;

  1993.     now = ngx_time();

  1994.     if (valid < now) {
  1995.         return NGX_OK;
  1996.     }

  1997.     if (valid == NGX_MAX_TIME_T_VALUE) {
  1998.         valid = now + 3600;
  1999.     }

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

  2002.     cache = shm_zone->data;
  2003.     shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
  2004.     hash = ngx_hash_key(ctx->key.data, ctx->key.len);

  2005.     ngx_shmtx_lock(&shpool->mutex);

  2006.     node = ngx_slab_calloc_locked(shpool,
  2007.                              sizeof(ngx_ssl_ocsp_cache_node_t) + ctx->key.len);
  2008.     if (node == NULL) {

  2009.         if (!ngx_queue_empty(&cache->expire_queue)) {
  2010.             q = ngx_queue_last(&cache->expire_queue);
  2011.             node = ngx_queue_data(q, ngx_ssl_ocsp_cache_node_t, queue);

  2012.             ngx_rbtree_delete(&cache->rbtree, &node->node.node);
  2013.             ngx_queue_remove(q);
  2014.             ngx_slab_free_locked(shpool, node);

  2015.             node = ngx_slab_alloc_locked(shpool,
  2016.                              sizeof(ngx_ssl_ocsp_cache_node_t) + ctx->key.len);
  2017.         }

  2018.         if (node == NULL) {
  2019.             ngx_shmtx_unlock(&shpool->mutex);
  2020.             ngx_log_error(NGX_LOG_ALERT, ctx->log, 0,
  2021.                           "could not allocate new entry%s", shpool->log_ctx);
  2022.             return NGX_ERROR;
  2023.         }
  2024.     }

  2025.     node->node.str.len = ctx->key.len;
  2026.     node->node.str.data = (u_char *) node + sizeof(ngx_ssl_ocsp_cache_node_t);
  2027.     ngx_memcpy(node->node.str.data, ctx->key.data, ctx->key.len);
  2028.     node->node.node.key = hash;
  2029.     node->status = ctx->status;
  2030.     node->valid = valid;

  2031.     ngx_rbtree_insert(&cache->rbtree, &node->node.node);
  2032.     ngx_queue_insert_head(&cache->expire_queue, &node->queue);

  2033.     ngx_shmtx_unlock(&shpool->mutex);

  2034.     return NGX_OK;
  2035. }


  2036. static ngx_int_t
  2037. ngx_ssl_ocsp_create_key(ngx_ssl_ocsp_ctx_t *ctx)
  2038. {
  2039.     u_char           *p;
  2040.     ngx_int_t         length;
  2041.     ASN1_INTEGER     *serial;
  2042.     const X509_NAME  *name;

  2043.     p = ngx_pnalloc(ctx->pool, 60);
  2044.     if (p == NULL) {
  2045.         return NGX_ERROR;
  2046.     }

  2047.     ctx->key.data = p;
  2048.     ctx->key.len = 60;

  2049.     name = X509_get_subject_name(ctx->issuer);
  2050.     if (X509_NAME_digest(name, EVP_sha1(), p, NULL) == 0) {
  2051.         return NGX_ERROR;
  2052.     }

  2053.     p += 20;

  2054.     if (X509_pubkey_digest(ctx->issuer, EVP_sha1(), p, NULL) == 0) {
  2055.         return NGX_ERROR;
  2056.     }

  2057.     p += 20;

  2058.     serial = X509_get_serialNumber(ctx->cert);
  2059.     length = ASN1_STRING_length(serial);

  2060.     if (length > 20) {
  2061.         return NGX_ERROR;
  2062.     }

  2063.     p = ngx_cpymem(p, ASN1_STRING_get0_data(serial), length);
  2064.     ngx_memzero(p, 20 - length);

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

  2067.     return NGX_OK;
  2068. }


  2069. static u_char *
  2070. ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len)
  2071. {
  2072.     u_char              *p;
  2073.     ngx_ssl_ocsp_ctx_t  *ctx;

  2074.     p = buf;

  2075.     if (log->action) {
  2076.         p = ngx_snprintf(buf, len, " while %s", log->action);
  2077.         len -= p - buf;
  2078.         buf = p;
  2079.     }

  2080.     ctx = log->data;

  2081.     if (ctx) {
  2082.         p = ngx_snprintf(buf, len, ", responder: %V", &ctx->host);
  2083.         len -= p - buf;
  2084.         buf = p;
  2085.     }

  2086.     if (ctx && ctx->peer.name) {
  2087.         p = ngx_snprintf(buf, len, ", peer: %V", ctx->peer.name);
  2088.         len -= p - buf;
  2089.         buf = p;
  2090.     }

  2091.     if (ctx && ctx->name) {
  2092.         p = ngx_snprintf(buf, len, ", certificate: \"%s\"", ctx->name);
  2093.         len -= p - buf;
  2094.         buf = p;
  2095.     }

  2096.     return p;
  2097. }


  2098. #else


  2099. ngx_int_t
  2100. ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
  2101.     ngx_str_t *responder, ngx_uint_t verify)
  2102. {
  2103.     ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
  2104.                   "\"ssl_stapling\" ignored, not supported");

  2105.     return NGX_OK;
  2106. }


  2107. ngx_int_t
  2108. ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
  2109.     ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
  2110. {
  2111.     return NGX_OK;
  2112. }


  2113. ngx_int_t
  2114. ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
  2115.     ngx_uint_t depth, ngx_shm_zone_t *shm_zone)
  2116. {
  2117.     ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,
  2118.                   "\"ssl_ocsp\" is not supported on this platform");

  2119.     return NGX_ERROR;
  2120. }


  2121. ngx_int_t
  2122. ngx_ssl_ocsp_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
  2123.     ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
  2124. {
  2125.     return NGX_OK;
  2126. }


  2127. ngx_int_t
  2128. ngx_ssl_ocsp_validate(ngx_connection_t *c)
  2129. {
  2130.     return NGX_OK;
  2131. }


  2132. ngx_int_t
  2133. ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s)
  2134. {
  2135.     return NGX_OK;
  2136. }


  2137. void
  2138. ngx_ssl_ocsp_cleanup(ngx_connection_t *c)
  2139. {
  2140. }


  2141. ngx_int_t
  2142. ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data)
  2143. {
  2144.     return NGX_OK;
  2145. }


  2146. #endif