#include <gnutls/x509.h>
#include <gnutls/openpgp.h>
#include <gnutls/pkcs11.h>
+#include <gnutls/crypto.h>
/* Gnulib portability files. */
#include <read-file.h>
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);
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;
}
/* 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)
name = nonce;
disabled = yes;
disable = "no";
- descrip = "Don't add nonce to OCSP request";
+ descrip = "Use (or not) a nonce to OCSP request";
doc = "";
};
/*
- * Copyright (C) 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2012-2014 Free Software Foundation, Inc.
*
* This file is part of GnuTLS.
*
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;
}
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));
/* 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;
*/
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;
goto cleanup;
}
+
ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
&cert_status, &vtime, &ntime,
&rtime, NULL);
}
}
+ 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;
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
/*
- * Copyright (C) 2011-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2011-2014 Free Software Foundation, Inc.
*
* This file is part of GnuTLS.
*
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);
}
-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;
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);
return verify;
}
-static void verify_response(void)
+static void verify_response(gnutls_datum_t *nonce)
{
gnutls_datum_t dat;
size_t size;
}
dat.size = size;
- _verify_response(&dat);
+ _verify_response(&dat, nonce);
}
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);
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");
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 {