diff options
Diffstat (limited to 'libdane/dane.c')
-rw-r--r-- | libdane/dane.c | 51 |
1 files changed, 51 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; |