Sync pki to chromium ce4bc9571462aa298d79b591df9d997323cf5157

Bug: chromium:1322914
Change-Id: Ic5a1349013bcfb279e5fee9f9838c63558d663b7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63025
Auto-Submit: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt
index 3905f55..adf7aa5 100644
--- a/fuzz/CMakeLists.txt
+++ b/fuzz/CMakeLists.txt
@@ -36,6 +36,7 @@
 fuzzer(ocsp_parse_ocsp_single_response_fuzzer pki)
 fuzzer(parse_authority_key_identifier_fuzzer pki)
 fuzzer(parse_certificate_fuzzer pki)
+fuzzer(parse_crldp_fuzzer pki)
 fuzzer(pkcs12)
 fuzzer(pkcs8)
 fuzzer(privkey)
diff --git a/fuzz/parse_crldp_fuzzer.cc b/fuzz/parse_crldp_fuzzer.cc
new file mode 100644
index 0000000..ebf3ba2
--- /dev/null
+++ b/fuzz/parse_crldp_fuzzer.cc
@@ -0,0 +1,24 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "../pki/parse_certificate.h"
+#include "../pki/input.h"
+#include <openssl/base.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  std::vector<bssl::ParsedDistributionPoint> distribution_points;
+
+  bool success = ParseCrlDistributionPoints(bssl::der::Input(data, size),
+                                            &distribution_points);
+
+  if (success) {
+    // A valid CRLDistributionPoints must have at least 1 element.
+    BSSL_CHECK(!distribution_points.empty());
+  }
+
+  return 0;
+}
diff --git a/fuzz/parse_crldp_fuzzer_corpus/crldp_issuer_as_dirname.der b/fuzz/parse_crldp_fuzzer_corpus/crldp_issuer_as_dirname.der
new file mode 100644
index 0000000..26241d2
--- /dev/null
+++ b/fuzz/parse_crldp_fuzzer_corpus/crldp_issuer_as_dirname.der
@@ -0,0 +1,3 @@
+0â0ß „ ¤0}10	UUS10U
+Test Certificates 20111"0 UindirectCRL CA3 cRLIssuer1)0'U indirect CRL for indirectCRL CA3¢V¤T0R10	UUS10U
+Test Certificates 20111"0 UindirectCRL CA3 cRLIssuer
\ No newline at end of file
diff --git a/fuzz/parse_crldp_fuzzer_corpus/relative_name_and_reasons_and_multiple_dps.der b/fuzz/parse_crldp_fuzzer_corpus/relative_name_and_reasons_and_multiple_dps.der
new file mode 100644
index 0000000..c81bcf3
--- /dev/null
+++ b/fuzz/parse_crldp_fuzzer_corpus/relative_name_and_reasons_and_multiple_dps.der
Binary files differ
diff --git a/pki/encode_values_unittest.cc b/pki/encode_values_unittest.cc
index f3009c1..ab42418 100644
--- a/pki/encode_values_unittest.cc
+++ b/pki/encode_values_unittest.cc
@@ -14,7 +14,7 @@
 namespace {
 
 template <size_t N>
-std::string_view ToStringPiece(const uint8_t (&data)[N]) {
+std::string_view ToStringView(const uint8_t (&data)[N]) {
   return std::string_view(reinterpret_cast<const char*>(data), N);
 }
 
@@ -75,7 +75,7 @@
   // Encode a time where no components have leading zeros.
   uint8_t out[kGeneralizedTimeLength];
   ASSERT_TRUE(EncodeGeneralizedTime(time, out));
-  EXPECT_EQ("20141218161259Z", ToStringPiece(out));
+  EXPECT_EQ("20141218161259Z", ToStringView(out));
 
   // Test bounds on all components. Note the encoding function does not validate
   // the input is a valid time, only that it is encodable.
@@ -86,7 +86,7 @@
   time.minutes = 0;
   time.seconds = 0;
   ASSERT_TRUE(EncodeGeneralizedTime(time, out));
-  EXPECT_EQ("00000000000000Z", ToStringPiece(out));
+  EXPECT_EQ("00000000000000Z", ToStringView(out));
 
   time.year = 9999;
   time.month = 99;
@@ -95,7 +95,7 @@
   time.minutes = 99;
   time.seconds = 99;
   ASSERT_TRUE(EncodeGeneralizedTime(time, out));
-  EXPECT_EQ("99999999999999Z", ToStringPiece(out));
+  EXPECT_EQ("99999999999999Z", ToStringView(out));
 
   time.year = 10000;
   EXPECT_FALSE(EncodeGeneralizedTime(time, out));
@@ -117,23 +117,23 @@
   // Encode a time where no components have leading zeros.
   uint8_t out[kUTCTimeLength];
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("141218161259Z", ToStringPiece(out));
+  EXPECT_EQ("141218161259Z", ToStringView(out));
 
   time.year = 2049;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("491218161259Z", ToStringPiece(out));
+  EXPECT_EQ("491218161259Z", ToStringView(out));
 
   time.year = 2000;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("001218161259Z", ToStringPiece(out));
+  EXPECT_EQ("001218161259Z", ToStringView(out));
 
   time.year = 1999;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("991218161259Z", ToStringPiece(out));
+  EXPECT_EQ("991218161259Z", ToStringView(out));
 
   time.year = 1950;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("501218161259Z", ToStringPiece(out));
+  EXPECT_EQ("501218161259Z", ToStringView(out));
 
   time.year = 2050;
   EXPECT_FALSE(EncodeUTCTime(time, out));
@@ -150,7 +150,7 @@
   time.minutes = 0;
   time.seconds = 0;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("000000000000Z", ToStringPiece(out));
+  EXPECT_EQ("000000000000Z", ToStringView(out));
 
   time.year = 1999;
   time.month = 99;
@@ -159,7 +159,7 @@
   time.minutes = 99;
   time.seconds = 99;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("999999999999Z", ToStringPiece(out));
+  EXPECT_EQ("999999999999Z", ToStringView(out));
 
   time.year = 2000;
   time.month = 100;
diff --git a/pki/fillins/inet.h b/pki/fillins/inet.h
deleted file mode 100644
index 905e958..0000000
--- a/pki/fillins/inet.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PKI_FILLINS_INET_H_
-#define PKI_FILLINS_INET_H_
-
-#include <openssl/base.h>
-
-#if defined(OPENSSL_WINDOWS)
-#include <winsock2.h>
-#else
-#include <arpa/inet.h>
-#endif  // OPENSSL_WINDOWS
-
-#endif  // PKI_FILLINS_INET_H_
diff --git a/pki/fillins/utf_string_conversions.cc b/pki/fillins/utf_string_conversions.cc
deleted file mode 100644
index 9341964..0000000
--- a/pki/fillins/utf_string_conversions.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "utf_string_conversions.h"
-
-namespace bssl {
-
-namespace fillins {
-
-static const size_t kMaxUTF8Bytes = 4;
-
-static size_t EncodeUTF8(uint32_t codepoint, char *out_buf) {
-  if (codepoint < 0x7f) {
-    out_buf[0] = codepoint;
-    return 1;
-  }
-
-  if (codepoint <= 0x7ff) {
-    out_buf[0] = 0xc0 | (codepoint >> 6);
-    out_buf[1] = 0x80 | (codepoint & 0x3f);
-    return 2;
-  }
-
-  if (codepoint <= 0xffff) {
-    out_buf[0] = 0xe0 | (codepoint >> 12);
-    out_buf[1] = 0x80 | ((codepoint >> 6) & 0x3f);
-    out_buf[2] = 0x80 | (codepoint & 0x3f);
-    return 3;
-  }
-
-  out_buf[0] = 0xf0 | (codepoint >> 18);
-  out_buf[1] = 0x80 | ((codepoint >> 12) & 0x3f);
-  out_buf[2] = 0x80 | ((codepoint >> 6) & 0x3f);
-  out_buf[3] = 0x80 | (codepoint & 0x3f);
-  return 4;
-}
-
-void WriteUnicodeCharacter(uint32_t codepoint, std::string *append_to) {
-  char buf[kMaxUTF8Bytes];
-  const size_t num_bytes = EncodeUTF8(codepoint, buf);
-  append_to->append(buf, num_bytes);
-}
-
-}  // namespace fillins
-
-}  // namespace bssl
diff --git a/pki/fillins/utf_string_conversions.h b/pki/fillins/utf_string_conversions.h
deleted file mode 100644
index c8cdbc1..0000000
--- a/pki/fillins/utf_string_conversions.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BSSL_FILLINS_UTF_STRING_CONVERSIONS
-#define BSSL_FILLINS_UTF_STRING_CONVERSIONS
-
-#include <openssl/base.h>
-
-#include <string>
-
-#define CBU_IS_SURROGATE(c) (((c)&0xfffff800) == 0xd800)
-
-#define CBU_IS_UNICODE_NONCHAR(c)                                          \
-  ((c) >= 0xfdd0 && ((uint32_t)(c) <= 0xfdef || ((c)&0xfffe) == 0xfffe) && \
-   (uint32_t)(c) <= 0x10ffff)
-
-#define CBU_IS_UNICODE_CHAR(c)                             \
-  ((uint32_t)(c) < 0xd800 ||                               \
-   ((uint32_t)(c) > 0xdfff && (uint32_t)(c) <= 0x10ffff && \
-    !CBU_IS_UNICODE_NONCHAR(c)))
-
-namespace bssl {
-
-namespace fillins {
-
-OPENSSL_EXPORT void WriteUnicodeCharacter(uint32_t codepoint,
-                                          std::string *append_to);
-
-}  // namespace fillins
-
-}  // namespace bssl
-
-#endif  // BSSL_FILLINS_UTF_STRING_CONVERSIONS
diff --git a/pki/import_spec.json b/pki/import_spec.json
index 2fc97e5..0594c3b 100644
--- a/pki/import_spec.json
+++ b/pki/import_spec.json
@@ -281,6 +281,7 @@
     "net/cert/pki/parsed_certificate.h",
     "net/cert/pki/parse_certificate_fuzzer.cc",
     "net/cert/pki/parsed_certificate_unittest.cc",
+    "net/cert/pki/parse_crldp_fuzzer.cc",
     "net/cert/pki/parse_name.cc",
     "net/cert/pki/parse_name.h",
     "net/cert/pki/parse_name_unittest.cc",
diff --git a/pki/ip_util.h b/pki/ip_util.h
index a29f6e9..e78b9e6 100644
--- a/pki/ip_util.h
+++ b/pki/ip_util.h
@@ -14,9 +14,9 @@
 inline constexpr size_t kIPv4AddressSize = 4;
 inline constexpr size_t kIPv6AddressSize = 16;
 
-// Returns whether `mask` is a valid netmask. I.e., whether it the length of an
-// IPv4 or IPv6 address, and is some number of ones, followed by some number of
-// zeros.
+// Returns whether `mask` is a valid netmask. I.e., whether it is the length of
+// an IPv4 or IPv6 address, and is some number of ones, followed by some number
+// of zeros.
 OPENSSL_EXPORT bool IsValidNetmask(der::Input mask);
 
 // Returns whether `addr1` and `addr2` are equal under the netmask `mask`.
diff --git a/pki/parse_values.cc b/pki/parse_values.cc
index 7c142f8..505a10c 100644
--- a/pki/parse_values.cc
+++ b/pki/parse_values.cc
@@ -4,17 +4,13 @@
 
 #include "parse_values.h"
 
+#include <stdlib.h>
+
 #include <tuple>
-#include <vector>
 
-
-#include "fillins/fillins_string_util.h"
-
-#include "fillins/utf_string_conversions.h"
-#include "fillins/inet.h"
-#include "fillins/utf_string_conversions.h"
 #include <openssl/base.h>
 #include <openssl/bytestring.h>
+#include <openssl/mem.h>
 
 namespace bssl::der {
 
@@ -116,7 +112,7 @@
       }
       break;
     default:
-      abort(); //NOTREACHED_NORETURN;
+      abort();
   }
   return true;
 }
@@ -369,7 +365,7 @@
 
 bool ParsePrintableString(Input in, std::string* out) {
   for (char c : in.AsStringView()) {
-    if (!(fillins::IsAsciiAlpha(c) || c == ' ' || (c >= '\'' && c <= ':') ||
+    if (!(OPENSSL_isalpha(c) || c == ' ' || (c >= '\'' && c <= ':') ||
           c == '=' || c == '?')) {
       return false;
     }
@@ -402,44 +398,50 @@
 }
 
 bool ParseUniversalString(Input in, std::string* out) {
-  if (in.Length() % 4 != 0)
+  if (in.Length() % 4 != 0) {
     return false;
-
-  out->clear();
-  std::vector<uint32_t> in_32bit(in.Length() / 4);
-  if (in.Length())
-    memcpy(in_32bit.data(), in.UnsafeData(), in.Length());
-  for (const uint32_t c : in_32bit) {
-    // UniversalString is UCS-4 in big-endian order.
-    auto codepoint = static_cast<uint32_t>(ntohl(c));
-    if (!CBU_IS_UNICODE_CHAR(codepoint))
-      return false;
-
-    fillins::WriteUnicodeCharacter(codepoint, out);
   }
+
+  CBS cbs;
+  CBS_init(&cbs, in.UnsafeData(), in.Length());
+  bssl::ScopedCBB cbb;
+  if (!CBB_init(cbb.get(), in.Length())) {
+    return false;
+  }
+
+  while (CBS_len(&cbs) != 0) {
+    uint32_t c;
+    if (!CBS_get_utf32_be(&cbs, &c) ||  //
+        !CBB_add_utf8(cbb.get(), c)) {
+      return false;
+    }
+  }
+
+  out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
   return true;
 }
 
 bool ParseBmpString(Input in, std::string* out) {
-  if (in.Length() % 2 != 0)
+  if (in.Length() % 2 != 0) {
     return false;
-
-  out->clear();
-  std::vector<uint16_t> in_16bit(in.Length() / 2);
-  if (in.Length())
-    memcpy(in_16bit.data(), in.UnsafeData(), in.Length());
-  for (const uint16_t c : in_16bit) {
-    // BMPString is UCS-2 in big-endian order.
-    uint32_t codepoint = ntohs(c);
-
-    // BMPString only supports codepoints in the Basic Multilingual Plane;
-    // surrogates are not allowed. CBU_IS_UNICODE_CHAR excludes the surrogate
-    // code points, among other invalid values.
-    if (!CBU_IS_UNICODE_CHAR(codepoint))
-      return false;
-
-    fillins::WriteUnicodeCharacter(codepoint, out);
   }
+
+  CBS cbs;
+  CBS_init(&cbs, in.UnsafeData(), in.Length());
+  bssl::ScopedCBB cbb;
+  if (!CBB_init(cbb.get(), in.Length())) {
+    return false;
+  }
+
+  while (CBS_len(&cbs) != 0) {
+    uint32_t c;
+    if (!CBS_get_ucs2_be(&cbs, &c) ||  //
+        !CBB_add_utf8(cbb.get(), c)) {
+      return false;
+    }
+  }
+
+  out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
   return true;
 }
 
diff --git a/sources.cmake b/sources.cmake
index 0fab297..d2e15c7 100644
--- a/sources.cmake
+++ b/sources.cmake
@@ -356,7 +356,6 @@
   pki/fillins/fillins_base64.cc
   pki/fillins/openssl_util.cc
   pki/fillins/fillins_string_util.cc
-  pki/fillins/utf_string_conversions.cc
   pki/general_names.cc
   pki/input.cc
   pki/ip_util.cc