Use more span patterns for strings vs bytes

There's certainly lots more to rework over time, but here are some easy
ones.

Bug: 42290600
Change-Id: I378cc58d716a3178dbcc3f2a7272ff13f37814ff
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/75209
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/bio/bio_test.cc b/crypto/bio/bio_test.cc
index 96d2191..4a7f337 100644
--- a/crypto/bio/bio_test.cc
+++ b/crypto/bio/bio_test.cc
@@ -356,8 +356,7 @@
     const uint8_t *contents;
     size_t len;
     ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len));
-    EXPECT_EQ("test " + in,
-              std::string(reinterpret_cast<const char *>(contents), len));
+    EXPECT_EQ("test " + in, bssl::BytesAsStringView(bssl::Span(contents, len)));
 
     ASSERT_TRUE(BIO_reset(bio.get()));
   }
diff --git a/crypto/pkcs8/pkcs12_test.cc b/crypto/pkcs8/pkcs12_test.cc
index fd80607..14d608c 100644
--- a/crypto/pkcs8/pkcs12_test.cc
+++ b/crypto/pkcs8/pkcs12_test.cc
@@ -56,9 +56,8 @@
   if (friendly_name == nullptr) {
     EXPECT_EQ(nullptr, actual_name);
   } else {
-    EXPECT_EQ(friendly_name,
-              std::string(reinterpret_cast<const char *>(actual_name),
-                          static_cast<size_t>(actual_name_len)));
+    EXPECT_EQ(friendly_name, bssl::BytesAsStringView(
+                                 bssl::Span(actual_name, actual_name_len)));
   }
 }
 
@@ -381,8 +380,8 @@
     if (name == NULL) {
       EXPECT_EQ(nullptr, actual_name);
     } else {
-      EXPECT_EQ(name, std::string(reinterpret_cast<const char *>(actual_name),
-                                  static_cast<size_t>(actual_name_len)));
+      EXPECT_EQ(name, bssl::BytesAsStringView(
+                          bssl::Span(actual_name, actual_name_len)));
     }
   }
 
@@ -650,8 +649,8 @@
   const unsigned char *parsed_alias =
       X509_alias_get0(sk_X509_value(ca_certs, 0), &alias_len);
   ASSERT_TRUE(parsed_alias);
-  ASSERT_EQ(alias, std::string(reinterpret_cast<const char *>(parsed_alias),
-                               static_cast<size_t>(alias_len)));
+  ASSERT_EQ(alias,
+            bssl::BytesAsStringView(bssl::Span(parsed_alias, alias_len)));
 }
 
 // PKCS#12 is built on top of PKCS#7, a misdesigned, overgeneralized combinator
diff --git a/crypto/test/test_util.h b/crypto/test/test_util.h
index 7815093..b9d4b92 100644
--- a/crypto/test/test_util.h
+++ b/crypto/test/test_util.h
@@ -21,7 +21,7 @@
 #include <string.h>
 
 #include <iosfwd>
-#include <string>
+#include <string_view>
 #include <vector>
 
 #include <gtest/gtest.h>
@@ -43,12 +43,8 @@
   Bytes(const char *data_arg, size_t len_arg)
       : span_(reinterpret_cast<const uint8_t *>(data_arg), len_arg) {}
 
-  explicit Bytes(const char *str)
-      : span_(reinterpret_cast<const uint8_t *>(str), strlen(str)) {}
-  explicit Bytes(const std::string &str)
-      : span_(reinterpret_cast<const uint8_t *>(str.data()), str.size()) {}
-  explicit Bytes(bssl::Span<const uint8_t> span)
-      : span_(span) {}
+  explicit Bytes(std::string_view str) : span_(bssl::StringAsBytes(str)) {}
+  explicit Bytes(bssl::Span<const uint8_t> span) : span_(span) {}
 
   bssl::Span<const uint8_t> span_;
 };
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index 589d395..ad1297a 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -2774,8 +2774,7 @@
     size_t len;
     ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len));
     EXPECT_EQ(ok, (strcmp(t.want, "Bad time value") != 0) ? 1 : 0);
-    EXPECT_EQ(t.want,
-              std::string(reinterpret_cast<const char *>(contents), len));
+    EXPECT_EQ(t.want, bssl::BytesAsStringView(bssl::Span(contents, len)));
   }
 }
 
@@ -5440,7 +5439,7 @@
   const uint8_t *data;
   size_t data_len;
   ASSERT_TRUE(BIO_mem_contents(bio.get(), &data, &data_len));
-  std::string print(reinterpret_cast<const char *>(data), data_len);
+  auto print = bssl::BytesAsStringView(bssl::Span(data, data_len));
   EXPECT_EQ(print, R"(Certificate:
     Data:
         Version: 3 (0x2)
diff --git a/fuzz/ssl_ctx_api.cc b/fuzz/ssl_ctx_api.cc
index 93e1363..e9aa8e8 100644
--- a/fuzz/ssl_ctx_api.cc
+++ b/fuzz/ssl_ctx_api.cc
@@ -231,7 +231,7 @@
     return false;
   }
 
-  out->assign(reinterpret_cast<const char *>(CBS_data(&str)), CBS_len(&str));
+  *out = bssl::BytesAsStringView(str);
   return true;
 }
 
diff --git a/pki/encode_values_unittest.cc b/pki/encode_values_unittest.cc
index 2e60a43..9c6509d 100644
--- a/pki/encode_values_unittest.cc
+++ b/pki/encode_values_unittest.cc
@@ -12,15 +12,6 @@
 BSSL_NAMESPACE_BEGIN
 namespace der::test {
 
-namespace {
-
-template <size_t N>
-std::string_view ToStringView(const uint8_t (&data)[N]) {
-  return std::string_view(reinterpret_cast<const char *>(data), N);
-}
-
-}  // namespace
-
 TEST(EncodeValuesTest, EncodePosixTimeAsGeneralizedTime) {
   // Fri, 24 Jun 2016 17:04:54 GMT
   int64_t time = 1466787894;
@@ -76,7 +67,7 @@
   // Encode a time where no components have leading zeros.
   uint8_t out[kGeneralizedTimeLength];
   ASSERT_TRUE(EncodeGeneralizedTime(time, out));
-  EXPECT_EQ("20141218161259Z", ToStringView(out));
+  EXPECT_EQ("20141218161259Z", bssl::BytesAsStringView(out));
 
   // Test bounds on all components. Note the encoding function does not validate
   // the input is a valid time, only that it is encodable.
@@ -87,7 +78,7 @@
   time.minutes = 0;
   time.seconds = 0;
   ASSERT_TRUE(EncodeGeneralizedTime(time, out));
-  EXPECT_EQ("00000000000000Z", ToStringView(out));
+  EXPECT_EQ("00000000000000Z", bssl::BytesAsStringView(out));
 
   time.year = 9999;
   time.month = 99;
@@ -96,7 +87,7 @@
   time.minutes = 99;
   time.seconds = 99;
   ASSERT_TRUE(EncodeGeneralizedTime(time, out));
-  EXPECT_EQ("99999999999999Z", ToStringView(out));
+  EXPECT_EQ("99999999999999Z", bssl::BytesAsStringView(out));
 
   time.year = 10000;
   EXPECT_FALSE(EncodeGeneralizedTime(time, out));
@@ -118,23 +109,23 @@
   // Encode a time where no components have leading zeros.
   uint8_t out[kUTCTimeLength];
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("141218161259Z", ToStringView(out));
+  EXPECT_EQ("141218161259Z", bssl::BytesAsStringView(out));
 
   time.year = 2049;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("491218161259Z", ToStringView(out));
+  EXPECT_EQ("491218161259Z", bssl::BytesAsStringView(out));
 
   time.year = 2000;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("001218161259Z", ToStringView(out));
+  EXPECT_EQ("001218161259Z", bssl::BytesAsStringView(out));
 
   time.year = 1999;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("991218161259Z", ToStringView(out));
+  EXPECT_EQ("991218161259Z", bssl::BytesAsStringView(out));
 
   time.year = 1950;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("501218161259Z", ToStringView(out));
+  EXPECT_EQ("501218161259Z", bssl::BytesAsStringView(out));
 
   time.year = 2050;
   EXPECT_FALSE(EncodeUTCTime(time, out));
@@ -151,7 +142,7 @@
   time.minutes = 0;
   time.seconds = 0;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("000000000000Z", ToStringView(out));
+  EXPECT_EQ("000000000000Z", bssl::BytesAsStringView(out));
 
   time.year = 1999;
   time.month = 99;
@@ -160,7 +151,7 @@
   time.minutes = 99;
   time.seconds = 99;
   ASSERT_TRUE(EncodeUTCTime(time, out));
-  EXPECT_EQ("999999999999Z", ToStringView(out));
+  EXPECT_EQ("999999999999Z", bssl::BytesAsStringView(out));
 
   time.year = 2000;
   time.month = 100;
diff --git a/pki/input_unittest.cc b/pki/input_unittest.cc
index 6aa009d..80d8a7f 100644
--- a/pki/input_unittest.cc
+++ b/pki/input_unittest.cc
@@ -42,9 +42,7 @@
 
 TEST(InputTest, AsString) {
   Input input(kInput);
-  std::string expected_string(reinterpret_cast<const char *>(kInput),
-                              std::size(kInput));
-  EXPECT_EQ(expected_string, input.AsString());
+  EXPECT_EQ(bssl::BytesAsStringView(kInput), input.AsString());
 }
 
 TEST(InputTest, StaticArray) {
diff --git a/ssl/handshake.cc b/ssl/handshake.cc
index 4ecb5fb..84df6f0 100644
--- a/ssl/handshake.cc
+++ b/ssl/handshake.cc
@@ -238,10 +238,8 @@
           sk_CRYPTO_BUFFER_value(prev_session->certs.get(), i);
       const CRYPTO_BUFFER *new_cert =
           sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), i);
-      if (CRYPTO_BUFFER_len(old_cert) != CRYPTO_BUFFER_len(new_cert) ||
-          OPENSSL_memcmp(CRYPTO_BUFFER_data(old_cert),
-                         CRYPTO_BUFFER_data(new_cert),
-                         CRYPTO_BUFFER_len(old_cert)) != 0) {
+      if (Span(CRYPTO_BUFFER_data(old_cert), CRYPTO_BUFFER_len(old_cert)) !=
+          Span(CRYPTO_BUFFER_data(new_cert), CRYPTO_BUFFER_len(new_cert))) {
         OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED);
         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
         return ssl_verify_invalid;
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc
index 8b7e4ec..772a1b6 100644
--- a/ssl/s3_both.cc
+++ b/ssl/s3_both.cc
@@ -468,16 +468,16 @@
     // Some dedicated error codes for protocol mixups should the application
     // wish to interpret them differently. (These do not overlap with
     // ClientHello or V2ClientHello.)
-    const char *str = reinterpret_cast<const char *>(in.data());
-    if (strncmp("GET ", str, 4) == 0 ||   //
-        strncmp("POST ", str, 5) == 0 ||  //
-        strncmp("HEAD ", str, 5) == 0 ||  //
-        strncmp("PUT ", str, 4) == 0) {
+    auto str = bssl::BytesAsStringView(in);
+    if (str.substr(0, 4) == "GET " ||   //
+        str.substr(0, 5) == "POST " ||  //
+        str.substr(0, 5) == "HEAD " ||  //
+        str.substr(0, 4) == "PUT ") {
       OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST);
       *out_alert = 0;
       return ssl_open_record_error;
     }
-    if (strncmp("CONNE", str, 5) == 0) {
+    if (str.substr(0, 5) == "CONNE") {
       OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST);
       *out_alert = 0;
       return ssl_open_record_error;
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 41d071c..a77b50b 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -178,10 +178,10 @@
 
   ScopedCBB cbb;
   Array<uint8_t> line;
+  auto label_bytes = bssl::StringAsBytes(label);
   if (!CBB_init(cbb.get(), strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 +
                                secret.size() * 2 + 1) ||
-      !CBB_add_bytes(cbb.get(), reinterpret_cast<const uint8_t *>(label),
-                     strlen(label)) ||
+      !CBB_add_bytes(cbb.get(), label_bytes.data(), label_bytes.size()) ||
       !CBB_add_u8(cbb.get(), ' ') ||
       !cbb_add_hex_consttime(cbb.get(), ssl->s3->client_random) ||
       !CBB_add_u8(cbb.get(), ' ') ||
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 968b95c..5079f7e 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -332,8 +332,8 @@
     const uint8_t *data;
     size_t len;
     SSL_get0_ocsp_response(ssl, &data, &len);
-    if (config->expect_ocsp_response.size() != len ||
-        OPENSSL_memcmp(config->expect_ocsp_response.data(), data, len) != 0) {
+    if (bssl::StringAsBytes(config->expect_ocsp_response) !=
+        bssl::Span(data, len)) {
       fprintf(stderr, "OCSP response mismatch\n");
       return false;
     }
@@ -343,9 +343,8 @@
     const uint8_t *data;
     size_t len;
     SSL_get0_signed_cert_timestamp_list(ssl, &data, &len);
-    if (config->expect_signed_cert_timestamps.size() != len ||
-        OPENSSL_memcmp(config->expect_signed_cert_timestamps.data(), data,
-                       len) != 0) {
+    if (bssl::StringAsBytes(config->expect_signed_cert_timestamps) !=
+        bssl::Span(data, len)) {
       fprintf(stderr, "SCT list mismatch\n");
       return false;
     }
@@ -523,9 +522,8 @@
     const uint8_t *next_proto;
     unsigned next_proto_len;
     SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
-    if (next_proto_len != config->expect_next_proto.size() ||
-        OPENSSL_memcmp(next_proto, config->expect_next_proto.data(),
-                       next_proto_len) != 0) {
+    if (bssl::StringAsBytes(config->expect_next_proto) !=
+        bssl::Span(next_proto, next_proto_len)) {
       fprintf(stderr, "negotiated next proto mismatch\n");
       return false;
     }
@@ -539,8 +537,8 @@
   const uint8_t *alpn_proto;
   unsigned alpn_proto_len;
   SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
-  if (alpn_proto_len != expect_alpn.size() ||
-      OPENSSL_memcmp(alpn_proto, expect_alpn.data(), alpn_proto_len) != 0) {
+  if (bssl::StringAsBytes(expect_alpn) !=
+      bssl::Span(alpn_proto, alpn_proto_len)) {
     fprintf(stderr, "negotiated alpn proto mismatch\n");
     return false;
   }
@@ -558,9 +556,8 @@
   const uint8_t *peer_settings;
   size_t peer_settings_len;
   SSL_get0_peer_application_settings(ssl, &peer_settings, &peer_settings_len);
-  if (expect_settings !=
-      std::string(reinterpret_cast<const char *>(peer_settings),
-                  peer_settings_len)) {
+  if (bssl::StringAsBytes(expect_settings) !=
+      bssl::Span(peer_settings, peer_settings_len)) {
     fprintf(stderr, "peer application settings mismatch\n");
     return false;
   }
@@ -569,10 +566,8 @@
     const uint8_t *peer_params;
     size_t peer_params_len;
     SSL_get_peer_quic_transport_params(ssl, &peer_params, &peer_params_len);
-    if (peer_params_len != config->expect_quic_transport_params.size() ||
-        OPENSSL_memcmp(peer_params,
-                       config->expect_quic_transport_params.data(),
-                       peer_params_len) != 0) {
+    if (bssl::StringAsBytes(config->expect_quic_transport_params) !=
+        bssl::Span(peer_params, peer_params_len)) {
       fprintf(stderr, "QUIC transport params mismatch\n");
       return false;
     }
@@ -584,9 +579,7 @@
       fprintf(stderr, "no channel id negotiated\n");
       return false;
     }
-    if (config->expect_channel_id.size() != 64 ||
-        OPENSSL_memcmp(config->expect_channel_id.data(), channel_id, 64) !=
-            0) {
+    if (bssl::StringAsBytes(config->expect_channel_id) != channel_id) {
       fprintf(stderr, "channel id mismatch\n");
       return false;
     }
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 1396b2c..fbe3bbf 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -961,9 +961,8 @@
   }
 
   if (!config->expect_advertised_alpn.empty() &&
-      (config->expect_advertised_alpn.size() != inlen ||
-       OPENSSL_memcmp(config->expect_advertised_alpn.data(), in, inlen) !=
-           0)) {
+      bssl::StringAsBytes(config->expect_advertised_alpn) !=
+          bssl::Span(in, inlen)) {
     fprintf(stderr, "bad ALPN select callback inputs.\n");
     exit(1);
   }
@@ -1577,10 +1576,8 @@
     const uint8_t *certificate_types;
     size_t certificate_types_len =
         SSL_get0_certificate_types(ssl, &certificate_types);
-    if (certificate_types_len != config->expect_certificate_types.size() ||
-        OPENSSL_memcmp(certificate_types,
-                       config->expect_certificate_types.data(),
-                       certificate_types_len) != 0) {
+    if (bssl::StringAsBytes(config->expect_certificate_types) !=
+        bssl::Span(certificate_types, certificate_types_len)) {
       fprintf(stderr, "certificate types mismatch.\n");
       return false;
     }
diff --git a/util/fipstools/acvp/modulewrapper/main.cc b/util/fipstools/acvp/modulewrapper/main.cc
index 6e4bd49..b5461e6 100644
--- a/util/fipstools/acvp/modulewrapper/main.cc
+++ b/util/fipstools/acvp/modulewrapper/main.cc
@@ -17,6 +17,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <string>
+#include <string_view>
 
 #include <openssl/crypto.h>
 #include <openssl/span.h>
@@ -24,10 +25,6 @@
 #include "modulewrapper.h"
 
 
-static bool EqString(bssl::Span<const uint8_t> cmd, const char *str) {
-  return cmd.size() == strlen(str) && memcmp(str, cmd.data(), cmd.size()) == 0;
-}
-
 int main(int argc, char **argv) {
   if (argc == 2 && strcmp(argv[1], "--version") == 0) {
     printf("Built for architecture: ");
@@ -95,7 +92,8 @@
       return 1;
     }
 
-    if (EqString(args[0], "flush")) {
+    auto name = bssl::BytesAsStringView(args[0]);
+    if (name == "flush") {
       if (!bssl::acvp::FlushBuffer(STDOUT_FILENO)) {
         abort();
       }
@@ -107,12 +105,9 @@
       return 2;
     }
 
-    auto &reply_callback =
-        EqString(args[0], "getConfig") ? write_reply : buffer_reply;
+    auto &reply_callback = name == "getConfig" ? write_reply : buffer_reply;
     if (!handler(args.subspan(1).data(), reply_callback)) {
-      const std::string name(reinterpret_cast<const char *>(args[0].data()),
-                             args[0].size());
-      fprintf(stderr, "\'%s\' operation failed.\n", name.c_str());
+      fprintf(stderr, "\'%s\' operation failed.\n", std::string(name).c_str());
       return 3;
     }
   }
diff --git a/util/fipstools/acvp/modulewrapper/modulewrapper.cc b/util/fipstools/acvp/modulewrapper/modulewrapper.cc
index 92f7fa9..af5d37c 100644
--- a/util/fipstools/acvp/modulewrapper/modulewrapper.cc
+++ b/util/fipstools/acvp/modulewrapper/modulewrapper.cc
@@ -15,6 +15,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include <assert.h>
@@ -1060,8 +1061,7 @@
         ]
       }
     ])";
-  return write_reply({Span<const uint8_t>(
-      reinterpret_cast<const uint8_t *>(kConfig), sizeof(kConfig) - 1)});
+  return write_reply({bssl::StringAsBytes(kConfig)});
 }
 
 static bool Flush(const Span<const uint8_t> args[], ReplyCallback write_reply) {
@@ -1100,8 +1100,7 @@
     memcpy(buf + DigestLength * 2, digest, DigestLength);
   }
 
-  return write_reply(
-      {Span<const uint8_t>(buf + 2 * DigestLength, DigestLength)});
+  return write_reply({Span(buf).subspan(2 * DigestLength, DigestLength)});
 }
 
 static uint32_t GetIterations(const Span<const uint8_t> iterations_bytes) {
@@ -2106,7 +2105,7 @@
                    ReplyCallback write_reply) {
   const Span<const uint8_t> out_len_bytes = args[0];
   const Span<const uint8_t> secret = args[1];
-  const Span<const uint8_t> label = args[2];
+  const std::string_view label = bssl::BytesAsStringView(args[2]);
   const Span<const uint8_t> seed1 = args[3];
   const Span<const uint8_t> seed2 = args[4];
   const EVP_MD *md = MDFunc();
@@ -2117,11 +2116,10 @@
   }
   memcpy(&out_len, out_len_bytes.data(), sizeof(out_len));
 
-  std::vector<uint8_t> out(static_cast<size_t>(out_len));
+  std::vector<uint8_t> out(size_t{out_len});
   if (!CRYPTO_tls1_prf(md, out.data(), out.size(), secret.data(), secret.size(),
-                       reinterpret_cast<const char *>(label.data()),
-                       label.size(), seed1.data(), seed1.size(), seed2.data(),
-                       seed2.size())) {
+                       label.data(), label.size(), seed1.data(), seed1.size(),
+                       seed2.data(), seed2.size())) {
     return 0;
   }
 
@@ -2621,10 +2619,9 @@
 };
 
 Handler FindHandler(Span<const Span<const uint8_t>> args) {
-  const bssl::Span<const uint8_t> algorithm = args[0];
+  auto algorithm = bssl::BytesAsStringView(args[0]);
   for (const auto &func : kFunctions) {
-    if (algorithm.size() == strlen(func.name) &&
-        memcmp(algorithm.data(), func.name, algorithm.size()) == 0) {
+    if (algorithm == func.name) {
       if (args.size() - 1 != func.num_expected_args) {
         LOG_ERROR("\'%s\' operation received %zu arguments but expected %u.\n",
                   func.name, args.size() - 1, func.num_expected_args);
@@ -2635,9 +2632,7 @@
     }
   }
 
-  const std::string name(reinterpret_cast<const char *>(algorithm.data()),
-                         algorithm.size());
-  LOG_ERROR("Unknown operation: %s\n", name.c_str());
+  LOG_ERROR("Unknown operation: %s\n", std::string(algorithm).c_str());
   return nullptr;
 }