summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2015-02-17 14:20:10 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2015-02-17 14:27:34 +0100
commit1234b21ada2809b8a779046c24437598a1067f36 (patch)
treea14cd9ab6749ae7a214d465918b577eb2c66ac45
parent0a7511b442413d8a85634f5706097ebc1792615a (diff)
downloadgnutls-1234b21ada2809b8a779046c24437598a1067f36.tar.gz
when importing a certificate ensure that the signature parameters match
-rw-r--r--lib/x509/x509.c79
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",