diff options
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | doc/invoke-danetool.texi | 16 | ||||
-rw-r--r-- | libdane/dane.c | 17 | ||||
-rw-r--r-- | libdane/includes/gnutls/dane.h | 15 | ||||
-rw-r--r-- | src/danetool-args.c | 282 | ||||
-rw-r--r-- | src/danetool-args.def | 14 | ||||
-rw-r--r-- | src/danetool-args.h | 58 | ||||
-rw-r--r-- | src/danetool.c | 15 | ||||
-rw-r--r-- | tests/suite/Makefile.am | 4 | ||||
-rwxr-xr-x | tests/suite/testdane | 71 |
10 files changed, 344 insertions, 156 deletions
@@ -2,6 +2,14 @@ GnuTLS NEWS -- History of user-visible changes. -*- outline -*- Copyright (C) 2000-2012 Free Software Foundation, Inc. See the end for copying conditions. +* Version 3.1.10 (unreleased) + +** libgnutls-dane: Updated DANE verification options. + +** API and ABI modifications: +No changes since last version. + + * Version 3.1.9 (released 2013-02-27) ** certtool: Option --to-p12 will now ask for a password to generate diff --git a/doc/invoke-danetool.texi b/doc/invoke-danetool.texi index 0aa41ebeba..cb34077cd7 100644 --- a/doc/invoke-danetool.texi +++ b/doc/invoke-danetool.texi @@ -6,7 +6,7 @@ # # DO NOT EDIT THIS FILE (invoke-danetool.texi) # -# It has been AutoGen-ed January 18, 2013 at 06:50:16 PM by AutoGen 5.16 +# It has been AutoGen-ed March 1, 2013 at 05:06:53 PM by AutoGen 5.16 # From the definitions ../src/danetool-args.def # and the template file agtexi-cmd.tpl @end ignore @@ -49,6 +49,8 @@ USAGE: danetool [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]... --dlv=str Sets a DLV file --hash=str Hash algorithm to use for signing. --check=str Check a host's DANE TLSA entry. + --check-ee Check only the end-entity's certificate. + --check-ca Check only the CA's certificate. --insecure Do not verify any DNSSEC signature. --local-dns Use the local DNS server for DNSSEC resolving. - disabled as --no-local-dns @@ -115,7 +117,17 @@ Available hash functions are SHA1, RMD160, SHA256, SHA384, SHA512. This is the ``check a host's dane tlsa entry.'' option. This option takes an argument string. -Obtains the DANE TLSA entry from the given hostname and prints information. +Obtains the DANE TLSA entry from the given hostname and prints information. Note that the actual certificate of the host has to be provided using --load-certificate. +@anchor{danetool check-ee} +@subsubheading check-ee option + +This is the ``check only the end-entity's certificate.'' option. +Checks the end-entity's certificate only. Trust anchors or CAs are not considered. +@anchor{danetool check-ca} +@subsubheading check-ca option + +This is the ``check only the ca's certificate.'' option. +Checks the trust anchor's and CA's certificate only. End-entities are not considered. @anchor{danetool insecure} @subsubheading insecure option diff --git a/libdane/dane.c b/libdane/dane.c index 9f2d8d7156..7c2be56a07 100644 --- a/libdane/dane.c +++ b/libdane/dane.c @@ -545,7 +545,7 @@ cleanup: * @proto: The protocol of the service connecting (e.g. tcp) * @port: The port of the service connecting (e.g. 443) * @sflags: Flags for the the initialization of @s (if NULL) - * @vflags: Verification flags; should be zero + * @vflags: Verification flags; an OR'ed list of %dane_verify_flags_t. * @verify: An OR'ed list of %dane_verify_status_t. * * This function will verify the given certificate chain against the @@ -578,6 +578,7 @@ int dane_verify_crt (dane_state_t s, dane_state_t _s = NULL; dane_query_t r = NULL; int ret; +unsigned checked = 0; unsigned int usage, type, match, idx; gnutls_datum_t data; @@ -611,24 +612,28 @@ gnutls_datum_t data; gnutls_assert(); goto cleanup; } - - if (usage == DANE_CERT_USAGE_LOCAL_CA || usage == DANE_CERT_USAGE_CA) { + + if (!(vflags & DANE_VFLAG_ONLY_CHECK_EE_USAGE) && (usage == DANE_CERT_USAGE_LOCAL_CA || usage == DANE_CERT_USAGE_CA)) { ret = verify_ca(chain, chain_size, chain_type, type, match, &data, verify); if (ret < 0) { gnutls_assert(); goto cleanup; } - - } else if (usage == DANE_CERT_USAGE_LOCAL_EE || usage == DANE_CERT_USAGE_EE) { + checked = 1; + } else if (!(vflags & DANE_VFLAG_ONLY_CHECK_CA_USAGE) && (usage == DANE_CERT_USAGE_LOCAL_EE || usage == DANE_CERT_USAGE_EE)) { ret = verify_ee(&chain[0], chain_type, type, match, &data, verify); if (ret < 0) { gnutls_assert(); goto cleanup; } + checked = 1; } } while(1); - ret = 0; + if ((vflags & DANE_VFLAG_FAIL_IF_NOT_CHECKED) && checked == 0) + ret = gnutls_assert_val(DANE_E_REQUESTED_DATA_NOT_AVAILABLE); + else + ret = 0; cleanup: if (s == NULL) dane_state_deinit(_s); diff --git a/libdane/includes/gnutls/dane.h b/libdane/includes/gnutls/dane.h index 94841b9989..f5b9104611 100644 --- a/libdane/includes/gnutls/dane.h +++ b/libdane/includes/gnutls/dane.h @@ -123,6 +123,21 @@ const char* dane_match_type_name(dane_match_type_t type); const char* dane_cert_usage_name(dane_cert_usage_t usage); /** + * dane_verify_flags_t: + * @DANE_VFLAG_FAIL_IF_NOT_CHECKED: If irrelevant to this certificate DANE entries are received fail instead of succeeding. + * @DANE_VFLAG_CHECK_EE_USAGE: The provided certificates will be verified only against any EE field. Combine with %DANE_VFLAG_FAIL_IF_NOT_CHECKED to fail if EE entries are not present. + * @DANE_VFLAG_CHECK_CA_USAGE: The provided certificates will be verified only against any CA field. Combine with %DANE_VFLAG_FAIL_IF_NOT_CHECKED to fail if CA entries are not present. + * + * Enumeration of different verification status flags. + */ +typedef enum dane_verify_flags_t +{ + DANE_VFLAG_FAIL_IF_NOT_CHECKED = 1, + DANE_VFLAG_ONLY_CHECK_EE_USAGE = 1<<1, + DANE_VFLAG_ONLY_CHECK_CA_USAGE = 1<<2, +} dane_verify_flags_t; + +/** * dane_verify_status_t: * @DANE_VERIFY_CA_CONSTRAINS_VIOLATED: The CA constrains was violated. * @DANE_VERIFY_CERT_DIFFERS: The certificate obtained via DNS differs. diff --git a/src/danetool-args.c b/src/danetool-args.c index 25d3afc088..2538974dbf 100644 --- a/src/danetool-args.c +++ b/src/danetool-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (danetool-args.c) * - * It has been AutoGen-ed January 18, 2013 at 06:50:09 PM by AutoGen 5.16 + * It has been AutoGen-ed March 1, 2013 at 05:01:34 PM by AutoGen 5.16 * From the definitions danetool-args.def * and the template file options * @@ -67,7 +67,7 @@ extern FILE * option_usage_fp; /* * danetool option static const strings */ -static char const danetool_opt_strs[2357] = +static char const danetool_opt_strs[2467] = /* 0 */ "danetool @VERSION@\n" "Copyright (C) 2000-2012 Free Software Foundation, all rights reserved.\n" "This is free software. It is licensed for use, modification and\n" @@ -111,55 +111,61 @@ static char const danetool_opt_strs[2357] = /* 1179 */ "Check a host's DANE TLSA entry.\0" /* 1211 */ "CHECK\0" /* 1217 */ "check\0" -/* 1223 */ "Do not verify any DNSSEC signature.\0" -/* 1259 */ "INSECURE\0" -/* 1268 */ "insecure\0" -/* 1277 */ "Use the local DNS server for DNSSEC resolving.\0" -/* 1324 */ "LOCAL_DNS\0" -/* 1334 */ "no-local-dns\0" -/* 1347 */ "no\0" -/* 1350 */ "Use DER format for input certificates and private keys.\0" -/* 1406 */ "INDER\0" -/* 1412 */ "no-inder\0" -/* 1421 */ "This is an alias for 'inder'\0" -/* 1450 */ "inraw\0" -/* 1456 */ "Print the DANE RR data on a certificate or public key\0" -/* 1510 */ "TLSA_RR\0" -/* 1518 */ "tlsa-rr\0" -/* 1526 */ "Specify the hostname to be used in the DANE RR\0" -/* 1573 */ "HOST\0" -/* 1578 */ "host\0" -/* 1583 */ "The protocol set for DANE data (tcp, udp etc.)\0" -/* 1630 */ "PROTO\0" -/* 1636 */ "proto\0" -/* 1642 */ "Specify the port number for the DANE data.\0" -/* 1685 */ "PORT\0" -/* 1690 */ "port\0" -/* 1695 */ "Whether the provided certificate or public key is a Certificate\n" +/* 1223 */ "Check only the end-entity's certificate.\0" +/* 1264 */ "CHECK_EE\0" +/* 1273 */ "check-ee\0" +/* 1282 */ "Check only the CA's certificate.\0" +/* 1315 */ "CHECK_CA\0" +/* 1324 */ "check-ca\0" +/* 1333 */ "Do not verify any DNSSEC signature.\0" +/* 1369 */ "INSECURE\0" +/* 1378 */ "insecure\0" +/* 1387 */ "Use the local DNS server for DNSSEC resolving.\0" +/* 1434 */ "LOCAL_DNS\0" +/* 1444 */ "no-local-dns\0" +/* 1457 */ "no\0" +/* 1460 */ "Use DER format for input certificates and private keys.\0" +/* 1516 */ "INDER\0" +/* 1522 */ "no-inder\0" +/* 1531 */ "This is an alias for 'inder'\0" +/* 1560 */ "inraw\0" +/* 1566 */ "Print the DANE RR data on a certificate or public key\0" +/* 1620 */ "TLSA_RR\0" +/* 1628 */ "tlsa-rr\0" +/* 1636 */ "Specify the hostname to be used in the DANE RR\0" +/* 1683 */ "HOST\0" +/* 1688 */ "host\0" +/* 1693 */ "The protocol set for DANE data (tcp, udp etc.)\0" +/* 1740 */ "PROTO\0" +/* 1746 */ "proto\0" +/* 1752 */ "Specify the port number for the DANE data.\0" +/* 1795 */ "PORT\0" +/* 1800 */ "port\0" +/* 1805 */ "Whether the provided certificate or public key is a Certificate\n" "Authority.\0" -/* 1770 */ "CA\0" -/* 1773 */ "ca\0" -/* 1776 */ "Use the hash of the X.509 certificate, rather than the public key.\0" -/* 1843 */ "X509\0" -/* 1848 */ "x509\0" -/* 1853 */ "The provided certificate or public key is a local entity.\0" -/* 1911 */ "LOCAL\0" -/* 1917 */ "local\0" -/* 1923 */ "Display extended usage information and exit\0" -/* 1967 */ "help\0" -/* 1972 */ "Extended usage information passed thru pager\0" -/* 2017 */ "more-help\0" -/* 2027 */ "Output version information and exit\0" -/* 2063 */ "version\0" -/* 2071 */ "DANETOOL\0" -/* 2080 */ "danetool - GnuTLS DANE tool - Ver. @VERSION@\n" +/* 1880 */ "CA\0" +/* 1883 */ "ca\0" +/* 1886 */ "Use the hash of the X.509 certificate, rather than the public key.\0" +/* 1953 */ "X509\0" +/* 1958 */ "x509\0" +/* 1963 */ "The provided certificate or public key is a local entity.\0" +/* 2021 */ "LOCAL\0" +/* 2027 */ "local\0" +/* 2033 */ "Display extended usage information and exit\0" +/* 2077 */ "help\0" +/* 2082 */ "Extended usage information passed thru pager\0" +/* 2127 */ "more-help\0" +/* 2137 */ "Output version information and exit\0" +/* 2173 */ "version\0" +/* 2181 */ "DANETOOL\0" +/* 2190 */ "danetool - GnuTLS DANE tool - Ver. @VERSION@\n" "USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0" -/* 2183 */ "bug-gnutls@gnu.org\0" -/* 2202 */ "\n\n\0" -/* 2205 */ "\n" +/* 2293 */ "bug-gnutls@gnu.org\0" +/* 2312 */ "\n\n\0" +/* 2315 */ "\n" "Tool to generate and check DNS resource records for the DANE protocol.\n\0" -/* 2278 */ "danetool @VERSION@\0" -/* 2297 */ "danetool [options]\n" +/* 2388 */ "danetool @VERSION@\0" +/* 2407 */ "danetool [options]\n" "danetool --help for usage instructions.\n"; /* @@ -243,48 +249,64 @@ static char const danetool_opt_strs[2357] = | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) /* + * check-ee option description: + */ +#define CHECK_EE_DESC (danetool_opt_strs+1223) +#define CHECK_EE_NAME (danetool_opt_strs+1264) +#define CHECK_EE_name (danetool_opt_strs+1273) +#define CHECK_EE_FLAGS (OPTST_DISABLED) + +/* + * check-ca option description: + */ +#define CHECK_CA_DESC (danetool_opt_strs+1282) +#define CHECK_CA_NAME (danetool_opt_strs+1315) +#define CHECK_CA_name (danetool_opt_strs+1324) +#define CHECK_CA_FLAGS (OPTST_DISABLED) + +/* * insecure option description: */ -#define INSECURE_DESC (danetool_opt_strs+1223) -#define INSECURE_NAME (danetool_opt_strs+1259) -#define INSECURE_name (danetool_opt_strs+1268) +#define INSECURE_DESC (danetool_opt_strs+1333) +#define INSECURE_NAME (danetool_opt_strs+1369) +#define INSECURE_name (danetool_opt_strs+1378) #define INSECURE_FLAGS (OPTST_DISABLED) /* * local-dns option description: */ -#define LOCAL_DNS_DESC (danetool_opt_strs+1277) -#define LOCAL_DNS_NAME (danetool_opt_strs+1324) -#define NOT_LOCAL_DNS_name (danetool_opt_strs+1334) -#define NOT_LOCAL_DNS_PFX (danetool_opt_strs+1347) +#define LOCAL_DNS_DESC (danetool_opt_strs+1387) +#define LOCAL_DNS_NAME (danetool_opt_strs+1434) +#define NOT_LOCAL_DNS_name (danetool_opt_strs+1444) +#define NOT_LOCAL_DNS_PFX (danetool_opt_strs+1457) #define LOCAL_DNS_name (NOT_LOCAL_DNS_name + 3) #define LOCAL_DNS_FLAGS (OPTST_DISABLED) /* * inder option description: */ -#define INDER_DESC (danetool_opt_strs+1350) -#define INDER_NAME (danetool_opt_strs+1406) -#define NOT_INDER_name (danetool_opt_strs+1412) -#define NOT_INDER_PFX (danetool_opt_strs+1347) +#define INDER_DESC (danetool_opt_strs+1460) +#define INDER_NAME (danetool_opt_strs+1516) +#define NOT_INDER_name (danetool_opt_strs+1522) +#define NOT_INDER_PFX (danetool_opt_strs+1457) #define INDER_name (NOT_INDER_name + 3) #define INDER_FLAGS (OPTST_DISABLED) /* * inraw option description: */ -#define INRAW_DESC (danetool_opt_strs+1421) +#define INRAW_DESC (danetool_opt_strs+1531) #define INRAW_NAME NULL -#define INRAW_name (danetool_opt_strs+1450) +#define INRAW_name (danetool_opt_strs+1560) #define INRAW_FLAGS (INDER_FLAGS | OPTST_ALIAS) /* * tlsa-rr option description with * "Must also have options" and "Incompatible options": */ -#define TLSA_RR_DESC (danetool_opt_strs+1456) -#define TLSA_RR_NAME (danetool_opt_strs+1510) -#define TLSA_RR_name (danetool_opt_strs+1518) +#define TLSA_RR_DESC (danetool_opt_strs+1566) +#define TLSA_RR_NAME (danetool_opt_strs+1620) +#define TLSA_RR_name (danetool_opt_strs+1628) static int const aTlsa_RrMustList[] = { INDEX_OPT_HOST, NO_EQUIVALENT }; #define TLSA_RR_FLAGS (OPTST_DISABLED) @@ -292,62 +314,62 @@ static int const aTlsa_RrMustList[] = { /* * host option description: */ -#define HOST_DESC (danetool_opt_strs+1526) -#define HOST_NAME (danetool_opt_strs+1573) -#define HOST_name (danetool_opt_strs+1578) +#define HOST_DESC (danetool_opt_strs+1636) +#define HOST_NAME (danetool_opt_strs+1683) +#define HOST_name (danetool_opt_strs+1688) #define HOST_FLAGS (OPTST_DISABLED \ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) /* * proto option description: */ -#define PROTO_DESC (danetool_opt_strs+1583) -#define PROTO_NAME (danetool_opt_strs+1630) -#define PROTO_name (danetool_opt_strs+1636) +#define PROTO_DESC (danetool_opt_strs+1693) +#define PROTO_NAME (danetool_opt_strs+1740) +#define PROTO_name (danetool_opt_strs+1746) #define PROTO_FLAGS (OPTST_DISABLED \ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) /* * port option description: */ -#define PORT_DESC (danetool_opt_strs+1642) -#define PORT_NAME (danetool_opt_strs+1685) -#define PORT_name (danetool_opt_strs+1690) +#define PORT_DESC (danetool_opt_strs+1752) +#define PORT_NAME (danetool_opt_strs+1795) +#define PORT_name (danetool_opt_strs+1800) #define PORT_FLAGS (OPTST_DISABLED \ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) /* * ca option description: */ -#define CA_DESC (danetool_opt_strs+1695) -#define CA_NAME (danetool_opt_strs+1770) -#define CA_name (danetool_opt_strs+1773) +#define CA_DESC (danetool_opt_strs+1805) +#define CA_NAME (danetool_opt_strs+1880) +#define CA_name (danetool_opt_strs+1883) #define CA_FLAGS (OPTST_DISABLED) /* * x509 option description: */ -#define X509_DESC (danetool_opt_strs+1776) -#define X509_NAME (danetool_opt_strs+1843) -#define X509_name (danetool_opt_strs+1848) +#define X509_DESC (danetool_opt_strs+1886) +#define X509_NAME (danetool_opt_strs+1953) +#define X509_name (danetool_opt_strs+1958) #define X509_FLAGS (OPTST_DISABLED) /* * local option description: */ -#define LOCAL_DESC (danetool_opt_strs+1853) -#define LOCAL_NAME (danetool_opt_strs+1911) -#define LOCAL_name (danetool_opt_strs+1917) +#define LOCAL_DESC (danetool_opt_strs+1963) +#define LOCAL_NAME (danetool_opt_strs+2021) +#define LOCAL_name (danetool_opt_strs+2027) #define LOCAL_FLAGS (OPTST_DISABLED) /* * Help/More_Help/Version option descriptions: */ -#define HELP_DESC (danetool_opt_strs+1923) -#define HELP_name (danetool_opt_strs+1967) +#define HELP_DESC (danetool_opt_strs+2033) +#define HELP_name (danetool_opt_strs+2077) #ifdef HAVE_WORKING_FORK -#define MORE_HELP_DESC (danetool_opt_strs+1972) -#define MORE_HELP_name (danetool_opt_strs+2017) +#define MORE_HELP_DESC (danetool_opt_strs+2082) +#define MORE_HELP_name (danetool_opt_strs+2127) #define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) #else #define MORE_HELP_DESC NULL @@ -360,8 +382,8 @@ static int const aTlsa_RrMustList[] = { # define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) #endif -#define VER_DESC (danetool_opt_strs+2027) -#define VER_name (danetool_opt_strs+2063) +#define VER_DESC (danetool_opt_strs+2137) +#define VER_name (danetool_opt_strs+2173) /* * Declare option callback procedures */ @@ -489,8 +511,32 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ CHECK_DESC, CHECK_NAME, CHECK_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 9, VALUE_OPT_INSECURE, - /* equiv idx, value */ 9, VALUE_OPT_INSECURE, + { /* entry idx, value */ 9, VALUE_OPT_CHECK_EE, + /* equiv idx, value */ 9, VALUE_OPT_CHECK_EE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ CHECK_EE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --check-ee */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ CHECK_EE_DESC, CHECK_EE_NAME, CHECK_EE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 10, VALUE_OPT_CHECK_CA, + /* equiv idx, value */ 10, VALUE_OPT_CHECK_CA, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ CHECK_CA_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --check-ca */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ CHECK_CA_DESC, CHECK_CA_NAME, CHECK_CA_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 11, VALUE_OPT_INSECURE, + /* equiv idx, value */ 11, VALUE_OPT_INSECURE, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ INSECURE_FLAGS, 0, @@ -501,8 +547,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ INSECURE_DESC, INSECURE_NAME, INSECURE_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 10, VALUE_OPT_LOCAL_DNS, - /* equiv idx, value */ 10, VALUE_OPT_LOCAL_DNS, + { /* entry idx, value */ 12, VALUE_OPT_LOCAL_DNS, + /* equiv idx, value */ 12, VALUE_OPT_LOCAL_DNS, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ LOCAL_DNS_FLAGS, 0, @@ -513,8 +559,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ LOCAL_DNS_DESC, LOCAL_DNS_NAME, LOCAL_DNS_name, /* disablement strs */ NOT_LOCAL_DNS_name, NOT_LOCAL_DNS_PFX }, - { /* entry idx, value */ 11, VALUE_OPT_INDER, - /* equiv idx, value */ 11, VALUE_OPT_INDER, + { /* entry idx, value */ 13, VALUE_OPT_INDER, + /* equiv idx, value */ 13, VALUE_OPT_INDER, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ INDER_FLAGS, 0, @@ -525,8 +571,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ INDER_DESC, INDER_NAME, INDER_name, /* disablement strs */ NOT_INDER_name, NOT_INDER_PFX }, - { /* entry idx, value */ 12, VALUE_OPT_INRAW, - /* equiv idx, value */ 12, VALUE_OPT_INRAW, + { /* entry idx, value */ 14, VALUE_OPT_INRAW, + /* equiv idx, value */ 14, VALUE_OPT_INRAW, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ INRAW_FLAGS, 0, @@ -537,8 +583,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ INRAW_DESC, INRAW_NAME, INRAW_name, /* disablement strs */ 0, 0 }, - { /* entry idx, value */ 13, VALUE_OPT_TLSA_RR, - /* equiv idx, value */ 13, VALUE_OPT_TLSA_RR, + { /* entry idx, value */ 15, VALUE_OPT_TLSA_RR, + /* equiv idx, value */ 15, VALUE_OPT_TLSA_RR, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ TLSA_RR_FLAGS, 0, @@ -549,8 +595,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ TLSA_RR_DESC, TLSA_RR_NAME, TLSA_RR_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 14, VALUE_OPT_HOST, - /* equiv idx, value */ 14, VALUE_OPT_HOST, + { /* entry idx, value */ 16, VALUE_OPT_HOST, + /* equiv idx, value */ 16, VALUE_OPT_HOST, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ HOST_FLAGS, 0, @@ -561,8 +607,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ HOST_DESC, HOST_NAME, HOST_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 15, VALUE_OPT_PROTO, - /* equiv idx, value */ 15, VALUE_OPT_PROTO, + { /* entry idx, value */ 17, VALUE_OPT_PROTO, + /* equiv idx, value */ 17, VALUE_OPT_PROTO, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ PROTO_FLAGS, 0, @@ -573,8 +619,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ PROTO_DESC, PROTO_NAME, PROTO_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 16, VALUE_OPT_PORT, - /* equiv idx, value */ 16, VALUE_OPT_PORT, + { /* entry idx, value */ 18, VALUE_OPT_PORT, + /* equiv idx, value */ 18, VALUE_OPT_PORT, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ PORT_FLAGS, 0, @@ -585,8 +631,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ PORT_DESC, PORT_NAME, PORT_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 17, VALUE_OPT_CA, - /* equiv idx, value */ 17, VALUE_OPT_CA, + { /* entry idx, value */ 19, VALUE_OPT_CA, + /* equiv idx, value */ 19, VALUE_OPT_CA, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ CA_FLAGS, 0, @@ -597,8 +643,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ CA_DESC, CA_NAME, CA_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 18, VALUE_OPT_X509, - /* equiv idx, value */ 18, VALUE_OPT_X509, + { /* entry idx, value */ 20, VALUE_OPT_X509, + /* equiv idx, value */ 20, VALUE_OPT_X509, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ X509_FLAGS, 0, @@ -609,8 +655,8 @@ static tOptDesc optDesc[OPTION_CT] = { /* desc, NAME, name */ X509_DESC, X509_NAME, X509_name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 19, VALUE_OPT_LOCAL, - /* equiv idx, value */ 19, VALUE_OPT_LOCAL, + { /* entry idx, value */ 21, VALUE_OPT_LOCAL, + /* equiv idx, value */ 21, VALUE_OPT_LOCAL, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ LOCAL_FLAGS, 0, @@ -665,14 +711,14 @@ static tOptDesc optDesc[OPTION_CT] = { * * Define the danetool Option Environment */ -#define zPROGNAME (danetool_opt_strs+2071) -#define zUsageTitle (danetool_opt_strs+2080) +#define zPROGNAME (danetool_opt_strs+2181) +#define zUsageTitle (danetool_opt_strs+2190) #define zRcName NULL #define apzHomeList NULL -#define zBugsAddr (danetool_opt_strs+2183) -#define zExplain (danetool_opt_strs+2202) -#define zDetail (danetool_opt_strs+2205) -#define zFullVersion (danetool_opt_strs+2278) +#define zBugsAddr (danetool_opt_strs+2293) +#define zExplain (danetool_opt_strs+2312) +#define zDetail (danetool_opt_strs+2315) +#define zFullVersion (danetool_opt_strs+2388) /* extracted from optcode.tlib near line 350 */ #if defined(ENABLE_NLS) @@ -686,7 +732,7 @@ static tOptDesc optDesc[OPTION_CT] = { #define danetool_full_usage (NULL) -#define danetool_short_usage (danetool_opt_strs+2297) +#define danetool_short_usage (danetool_opt_strs+2407) #endif /* not defined __doxygen__ */ @@ -845,7 +891,7 @@ tOptions danetoolOptions = { NO_EQUIVALENT, /* '-#' option index */ NO_EQUIVALENT /* index of default opt */ }, - 23 /* full option count */, 20 /* user option count */, + 25 /* full option count */, 22 /* user option count */, danetool_full_usage, danetool_short_usage, NULL, NULL, PKGDATADIR, danetool_packager_info diff --git a/src/danetool-args.def b/src/danetool-args.def index a6673aad1a..36ffd1e4bb 100644 --- a/src/danetool-args.def +++ b/src/danetool-args.def @@ -43,7 +43,19 @@ flag = { name = check; arg-type = string; descrip = "Check a host's DANE TLSA entry."; - doc = "Obtains the DANE TLSA entry from the given hostname and prints information."; + doc = "Obtains the DANE TLSA entry from the given hostname and prints information. Note that the actual certificate of the host has to be provided using --load-certificate."; +}; + +flag = { + name = check-ee; + descrip = "Check only the end-entity's certificate."; + doc = "Checks the end-entity's certificate only. Trust anchors or CAs are not considered."; +}; + +flag = { + name = check-ca; + descrip = "Check only the CA's certificate."; + doc = "Checks the trust anchor's and CA's certificate only. End-entities are not considered."; }; flag = { diff --git a/src/danetool-args.h b/src/danetool-args.h index fbc1e9ee89..1e37cbd966 100644 --- a/src/danetool-args.h +++ b/src/danetool-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (danetool-args.h) * - * It has been AutoGen-ed January 18, 2013 at 06:50:09 PM by AutoGen 5.16 + * It has been AutoGen-ed March 1, 2013 at 05:01:34 PM by AutoGen 5.16 * From the definitions danetool-args.def * and the template file options * @@ -76,23 +76,25 @@ typedef enum { INDEX_OPT_DLV = 6, INDEX_OPT_HASH = 7, INDEX_OPT_CHECK = 8, - INDEX_OPT_INSECURE = 9, - INDEX_OPT_LOCAL_DNS = 10, - INDEX_OPT_INDER = 11, - INDEX_OPT_INRAW = 12, - INDEX_OPT_TLSA_RR = 13, - INDEX_OPT_HOST = 14, - INDEX_OPT_PROTO = 15, - INDEX_OPT_PORT = 16, - INDEX_OPT_CA = 17, - INDEX_OPT_X509 = 18, - INDEX_OPT_LOCAL = 19, - INDEX_OPT_VERSION = 20, - INDEX_OPT_HELP = 21, - INDEX_OPT_MORE_HELP = 22 + INDEX_OPT_CHECK_EE = 9, + INDEX_OPT_CHECK_CA = 10, + INDEX_OPT_INSECURE = 11, + INDEX_OPT_LOCAL_DNS = 12, + INDEX_OPT_INDER = 13, + INDEX_OPT_INRAW = 14, + INDEX_OPT_TLSA_RR = 15, + INDEX_OPT_HOST = 16, + INDEX_OPT_PROTO = 17, + INDEX_OPT_PORT = 18, + INDEX_OPT_CA = 19, + INDEX_OPT_X509 = 20, + INDEX_OPT_LOCAL = 21, + INDEX_OPT_VERSION = 22, + INDEX_OPT_HELP = 23, + INDEX_OPT_MORE_HELP = 24 } teOptIndex; -#define OPTION_CT 23 +#define OPTION_CT 25 #define DANETOOL_VERSION "@VERSION@" #define DANETOOL_FULL_VERSION "danetool @VERSION@" @@ -141,19 +143,21 @@ typedef enum { #define VALUE_OPT_DLV 6 #define VALUE_OPT_HASH 7 #define VALUE_OPT_CHECK 8 -#define VALUE_OPT_INSECURE 9 -#define VALUE_OPT_LOCAL_DNS 10 -#define VALUE_OPT_INDER 11 -#define VALUE_OPT_INRAW 12 -#define VALUE_OPT_TLSA_RR 13 -#define VALUE_OPT_HOST 14 -#define VALUE_OPT_PROTO 15 -#define VALUE_OPT_PORT 16 +#define VALUE_OPT_CHECK_EE 9 +#define VALUE_OPT_CHECK_CA 10 +#define VALUE_OPT_INSECURE 11 +#define VALUE_OPT_LOCAL_DNS 12 +#define VALUE_OPT_INDER 13 +#define VALUE_OPT_INRAW 14 +#define VALUE_OPT_TLSA_RR 15 +#define VALUE_OPT_HOST 16 +#define VALUE_OPT_PROTO 17 +#define VALUE_OPT_PORT 18 #define OPT_VALUE_PORT (DESC(PORT).optArg.argInt) -#define VALUE_OPT_CA 17 -#define VALUE_OPT_X509 18 -#define VALUE_OPT_LOCAL 19 +#define VALUE_OPT_CA 19 +#define VALUE_OPT_X509 20 +#define VALUE_OPT_LOCAL 21 #define VALUE_OPT_HELP 'h' #define VALUE_OPT_MORE_HELP '!' #define VALUE_OPT_VERSION 'v' diff --git a/src/danetool.c b/src/danetool.c index ad6791e215..05e24e1c6f 100644 --- a/src/danetool.c +++ b/src/danetool.c @@ -187,12 +187,13 @@ static void dane_check(const char* host, const char* proto, unsigned int port, #ifdef HAVE_DANE dane_state_t s; dane_query_t q; -int ret; +int ret, retcode = 0; unsigned entries; unsigned int flags = DANE_F_IGNORE_LOCAL_RESOLVER, i; unsigned int usage, type, match; gnutls_datum_t data, file; size_t size; +unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED; if (ENABLED_OPT(LOCAL_DNS)) flags = 0; @@ -200,6 +201,12 @@ size_t size; if (HAVE_OPT(INSECURE)) flags |= DANE_F_INSECURE; + if (HAVE_OPT(CHECK_EE)) + vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE; + + if (HAVE_OPT(CHECK_CA)) + vflags |= DANE_VFLAG_ONLY_CHECK_CA_USAGE; + printf("Querying %s (%s:%d)...\n", host, proto, port); ret = dane_state_init(&s, flags); if (ret < 0) @@ -265,7 +272,7 @@ size_t size; } ret = dane_verify_crt( s, certs, clist_size, GNUTLS_CRT_X509, - host, proto, port, 0, 0, &status); + host, proto, port, 0, vflags, &status); if (ret < 0) error (EXIT_FAILURE, 0, "dane_verify_crt: %s", dane_strerror (ret)); @@ -275,6 +282,8 @@ size_t size; printf("\nVerification: %s\n", out.data); gnutls_free(out.data); + + if (status != 0) retcode = 1; for (i=0;i<clist_size;i++) { @@ -289,6 +298,8 @@ size_t size; dane_query_deinit(q); dane_state_deinit(s); + + exit(retcode); #else fprintf(stderr, "This functionality was disabled (GnuTLS was not compiled with support for DANE).\n"); return; diff --git a/tests/suite/Makefile.am b/tests/suite/Makefile.am index 1ba8d5bf35..cb151e9b46 100644 --- a/tests/suite/Makefile.am +++ b/tests/suite/Makefile.am @@ -86,6 +86,10 @@ nodist_check_SCRIPTS = eagain testsrn testcompat chain invalid-cert testrandom TESTS = eagain testsrn testcompat chain invalid-cert +if ENABLE_DANE +TESTS += testdane +endif + if !MACOSX noinst_LTLIBRARIES = libecore.la diff --git a/tests/suite/testdane b/tests/suite/testdane new file mode 100755 index 0000000000..243ff612d3 --- /dev/null +++ b/tests/suite/testdane @@ -0,0 +1,71 @@ +#!/bin/sh + +# Copyright (C) 2013 Nikos Mavrogiannopoulos +# +# This file is part of GnuTLS. +# +# GnuTLS is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# GnuTLS is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GnuTLS; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +srcdir="${srcdir:-.}" +CLI="${CLI:-../../src/gnutls-cli$EXEEXT}" +DANETOOL="${DANETOOL:-../../src/danetool$EXEEXT}" +unset RETCODE + +if test "${WINDIR}" != "";then + exit 77 +fi + +. $srcdir/../scripts/common.sh + +# Not ok +HOSTS="bad-hash.dane.verisignlabs.com dane-broken.rd.nic.fr bad-params.dane.verisignlabs.com" +HOSTS="$HOSTS bad-sig.dane.verisignlabs.com" +for i in $HOSTS;do +rm -f tmp +$CLI $i -p 443 --print-cert --insecure >tmp 2>&1 </dev/null +if [ $? != 0 ];then + echo "Error connecting to $i" + exit 1 +fi + +$DANETOOL --load-certificate tmp --check $i >/dev/null 2>&1 +if [ $? = 0 ];then + echo "Checking $i should have failed" + exit 1 +fi +done + +# Fine hosts + +HOSTS="torproject.org jhcloos.com good.dane.verisignlabs.com \ +www.kumari.net" +HOSTS="$HOSTS nohats.ca dane.nox.su" +for i in $HOSTS;do +rm -f tmp +$CLI $i -p 443 --print-cert --insecure >tmp 2>&1 </dev/null +if [ $? != 0 ];then + echo "Error connecting to $i" + exit 1 +fi + +$DANETOOL --load-certificate tmp --check $i >/dev/null 2>&1 +if [ $? != 0 ];then + echo "Error checking $i" + exit 1 +fi +done + + +exit 0 |