hitch  1.5.2
About: Hitch is a libev-based high performance SSL/TLS proxy that terminates TLS/SSL connections and forwards the unencrypted traffic to some backend.
  Fossies Dox: hitch-1.5.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ocsp.c
Go to the documentation of this file.
1 
32 #include <sys/select.h>
33 #include <sys/socket.h>
34 
35 #include <unistd.h>
36 
37 #include "logging.h"
38 #include "hitch.h"
39 #include "ocsp.h"
40 #include "configuration.h"
41 
42 /* hitch.c */
43 extern hitch_config *CONFIG;
44 extern struct ev_loop *loop;
45 
46 void
48 {
49  if (*staple == NULL)
50  return;
51  free((*staple)->staple);
52  FREE_OBJ(*staple);
53  *staple = NULL;
54 }
55 
56 
57 int
58 HOCSP_verify(sslctx *sc, OCSP_RESPONSE *resp, double *nextupd)
59 {
60  OCSP_BASICRESP *br = NULL;
61  X509_STORE *store;
62  STACK_OF(X509) *chain = NULL;
63  OCSP_CERTID *cid = NULL;
64  int status = -1, reason;
65  ASN1_GENERALIZEDTIME *asn_nextupd = NULL;
66  X509 *issuer;
67  int i;
68  int do_verify = sc->staple_vfy;
69  int verify_flags = OCSP_TRUSTOTHER;
70 
71  if (sc->staple_vfy < 0)
72  do_verify = CONFIG->OCSP_VFY;
73 
74  if (!do_verify)
75  verify_flags |= OCSP_NOVERIFY;
76 
77  store = SSL_CTX_get_cert_store(sc->ctx);
78  AN(store);
79 
80 #ifdef SSL_CTRL_GET_CHAIN_CERTS
81  AN(SSL_CTX_get0_chain_certs(sc->ctx, &chain));
82 #else
83  chain = sc->ctx->extra_certs;
84 #endif
85  br = OCSP_response_get1_basic(resp);
86  if (br == NULL) {
87  ERR("{core} OCSP_response_get1_basic failed (cert: %s)\n",
88  sc->filename);
89  goto err;
90  }
91  i = OCSP_basic_verify(br, chain, store, verify_flags);
92  if (i <= 0) {
93  log_ssl_error(NULL, "{core} Staple verification failed "
94  "for cert %s\n", sc->filename);
95  goto err;
96  }
97 
98  issuer = Find_issuer(sc->x509, chain);
99  if (issuer == NULL) {
100  ERR("{core} Unable to find issuer for cert %s\n.",
101  sc->filename);
102  goto err;
103  }
104 
105  cid = OCSP_cert_to_id(NULL, sc->x509, issuer);
106  if (cid == NULL) {
107  ERR("{core} OCSP_cert_to_id failed\n");
108  goto err;
109  }
110 
111  if (OCSP_resp_find_status(br, cid, &status, &reason,
112  NULL, NULL, &asn_nextupd) != 1) {
113  ERR("{core} OCSP_resp_find_status failed: Unable to "
114  "find OCSP response with a matching certificate id\n");
115  goto err;
116  }
117 
118  if (status != V_OCSP_CERTSTATUS_GOOD) {
119  ERR("{core} Certificate %s has status %s\n", sc->filename,
120  OCSP_cert_status_str(status));
121  if (status == V_OCSP_CERTSTATUS_REVOKED)
122  ERR("{core} Certificate %s revocation reason: %s\n",
123  sc->filename, OCSP_crl_reason_str(reason));
124  goto err;
125  }
126 
127  if (asn_nextupd != NULL)
128  *nextupd = asn1_gentime_parse(asn_nextupd);
129  else {
130  *nextupd = -1.0;
131  }
132 
133  OCSP_CERTID_free(cid);
134  OCSP_BASICRESP_free(br);
135  return (0);
136 
137 err:
138  if (cid != NULL)
139  OCSP_CERTID_free(cid);
140  if (br != NULL)
141  OCSP_BASICRESP_free(br);
142  return (1);
143 }
144 
145 #ifndef OPENSSL_NO_TLSEXT
146 int
147 HOCSP_staple_cb(SSL *ssl, void *priv)
148 {
149  sslstaple *staple;
150  unsigned char *buf;
151  CAST_OBJ_NOTNULL(staple, priv, SSLSTAPLE_MAGIC);
152 
153  if (staple->nextupd != -1 &&
154  staple->nextupd < Time_now()) {
155  return (SSL_TLSEXT_ERR_NOACK);
156  }
157 
158  /* SSL_set_tlsext_status_ocsp_resp will issue a free() on the
159  * provided input, so we need to pass a copy. */
160  buf = malloc(staple->len);
161  AN(buf);
162  memcpy(buf, staple->staple, staple->len);
163 
164  if (SSL_set_tlsext_status_ocsp_resp(ssl,
165  buf, staple->len) == 1)
166  return (SSL_TLSEXT_ERR_OK);
167  else
168  free(buf);
169 
170  return (SSL_TLSEXT_ERR_NOACK);
171 }
172 #endif
173 
174 
175 int
176 HOCSP_init_resp(sslctx *sc, OCSP_RESPONSE *resp)
177 {
178  sslstaple *staple = NULL;
179  int len, i;
180  unsigned char *tmp, *buf;
181 
182  i = OCSP_response_status(resp);
183  if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
184  ERR("{core} Error: OCSP response for cert %s has status %s\n",
185  sc->filename, OCSP_response_status_str(i));
186  goto err;
187  }
188 
189  len = i2d_OCSP_RESPONSE(resp, NULL);
190  if (len < 0) {
191  log_ssl_error(NULL, "{core} i2d_OCSP_RESPONSE");
192  goto err;
193  }
194  buf = malloc(len);
195  AN(buf);
196  tmp = buf;
197  i = i2d_OCSP_RESPONSE(resp, &tmp);
198  assert(i > 0);
199 
200  ALLOC_OBJ(staple, SSLSTAPLE_MAGIC);
201  AN(staple);
202  staple->staple = buf;
203  staple->len = len;
204 
205  if (HOCSP_verify(sc, resp, &staple->nextupd) != 0) {
206  goto err;
207  }
208 
209  if (!SSL_CTX_set_tlsext_status_cb(sc->ctx, HOCSP_staple_cb)) {
210  ERR("Error configuring status callback.\n");
211  goto err;
212  } else if (!SSL_CTX_set_tlsext_status_arg(sc->ctx, staple)) {
213  ERR("Error setting status callback argument.\n");
214  goto err;
215  }
216 
217  if (sc->staple != NULL)
218  HOCSP_free(&sc->staple);
219  sc->staple = staple;
220  return (0);
221 
222 err:
223  if (staple != NULL)
224  HOCSP_free(&staple);
225  return (1);
226 }
227 
228 
229 static void
230 hocsp_stat_cb(struct ev_loop *loop, ev_stat *w, int revents)
231 {
232  sslctx *sc;
233  sslstaple *oldstaple;
234 
235  (void) revents;
236  (void) loop;
237  CAST_OBJ_NOTNULL(sc, w->data, SSLCTX_MAGIC);
238 
239  if (w->attr.st_nlink) {
240  oldstaple = sc->staple;
241  sc->staple = NULL;
242  AN(sc->staple_fn);
243 
244  if (HOCSP_init_file(sc->staple_fn, sc, 1) != 0) {
245  sc->staple = oldstaple;
246  return;
247  }
248 
249  HOCSP_free(&oldstaple);
250  LOG("{core} Loaded cached OCSP staple for cert '%s'\n",
251  sc->filename);
252  }
253 }
254 
255 void
257 {
258  char *fn;
259  STACK_OF(OPENSSL_STRING) *sk_uri = NULL;
260  AN(sc->x509);
261  sk_uri = X509_get1_ocsp(sc->x509);
262 
263  if (sk_uri == NULL
264  || sk_OPENSSL_STRING_num(sk_uri) == 0) {
265  goto err;
266  }
267 
268  fn = HOCSP_fn(sc->filename);
269  if (fn == NULL)
270  goto err;
271 
272  free(sc->staple_fn);
273  sc->staple_fn = fn;
274  sc->ev_staple = malloc(sizeof *sc->ev_staple);
275  AN(sc->ev_staple);
276  sc->ev_staple->data = sc;
277  ev_stat_init(sc->ev_staple, hocsp_stat_cb, fn, 0);
278 
279 err:
280  if (sk_uri != NULL)
281  X509_email_free(sk_uri);
282 }
283 
284 static OCSP_REQUEST *
286 {
287  OCSP_REQUEST *req;
288  OCSP_CERTID *cid;
289  STACK_OF(X509) *chain = NULL;
290  X509 *issuer;
291 
294 
295 #ifdef SSL_CTRL_GET_CHAIN_CERTS
296  AN(SSL_CTX_get0_chain_certs(oq->sctx->ctx, &chain));
297 #else
298  chain = oq->sctx->ctx->extra_certs;
299 #endif
300  issuer = Find_issuer(oq->sctx->x509, chain);
301  if (issuer == NULL) {
302  ERR("{ocsp} Unable to find issuer for cert %s\n.",
303  oq->sctx->filename);
304  return (NULL);
305  }
306 
307  cid = OCSP_cert_to_id(NULL, oq->sctx->x509, issuer);
308  if (cid == NULL) {
309  ERR("{ocsp} OCSP_cert_to_id failed for cert %s\n",
310  oq->sctx->filename);
311  return (NULL);
312  }
313 
314  req = OCSP_REQUEST_new();
315  if (req == NULL) {
316  ERR("{ocsp} OCSP_REQUEST_new failed\n");
317  OCSP_CERTID_free(cid);
318  return (NULL);
319  }
320 
321  if (OCSP_request_add0_id(req, cid) == NULL) {
322  ERR("{ocsp} OCSP_request_add0_id failed\n");
323  OCSP_CERTID_free(cid);
324  OCSP_REQUEST_free(req);
325  return (NULL);
326  }
327 
328  return (req);
329 }
330 
331 
332 /* Save a downloaded staple to the file system.
333  * Process: OCSP child */
334 static int
336 {
337  char *dstfile = NULL;
338  int fd = -1;
339  struct vsb *tmpfn;
340 
343  dstfile = HOCSP_fn(sc->filename);
344  if (dstfile == NULL)
345  return (1);
346 
347  (void)umask(027);
348 
349  tmpfn = VSB_new_auto();
350  AN(tmpfn);
351  VSB_printf(tmpfn, "%s.XXXXXX", dstfile);
352  VSB_finish(tmpfn);
353  fd = mkstemp(VSB_data(tmpfn));
354  if (fd < 0) {
355  if (errno == EACCES)
356  ERR("{ocsp} Error: ocsp-dir '%s' is not "
357  "writable for the configured user\n",
358  CONFIG->OCSP_DIR);
359  else
360  ERR("{ocsp} hocsp_proc_persist: mkstemp: %s: %s\n",
361  VSB_data(tmpfn), strerror(errno));
362  goto err;
363  }
364 
365  if (write(fd, sc->staple->staple, sc->staple->len) != sc->staple->len) {
366  ERR("{ocsp} hocsp_proc_persist: write: %s\n", strerror(errno));
367  (void) close(fd);
368  goto err;
369  }
370 
371  if(close(fd) != 0) {
372  ERR("{ocsp} hocsp_proc_persist: close: %s\n", strerror(errno));
373  goto err;
374  }
375 
376  if (rename(VSB_data(tmpfn), dstfile) != 0) {
377  ERR("{ocsp} hocsp_proc_persist: rename: %s: %s\n",
378  strerror(errno), dstfile);
379  goto err;
380  }
381 
382  /* worker procs notified via ev_stat (inotify/stat) */
383 
384  VSB_delete(tmpfn);
385  free(dstfile);
386  return (0);
387 
388 err:
389  unlink(VSB_data(tmpfn));
390  VSB_delete(tmpfn);
391  free(dstfile);
392  return (1);
393 }
394 
395 
396 int
397 HOCSP_init_file(const char *ocspfn, sslctx *sc, int is_cached)
398 {
399  BIO *bio;
400  OCSP_RESPONSE *resp;
401 
402  if (ocspfn == NULL) {
403  return (1);
404  }
405 
406  bio = BIO_new_file(ocspfn, "r");
407  if (bio == NULL) {
408  if (is_cached)
409  return (1);
410  ERR("Error loading status file '%s'\n", ocspfn);
411  return (1);
412  }
413 
414  resp = d2i_OCSP_RESPONSE_bio(bio, NULL);
415  BIO_free(bio);
416  if (resp == NULL) {
417  ERR("Error parsing OCSP staple in '%s'\n", ocspfn);
418  return (1);
419  }
420 
421  if (HOCSP_init_resp(sc, resp) != 0)
422  goto err;
423 
425  OCSP_RESPONSE_free(resp);
426  return (0);
427 
428 err:
429  if (resp != NULL)
430  OCSP_RESPONSE_free(resp);
431  return (1);
432 }
433 
434 
435 char *
436 HOCSP_fn(const char *certfn)
437 {
438  EVP_MD_CTX *mdctx = NULL;
439  unsigned char md_val[EVP_MAX_MD_SIZE];
440  unsigned int i, md_len;
441  struct vsb *vsb;
442  char *res;
443 
444  if (CONFIG->OCSP_DIR == NULL) {
445  ERR("{ocsp} Error: OCSP directory not specified.\n");
446  return (NULL);
447  }
448 
449  mdctx = EVP_MD_CTX_create();
450  if (mdctx == NULL) {
451  ERR("{ocsp} EVP_MD_CTX_create failed\n");
452  goto err;
453  }
454  if (EVP_DigestInit_ex(mdctx, EVP_md5(), NULL) != 1) {
455  ERR("{ocsp} EVP_DigestInit_ex in ocsp_fn() failed\n");
456  goto err;
457  }
458  if (EVP_DigestUpdate(mdctx, certfn, strlen(certfn)) != 1) {
459  ERR("{ocsp} EVP_DigestUpdate in ocsp_fn() failed\n");
460  goto err;
461  }
462  if (EVP_DigestFinal_ex(mdctx, md_val, &md_len) != 1) {
463  ERR("{ocsp} EVP_DigestFinal_ex in ocsp_fn() failed\n");
464  goto err;
465  }
466 
467  EVP_MD_CTX_destroy(mdctx);
468 
469  vsb = VSB_new_auto();
470  AN(vsb);
472  VSB_putc(vsb, '/');
473  for (i = 0; i < md_len; i++)
474  VSB_printf(vsb, "%02x", md_val[i]);
475  VSB_finish(vsb);
476  res = strdup(VSB_data(vsb));
477  AN(res);
478  VSB_delete(vsb);
479  return (res);
480 
481 err:
482  if (mdctx != NULL)
483  EVP_MD_CTX_destroy(mdctx);
484  return (NULL);
485 }
486 
487 static void hocsp_query_responder(struct ev_loop *loop, ev_timer *w, int revents);
488 
489 
490 /* Start a per-sslctx evloop timer that downloads the OCSP staple.
491  * Process: OCSP child */
492 void
493 HOCSP_mktask(sslctx *sc, ocspquery *oq, double refresh_hint)
494 {
495  double refresh = -1.0;
496  double tnow;
497  STACK_OF(OPENSSL_STRING) *sk_uri;
498 
499  tnow = Time_now();
500 
501  if (sc->staple != NULL) {
503  if (sc->staple->nextupd > 0) {
504  refresh = sc->staple->nextupd - tnow - 600;
505  if (refresh < 0)
506  refresh = 0.0;
507  } else
508  refresh = CONFIG->OCSP_REFRESH_INTERVAL;
509  } else {
510  AN(sc->x509);
511  sk_uri = X509_get1_ocsp(sc->x509);
512  if (sk_uri == NULL || sk_OPENSSL_STRING_num(sk_uri) == 0) {
513  LOG("{ocsp} Note: No OCSP responder URI found "
514  "for cert %s\n", sc->filename);
515  if (sk_uri != NULL)
516  X509_email_free(sk_uri);
517  return;
518  }
519  /* schedule for immediate retrieval */
520  X509_email_free(sk_uri);
521  refresh = 0.0;
522  }
523 
524  if (refresh < refresh_hint)
525  refresh = refresh_hint;
526 
527  if (oq == NULL)
529 
531  oq->sctx = sc;
532 
533  assert(refresh >= 0.0);
534  ev_timer_init(&oq->ev_t_refresh,
535  hocsp_query_responder, refresh, 0.);
536  oq->ev_t_refresh.data = oq;
537  ev_timer_start(loop, &oq->ev_t_refresh);
538 
539  LOG("{ocsp} Refresh of OCSP staple for %s scheduled in "
540  "%.0lf seconds\n", sc->filename, refresh);
541 }
542 
543 
544 
545 static void
546 hocsp_query_responder(struct ev_loop *loop, ev_timer *w, int revents)
547 {
548  ocspquery *oq;
549  OCSP_REQUEST *req = NULL;
550  OCSP_REQ_CTX *rctx = NULL;
551  STACK_OF(OPENSSL_STRING) *sk_uri;
552  char *host = NULL, *port = NULL, *path = NULL;
553  int https = 0;
554  BIO *cbio = NULL, *sbio;
555  SSL_CTX *ctx = NULL;
556  OCSP_RESPONSE *resp = NULL;
557  double resp_tmo;
558  fd_set fds;
559  struct timeval tv;
560  int n, fd;
561  double refresh_hint = 60;
562 
563  (void) loop;
564  (void) revents;
565 
566  CAST_OBJ_NOTNULL(oq, w->data, OCSPQUERY_MAGIC);
567 
568  sk_uri = X509_get1_ocsp(oq->sctx->x509);
569  AN(sk_uri);
570 
571  AN(OCSP_parse_url(sk_OPENSSL_STRING_value(sk_uri, 0),
572  &host, &port, &path, &https));
573  X509_email_free(sk_uri);
574 
575  req = hocsp_mkreq(oq);
576  if (req == NULL) {
577  /* If we weren't able to create a request, there is no
578  * use in scheduling a retry. */
579  FREE_OBJ(oq);
580  goto err;
581  }
582 
583  /* printf("host: %s port: %s path: %s ssl: %d\n", */
584  /* host, port, path, https); */
585 
586  cbio = BIO_new_connect(host);
587  if (cbio == NULL) {
588  refresh_hint = 60;
589  goto retry;
590  }
591 
592  if (port == NULL) {
593  if (https)
594  port = "443";
595  else
596  port = "80";
597  }
598  AN(BIO_set_conn_port(cbio, port));
599 
600  if (https) {
601  ctx = SSL_CTX_new(SSLv23_client_method());
602  AN(ctx);
603  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
604  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
605  SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
606  sbio = BIO_new_ssl(ctx, 1);
607  if (sbio == NULL) {
608  ERR("{ocsp} BIO_new_ssl failed: %s\n", strerror(errno));
609  refresh_hint = 60;
610  goto retry;
611  }
612  cbio = BIO_push(sbio, cbio);
613  AN(cbio);
614  }
615 
616  /* set non-blocking */
617  BIO_set_nbio(cbio, 1);
618  n = BIO_do_connect(cbio);
619  if (n <= 0 && !BIO_should_retry(cbio)) {
620  ERR("{ocsp} Error connecting to %s:%s\n", host, port);
621  refresh_hint = 300;
622  goto retry;
623  }
624 
625  assert(BIO_get_fd(cbio, &fd) >= 0);
626 
627  if (n <= 0) {
628  FD_ZERO(&fds);
629  FD_SET(fd, &fds);
630  tv.tv_sec = CONFIG->OCSP_CONN_TMO;
631  tv.tv_usec = (CONFIG->OCSP_CONN_TMO - tv.tv_sec) * 1e6;
632  n = select(fd + 1, NULL, (void *) &fds, NULL, &tv);
633  if (n == 0) {
634  /* connect timeout */
635  ERR("{ocsp} Error: Connection to %s:%s timed out. "
636  "Hit parameter 'ocsp-connect-tmo"
637  " [current value: %.3fs]\n",
638  host, port, CONFIG->OCSP_CONN_TMO);
639  refresh_hint = 300;
640  goto retry;
641  } else if (n < 0) {
642  ERR("{ocsp} Error: Connecting to %s:%s failed: "
643  "select: %s\n",
644  host, port, strerror(errno));
645  refresh_hint = 300;
646  goto retry;
647  }
648  }
649 
650  rctx = OCSP_sendreq_new(cbio, path, NULL, 0);
651  if (rctx == NULL) {
652  ERR("{ocsp} OCSP_sendreq_new failed\n");
653  refresh_hint = 60;
654  goto retry;
655  }
656  if (OCSP_REQ_CTX_add1_header(rctx, "Host", host) == 0) {
657  ERR("{ocsp} OCSP_REQ_CTX_add1_header failed\n");
658  refresh_hint = 60;
659  goto retry;
660  }
661  if (OCSP_REQ_CTX_set1_req(rctx, req) == 0) {
662  ERR("{ocsp} OCSP_REQ_CTX_set1_req failed\n");
663  refresh_hint = 60;
664  goto retry;
665  }
666 
667  resp_tmo = Time_now() + CONFIG->OCSP_RESP_TMO;
668  while (1) {
669  double tnow;
670  n = OCSP_sendreq_nbio(&resp, rctx);
671  if (n == 0) {
672  /* this is an error, and we can't continue */
673  ERR("{ocsp} OCSP_sendreq_nbio failed for %s:%s.\n",
674  host, port);
675  refresh_hint = 300;
676  goto retry;
677  } else if (n == 1) {
678  /* complete */
679  break;
680  }
681 
682  FD_ZERO(&fds);
683  FD_SET(fd, &fds);
684 
685  tnow = Time_now();
686  tv.tv_sec = resp_tmo - tnow;
687  tv.tv_usec = ((resp_tmo - tnow) - tv.tv_sec) * 1e6;
688 
689  if (BIO_should_read(cbio))
690  n = select(fd + 1, (void *) &fds, NULL, NULL, &tv);
691  else if (BIO_should_write(cbio))
692  n = select(fd + 1, NULL, (void *) &fds, NULL, &tv);
693  else {
694  /* BIO_should_io_special? */
695  refresh_hint = 300;
696  goto retry;
697  }
698 
699  if (n == -1) {
700  if (errno == EINTR)
701  continue;
702  ERR("{ocsp} Error: Transmission failed:"
703  " select: %s\n", strerror(errno));
704  refresh_hint = 300;
705  goto retry;
706  }
707 
708  if (n == 0) {
709  /* timeout */
710  ERR("{ocsp} Error: Transmission timeout for %s:%s. "
711  "Consider increasing parameter 'ocsp-resp-tmo'"
712  " [current value: %.3fs]\n",
713  host, port, CONFIG->OCSP_RESP_TMO);
714  refresh_hint = 300;
715  goto retry;
716  }
717  }
718 
719  if (resp == NULL) {
720  /* fetch failed. Retry later. */
721  refresh_hint = 600.0;
722  } else {
723  if (HOCSP_init_resp(oq->sctx, resp) == 0) {
724  LOG("{ocsp} Retrieved new staple for cert %s\n",
725  oq->sctx->filename);
726  if (hocsp_proc_persist(oq->sctx) != 0) {
727  refresh_hint = 300;
728  goto retry;
729  }
730  } else {
731  refresh_hint = 300;
732  goto retry;
733  }
734  }
735 
736 retry:
737  HOCSP_mktask(oq->sctx, oq, refresh_hint);
738 err:
739  if (rctx)
740  OCSP_REQ_CTX_free(rctx);
741  if (req)
742  OCSP_REQUEST_free(req);
743  if (resp)
744  OCSP_RESPONSE_free(resp);
745  if (cbio)
746  BIO_free_all(cbio);
747  if (ctx)
748  SSL_CTX_free(ctx);
749 }
750 
SSLSTAPLE_MAGIC
#define SSLSTAPLE_MAGIC
Definition: hitch.h:88
vsb
Definition: vsb.h:37
log_ssl_error
void log_ssl_error(proxystate *ps, const char *what,...)
Definition: logging.c:182
VSB_new_auto
#define VSB_new_auto()
Definition: vsb.h:61
__hitch_config
Definition: configuration.h:88
HOCSP_mktask
void HOCSP_mktask(sslctx *sc, ocspquery *oq, double refresh_hint)
Definition: ocsp.c:493
OCSPQUERY_MAGIC
#define OCSPQUERY_MAGIC
Definition: ocsp.h:12
ocspquery_s
Definition: ocsp.h:10
__hitch_config::OCSP_CONN_TMO
double OCSP_CONN_TMO
Definition: configuration.h:144
HOCSP_ev_stat
void HOCSP_ev_stat(sslctx *sc)
Definition: ocsp.c:256
VSB_cat
int VSB_cat(struct vsb *s, const char *str)
Definition: vsb.c:306
ocspquery_s::ev_t_refresh
ev_timer ev_t_refresh
Definition: ocsp.h:13
sslctx_s::staple_fn
char * staple_fn
Definition: hitch.h:76
HOCSP_fn
char * HOCSP_fn(const char *certfn)
Definition: ocsp.c:436
__hitch_config::OCSP_REFRESH_INTERVAL
int OCSP_REFRESH_INTERVAL
Definition: configuration.h:145
sslstaple_s
Definition: hitch.h:86
asn1_gentime_parse
double asn1_gentime_parse(const ASN1_GENERALIZEDTIME *d)
Definition: asn_gentm.c:246
LOG
#define LOG(...)
Definition: logging.h:69
__hitch_config::OCSP_RESP_TMO
double OCSP_RESP_TMO
Definition: configuration.h:143
sslctx_s::filename
char * filename
Definition: hitch.h:71
Time_now
double Time_now(void)
Definition: logging.c:78
AN
#define AN(foo)
Definition: vas.h:74
__hitch_config::OCSP_DIR
char * OCSP_DIR
Definition: configuration.h:142
hitch.h
sslstaple_s::nextupd
double nextupd
Definition: hitch.h:91
sslctx_s::ctx
SSL_CTX * ctx
Definition: hitch.h:72
sslctx_s::staple
sslstaple * staple
Definition: hitch.h:74
VSB_putc
int VSB_putc(struct vsb *s, int c)
Definition: vsb.c:407
sslctx_s
Definition: hitch.h:68
sslstaple_s::len
int len
Definition: hitch.h:92
malloc
void * malloc(size_t)
sslctx_s::x509
X509 * x509
Definition: hitch.h:77
assert
#define assert(e)
Definition: vas.h:55
sslctx_s::ev_staple
ev_stat * ev_staple
Definition: hitch.h:78
free
void free(void *)
HOCSP_init_file
int HOCSP_init_file(const char *ocspfn, sslctx *sc, int is_cached)
Definition: ocsp.c:397
HOCSP_init_resp
int HOCSP_init_resp(sslctx *sc, OCSP_RESPONSE *resp)
Definition: ocsp.c:176
sslstaple_s::staple
unsigned char * staple
Definition: hitch.h:89
ALLOC_OBJ
#define ALLOC_OBJ(to, type_magic)
Definition: miniobj.h:14
CHECK_OBJ_NOTNULL
#define CHECK_OBJ_NOTNULL(ptr, type_magic)
Definition: miniobj.h:36
hocsp_stat_cb
static void hocsp_stat_cb(struct ev_loop *loop, ev_stat *w, int revents)
Definition: ocsp.c:230
__hitch_config::OCSP_VFY
int OCSP_VFY
Definition: configuration.h:141
ocspquery_s::sctx
sslctx * sctx
Definition: ocsp.h:14
VSB_delete
void VSB_delete(struct vsb *s)
Definition: vsb.c:476
logging.h
configuration.h
VSB_printf
int VSB_printf(struct vsb *s, const char *fmt,...)
Definition: vsb.c:392
hocsp_proc_persist
static int hocsp_proc_persist(sslctx *sc)
Definition: ocsp.c:335
VSB_data
char * VSB_data(const struct vsb *s)
Definition: vsb.c:448
HOCSP_verify
int HOCSP_verify(sslctx *sc, OCSP_RESPONSE *resp, double *nextupd)
Definition: ocsp.c:58
hocsp_mkreq
static OCSP_REQUEST * hocsp_mkreq(ocspquery *oq)
Definition: ocsp.c:285
HOCSP_free
void HOCSP_free(sslstaple **staple)
Definition: ocsp.c:47
ERR
#define ERR(...)
Definition: logging.h:75
SSLCTX_MAGIC
#define SSLCTX_MAGIC
Definition: hitch.h:70
sslctx_s::staple_vfy
int staple_vfy
Definition: hitch.h:75
loop
struct ev_loop * loop
Definition: hitch.c:130
FREE_OBJ
#define FREE_OBJ(to)
Definition: miniobj.h:21
VSB_finish
int VSB_finish(struct vsb *s)
Definition: vsb.c:430
HOCSP_staple_cb
int HOCSP_staple_cb(SSL *ssl, void *priv)
Definition: ocsp.c:147
CONFIG
hitch_config * CONFIG
Definition: hitch.c:131
CAST_OBJ_NOTNULL
#define CAST_OBJ_NOTNULL(to, from, type_magic)
Definition: miniobj.h:55
hocsp_query_responder
static void hocsp_query_responder(struct ev_loop *loop, ev_timer *w, int revents)
Definition: ocsp.c:546
Find_issuer
X509 * Find_issuer(X509 *subj, STACK_OF(X509) *chain)
Definition: hitch.c:877
ocsp.h