Add -timeout option to ocsp utility.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 17 Jul 2006 13:26:54 +0000 (13:26 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 17 Jul 2006 13:26:54 +0000 (13:26 +0000)
CHANGES
apps/ocsp.c

diff --git a/CHANGES b/CHANGES
index 4f3d4af2160a584e44786bedc3e4acb3f7ff88d9..89c016e17cb486c862cefc1adff5481b8b57fd22 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,7 +4,8 @@
 
  Changes between 0.9.8b and 0.9.9  [xx XXX xxxx]
 
 
  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
      [Steve Henson]
 
   *) Allow digests to supply their own micalg string for S/MIME type using
index 52af592a4a6174f3336d63f3d5aa240f238837f4..0369b2636cefd28e0905e83321761d215c90db16 100644 (file)
@@ -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 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
 
 #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;
        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;
        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 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])
                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);
                        }
                        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)
                BIO_free_all(cbio);
                cbio = NULL;
                if (!resp)
@@ -1225,4 +1240,77 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
        return 1;
        }
 
        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
 #endif