diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-08-09 17:31:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-08-09 17:31:57 +0200 |
commit | c14218ff07c41e78db7b87a47f340fbbc4f6a08a (patch) | |
tree | 4e881e9b1b64d5d1581b598985584007c6a3ccc2 /src/danetool.c | |
parent | 2abc6d12ad7a6d97a0ebae74e4f0a30743e7f737 (diff) | |
download | gnutls-c14218ff07c41e78db7b87a47f340fbbc4f6a08a.tar.gz |
danetool: obtain certificate only once
Diffstat (limited to 'src/danetool.c')
-rw-r--r-- | src/danetool.c | 178 |
1 files changed, 91 insertions, 87 deletions
diff --git a/src/danetool.c b/src/danetool.c index a1dcbca782..7538726bc2 100644 --- a/src/danetool.c +++ b/src/danetool.c @@ -45,6 +45,7 @@ /* Gnulib portability files. */ #include <read-file.h> +#include <minmax.h> #include <common.h> #include "danetool-args.h" @@ -178,6 +179,7 @@ static void cmd_parser(int argc, char **argv) gnutls_global_deinit(); } +#define MAX_CLIST_SIZE 32 static void dane_check(const char *host, const char *proto, unsigned int port, common_info_st * cinfo) { @@ -193,6 +195,9 @@ static void dane_check(const char *host, const char *proto, unsigned del = 0; unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED; const char *str; + gnutls_x509_crt_t *clist = NULL; + unsigned int clist_size = 0; + gnutls_datum_t certs[MAX_CLIST_SIZE]; if (ENABLED_OPT(LOCAL_DNS)) flags = 0; @@ -206,7 +211,17 @@ static void dane_check(const char *host, const char *proto, if (HAVE_OPT(CHECK_CA)) vflags |= DANE_VFLAG_ONLY_CHECK_CA_USAGE; - printf("Querying %s (%s:%d)...\n", host, proto, port); + if (!cinfo->cert) { + const char *app_proto = NULL; + if (HAVE_OPT(APP_PROTO)) + app_proto = OPT_ARG(APP_PROTO); + + cinfo->cert = obtain_cert(host, proto, port, app_proto, HAVE_OPT(QUIET)); + del = 1; + } + + if (!HAVE_OPT(QUIET)) + fprintf(stderr, "Querying DNS for %s (%s:%d)...\n", host, proto, port); ret = dane_state_init(&s, flags); if (ret < 0) { fprintf(stderr, "dane_state_init: %s\n", @@ -267,6 +282,46 @@ static void dane_check(const char *host, const char *proto, fprintf(outfile, "\n"); } + if (cinfo->cert) { + ret = gnutls_load_file(cinfo->cert, &file); + if (ret < 0) { + fprintf(stderr, "gnutls_load_file: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + ret = + gnutls_x509_crt_list_import2(&clist, + &clist_size, + &file, + cinfo-> + incert_format, 0); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_list_import2: %s\n", + gnutls_strerror(ret)); + exit(1); + } + + if (clist_size > 0) { + for (i = 0; i < MIN(MAX_CLIST_SIZE,clist_size); i++) { + ret = + gnutls_x509_crt_export2(clist + [i], + GNUTLS_X509_FMT_DER, + &certs + [i]); + if (ret < 0) { + fprintf(stderr, + "gnutls_x509_crt_export2: %s\n", + gnutls_strerror + (ret)); + exit(1); + } + } + } + } + entries = dane_query_entries(q); for (i = 0; i < entries; i++) { del = 0; @@ -278,7 +333,6 @@ static void dane_check(const char *host, const char *proto, exit(1); } - size = lbuffer_size; ret = gnutls_hex_encode(&data, (void *) lbuffer, &size); if (ret < 0) { @@ -306,112 +360,62 @@ static void dane_check(const char *host, const char *proto, str = dane_match_type_name(match); if (str == NULL) str= "Unknown"; fprintf(outfile, "Contents: %s (%.2x)\n", str, match); - fprintf(outfile, "Data: %s\n\n", lbuffer); - } - - if (!cinfo->cert) { - const char *app_proto = NULL; - if (HAVE_OPT(APP_PROTO)) - app_proto = OPT_ARG(APP_PROTO); - - cinfo->cert = obtain_cert(host, proto, port, app_proto, HAVE_OPT(QUIET)); - del = 1; + fprintf(outfile, "Data: %s\n", lbuffer); } /* Verify the DANE data */ if (cinfo->cert) { - gnutls_x509_crt_t *clist; - unsigned int clist_size, status; + unsigned int status; + gnutls_datum_t out; - ret = gnutls_load_file(cinfo->cert, &file); + ret = + dane_verify_crt(s, certs, clist_size, + GNUTLS_CRT_X509, host, + proto, port, 0, vflags, + &status); if (ret < 0) { - fprintf(stderr, "gnutls_load_file: %s\n", - gnutls_strerror(ret)); + fprintf(stderr, + "dane_verify_crt: %s\n", + dane_strerror(ret)); exit(1); } ret = - gnutls_x509_crt_list_import2(&clist, - &clist_size, - &file, - cinfo-> - incert_format, 0); + dane_verification_status_print(status, + &out, + 0); if (ret < 0) { fprintf(stderr, - "gnutls_x509_crt_list_import2: %s\n", - gnutls_strerror(ret)); + "dane_verification_status_print: %s\n", + dane_strerror(ret)); exit(1); } - if (clist_size > 0) { - gnutls_datum_t certs[clist_size]; - gnutls_datum_t out; - unsigned int i; - - for (i = 0; i < clist_size; i++) { - ret = - gnutls_x509_crt_export2(clist - [i], - GNUTLS_X509_FMT_DER, - &certs - [i]); - if (ret < 0) { - fprintf(stderr, - "gnutls_x509_crt_export2: %s\n", - gnutls_strerror - (ret)); - exit(1); - } - } + if (!HAVE_OPT(QUIET)) + fprintf(outfile, "\nVerification: %s\n", out.data); + gnutls_free(out.data); - ret = - dane_verify_crt(s, certs, clist_size, - GNUTLS_CRT_X509, host, - proto, port, 0, vflags, - &status); - if (ret < 0) { - fprintf(stderr, - "dane_verify_crt: %s\n", - dane_strerror(ret)); - exit(1); - } - - ret = - dane_verification_status_print(status, - &out, - 0); - if (ret < 0) { - fprintf(stderr, - "dane_verification_status_print: %s\n", - dane_strerror(ret)); - exit(1); - } - - if (!HAVE_OPT(QUIET)) - fprintf(outfile, "\nVerification: %s\n", out.data); - gnutls_free(out.data); - - /* if there is at least one correct accept */ - if (status == 0) - retcode = 0; - - for (i = 0; i < clist_size; i++) { - gnutls_free(certs[i].data); - gnutls_x509_crt_deinit(clist[i]); - } - gnutls_free(clist); - } - - if (del != 0) { - remove(cinfo->cert); - cinfo->cert = NULL; - } + /* if there is at least one correct accept */ + if (status == 0) + retcode = 0; } else { fprintf(stderr, "\nCertificate could not be obtained. You can explicitly load the certificate using --load-certificate.\n"); } } + if (clist_size > 0) { + for (i = 0; i < clist_size; i++) { + gnutls_free(certs[i].data); + gnutls_x509_crt_deinit(clist[i]); + } + gnutls_free(clist); + } + + if (del != 0 && cinfo->cert) { + remove(cinfo->cert); + } + dane_query_deinit(q); dane_state_deinit(s); @@ -419,7 +423,7 @@ static void dane_check(const char *host, const char *proto, exit(retcode); #else fprintf(stderr, - "This functionality was disabled (GnuTLS was not compiled with support for DANE).\n"); + "This functionality is disabled (GnuTLS was not compiled with support for DANE).\n"); return; #endif } |