diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-02-17 14:20:10 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-02-17 14:27:34 +0100 |
commit | 1234b21ada2809b8a779046c24437598a1067f36 (patch) | |
tree | a14cd9ab6749ae7a214d465918b577eb2c66ac45 | |
parent | 0a7511b442413d8a85634f5706097ebc1792615a (diff) | |
download | gnutls-1234b21ada2809b8a779046c24437598a1067f36.tar.gz |
when importing a certificate ensure that the signature parameters match
-rw-r--r-- | lib/x509/x509.c | 79 |
1 files changed, 67 insertions, 12 deletions
diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 5dcde4bc0d..4416be0f66 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -164,6 +164,71 @@ void 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. @@ -186,7 +251,7 @@ gnutls_x509_crt_import(gnutls_x509_crt_t cert, gnutls_x509_crt_fmt_t format) { int result = 0; - int version, s2; + int version; if (cert == NULL) { gnutls_assert(); @@ -247,22 +312,12 @@ gnutls_x509_crt_import(gnutls_x509_crt_t cert, goto cleanup; } - result = _gnutls_x509_get_signature_algorithm(cert->cert, - "signatureAlgorithm.algorithm"); + result = compare_sig_algorithm(cert); if (result < 0) { gnutls_assert(); goto cleanup; } - s2 = _gnutls_x509_get_signature_algorithm(cert->cert, - "tbsCertificate.signature.algorithm"); - if (result != s2) { - _gnutls_debug_log("signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n", - gnutls_sign_get_name(result), gnutls_sign_get_name(s2)); - gnutls_assert(); - result = GNUTLS_E_CERTIFICATE_ERROR; - goto cleanup; - } result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der, "tbsCertificate.issuer.rdnSequence", |