diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-02-17 14:36:05 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-02-17 14:36:05 +0100 |
commit | 81e534c320d2a160798f4894fce7910ab3ad8081 (patch) | |
tree | 995be721c1a3dec5cc68e8867cd4796cadc8f327 | |
parent | 957cfd54859c2520a0a08991e12531d067e8625f (diff) | |
download | gnutls_3_1_x.tar.gz |
when importing a certificate ensure that the signature parameters matchgnutls_3_1_x
-rw-r--r-- | lib/x509/x509.c | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 6c0175c48e..5cdefd6563 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -142,6 +142,83 @@ gnutls_x509_crt_deinit (gnutls_x509_crt_t cert) gnutls_free (cert); } +static int compare_sig_algorithm(gnutls_x509_crt_t cert) +{ + int ret, s2; + gnutls_datum_t sp1 = {NULL, 0}; + gnutls_datum_t sp2 = {NULL, 0}; + unsigned empty1 = 0, empty2 = 0; + + ret = _gnutls_x509_get_signature_algorithm(cert->cert, + "signatureAlgorithm.algorithm"); + if (ret < 0) + { + gnutls_assert(); + return ret; + } + + s2 = _gnutls_x509_get_signature_algorithm(cert->cert, + "tbsCertificate.signature.algorithm"); + if (ret != s2) + { + _gnutls_debug_log("signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n", + gnutls_sign_get_name(ret), gnutls_sign_get_name(s2)); + gnutls_assert(); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + /* compare the parameters */ + ret = _gnutls_x509_read_value(cert->cert, "signatureAlgorithm.parameters", &sp1); + if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) + { + empty1 = 1; + } + else if (ret < 0) + { + gnutls_assert(); + return ret; + } + + ret = _gnutls_x509_read_value(cert->cert, "signatureAlgorithm.parameters", &sp2); + if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) + { + empty2 = 1; + } + else if (ret < 0) + { + gnutls_assert(); + return ret; + } + + /* handle equally empty parameters with missing parameters */ + if (sp1.size == 2 && memcmp(sp1.data, "\x05\x00", 2) == 0) + { + empty1 = 1; + _gnutls_free_datum(&sp1); + } + + if (sp2.size == 2 && memcmp(sp2.data, "\x05\x00", 2) == 0) + { + empty2 = 1; + _gnutls_free_datum(&sp2); + } + + if (empty1 != empty2 || + sp1.size != sp2.size || memcmp(sp1.data, sp2.data, sp1.size) != 0) + { + gnutls_assert(); + ret = GNUTLS_E_CERTIFICATE_ERROR; + goto cleanup; + } + + ret = 0; + + cleanup: + _gnutls_free_datum(&sp1); + _gnutls_free_datum(&sp2); + return ret; +} + /** * gnutls_x509_crt_import: * @cert: The structure to store the parsed certificate. @@ -226,7 +303,14 @@ gnutls_x509_crt_import (gnutls_x509_crt_t cert, gnutls_assert (); goto cleanup; } - + + result = compare_sig_algorithm(cert); + if (result < 0) + { + gnutls_assert(); + goto cleanup; + } + result = _gnutls_x509_get_raw_dn2 (cert->cert, &_data, "tbsCertificate.issuer.rdnSequence", &cert->raw_issuer_dn); |