]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
When sending a nonce in OCSP check if it is available on the reply.
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 18 Feb 2014 15:36:38 +0000 (16:36 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 18 Feb 2014 15:36:38 +0000 (16:36 +0100)
src/cli.c
src/ocsptool-args.def
src/ocsptool-common.c
src/ocsptool-common.h
src/ocsptool.c

index 18af11158992745383406bf94a342566875c6905..68004aa756417ce5e045d5e5ac1e10a2a16d3a62 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -45,6 +45,7 @@
 #include <gnutls/x509.h>
 #include <gnutls/openpgp.h>
 #include <gnutls/pkcs11.h>
+#include <gnutls/crypto.h>
 
 /* Gnulib portability files. */
 #include <read-file.h>
@@ -1710,6 +1711,8 @@ static int cert_verify_ocsp(gnutls_session_t session)
        unsigned int cert_list_size = 0;
        int deinit_issuer = 0;
        gnutls_datum_t resp;
+       unsigned char noncebuf[23];
+       gnutls_datum_t nonce = { noncebuf, sizeof(noncebuf) };
        int ret;
 
        cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
@@ -1746,7 +1749,16 @@ static int cert_verify_ocsp(gnutls_session_t session)
                goto cleanup;
        }
 
-       ret = send_ocsp_request(NULL, crt, issuer, &resp, 1);
+       ret =
+           gnutls_rnd(GNUTLS_RND_NONCE, nonce.data, nonce.size);
+       if (ret < 0) {
+               fprintf(stderr, "gnutls_rnd: %s",
+                       gnutls_strerror(ret));
+               ret = -1;
+               goto cleanup;
+       }
+
+       ret = send_ocsp_request(NULL, crt, issuer, &resp, &nonce);
        if (ret < 0) {
                fprintf(stderr, "Cannot contact OCSP server\n");
                ret = -1;
@@ -1754,7 +1766,7 @@ static int cert_verify_ocsp(gnutls_session_t session)
        }
 
        /* verify and check the response for revoked cert */
-       ret = check_ocsp_response(crt, issuer, &resp);
+       ret = check_ocsp_response(crt, issuer, &resp, &nonce);
 
       cleanup:
        if (deinit_issuer)
index ad9e4dd0df36162938926b5f44bc01e83987df1a..74c3fa503835b07afcd7a820cfa2389f037fe981 100644 (file)
@@ -56,7 +56,7 @@ flag = {
     name      = nonce;
     disabled  = yes;
     disable   = "no";
-    descrip   = "Don't add nonce to OCSP request";
+    descrip   = "Use (or not) a nonce to OCSP request";
     doc = "";
 };
 
index 42ca2fee961a437f2ec9bb578849a05aa9cbc734..9404865ce5bde008327ec8f71d117b3b1dda564e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2012-2014 Free Software Foundation, Inc.
  *
  * This file is part of GnuTLS.
  *
@@ -73,7 +73,7 @@ static const char *host_from_url(const char *url, unsigned int *port)
 
 void
 _generate_request(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
-                 gnutls_datum_t * rdata, int nonce)
+                 gnutls_datum_t * rdata, gnutls_datum_t *nonce)
 {
        gnutls_ocsp_req_t req;
        int ret;
@@ -92,18 +92,7 @@ _generate_request(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
        }
 
        if (nonce) {
-               unsigned char noncebuf[23];
-               gnutls_datum_t nonce = { noncebuf, sizeof(noncebuf) };
-
-               ret =
-                   gnutls_rnd(GNUTLS_RND_RANDOM, nonce.data, nonce.size);
-               if (ret < 0) {
-                       fprintf(stderr, "gnutls_rnd: %s",
-                               gnutls_strerror(ret));
-                       exit(1);
-               }
-
-               ret = gnutls_ocsp_req_set_nonce(req, 0, &nonce);
+               ret = gnutls_ocsp_req_set_nonce(req, 0, nonce);
                if (ret < 0) {
                        fprintf(stderr, "ocsp_req_set_nonce: %s",
                                gnutls_strerror(ret));
@@ -144,7 +133,7 @@ static size_t get_data(void *buffer, size_t size, size_t nmemb,
 /* Returns 0 on ok, and -1 on error */
 int send_ocsp_request(const char *server,
                      gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
-                     gnutls_datum_t * resp_data, int nonce)
+                     gnutls_datum_t * resp_data, gnutls_datum_t *nonce)
 {
        gnutls_datum_t ud;
        int ret;
@@ -311,7 +300,8 @@ void print_ocsp_verify_res(unsigned int output)
  */
 int
 check_ocsp_response(gnutls_x509_crt_t cert,
-                   gnutls_x509_crt_t issuer, gnutls_datum_t * data)
+                   gnutls_x509_crt_t issuer, gnutls_datum_t * data,
+                   gnutls_datum_t * nonce)
 {
        gnutls_ocsp_resp_t resp;
        int ret;
@@ -361,6 +351,7 @@ check_ocsp_response(gnutls_x509_crt_t cert,
                goto cleanup;
        }
 
+
        ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
                                          &cert_status, &vtime, &ntime,
                                          &rtime, NULL);
@@ -395,10 +386,35 @@ check_ocsp_response(gnutls_x509_crt_t cert,
                }
        }
 
+       if (nonce) {
+               gnutls_datum_t rnonce;
+
+               ret = gnutls_ocsp_resp_get_nonce(resp, NULL, &rnonce);
+               if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+                       fprintf(stderr, "*** The OCSP reply did not include the requested nonce.\n");
+                       goto finish_ok;
+               }
+
+               if (ret < 0) {
+                       fprintf(stderr, "could not read response's nonce: %s\n",
+                               gnutls_strerror(ret));
+                       exit(1);
+               }
+
+               if (rnonce.size != nonce->size || memcmp(nonce->data, rnonce.data,
+                       nonce->size) != 0) {
+                       fprintf(stderr, "nonce in the response doesn't match\n");
+                       exit(1);
+               }
+
+               gnutls_free(rnonce.data);
+       }
+
+ finish_ok:
        printf("- OCSP server flags certificate not revoked as of %s",
               ctime(&vtime));
        ret = 1;
     cleanup:
+ cleanup:
        gnutls_ocsp_resp_deinit(resp);
 
        return ret;
index 67d255eae3e8edc50bf01bd096e356ad2aa98d2a..5922cb0ae519b0537291a3d18b6573872a0ad5d4 100644 (file)
@@ -34,14 +34,14 @@ enum {
 extern void ocsptool_version(void);
 void
 _generate_request(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
-                 gnutls_datum_t * rdata, int nonce);
+                 gnutls_datum_t * rdata, gnutls_datum_t* nonce);
 int send_ocsp_request(const char *server,
                      gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
-                     gnutls_datum_t * resp_data, int nonce);
+                     gnutls_datum_t * resp_data, gnutls_datum_t* nonce);
 void print_ocsp_verify_res(unsigned int output);
 
 int
 check_ocsp_response(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
-                   gnutls_datum_t * data);
+                   gnutls_datum_t * data, gnutls_datum_t *nonce);
 
 #endif
index a8dcfc34e52a2ecf5219fb66f9e15770da634729..077c7d596e709fd8dc9715e26ed3fc938524b114 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2011-2014 Free Software Foundation, Inc.
  *
  * This file is part of GnuTLS.
  *
@@ -230,12 +230,11 @@ static gnutls_x509_crt_t load_cert(void)
        return crt;
 }
 
-static void generate_request(void)
+static void generate_request(gnutls_datum_t *nonce)
 {
        gnutls_datum_t dat;
 
-       _generate_request(load_cert(), load_issuer(), &dat,
-                         ENABLED_OPT(NONCE));
+       _generate_request(load_cert(), load_issuer(), &dat, nonce);
 
        fwrite(dat.data, 1, dat.size, outfile);
 
@@ -243,7 +242,7 @@ static void generate_request(void)
 }
 
 
-static int _verify_response(gnutls_datum_t * data)
+static int _verify_response(gnutls_datum_t * data, gnutls_datum_t * nonce)
 {
        gnutls_ocsp_resp_t resp;
        int ret;
@@ -269,6 +268,25 @@ static int _verify_response(gnutls_datum_t * data)
                exit(1);
        }
 
+       if (nonce) {
+               gnutls_datum_t rnonce;
+
+               ret = gnutls_ocsp_resp_get_nonce(resp, NULL, &rnonce);
+               if (ret < 0) {
+                       fprintf(stderr, "could not read response's nonce: %s\n",
+                               gnutls_strerror(ret));
+                       exit(1);
+               }
+
+               if (rnonce.size != nonce->size || memcmp(nonce->data, rnonce.data,
+                       nonce->size) != 0) {
+                       fprintf(stderr, "nonce in the response doesn't match\n");
+                       exit(1);
+               }
+
+               gnutls_free(rnonce.data);
+       }
+
        if (HAVE_OPT(LOAD_TRUST)) {
                dat.data =
                    (void *) read_binary_file(OPT_ARG(LOAD_TRUST), &size);
@@ -407,7 +425,7 @@ static int _verify_response(gnutls_datum_t * data)
        return verify;
 }
 
-static void verify_response(void)
+static void verify_response(gnutls_datum_t *nonce)
 {
        gnutls_datum_t dat;
        size_t size;
@@ -424,7 +442,7 @@ static void verify_response(void)
        }
        dat.size = size;
 
-       _verify_response(&dat);
+       _verify_response(&dat, nonce);
 }
 
 static void ask_server(const char *url)
@@ -432,13 +450,27 @@ static void ask_server(const char *url)
        gnutls_datum_t resp_data;
        int ret, v;
        gnutls_x509_crt_t cert, issuer;
+       unsigned char noncebuf[23];
+       gnutls_datum_t nonce = { noncebuf, sizeof(noncebuf) };
 
        cert = load_cert();
        issuer = load_issuer();
 
-       ret =
-           send_ocsp_request(url, cert, issuer, &resp_data,
-                             ENABLED_OPT(NONCE));
+       if (ENABLED_OPT(NONCE)) {
+               ret =
+                   gnutls_rnd(GNUTLS_RND_NONCE, nonce.data, nonce.size);
+               if (ret < 0) {
+                       fprintf(stderr, "gnutls_rnd: %s",
+                               gnutls_strerror(ret));
+                       exit(1);
+               }
+
+               ret =
+                   send_ocsp_request(url, cert, issuer, &resp_data, &nonce);
+       } else {
+               ret =
+                   send_ocsp_request(url, cert, issuer, &resp_data, NULL);
+       }
        if (ret < 0) {
                fprintf(stderr, "Cannot send OCSP request\n");
                exit(1);
@@ -448,7 +480,11 @@ static void ask_server(const char *url)
 
        if (HAVE_OPT(LOAD_SIGNER) || HAVE_OPT(LOAD_TRUST)) {
                fprintf(outfile, "\n");
-               v = _verify_response(&resp_data);
+               if (ENABLED_OPT(NONCE)) {
+                       v = _verify_response(&resp_data, &nonce);
+               } else {
+                       v = _verify_response(&resp_data, NULL);
+               }
        } else {
                fprintf(stderr,
                        "\nResponse could not be verified (use --load-signer).\n");
@@ -502,9 +538,9 @@ int main(int argc, char **argv)
        else if (HAVE_OPT(RESPONSE_INFO))
                response_info();
        else if (HAVE_OPT(GENERATE_REQUEST))
-               generate_request();
+               generate_request(NULL);
        else if (HAVE_OPT(VERIFY_RESPONSE))
-               verify_response();
+               verify_response(NULL);
        else if (HAVE_OPT(ASK))
                ask_server(OPT_ARG(ASK));
        else {