diff options
-rw-r--r-- | lib/x509/x509.c | 45 | ||||
-rw-r--r-- | lib/x509/x509_int.h | 2 | ||||
-rw-r--r-- | lib/x509/x509_write.c | 6 |
3 files changed, 37 insertions, 16 deletions
diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 6462ebb3d0..c42a948887 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -394,7 +394,7 @@ static int cache_alt_names(gnutls_x509_crt_t cert) return 0; } -static int check_cert_sanity(gnutls_x509_crt_t cert) +int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert) { int result = 0, version; gnutls_datum_t exts; @@ -407,32 +407,45 @@ static int check_cert_sanity(gnutls_x509_crt_t cert) } version = result; + if (version < 3) { - result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der, - "tbsCertificate.extensions", &exts); - if (result >= 0 && exts.size > 0) { - gnutls_assert(); - _gnutls_debug_log("error: extensions present in certificate with version %d\n", version); - result = GNUTLS_E_X509_CERTIFICATE_ERROR; - goto cleanup; + if (!cert->modified) { + result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der, + "tbsCertificate.extensions", &exts); + if (result >= 0 && exts.size > 0) { + gnutls_assert(); + _gnutls_debug_log("error: extensions present in certificate with version %d\n", version); + result = GNUTLS_E_X509_CERTIFICATE_ERROR; + goto cleanup; + } + } else { + if (cert->use_extensions) { + gnutls_assert(); + _gnutls_debug_log("error: extensions set in certificate with version %d\n", version); + result = GNUTLS_E_X509_CERTIFICATE_ERROR; + goto cleanup; + } } } if (version < 2) { - result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der, - "tbsCertificate.subjectUniqueID", &exts); - if (result >= 0 && exts.size > 0) { + char id[128]; + size_t id_size; + + id_size = sizeof(id); + result = gnutls_x509_crt_get_subject_unique_id(cert, id, &id_size); + if (result >= 0 || result == GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert(); _gnutls_debug_log("error: subjectUniqueID present in certificate with version %d\n", version); result = GNUTLS_E_X509_CERTIFICATE_ERROR; goto cleanup; } - result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der, - "tbsCertificate.issuerUniqueID", &exts); - if (result >= 0 && exts.size > 0) { + id_size = sizeof(id); + result = gnutls_x509_crt_get_issuer_unique_id(cert, id, &id_size); + if (result >= 0 || result == GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert(); - _gnutls_debug_log("error: issuerUniqueID present in certificate with version %d\n", version); + _gnutls_debug_log("error: subjectUniqueID present in certificate with version %d\n", version); result = GNUTLS_E_X509_CERTIFICATE_ERROR; goto cleanup; } @@ -559,7 +572,7 @@ gnutls_x509_crt_import(gnutls_x509_crt_t cert, goto cleanup; } - result = check_cert_sanity(cert); + result = _gnutls_check_cert_sanity(cert); if (result < 0) { gnutls_assert(); goto cleanup; diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index 85c4e17b42..5f5c180028 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -440,6 +440,8 @@ _gnutls_pkcs11_verify_crt_status(const char* url, gnutls_verify_output_function func); #endif +int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert); + int _gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert, const gnutls_x509_crl_t * crl_list, diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c index 3e466bd102..5a4c4de327 100644 --- a/lib/x509/x509_write.c +++ b/lib/x509/x509_write.c @@ -1746,6 +1746,12 @@ gnutls_x509_crt_privkey_sign(gnutls_x509_crt_t crt, */ disable_optional_stuff(crt); + result = _gnutls_check_cert_sanity(crt); + if (result < 0) { + gnutls_assert(); + return result; + } + result = _gnutls_x509_pkix_sign(crt->cert, "tbsCertificate", dig, issuer, issuer_key); if (result < 0) { |