Fix error-handling in X509V3_EXT_add_nconf_sk and X509v3_add_ext.
See also upstream's abcf241114c4dc33af95288ae7f7d10916c67db0.
Fixed: oss-fuzz:55555, oss-fuzz:55556, oss-fuzz:55560
Change-Id: I3b015822806ced39a498017bd2329323ed8dfbf0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56685
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index fea26e7..aebc76a 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -6205,3 +6205,14 @@
}
}
}
+
+TEST(X509, AddUnserializableExtension) {
+ bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
+ ASSERT_TRUE(key);
+ bssl::UniquePtr<X509> x509 =
+ MakeTestCert("Issuer", "Subject", key.get(), /*is_ca=*/true);
+ ASSERT_TRUE(x509);
+ bssl::UniquePtr<X509_EXTENSION> ext(X509_EXTENSION_new());
+ ASSERT_TRUE(X509_EXTENSION_set_object(ext.get(), OBJ_nid2obj(NID_undef)));
+ EXPECT_FALSE(X509_add_ext(x509.get(), ext.get(), /*loc=*/-1));
+}
diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c
index 9153dce..dd84352 100644
--- a/crypto/x509/x509_v3.c
+++ b/crypto/x509/x509_v3.c
@@ -148,6 +148,7 @@
X509_EXTENSION *new_ex = NULL;
int n;
STACK_OF(X509_EXTENSION) *sk = NULL;
+ int free_sk = 0;
if (x == NULL) {
OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
@@ -158,6 +159,7 @@
if ((sk = sk_X509_EXTENSION_new_null()) == NULL) {
goto err;
}
+ free_sk = 1;
} else {
sk = *x;
}
@@ -183,7 +185,9 @@
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
err2:
X509_EXTENSION_free(new_ex);
- sk_X509_EXTENSION_free(sk);
+ if (free_sk) {
+ sk_X509_EXTENSION_free(sk);
+ }
return NULL;
}
diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509v3/v3_conf.c
index 480bb3b..a4f172d 100644
--- a/crypto/x509v3/v3_conf.c
+++ b/crypto/x509v3/v3_conf.c
@@ -357,13 +357,12 @@
for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i);
X509_EXTENSION *ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value);
- if (ext == NULL) {
+ int ok = ext != NULL && //
+ (sk == NULL || X509v3_add_ext(sk, ext, -1) != NULL);
+ X509_EXTENSION_free(ext);
+ if (!ok) {
return 0;
}
- if (sk) {
- X509v3_add_ext(sk, ext, -1);
- }
- X509_EXTENSION_free(ext);
}
return 1;
}