Add OCSP timeout option
authorMatthew Newton <mcn4@leicester.ac.uk>
Mon, 23 Jan 2012 12:45:50 +0000 (13:45 +0100)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 23 Jan 2012 12:45:50 +0000 (13:45 +0100)
Manual pull of commit 07a4b30f181

raddb/mods-available/eap
src/include/tls.h
src/main/tls.c

index 26195d5..0e767d8 100644 (file)
                              # See http://technet.microsoft.com/en-us/library/cc770413%28WS.10%29.aspx
                              #
                              # use_nonce = yes
+
+                             #
+                             # Number of seconds before giving up waiting
+                             # for OCSP response. 0 uses system default.
+                             #
+                             # timeout = 0
                        }
                }
 
index 2e88383..2b86902 100644 (file)
@@ -376,6 +376,7 @@ struct fr_tls_server_conf_t {
        char            *ocsp_url;
        int             ocsp_use_nonce;
        X509_STORE      *ocsp_store;
+       int             ocsp_timeout;
 #endif
 
 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
index c975758..de0c428 100644 (file)
@@ -781,6 +781,8 @@ static CONF_PARSER ocsp_config[] = {
          offsetof(fr_tls_server_conf_t, ocsp_url), NULL, NULL },
        { "use_nonce", PW_TYPE_BOOLEAN,
          offsetof(fr_tls_server_conf_t, ocsp_use_nonce), NULL, "yes"},
+       { "timeout", PW_TYPE_INTEGER,
+         offsetof(fr_tls_server_conf_t, ocsp_timeout), NULL, "yes"},
        { NULL, -1, 0, NULL, NULL }           /* end the list */
 };
 #endif
@@ -1057,7 +1059,7 @@ static int ocsp_check(X509_STORE *store, X509 *issuer_cert, X509 *client_cert,
 {
        OCSP_CERTID *certid;
        OCSP_REQUEST *req;
-       OCSP_RESPONSE *resp;
+       OCSP_RESPONSE *resp = NULL;
        OCSP_BASICRESP *bresp = NULL;
        char *host = NULL;
        char *port = NULL;
@@ -1069,6 +1071,10 @@ static int ocsp_check(X509_STORE *store, X509 *issuer_cert, X509 *client_cert,
        int status ;
        ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
        int reason;
+       OCSP_REQ_CTX *ctx;
+       int rc;
+       struct timeval now;
+       struct timeval when;
 
        /*
         * Create OCSP Request
@@ -1100,11 +1106,42 @@ static int ocsp_check(X509_STORE *store, X509 *issuer_cert, X509 *client_cert,
        bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
 
        BIO_set_conn_port(cbio, port);
-       BIO_do_connect(cbio);
 
-       /* Send OCSP request and wait for response */
-       resp = OCSP_sendreq_bio(cbio, path, req);
-       if(resp==0) {
+       if (conf->ocsp_timeout)
+               BIO_set_nbio(cbio, 1);
+
+       rc = BIO_do_connect(cbio);
+       if ((rc <= 0) && ((!conf->ocsp_timeout) || !BIO_should_retry(cbio))) {
+               radlog(L_ERR, "Error: Couldn't connect to OCSP responder");
+               goto ocsp_end;
+       }
+
+       ctx = OCSP_sendreq_new(cbio, path, req, -1);
+       if (!ctx) {
+               radlog(L_ERR, "Error: Couldn't send OCSP request");
+               goto ocsp_end;
+       }
+
+       gettimeofday(&when, NULL);
+       when.tv_sec += conf->ocsp_timeout;
+
+       do {
+               rc = OCSP_sendreq_nbio(&resp, ctx);
+               if (conf->ocsp_timeout) {
+                       gettimeofday(&now, NULL);
+                       if (!timercmp(&now, &when, <))
+                               break;
+               }
+       } while ((rc == -1) && BIO_should_retry(cbio));
+
+       if (conf->ocsp_timeout && (rc == -1) && BIO_should_retry(cbio)) {
+               radlog(L_ERR, "Error: OCSP response timed out");
+               goto ocsp_end;
+       }
+
+       OCSP_REQ_CTX_free(ctx);
+
+       if (rc == 0) {
                radlog(L_ERR, "Error: Couldn't get OCSP response");
                goto ocsp_end;
        }