diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2014-02-18 16:36:38 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2014-02-18 16:53:09 +0100 |
commit | 00c1ba83e1b4b301d0b177ab417b987f89fa7289 (patch) | |
tree | bdf8549d5e7fba92d3fa435e5e964efe89d713e3 | |
parent | ed0eb62f6e5890170f29799e5c0ad4b0484d41df (diff) | |
download | gnutls-00c1ba83e1b4b301d0b177ab417b987f89fa7289.tar.gz |
When sending a nonce in OCSP check if it is available on the reply.
-rw-r--r-- | src/cli.c | 16 | ||||
-rw-r--r-- | src/ocsptool-args.def | 2 | ||||
-rw-r--r-- | src/ocsptool-common.c | 50 | ||||
-rw-r--r-- | src/ocsptool-common.h | 6 | ||||
-rw-r--r-- | src/ocsptool.c | 62 |
5 files changed, 100 insertions, 36 deletions
@@ -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) diff --git a/src/ocsptool-args.def b/src/ocsptool-args.def index ad9e4dd0df..74c3fa5038 100644 --- a/src/ocsptool-args.def +++ b/src/ocsptool-args.def @@ -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 = ""; }; diff --git a/src/ocsptool-common.c b/src/ocsptool-common.c index 42ca2fee96..9404865ce5 100644 --- a/src/ocsptool-common.c +++ b/src/ocsptool-common.c @@ -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; diff --git a/src/ocsptool-common.h b/src/ocsptool-common.h index 67d255eae3..5922cb0ae5 100644 --- a/src/ocsptool-common.h +++ b/src/ocsptool-common.h @@ -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 diff --git a/src/ocsptool.c b/src/ocsptool.c index a8dcfc34e5..077c7d596e 100644 --- a/src/ocsptool.c +++ b/src/ocsptool.c @@ -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 { |