** 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.
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
#
# 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
--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'
--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
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
--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
_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:
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
#include <gnutls/x509.h>
#include <gnutls/abstract.h>
#include <gnutls/crypto.h>
+#include "../lib/gnutls_int.h"
#define MAX_DATA_ENTRIES 4
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;
+}
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,
dane_cert_type_name;
dane_match_type_name;
dane_cert_usage_name;
+ dane_verification_status_print;
local:
*;
};
}
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);
}
}
return 0;
}
- printf ("- %s", out.data);
+ printf ("- %s\n", out.data);
gnutls_free(out.data);
*
* 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
*
/* 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"
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.";
};
$ 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_;
};
*
* 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
*
if (HAVE_OPT(LOAD_CERTIFICATE))
cinfo.cert = OPT_ARG(LOAD_CERTIFICATE);
-
+
if (HAVE_OPT(PORT))
port = OPT_VALUE_PORT;
if (HAVE_OPT(PROTO))
HAVE_OPT(CA), HAVE_OPT(LOCAL), &cinfo);
else if (HAVE_OPT(CHECK))
dane_check (OPT_ARG(CHECK), proto, port,
- &cinfo);
+ &cinfo);
else
USAGE(1);
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))
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);