summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--doc/invoke-danetool.texi30
-rw-r--r--lib/libgnutls.map4
-rw-r--r--libdane/Makefile.am7
-rw-r--r--libdane/dane.c44
-rw-r--r--libdane/includes/gnutls/dane.h3
-rw-r--r--libdane/libdane.map1
-rw-r--r--src/cli.c18
-rw-r--r--src/common.c2
-rw-r--r--src/danetool-args.c4
-rw-r--r--src/danetool-args.def6
-rw-r--r--src/danetool-args.h2
-rw-r--r--src/danetool.c54
13 files changed, 150 insertions, 30 deletions
diff --git a/NEWS b/NEWS
index 74d5fcbe82..b50a73568b 100644
--- a/NEWS
+++ b/NEWS
@@ -19,8 +19,8 @@ for SRTP.
** danetool: Corrected bug that prevented loading PEM files.
-** danetool: Added --check option to allow querying sites for
-DANE data.
+** danetool: Added --check option to allow querying and verifying
+a site's DANE data.
** libgnutls-dane: Added pkg-config file for the library.
@@ -38,6 +38,7 @@ gnutls_srtp_profile_t: Added
dane_cert_type_name: Added
dane_match_type_name: Added
dane_cert_usage_name: Added
+dane_verification_status_print: Added
GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: Added
GNUTLS_CERT_REVOCATION_DATA_INVALID: Added
GNUTLS_CERT_UNEXPECTED_OWNER: Added
diff --git a/doc/invoke-danetool.texi b/doc/invoke-danetool.texi
index 636ab982ac..e840936351 100644
--- a/doc/invoke-danetool.texi
+++ b/doc/invoke-danetool.texi
@@ -7,7 +7,7 @@
#
# DO NOT EDIT THIS FILE (invoke-danetool.texi)
#
-# It has been AutoGen-ed October 29, 2012 at 07:37:13 PM by AutoGen 5.16
+# It has been AutoGen-ed November 1, 2012 at 07:51:08 PM by AutoGen 5.16
# From the definitions ../src/danetool-args.def
# and the template file agtexi-cmd.tpl
@end ignore
@@ -48,6 +48,9 @@ USAGE: danetool [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]...
--load-pubkey=str Loads a public key file
--load-certificate=str Loads a certificate file
--hash=str Hash algorithm to use for signing.
+ --check=str Check DANE TLSA entry.
+ --local-dns Use the local DNS server for DNSSEC resolving.
+ - disabled as --no-local-dns
--inder Use DER format for input certificates and private keys.
- disabled as --no-inder
--inraw This is an alias for 'inder'
@@ -58,7 +61,7 @@ USAGE: danetool [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]...
--proto=str The protocol set for DANE data (tcp, udp etc.)
--port=num Specify the port number for the DANE data.
--ca Whether the provided certificate or public key is a Certificate
-authority.
+Authority.
--x509 Use the hash of the X.509 certificate, rather than the public key.
--local The provided certificate or public key is a local entity.
-v, --version[=arg] Output version information and exit
@@ -104,6 +107,20 @@ This can be either a file or a PKCS #11 URL
This is the ``hash algorithm to use for signing.'' option.
This option takes an argument string.
Available hash functions are SHA1, RMD160, SHA256, SHA384, SHA512.
+@anchor{danetool check}
+@subheading check option
+@cindex danetool-check
+
+This is the ``check dane tlsa entry.'' option.
+This option takes an argument string.
+Obtains the DANE TLSA entry from the given hostname and prints information.
+@anchor{danetool local-dns}
+@subheading local-dns option
+@cindex danetool-local-dns
+
+This is the ``use the local dns server for dnssec resolving.'' option.
+This option will use the local DNS server for DNSSEC.
+This is disabled by default due to many servers not allowing DNSSEC.
@anchor{danetool inder}
@subheading inder option
@cindex danetool-inder
@@ -206,8 +223,13 @@ $ danetool --tlsa-rr --host www.example.com --load-certificate cert.pem \
--ca
@end example
-To read a server's DANE TLSA entry, using the dig tool, use:
+To read a server's DANE TLSA entry, use:
+@example
+$ danetool --check www.example.com --proto tcp --port 443
+@end example
+
+To verify a server's DANE TLSA entry, use:
@example
-$ dig +short TYPE52 _443._tcp.www.example.com
+$ danetool --check www.example.com --proto tcp --port 443 --load-certificate chain.pem
@end example
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index b1f5b91948..975a32e072 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -896,7 +896,9 @@ GNUTLS_PRIVATE {
_gnutls_buffer_append_data_prefix;
_gnutls_buffer_pop_data;
_gnutls_buffer_pop_prefix;
-
+ _gnutls_buffer_init;
+ _gnutls_buffer_append_str;
+ _gnutls_buffer_to_datum;
# Internal symbols needed by psktool:
# Internal symbols needed by gnutls-cli-debug:
diff --git a/libdane/Makefile.am b/libdane/Makefile.am
index bffa102fbe..d880cc8aaa 100644
--- a/libdane/Makefile.am
+++ b/libdane/Makefile.am
@@ -22,12 +22,13 @@ ACLOCAL_AMFLAGS = -I ../m4 -I ../gl/m4
AM_CFLAGS = $(WERROR_CFLAGS) $(WSTACK_CFLAGS) $(WARN_CFLAGS)
AM_CPPFLAGS = \
- -I$(srcdir)/../gl \
- -I$(builddir)/../gl \
+ -I$(srcdir)/../gl \
+ -I$(builddir)/../gl \
-I$(builddir)/../lib/includes \
-I$(srcdir)/../lib/includes \
-I$(srcdir)/includes \
- -I$(builddir)/includes
+ -I$(builddir)/includes \
+ -I$(srcdir)/../lib
SUBDIRS = includes
diff --git a/libdane/dane.c b/libdane/dane.c
index 5428a33173..b1b83a0249 100644
--- a/libdane/dane.c
+++ b/libdane/dane.c
@@ -32,6 +32,7 @@
#include <gnutls/x509.h>
#include <gnutls/abstract.h>
#include <gnutls/crypto.h>
+#include "../lib/gnutls_int.h"
#define MAX_DATA_ENTRIES 4
@@ -602,3 +603,46 @@ unsigned int type;
return dane_verify_crt(s, cert_list, cert_list_size, type, hostname, proto, port, sflags, vflags, verify);
}
+/**
+ * dane_verification_status_print:
+ * @status: The status flags to be printed
+ * @type: The certificate type
+ * @out: Newly allocated datum with (0) terminated string.
+ * @flags: should be zero
+ *
+ * This function will pretty print the status of a verification
+ * process -- eg. the one obtained by dane_verify_crt().
+ *
+ * The output @out needs to be deallocated using gnutls_free().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ **/
+int
+dane_verification_status_print (unsigned int status,
+ gnutls_datum_t * out, unsigned int flags)
+{
+ gnutls_buffer_st str;
+ int ret;
+
+ _gnutls_buffer_init (&str);
+
+ if (status == 0)
+ _gnutls_buffer_append_str (&str, _("DANE verification didn't reject the certificate. "));
+ else
+ _gnutls_buffer_append_str (&str, _("DANE verification failed. "));
+
+ if (status & DANE_VERIFY_CA_CONSTRAINS_VIOLATED)
+ _gnutls_buffer_append_str (&str, _("CA constrains were violated. "));
+
+ if (status & DANE_VERIFY_CERT_DIFFERS)
+ _gnutls_buffer_append_str (&str, _("The certificate differs. "));
+
+ if (status & DANE_VERIFY_NO_DANE_INFO)
+ _gnutls_buffer_append_str (&str, _("There was no DANE information. "));
+
+ ret = _gnutls_buffer_to_datum( &str, out);
+ if (out->size > 0) out->size--;
+
+ return ret;
+}
diff --git a/libdane/includes/gnutls/dane.h b/libdane/includes/gnutls/dane.h
index 9a08737a6a..75d2e36e6b 100644
--- a/libdane/includes/gnutls/dane.h
+++ b/libdane/includes/gnutls/dane.h
@@ -134,6 +134,9 @@ typedef enum dane_verify_status_t
DANE_VERIFY_NO_DANE_INFO = 1<<2,
} dane_verify_status_t;
+int
+dane_verification_status_print (unsigned int status,
+ gnutls_datum_t * out, unsigned int flags);
int dane_verify_crt (dane_state_t s,
const gnutls_datum_t *chain, unsigned chain_size,
diff --git a/libdane/libdane.map b/libdane/libdane.map
index 335869c1c8..b3894e1b37 100644
--- a/libdane/libdane.map
+++ b/libdane/libdane.map
@@ -16,6 +16,7 @@ DANE_0_0
dane_cert_type_name;
dane_match_type_name;
dane_cert_usage_name;
+ dane_verification_status_print;
local:
*;
};
diff --git a/src/cli.c b/src/cli.c
index 6064ad4e31..513dda7d81 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -498,20 +498,18 @@ cert_verify_callback (gnutls_session_t session)
}
else
{
- if (status != 0)
+ gnutls_datum_t out;
+
+ rc = dane_verification_status_print( status, &out, 0);
+ if (rc < 0)
{
- fprintf(stderr, "*** DANE certificate verification failed (flags %x).\n", status);
- if (status & DANE_VERIFY_CA_CONSTRAINS_VIOLATED)
- fprintf(stderr, "- CA constrains were violated.\n");
- if (status & DANE_VERIFY_CERT_DIFFERS)
- fprintf(stderr, "- The certificate differs.\n");
- if (status & DANE_VERIFY_NO_DANE_INFO)
- fprintf(stderr, "- There was no DANE information.\n");
+ fprintf(stderr, "*** DANE error: %s\n", dane_strerror(rc));
if (!insecure)
return -1;
}
- else
- printf("- DANE verification didn't reject the certificate.\n");
+
+ fprintf(stderr, "- %s\n", out.data);
+ gnutls_free(out.data);
}
}
diff --git a/src/common.c b/src/common.c
index 7841d43f49..9836125f7d 100644
--- a/src/common.c
+++ b/src/common.c
@@ -340,7 +340,7 @@ cert_verify (gnutls_session_t session, const char* hostname)
return 0;
}
- printf ("- %s", out.data);
+ printf ("- %s\n", out.data);
gnutls_free(out.data);
diff --git a/src/danetool-args.c b/src/danetool-args.c
index 4eff549628..d50d47643b 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 November 1, 2012 at 06:12:17 PM by AutoGen 5.16
+ * It has been AutoGen-ed November 1, 2012 at 07:45:47 PM by AutoGen 5.16
* From the definitions danetool-args.def
* and the template file options
*
@@ -130,7 +130,7 @@ static char const danetool_opt_strs[2257] =
/* 1598 */ "PORT\0"
/* 1603 */ "port\0"
/* 1608 */ "Whether the provided certificate or public key is a Certificate\n"
- "authority.\0"
+ "Authority.\0"
/* 1683 */ "CA\0"
/* 1686 */ "ca\0"
/* 1689 */ "Use the hash of the X.509 certificate, rather than the public key.\0"
diff --git a/src/danetool-args.def b/src/danetool-args.def
index 06390c9a44..dc29c4fa13 100644
--- a/src/danetool-args.def
+++ b/src/danetool-args.def
@@ -96,7 +96,7 @@ flag = {
flag = {
name = ca;
- descrip = "Whether the provided certificate or public key is a Certificate authority.";
+ descrip = "Whether the provided certificate or public key is a Certificate Authority.";
doc = "Marks the DANE RR as a CA certificate if specified.";
};
@@ -153,9 +153,9 @@ To read a server's DANE TLSA entry, use:
$ danetool --check www.example.com --proto tcp --port 443
@end example
-To read a server's DANE TLSA entry, using the dig tool, use:
+To verify a server's DANE TLSA entry, use:
@example
-$ dig +short TYPE52 _443._tcp.www.example.com
+$ danetool --check www.example.com --proto tcp --port 443 --load-certificate chain.pem
@end example
_EOT_;
};
diff --git a/src/danetool-args.h b/src/danetool-args.h
index 4980c4e48a..dfab6bb1d9 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 November 1, 2012 at 06:12:16 PM by AutoGen 5.16
+ * It has been AutoGen-ed November 1, 2012 at 07:45:46 PM by AutoGen 5.16
* From the definitions danetool-args.def
* and the template file options
*
diff --git a/src/danetool.c b/src/danetool.c
index 5770854dca..f7736ed4a9 100644
--- a/src/danetool.c
+++ b/src/danetool.c
@@ -155,7 +155,7 @@ cmd_parser (int argc, char **argv)
if (HAVE_OPT(LOAD_CERTIFICATE))
cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
-
+
if (HAVE_OPT(PORT))
port = OPT_VALUE_PORT;
if (HAVE_OPT(PROTO))
@@ -166,7 +166,7 @@ cmd_parser (int argc, char **argv)
HAVE_OPT(CA), HAVE_OPT(LOCAL), &cinfo);
else if (HAVE_OPT(CHECK))
dane_check (OPT_ARG(CHECK), proto, port,
- &cinfo);
+ &cinfo);
else
USAGE(1);
@@ -186,7 +186,7 @@ dane_query_t q;
int ret;
unsigned int flags = DANE_F_IGNORE_LOCAL_RESOLVER, i;
unsigned int usage, type, match;
-gnutls_datum_t data;
+gnutls_datum_t data, file;
size_t size;
if (ENABLED_OPT(LOCAL_DNS))
@@ -221,6 +221,54 @@ size_t size;
fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n", port, proto, host, usage, type, match, buffer);
}
+ /* Verify the DANE data */
+ if (cinfo->cert)
+ {
+ gnutls_x509_crt_t *clist;
+ unsigned int clist_size, status;
+
+ ret = gnutls_load_file(cinfo->cert, &file);
+ if (ret < 0)
+ error (EXIT_FAILURE, 0, "gnutls_load_file: %s", gnutls_strerror (ret));
+
+ ret = gnutls_x509_crt_list_import2( &clist, &clist_size, &file, cinfo->incert_format, 0);
+ if (ret < 0)
+ error (EXIT_FAILURE, 0, "gnutls_x509_crt_list_import2: %s", gnutls_strerror (ret));
+
+ 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)
+ error (EXIT_FAILURE, 0, "gnutls_x509_crt_export2: %s", gnutls_strerror (ret));
+ }
+
+ ret = dane_verify_crt( s, certs, clist_size, GNUTLS_CRT_X509,
+ host, proto, port, 0, 0, &status);
+ if (ret < 0)
+ error (EXIT_FAILURE, 0, "dane_verify_crt: %s", dane_strerror (ret));
+
+ ret = dane_verification_status_print(status, &out, 0);
+ if (ret < 0)
+ error (EXIT_FAILURE, 0, "dane_verification_status_print: %s", dane_strerror (ret));
+
+ printf("\n%s\n", out.data);
+ gnutls_free(out.data);
+
+ for (i=0;i<clist_size;i++)
+ {
+ gnutls_free(certs[i].data);
+ gnutls_x509_crt_deinit(clist[i]);
+ }
+ gnutls_free(clist);
+ }
+ }
+
dane_query_deinit(q);
dane_state_deinit(s);