From 454dbbc593cd8d9ddd7969e94c6118fc64c57f7b Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 17 Jul 2006 13:26:54 +0000 Subject: [PATCH] Add -timeout option to ocsp utility. --- CHANGES | 3 +- apps/ocsp.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 4f3d4af216..89c016e17c 100644 --- a/CHANGES +++ b/CHANGES @@ -4,7 +4,8 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] - *) Non-blocking OCSP request processing. + *) Non-blocking OCSP request processing. Add -timeout option to ocsp + utility. [Steve Henson] *) Allow digests to supply their own micalg string for S/MIME type using diff --git a/apps/ocsp.c b/apps/ocsp.c index 52af592a4a..0369b2636c 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -86,6 +86,8 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser); static BIO *init_responder(char *port); static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, char *port); static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp); +static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, + OCSP_REQUEST *req, int req_timeout); #undef PROG #define PROG ocsp_main @@ -112,6 +114,7 @@ int MAIN(int argc, char **argv) BIO *acbio = NULL, *cbio = NULL; BIO *derbio = NULL; BIO *out = NULL; + int req_timeout = -1; int req_text = 0, resp_text = 0; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; char *CAfile = NULL, *CApath = NULL; @@ -153,6 +156,22 @@ int MAIN(int argc, char **argv) } else badarg = 1; } + else if (!strcmp(*args, "-timeout")) + { + if (args[1]) + { + args++; + req_timeout = atol(*args); + if (req_timeout < 0) + { + BIO_printf(bio_err, + "Illegal timeout value %s\n", + *args); + badarg = 1; + } + } + else badarg = 1; + } else if (!strcmp(*args, "-url")) { if (args[1]) @@ -730,12 +749,8 @@ int MAIN(int argc, char **argv) sbio = BIO_new_ssl(ctx, 1); cbio = BIO_push(sbio, cbio); } - if (BIO_do_connect(cbio) <= 0) - { - BIO_printf(bio_err, "Error connecting BIO\n"); - goto end; - } - resp = OCSP_sendreq_bio(cbio, path, req); + + resp = query_responder(bio_err, cbio, path, req, req_timeout); BIO_free_all(cbio); cbio = NULL; if (!resp) @@ -1225,4 +1240,77 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp) return 1; } +static OCSP_RESPONSE *query_responder(BIO *err, BIO *cbio, char *path, + OCSP_REQUEST *req, int req_timeout) + { + int fd; + int rv; + OCSP_REQ_CTX *ctx = NULL; + OCSP_RESPONSE *rsp = NULL; + fd_set confds; + struct timeval tv; + + if (req_timeout != -1) + BIO_set_nbio(cbio, 1); + + rv = BIO_do_connect(cbio); + + if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) + { + BIO_puts(err, "Error connecting BIO\n"); + return NULL; + } + + if (req_timeout == -1) + return OCSP_sendreq_bio(cbio, path, req); + + if (BIO_get_fd(cbio, &fd) <= 0) + { + BIO_puts(err, "Can't get connection fd\n"); + goto err; + } + + ctx = OCSP_sendreq_new(cbio, path, req, -1); + + if (!ctx) + return NULL; + + for (;;) + { + rv = OCSP_sendreq_nbio(&rsp, ctx); + if (rv != -1) + break; + FD_ZERO(&confds); + FD_SET(fd, &confds); + tv.tv_usec = 0; + tv.tv_sec = req_timeout; + if (BIO_should_read(cbio) || BIO_should_io_special(cbio)) + rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); + else if (BIO_should_write(cbio)) + rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); + else + { + BIO_puts(err, "Unexpected retry condition\n"); + goto err; + } + if (rv == 0) + { + BIO_puts(err, "Timeout on request\n"); + break; + } + if (rv == -1) + { + BIO_puts(err, "Select error\n"); + break; + } + + } + + err: + + OCSP_REQ_CTX_free(ctx); + + return rsp; + } + #endif