summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2014-02-18 16:36:38 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2014-02-18 16:53:09 +0100
commit00c1ba83e1b4b301d0b177ab417b987f89fa7289 (patch)
treebdf8549d5e7fba92d3fa435e5e964efe89d713e3
parented0eb62f6e5890170f29799e5c0ad4b0484d41df (diff)
downloadgnutls-00c1ba83e1b4b301d0b177ab417b987f89fa7289.tar.gz
When sending a nonce in OCSP check if it is available on the reply.
-rw-r--r--src/cli.c16
-rw-r--r--src/ocsptool-args.def2
-rw-r--r--src/ocsptool-common.c50
-rw-r--r--src/ocsptool-common.h6
-rw-r--r--src/ocsptool.c62
5 files changed, 100 insertions, 36 deletions
diff --git a/src/cli.c b/src/cli.c
index 18af111589..68004aa756 100644
--- 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)
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 {