summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-02-17 10:06:58 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-02-17 10:41:33 +0100
commit93467cf4a2852eea0941ce79df8d667f7349b753 (patch)
tree969b957159088d69aa4ab23578c03306dc62f50c
parentc7e029cbffcfe061e6dd75fd76d9d4970cd6a521 (diff)
downloadgnutls-93467cf4a2852eea0941ce79df8d667f7349b753.tar.gz
gnutls_x509_crt_sign2: refuse to sign invalid X.509 certificates
That is, do not sign X.509 certificates which have fields that shouldn't be present on their corresponding version. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/x509/x509.c45
-rw-r--r--lib/x509/x509_int.h2
-rw-r--r--lib/x509/x509_write.c6
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) {