diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-11-21 16:20:48 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-02-19 15:29:36 +0100 |
commit | 6a4251c035772691b6928cd7e24c194e5adcfc4b (patch) | |
tree | 8a83f198640a497379279be764897742d1adaf87 /src | |
parent | 64a17eca87c13d4a3d88c37b3ec52123def45e88 (diff) | |
download | gnutls-6a4251c035772691b6928cd7e24c194e5adcfc4b.tar.gz |
ocsptool: import and export OCSP responses in PEM format
That also modifies the 'request-info' and 'response-info' commands
to check the 'outfile' parameter and if set, to store the corresponding
structure into that file. Currently for OCSP requests there is no
printing of PEM data.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/ocsptool-args.def | 16 | ||||
-rw-r--r-- | src/ocsptool.c | 131 |
2 files changed, 114 insertions, 33 deletions
diff --git a/src/ocsptool-args.def b/src/ocsptool-args.def index 54752b01ec..b57088fead 100644 --- a/src/ocsptool-args.def +++ b/src/ocsptool-args.def @@ -3,7 +3,9 @@ prog-name = ocsptool; prog-title = "GnuTLS OCSP tool"; prog-desc = "Program to handle OCSP request/responses."; detail = "ocsptool is a program that can parse and print information about -OCSP requests/responses, generate requests and verify responses."; +OCSP requests/responses, generate requests and verify responses. Unlike +other GnuTLS applications it outputs DER encoded structures by default +unless the '--outpem' option is specified."; short-usage = "ocsptool [options]\nocsptool --help for usage instructions.\n"; explain = ""; @@ -129,6 +131,18 @@ flag = { }; flag = { + name = outder; + descrip = "Use DER format for output of responses (this is the default)"; + doc = "The output will be in DER encoded format. Unlike other GnuTLS tools, this is the default for this tool"; +}; + +flag = { + name = outpem; + descrip = "Use PEM format for output of responses"; + doc = "The output will be in PEM format."; +}; + +flag = { name = load-request; value = Q; arg-type = file; diff --git a/src/ocsptool.c b/src/ocsptool.c index 1338d6122b..ef181dae5e 100644 --- a/src/ocsptool.c +++ b/src/ocsptool.c @@ -43,6 +43,7 @@ #include "certtool-common.h" FILE *outfile; +static unsigned int incert_format, outcert_format; static const char *outfile_name = NULL; /* to delete on exit */ FILE *infile; static unsigned int encoding; @@ -87,7 +88,7 @@ static void request_info(void) { gnutls_ocsp_req_t req; int ret; - gnutls_datum_t dat; + gnutls_datum_t dat, rbuf; size_t size; ret = gnutls_ocsp_req_init(&req); @@ -108,6 +109,7 @@ static void request_info(void) } dat.size = size; + ret = gnutls_ocsp_req_import(req, &dat); free(dat.data); if (ret < 0) { @@ -123,17 +125,36 @@ static void request_info(void) app_exit(1); } - printf("%.*s", dat.size, dat.data); + if (HAVE_OPT(OUTFILE)) { + ret = gnutls_ocsp_req_export(req, &rbuf); + if (ret < 0) { + fprintf(stderr, "error exporting request: %s\n", + gnutls_strerror(ret)); + app_exit(1); + } + + if (outcert_format == GNUTLS_X509_FMT_PEM) { + fprintf(stderr, "Cannot export requests into PEM form\n"); + app_exit(1); + } else { + fwrite(rbuf.data, 1, rbuf.size, outfile); + } + + gnutls_free(rbuf.data); + } else { + printf("%.*s", dat.size, dat.data); + } + gnutls_free(dat.data); gnutls_ocsp_req_deinit(req); } -static void _response_info(const gnutls_datum_t * data) +static void _response_info(const gnutls_datum_t * data, unsigned force_print) { gnutls_ocsp_resp_t resp; int ret; - gnutls_datum_t buf; + gnutls_datum_t buf, rbuf; if (data->size == 0) { fprintf(stderr, "Received empty response\n"); @@ -147,9 +168,14 @@ static void _response_info(const gnutls_datum_t * data) app_exit(1); } - ret = gnutls_ocsp_resp_import(resp, data); + ret = gnutls_ocsp_resp_import2(resp, data, incert_format); + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) { + int ret2 = gnutls_ocsp_resp_import(resp, data); + if (ret2 >= 0) + ret = ret2; + } if (ret < 0) { - fprintf(stderr, "importing response: %s\n", + fprintf(stderr, "error importing response: %s\n", gnutls_strerror(ret)); app_exit(1); } @@ -168,7 +194,36 @@ static void _response_info(const gnutls_datum_t * data) app_exit(1); } - printf("%.*s", buf.size, buf.data); + if (HAVE_OPT(OUTFILE)) { + ret = gnutls_ocsp_resp_export2(resp, &rbuf, outcert_format); + if (ret < 0) { + fprintf(stderr, "error exporting response: %s\n", + gnutls_strerror(ret)); + app_exit(1); + } + + if (outcert_format == GNUTLS_X509_FMT_PEM) + fprintf(outfile, "%.*s\n", buf.size, buf.data); + + fwrite(rbuf.data, 1, rbuf.size, outfile); + + if (outcert_format == GNUTLS_X509_FMT_PEM) + fprintf(outfile, "\n"); + gnutls_free(rbuf.data); + } + + if (force_print || !HAVE_OPT(OUTFILE)) { + ret = gnutls_ocsp_resp_export2(resp, &rbuf, GNUTLS_X509_FMT_PEM); + if (ret < 0) { + fprintf(stderr, "error exporting response: %s\n", + gnutls_strerror(ret)); + app_exit(1); + } + + fprintf(stdout, "%.*s\n", buf.size, buf.data); + fwrite(rbuf.data, 1, rbuf.size, stdout); + gnutls_free(rbuf.data); + } gnutls_free(buf.data); gnutls_ocsp_resp_deinit(resp); @@ -191,7 +246,8 @@ static void response_info(void) } dat.size = size; - _response_info(&dat); + _response_info(&dat, 0); + gnutls_free(dat.data); } @@ -232,7 +288,7 @@ static void generate_request(gnutls_datum_t *nonce) static int _verify_response(gnutls_datum_t * data, gnutls_datum_t * nonce, - gnutls_x509_crt_t signer) + gnutls_x509_crt_t signer, unsigned print_resp) { gnutls_ocsp_resp_t resp; int ret; @@ -257,17 +313,19 @@ static int _verify_response(gnutls_datum_t * data, gnutls_datum_t * nonce, app_exit(1); } - ret = - gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_COMPACT, - &dat); - if (ret < 0) { - fprintf(stderr, "ocsp_resp_print: %s\n", - gnutls_strerror(ret)); - app_exit(1); - } + if (print_resp) { + ret = + gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_COMPACT, + &dat); + if (ret < 0) { + fprintf(stderr, "ocsp_resp_print: %s\n", + gnutls_strerror(ret)); + app_exit(1); + } - printf("%s\n", dat.data); - gnutls_free(dat.data); + printf("%s\n", dat.data); + gnutls_free(dat.data); + } if (nonce) { gnutls_datum_t rnonce; @@ -488,12 +546,12 @@ static void verify_response(gnutls_datum_t *nonce) else signer = chain[1]; - v = _verify_response(&dat, nonce, signer); + v = _verify_response(&dat, nonce, signer, 1); for (i=0;i<chain_size;i++) gnutls_x509_crt_deinit(chain[i]); } else if (HAVE_OPT(LOAD_TRUST)) { - v = _verify_response(&dat, nonce, NULL); + v = _verify_response(&dat, nonce, NULL, 1); } else { memset(&info, 0, sizeof(info)); info.verbose = verbose; @@ -505,7 +563,7 @@ static void verify_response(gnutls_datum_t *nonce) signer = load_cert(1, &info); - v = _verify_response(&dat, nonce, signer); + v = _verify_response(&dat, nonce, signer, 1); gnutls_x509_crt_deinit(signer); } @@ -530,8 +588,11 @@ static void ask_server(const char *url) chain_size = load_chain(chain); if (chain_size > 2 && HAVE_OPT(OUTFILE)) { - fprintf(stderr, "You cannot combine --outfile when more than 2 certificates are found in a chain\n"); - app_exit(1); + if (outcert_format != GNUTLS_X509_FMT_PEM) { + fprintf(stderr, "error: You cannot combine --outfile when more than 2 certificates are found in a chain\n"); + fprintf(stderr, "Did you mean to use --outpem?\n"); + app_exit(1); + } } counter = chain_size; @@ -556,26 +617,22 @@ static void ask_server(const char *url) app_exit(1); } - if (HAVE_OPT(OUTFILE)) { - fwrite(resp_data.data, 1, resp_data.size, outfile); - } - - _response_info(&resp_data); + _response_info(&resp_data, 1); if (HAVE_OPT(LOAD_TRUST)) { - v = _verify_response(&resp_data, n, NULL); + v = _verify_response(&resp_data, n, NULL, 0); } else if (HAVE_OPT(LOAD_SIGNER)) { memset(&info, 0, sizeof(info)); info.verbose = verbose; info.cert = OPT_ARG(LOAD_SIGNER); - v = _verify_response(&resp_data, n, load_cert(1, &info)); + v = _verify_response(&resp_data, n, load_cert(1, &info), 0); } else { if (!HAVE_OPT(LOAD_CHAIN)) fprintf(stderr, "\nAssuming response's signer = issuer (use --load-signer to override).\n"); - v = _verify_response(&resp_data, n, chain[idx+1]); + v = _verify_response(&resp_data, n, chain[idx+1], 0); } total_v += v; @@ -608,6 +665,16 @@ int main(int argc, char **argv) gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(OPT_VALUE_DEBUG); + if (ENABLED_OPT(INDER)) + incert_format = GNUTLS_X509_FMT_DER; + else + incert_format = GNUTLS_X509_FMT_PEM; + + if (HAVE_OPT(OUTPEM)) + outcert_format = GNUTLS_X509_FMT_PEM; + else + outcert_format = GNUTLS_X509_FMT_DER; + if (HAVE_OPT(VERIFY_ALLOW_BROKEN)) vflags |= GNUTLS_VERIFY_ALLOW_BROKEN; |