external/boringssl: Sync to ba9da449a4bf5b90cd020807f2c4176e3ab6fe3e.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/d89d65ba12e28e543df4fd9dfbc687bb8be1dba7..ba9da449a4bf5b90cd020807f2c4176e3ab6fe3e

Test: BoringSSL CTS Presubmits.
Change-Id: Id99aa90153bb7fc37270e9c58d406e5d8c7c44d3
diff --git a/src/crypto/x509/vpm_int.h b/src/crypto/x509/vpm_int.h
index 9c55def..53b4a0d 100644
--- a/src/crypto/x509/vpm_int.h
+++ b/src/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/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
index ed4978a..0c5fc2d 100644
--- a/src/crypto/x509/x509_test.cc
+++ b/src/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/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index aff2ee9..2b754f0 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/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/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 0b03361..43353c6 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/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(&param->id->email, &param->id->emaillen,
-                               email, emaillen);
+    if (OPENSSL_memchr(email, '\0', emaillen) != NULL ||
+        !int_x509_param_set1(&param->id->email, &param->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 **)&param->id->ip, &param->id->iplen,
+                             (char *)ip, iplen)) {
+        param->id->poison = 1;
         return 0;
-    return int_x509_param_set1((char **)&param->id->ip, &param->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)