Tighten and test name-checking functions.
This change follows up from e759a9cd with more extensive changes and
tests:
If a name checking function (like |X509_VERIFY_PARAM_set1_host|) fails,
it now poisons the |X509_VERIFY_PARAM| so that all verifications will
fail. This is because we have observed that some callers are not
checking the return value of these functions.
Using a length of zero for a hostname to mean |strlen| is now an error.
It also an error for email addresses and IP addresses now, and doesn't
end up trying to call |strlen| on a (binary) IP address.
Setting an email address with embedded NULs now fails. So does trying to
configure an empty hostname or email with (NULL, 0).
|X509_check_*| functions in BoringSSL don't accept zero lengths (unlike
OpenSSL). It's now tested that such calls always fail.
Change-Id: I4484176f2aae74e502a09081c7e912c85e8d090b
Update-Note: several behaviour changes. See change description.
Reviewed-on: https://boringssl-review.googlesource.com/26764
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/vpm_int.h b/crypto/x509/vpm_int.h
index 9c55def..53b4a0d 100644
--- a/crypto/x509/vpm_int.h
+++ b/crypto/x509/vpm_int.h
@@ -67,4 +67,5 @@
size_t emaillen;
unsigned char *ip; /* If not NULL IP address to match */
size_t iplen; /* Length of IP address */
+ unsigned char poison; /* Fail all verifications */
};
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index ed4978a..0c5fc2d 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -12,6 +12,7 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <functional>
#include <string>
#include <vector>
@@ -422,6 +423,78 @@
"recgVPpVS7B+d9g4EwtZXIh4lodTBDHBBw==\n"
"-----END CERTIFICATE-----\n";
+// kSANTypesLeaf is a leaf certificate (signed by |kSANTypesRoot|) which
+// contains SANS for example.com, test@example.com, 127.0.0.1, and
+// https://example.com/. (The latter is useless for now since crypto/x509
+// doesn't deal with URI SANs directly.)
+static const char kSANTypesLeaf[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIClzCCAgCgAwIBAgIJAOjwnT/iW+qmMA0GCSqGSIb3DQEBCwUAMCsxFzAVBgNV\n"
+ "BAoTDkJvcmluZ1NTTCBUZXN0MRAwDgYDVQQDEwdSb290IENBMB4XDTE1MDEwMTAw\n"
+ "MDAwMFoXDTI1MDEwMTAwMDAwMFowLzEXMBUGA1UEChMOQm9yaW5nU1NMIFRlc3Qx\n"
+ "FDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
+ "gQDbRn2TLhInBki8Bighq37EtqJd/h5SRYh6NkelCA2SQlvCgcC+l3mYQPtPbRT9\n"
+ "KxOLwqUuZ9jUCZ7WIji3Sgt0cyvCNPHRk+WW2XR781ifbGE8wLBB1NkrKyQjd1sc\n"
+ "O711Xc4gVM+hY4cdHiTE8x0aUIuqthRD7ZendWL0FMhS1wIDAQABo4G+MIG7MA4G\n"
+ "A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYD\n"
+ "VR0TAQH/BAIwADAZBgNVHQ4EEgQQn5EWH0NDPkmm3m22gNefYDAbBgNVHSMEFDAS\n"
+ "gBBAN9cB+0AvuBx+VAQnjFkBMEQGA1UdEQQ9MDuCC2V4YW1wbGUuY29tgRB0ZXN0\n"
+ "QGV4YW1wbGUuY29thwR/AAABhhRodHRwczovL2V4YW1wbGUuY29tLzANBgkqhkiG\n"
+ "9w0BAQsFAAOBgQBtwJvY6+Tk6D6DOtDVaNoJ5y8E25CCuE/Ga4OuIcYJas+yLckf\n"
+ "dZwUV3GUG2oBXl2MrpUFxXd4hKBO1CmlBY+hZEeIx0Yp6QWK9P/vnZeydOTP26mk\n"
+ "jusJ2PqSmtKNU1Zcaba4d29oFejmOAfeguhR8AHpsc/zHEaS5Q9cJsuJcw==\n"
+ "-----END CERTIFICATE-----\n";
+
+// -----BEGIN RSA PRIVATE KEY-----
+// MIICWwIBAAKBgQDbRn2TLhInBki8Bighq37EtqJd/h5SRYh6NkelCA2SQlvCgcC+
+// l3mYQPtPbRT9KxOLwqUuZ9jUCZ7WIji3Sgt0cyvCNPHRk+WW2XR781ifbGE8wLBB
+// 1NkrKyQjd1scO711Xc4gVM+hY4cdHiTE8x0aUIuqthRD7ZendWL0FMhS1wIDAQAB
+// AoGACwf7z0i1DxOI2zSwFimLghfyCSp8mgT3fbZ3Wj0SebYu6ZUffjceneM/AVrq
+// gGYHYLOVHcWJqfkl7X3hPo9SDhzLx0mM545/q21ZWCwjhswH7WiCEqV2/zeDO9WU
+// NIO1VU0VoLm0AQ7ZvwnyB+fpgF9kkkDtbBJW7XWrfNVtlnECQQD97YENpEJ3X1kj
+// 3rrkrHWDkKAyoWWY1i8Fm7LnganC9Bv6AVwgn5ZlE/479aWHF8vbOFEA3pFPiNZJ
+// t9FTCfpJAkEA3RCXjGI0Y6GALFLwEs+nL/XZAfJaIpJEZVLCVosYQOSaMS4SchfC
+// GGYVquT7ZgKk9uvz89Fg87OtBMWS9lrkHwJADGkGLKeBhBoJ3kHtem2fVK3F1pOi
+// xoR5SdnhNYVVyaxqjZ5xZTrHe+stOrr3uxGDqhQniVZXXb6/Ul0Egv1y2QJAVg/h
+// kAujba4wIhFf2VLyOZ+yjil1ocPj0LZ5Zgvcs1bMGJ1hHP3W2HzVrqRaowoggui1
+// HpTC891dXGA2qKYV7QJAFDmT2A7OVvh3y4AEgzVwHrDmCMwMHKjCIntS7fjxrJnF
+// YvJUG1zoHwUVrxxbR3DbpTODlktLcl/0b97D0IkH3w==
+// -----END RSA PRIVATE KEY-----
+
+static const char kSANTypesRoot[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICTTCCAbagAwIBAgIIAj5CwoHlWuYwDQYJKoZIhvcNAQELBQAwKzEXMBUGA1UE\n"
+ "ChMOQm9yaW5nU1NMIFRlc3QxEDAOBgNVBAMTB1Jvb3QgQ0EwHhcNMTUwMTAxMDAw\n"
+ "MDAwWhcNMjUwMTAxMDAwMDAwWjArMRcwFQYDVQQKEw5Cb3JpbmdTU0wgVGVzdDEQ\n"
+ "MA4GA1UEAxMHUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6Q5/\n"
+ "EQzmWuaGg3D2UQcuAngR9bIkkjjuJmICx5TxPqF3asCP1SJotl3iTNrghRE1wpJy\n"
+ "SY2BtIiXa7f8skRb2U0GcPkMxo/ps9+jaoRsQ1m+nbLQdpvD1/qZWcO45fNTA71J\n"
+ "1rPMokP+rcILuQG4VimUAySnDSghKamulFtK+Z8CAwEAAaN6MHgwDgYDVR0PAQH/\n"
+ "BAQDAgIEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8E\n"
+ "BTADAQH/MBkGA1UdDgQSBBBAN9cB+0AvuBx+VAQnjFkBMBsGA1UdIwQUMBKAEEA3\n"
+ "1wH7QC+4HH5UBCeMWQEwDQYJKoZIhvcNAQELBQADgYEAc4N6hTE62/3gwg+kyc2f\n"
+ "c/Jj1mHrOt+0NRaBnmvbmNpsEjHS96Ef4Wt/ZlPXPkkv1C1VosJnOIMF3Q522wRH\n"
+ "bqaxARldS12VAa3gcWisDWD+SqSyDxjyojz0XDiJkTrFuCTCUiZO+1GLB7SO10Ms\n"
+ "d5YVX0c90VMnUhF/dlrqS9U=\n"
+ "-----END CERTIFICATE-----\n";
+
+// -----BEGIN RSA PRIVATE KEY-----
+// MIICXAIBAAKBgQDpDn8RDOZa5oaDcPZRBy4CeBH1siSSOO4mYgLHlPE+oXdqwI/V
+// Imi2XeJM2uCFETXCknJJjYG0iJdrt/yyRFvZTQZw+QzGj+mz36NqhGxDWb6dstB2
+// m8PX+plZw7jl81MDvUnWs8yiQ/6twgu5AbhWKZQDJKcNKCEpqa6UW0r5nwIDAQAB
+// AoGALEF5daZqc+aEsp8X1yky3nsoheyPL0kqSBWii33IFemZgKcSaRnAoqjPWWLS
+// 8dHj0I/4rej2MW8iuezVSpDak9tK5boHORC3w4p/wifkizQkLt1DANxTVbzcKvrt
+// aZ7LjVaKkhjRJbLddniowFHkkWVbUccjvzcUd7Y2VuLbAhECQQDq4FE88aHio8zg
+// bxSd0PwjEFwLYQTR19u812SoR8PmR6ofIL+pDwOV+fVs+OGcAAOgkhIukOrksQ4A
+// 1cKtnyhXAkEA/gRI+u3tZ7UE1twIkBfZ6IvCdRodkPqHAYIxMRLzL+MhyZt4MEGc
+// Ngb/F6U9/WOBFnoR/PI7IwE3ejutzKcL+QJBAKh+6eilk7QKPETZi1m3/dmNt+p1
+// 3EZJ65pqjwxmB3Rg/vs7vCMk4TarTdSyKu+F1xRPFfoP/mK3Xctdjj6NyhsCQAYF
+// 7/0TOzfkUPMPUJyqFB6xgbDpJ55ScnUUsznoqx+NkTWInDb4t02IqO/UmT2y6FKy
+// Hk8TJ1fTJY+ebqaVp3ECQApx9gQ+n0zIhx97FMUuiRse73xkcW4+pZ8nF+8DmeQL
+// /JKuuFGmzkG+rUbXFmo/Zg2ozVplw71NnQJ4znPsf7A=
+// -----END RSA PRIVATE KEY-----
+
+
// CertFromPEM parses the given, NUL-terminated pem block and returns an
// |X509*|.
static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
@@ -484,12 +557,10 @@
}
static int Verify(X509 *leaf, const std::vector<X509 *> &roots,
- const std::vector<X509 *> &intermediates,
- const std::vector<X509_CRL *> &crls,
- unsigned long flags,
- bool use_additional_untrusted,
- const char *hostname,
- size_t hostname_len) {
+ const std::vector<X509 *> &intermediates,
+ const std::vector<X509_CRL *> &crls, unsigned long flags,
+ bool use_additional_untrusted,
+ std::function<void(X509_VERIFY_PARAM *)> configure_callback) {
bssl::UniquePtr<STACK_OF(X509)> roots_stack(CertsToStack(roots));
bssl::UniquePtr<STACK_OF(X509)> intermediates_stack(
CertsToStack(intermediates));
@@ -528,7 +599,9 @@
}
X509_VERIFY_PARAM_set_time(param, 1474934400 /* Sep 27th, 2016 */);
X509_VERIFY_PARAM_set_depth(param, 16);
- X509_VERIFY_PARAM_set1_host(param, hostname, hostname_len);
+ if (configure_callback) {
+ configure_callback(param);
+ }
if (flags) {
X509_VERIFY_PARAM_set_flags(param, flags);
}
@@ -547,9 +620,9 @@
const std::vector<X509_CRL *> &crls,
unsigned long flags = 0) {
const int r1 =
- Verify(leaf, roots, intermediates, crls, flags, false, nullptr, 0);
+ Verify(leaf, roots, intermediates, crls, flags, false, nullptr);
const int r2 =
- Verify(leaf, roots, intermediates, crls, flags, true, nullptr, 0);
+ Verify(leaf, roots, intermediates, crls, flags, true, nullptr);
if (r1 != r2) {
fprintf(stderr,
@@ -617,19 +690,152 @@
Verify(forgery.get(),
{intermediate_self_signed.get(), root_cross_signed.get()},
{leaf_no_key_usage.get(), intermediate.get()}, empty_crls));
+}
- static const char kHostname[] = "example.com";
- static const char kWrongHostname[] = "example2.com";
- ASSERT_EQ(X509_V_OK,
- Verify(leaf.get(), {root.get()}, {intermediate.get()}, empty_crls,
- 0, false, kHostname, strlen(kHostname)));
- // The wrong hostname should trigger a hostname error.
- ASSERT_EQ(X509_V_ERR_HOSTNAME_MISMATCH,
- Verify(leaf.get(), {root.get()}, {intermediate.get()}, empty_crls,
- 0, false, kWrongHostname, strlen(kWrongHostname)));
- // Passing zero, for this API, is supported for compatibility with OpenSSL.
- ASSERT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()},
- empty_crls, 0, false, kHostname, 0));
+static const char kHostname[] = "example.com";
+static const char kWrongHostname[] = "example2.com";
+static const char kEmail[] = "test@example.com";
+static const char kWrongEmail[] = "test2@example.com";
+static const uint8_t kIP[4] = {127, 0, 0, 1};
+static const uint8_t kWrongIP[4] = {127, 0, 0, 2};
+static const char kIPString[] = "127.0.0.1";
+static const char kWrongIPString[] = "127.0.0.2";
+
+TEST(X509Test, ZeroLengthsWithX509PARAM) {
+ bssl::UniquePtr<X509> leaf(CertFromPEM(kSANTypesLeaf));
+ bssl::UniquePtr<X509> root(CertFromPEM(kSANTypesRoot));
+ ASSERT_TRUE(leaf);
+ ASSERT_TRUE(root);
+
+ std::vector<X509_CRL *> empty_crls;
+
+ struct Test {
+ const char *correct_value;
+ size_t correct_value_len;
+ const char *incorrect_value;
+ size_t incorrect_value_len;
+ int (*func)(X509_VERIFY_PARAM *, const char *, size_t);
+ int mismatch_error;
+ };
+ const std::vector<Test> kTests = {
+ {kHostname, strlen(kHostname), kWrongHostname, strlen(kWrongHostname),
+ X509_VERIFY_PARAM_set1_host, X509_V_ERR_HOSTNAME_MISMATCH},
+ {kEmail, strlen(kEmail), kWrongEmail, strlen(kWrongEmail),
+ X509_VERIFY_PARAM_set1_email, X509_V_ERR_EMAIL_MISMATCH},
+ };
+
+ for (size_t i = 0; i < kTests.size(); i++) {
+ SCOPED_TRACE(i);
+ const Test &test = kTests[i];
+
+ // The correct value should work.
+ ASSERT_EQ(X509_V_OK,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [&test](X509_VERIFY_PARAM *param) {
+ ASSERT_TRUE(test.func(param, test.correct_value,
+ test.correct_value_len));
+ }));
+
+ // The wrong value should trigger a verification error.
+ ASSERT_EQ(test.mismatch_error,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [&test](X509_VERIFY_PARAM *param) {
+ ASSERT_TRUE(test.func(param, test.incorrect_value,
+ test.incorrect_value_len));
+ }));
+
+ // Passing zero as the length, unlike OpenSSL, should trigger an error and
+ // should cause verification to fail.
+ ASSERT_EQ(X509_V_ERR_INVALID_CALL,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [&test](X509_VERIFY_PARAM *param) {
+ ASSERT_FALSE(test.func(param, test.correct_value, 0));
+ }));
+
+ // Passing an empty value should be an error when setting and should cause
+ // verification to fail.
+ ASSERT_EQ(X509_V_ERR_INVALID_CALL,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [&test](X509_VERIFY_PARAM *param) {
+ ASSERT_FALSE(test.func(param, nullptr, 0));
+ }));
+
+ // Passing a value with embedded NULs should also be an error and should
+ // also cause verification to fail.
+ ASSERT_EQ(X509_V_ERR_INVALID_CALL,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [&test](X509_VERIFY_PARAM *param) {
+ ASSERT_FALSE(test.func(param, "a", 2));
+ }));
+ }
+
+ // IP addresses work slightly differently:
+
+ // The correct value should still work.
+ ASSERT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {}, empty_crls, 0,
+ false, [](X509_VERIFY_PARAM *param) {
+ ASSERT_TRUE(X509_VERIFY_PARAM_set1_ip(
+ param, kIP, sizeof(kIP)));
+ }));
+
+ // Incorrect values should still fail.
+ ASSERT_EQ(X509_V_ERR_IP_ADDRESS_MISMATCH,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [](X509_VERIFY_PARAM *param) {
+ ASSERT_TRUE(X509_VERIFY_PARAM_set1_ip(param, kWrongIP,
+ sizeof(kWrongIP)));
+ }));
+
+ // Zero length values should trigger an error when setting and cause
+ // verification to always fail.
+ ASSERT_EQ(X509_V_ERR_INVALID_CALL,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [](X509_VERIFY_PARAM *param) {
+ ASSERT_FALSE(X509_VERIFY_PARAM_set1_ip(param, kIP, 0));
+ }));
+
+ // ... and so should NULL values.
+ ASSERT_EQ(X509_V_ERR_INVALID_CALL,
+ Verify(leaf.get(), {root.get()}, {}, empty_crls, 0, false,
+ [](X509_VERIFY_PARAM *param) {
+ ASSERT_FALSE(X509_VERIFY_PARAM_set1_ip(param, nullptr, 0));
+ }));
+
+ // Zero bytes in an IP address are, of course, fine. This is tested above
+ // because |kIP| contains zeros.
+}
+
+TEST(X509Test, ZeroLengthsWithCheckFunctions) {
+ bssl::UniquePtr<X509> leaf(CertFromPEM(kSANTypesLeaf));
+
+ EXPECT_EQ(
+ 1, X509_check_host(leaf.get(), kHostname, strlen(kHostname), 0, nullptr));
+ EXPECT_NE(1, X509_check_host(leaf.get(), kWrongHostname,
+ strlen(kWrongHostname), 0, nullptr));
+
+ EXPECT_EQ(1, X509_check_email(leaf.get(), kEmail, strlen(kEmail), 0));
+ EXPECT_NE(1,
+ X509_check_email(leaf.get(), kWrongEmail, strlen(kWrongEmail), 0));
+
+ EXPECT_EQ(1, X509_check_ip(leaf.get(), kIP, sizeof(kIP), 0));
+ EXPECT_NE(1, X509_check_ip(leaf.get(), kWrongIP, sizeof(kWrongIP), 0));
+
+ EXPECT_EQ(1, X509_check_ip_asc(leaf.get(), kIPString, 0));
+ EXPECT_NE(1, X509_check_ip_asc(leaf.get(), kWrongIPString, 0));
+
+ // OpenSSL supports passing zero as the length for host and email. We do not
+ // and it should always fail.
+ EXPECT_NE(1, X509_check_host(leaf.get(), kHostname, 0, 0, nullptr));
+ EXPECT_NE(1, X509_check_host(leaf.get(), kWrongHostname, 0, 0, nullptr));
+
+ EXPECT_NE(1, X509_check_email(leaf.get(), kEmail, 0, 0));
+ EXPECT_NE(1, X509_check_email(leaf.get(), kWrongEmail, 0, 0));
+
+ EXPECT_NE(1, X509_check_ip(leaf.get(), kIP, 0, 0));
+ EXPECT_NE(1, X509_check_ip(leaf.get(), kWrongIP, 0, 0));
+
+ // Unlike all the other functions, |X509_check_ip_asc| doesn't take a length,
+ // so it cannot be zero.
}
TEST(X509Test, TestCRL) {
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index aff2ee9..2b754f0 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -784,6 +784,10 @@
X509_VERIFY_PARAM *vpm = ctx->param;
X509_VERIFY_PARAM_ID *id = vpm->id;
X509 *x = ctx->cert;
+ if (id->poison) {
+ if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL))
+ return 0;
+ }
if (id->hosts && check_hosts(x, id) <= 0) {
if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
return 0;
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 0b03361..43353c6 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -89,12 +89,9 @@
{
char *copy;
- // This is an OpenSSL quirk that BoringSSL typically doesn't support.
- // However, we didn't make this a fatal error at the time, which was a
- // mistake. Because of that, given the risk that someone could assume the
- // OpenSSL semantics from BoringSSL, it's supported in this case.
- if (name != NULL && namelen == 0) {
- namelen = strlen(name);
+ if (name == NULL || namelen == 0) {
+ // Unlike OpenSSL, we reject trying to set or add an empty name.
+ return 0;
}
/*
@@ -108,8 +105,6 @@
string_stack_free(id->hosts);
id->hosts = NULL;
}
- if (name == NULL || namelen == 0)
- return 1;
copy = BUF_strndup(name, namelen);
if (copy == NULL)
@@ -170,7 +165,7 @@
paramid->ip = NULL;
paramid->iplen = 0;
}
-
+ paramid->poison = 0;
}
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
@@ -324,6 +319,8 @@
return 0;
}
+ dest->id->poison = src->id->poison;
+
return 1;
}
@@ -342,18 +339,17 @@
const char *src, size_t srclen)
{
void *tmp;
- if (src) {
- if (srclen == 0) {
- tmp = BUF_strdup(src);
- srclen = strlen(src);
- } else
- tmp = BUF_memdup(src, srclen);
- if (!tmp)
- return 0;
- } else {
- tmp = NULL;
- srclen = 0;
+ if (src == NULL || srclen == 0) {
+ // Unlike OpenSSL, we do not allow an empty string to disable previously
+ // configured checks.
+ return 0;
}
+
+ tmp = BUF_memdup(src, srclen);
+ if (!tmp) {
+ return 0;
+ }
+
if (*pdest)
OPENSSL_free(*pdest);
*pdest = tmp;
@@ -462,13 +458,21 @@
int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
const char *name, size_t namelen)
{
- return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen);
+ if (!int_x509_param_set_hosts(param->id, SET_HOST, name, namelen)) {
+ param->id->poison = 1;
+ return 0;
+ }
+ return 1;
}
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
const char *name, size_t namelen)
{
- return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen);
+ if (!int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen)) {
+ param->id->poison = 1;
+ return 0;
+ }
+ return 1;
}
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
@@ -485,17 +489,27 @@
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
const char *email, size_t emaillen)
{
- return int_x509_param_set1(¶m->id->email, ¶m->id->emaillen,
- email, emaillen);
+ if (OPENSSL_memchr(email, '\0', emaillen) != NULL ||
+ !int_x509_param_set1(¶m->id->email, ¶m->id->emaillen,
+ email, emaillen)) {
+ param->id->poison = 1;
+ return 0;
+ }
+
+ return 1;
}
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
const unsigned char *ip, size_t iplen)
{
- if (iplen != 0 && iplen != 4 && iplen != 16)
+ if ((iplen != 4 && iplen != 16) ||
+ !int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen,
+ (char *)ip, iplen)) {
+ param->id->poison = 1;
return 0;
- return int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen,
- (char *)ip, iplen);
+ }
+
+ return 1;
}
int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
@@ -520,7 +534,7 @@
}
static const X509_VERIFY_PARAM_ID _empty_id =
- { NULL, 0U, NULL, NULL, 0, NULL, 0 };
+ { NULL, 0U, NULL, NULL, 0, NULL, 0, 0 };
#define vpm_empty_id ((X509_VERIFY_PARAM_ID *)&_empty_id)