diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-02-24 18:33:09 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-02-24 18:33:09 +0100 |
commit | 69c59573a5946eeb66e9e29b1db659ef41b58978 (patch) | |
tree | ce44248e2d713d5e7da1a2dbfb0a88f4d332849d /libdane | |
parent | d52eacc4513d8abe8d6a554fc52e4240b1802d48 (diff) | |
download | gnutls-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.c | 51 | ||||
-rw-r--r-- | libdane/errors.c | 4 | ||||
-rw-r--r-- | libdane/includes/gnutls/dane.h | 2 |
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 |