summaryrefslogtreecommitdiff
path: root/libdane
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2013-02-24 18:33:09 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2013-02-24 18:33:09 +0100
commit69c59573a5946eeb66e9e29b1db659ef41b58978 (patch)
treece44248e2d713d5e7da1a2dbfb0a88f4d332849d /libdane
parentd52eacc4513d8abe8d6a554fc52e4240b1802d48 (diff)
downloadgnutls-69c59573a5946eeb66e9e29b1db659ef41b58978.tar.gz
when verifying a DANE CA constraint make sure that the provided chain is actually a chain.
Diffstat (limited to 'libdane')
-rw-r--r--libdane/dane.c51
-rw-r--r--libdane/errors.c4
-rw-r--r--libdane/includes/gnutls/dane.h2
3 files changed, 57 insertions, 0 deletions
diff --git a/libdane/dane.c b/libdane/dane.c
index b6a950f6cb..9f2d8d7156 100644
--- a/libdane/dane.c
+++ b/libdane/dane.c
@@ -420,6 +420,8 @@ static int verify_ca(const gnutls_datum_t *raw_crt, unsigned raw_crt_size,
{
gnutls_datum_t pubkey = {NULL, 0};
int ret;
+unsigned int vstatus;
+gnutls_x509_crt_t crt = NULL, ca = NULL;
if (raw_crt_size < 2)
return gnutls_assert_val(DANE_E_INVALID_REQUEST);
@@ -442,11 +444,57 @@ int ret;
gnutls_assert();
*verify |= DANE_VERIFY_CA_CONSTRAINS_VIOLATED;
}
+ } else {
+ ret = gnutls_assert_val(DANE_E_UNKNOWN_DANE_DATA);
+ goto cleanup;
+ }
+
+ /* check if the certificate chain is actually a chain */
+ ret = gnutls_x509_crt_init(&crt);
+ if (ret < 0) {
+ ret = gnutls_assert_val(DANE_E_CERT_ERROR);
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_crt_init(&ca);
+ if (ret < 0) {
+ ret = gnutls_assert_val(DANE_E_CERT_ERROR);
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_crt_import(crt, &raw_crt[0], GNUTLS_X509_FMT_DER);
+ if (ret < 0) {
+ ret = gnutls_assert_val(DANE_E_CERT_ERROR);
+ goto cleanup;
}
+ ret = gnutls_x509_crt_import(ca, &raw_crt[1], GNUTLS_X509_FMT_DER);
+ if (ret < 0) {
+ ret = gnutls_assert_val(DANE_E_CERT_ERROR);
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_crt_check_issuer(crt, ca);
+ if (ret == 0) {
+ gnutls_assert();
+ *verify |= DANE_VERIFY_CA_CONSTRAINS_VIOLATED;
+ }
+
+ ret = gnutls_x509_crt_verify(crt, &ca, 1, 0, &vstatus);
+ if (ret < 0) {
+ ret = gnutls_assert_val(DANE_E_CERT_ERROR);
+ goto cleanup;
+ }
+ if (vstatus != 0)
+ *verify |= DANE_VERIFY_CA_CONSTRAINS_VIOLATED;
+
ret = 0;
cleanup:
free(pubkey.data);
+ if (crt != NULL)
+ gnutls_x509_crt_deinit(crt);
+ if (ca != NULL)
+ gnutls_x509_crt_deinit(ca);
return ret;
}
@@ -476,6 +524,9 @@ int ret;
gnutls_assert();
*verify |= DANE_VERIFY_CERT_DIFFERS;
}
+ } else {
+ ret = gnutls_assert_val(DANE_E_UNKNOWN_DANE_DATA);
+ goto cleanup;
}
ret = 0;
diff --git a/libdane/errors.c b/libdane/errors.c
index 773c018af2..2e345ad20f 100644
--- a/libdane/errors.c
+++ b/libdane/errors.c
@@ -47,6 +47,8 @@ static const error_entry error_algorithms[] = {
DANE_E_RESOLVING_ERROR),
ERROR_ENTRY (N_("No DANE data were found."),
DANE_E_NO_DANE_DATA),
+ ERROR_ENTRY (N_("Unknown DANE data were found."),
+ DANE_E_UNKNOWN_DANE_DATA),
ERROR_ENTRY (N_("No DNSSEC signature was found."),
DANE_E_NO_DNSSEC_SIG),
ERROR_ENTRY (N_("Received corrupt data."),
@@ -59,6 +61,8 @@ static const error_entry error_algorithms[] = {
DANE_E_REQUESTED_DATA_NOT_AVAILABLE),
ERROR_ENTRY (N_("There request is invalid."),
DANE_E_INVALID_REQUEST),
+ ERROR_ENTRY (N_("There was an error in the certificate."),
+ DANE_E_CERT_ERROR),
ERROR_ENTRY (N_("There was an error in the public key."),
DANE_E_PUBKEY_ERROR),
ERROR_ENTRY (N_("No certificate was found."),
diff --git a/libdane/includes/gnutls/dane.h b/libdane/includes/gnutls/dane.h
index 845e0766a7..94841b9989 100644
--- a/libdane/includes/gnutls/dane.h
+++ b/libdane/includes/gnutls/dane.h
@@ -170,4 +170,6 @@ const char * dane_strerror (int error);
#define DANE_E_PUBKEY_ERROR -10
#define DANE_E_NO_CERT -11
#define DANE_E_FILE_ERROR -12
+#define DANE_E_CERT_ERROR -13
+#define DANE_E_UNKNOWN_DANE_DATA -14