Convert bytestring_test to GTest.

This also fixes TestGetUint to actually test CBS_get_last_u8's behavior.
Right now it can't distinguish CBS_get_last_u8 and CBS_get_u8.

BUG=129

Change-Id: Ie431bb1a828f1c6877938ba7e75c82305b54cf13
Reviewed-on: https://boringssl-review.googlesource.com/15007
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt
index 0188cda..ef8c2d4 100644
--- a/crypto/CMakeLists.txt
+++ b/crypto/CMakeLists.txt
@@ -236,6 +236,7 @@
   asn1/asn1_test.cc
   base64/base64_test.cc
   bio/bio_test.cc
+  bytestring/bytestring_test.cc
   chacha/chacha_test.cc
   constant_time_test.cc
   curve25519/x25519_test.cc
diff --git a/crypto/bytestring/CMakeLists.txt b/crypto/bytestring/CMakeLists.txt
index 362e702..37ff51c 100644
--- a/crypto/bytestring/CMakeLists.txt
+++ b/crypto/bytestring/CMakeLists.txt
@@ -10,14 +10,3 @@
   cbs.c
   cbb.c
 )
-
-add_executable(
-  bytestring_test
-
-  bytestring_test.cc
-
-  $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(bytestring_test crypto)
-add_dependencies(all_tests bytestring_test)
diff --git a/crypto/bytestring/bytestring_test.cc b/crypto/bytestring/bytestring_test.cc
index 6ec6fcf..e8e14d9 100644
--- a/crypto/bytestring/bytestring_test.cc
+++ b/crypto/bytestring/bytestring_test.cc
@@ -22,49 +22,54 @@
 
 #include <vector>
 
+#include <gtest/gtest.h>
+
 #include <openssl/bytestring.h>
 #include <openssl/crypto.h>
 
 #include "internal.h"
 #include "../internal.h"
+#include "../test/test_util.h"
 
 
-static bool TestSkip() {
+TEST(CBSTest, Skip) {
   static const uint8_t kData[] = {1, 2, 3};
   CBS data;
 
   CBS_init(&data, kData, sizeof(kData));
-  return CBS_len(&data) == 3 &&
-      CBS_skip(&data, 1) &&
-      CBS_len(&data) == 2 &&
-      CBS_skip(&data, 2) &&
-      CBS_len(&data) == 0 &&
-      !CBS_skip(&data, 1);
+  EXPECT_EQ(3u, CBS_len(&data));
+  EXPECT_TRUE(CBS_skip(&data, 1));
+  EXPECT_EQ(2u, CBS_len(&data));
+  EXPECT_TRUE(CBS_skip(&data, 2));
+  EXPECT_EQ(0u, CBS_len(&data));
+  EXPECT_FALSE(CBS_skip(&data, 1));
 }
 
-static bool TestGetUint() {
-  static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+TEST(CBSTest, GetUint) {
+  static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
   uint8_t u8;
   uint16_t u16;
   uint32_t u32;
   CBS data;
 
   CBS_init(&data, kData, sizeof(kData));
-  return CBS_get_u8(&data, &u8) &&
-    u8 == 1 &&
-    CBS_get_u16(&data, &u16) &&
-    u16 == 0x203 &&
-    CBS_get_u24(&data, &u32) &&
-    u32 == 0x40506 &&
-    CBS_get_u32(&data, &u32) &&
-    u32 == 0x708090a &&
-    CBS_get_last_u8(&data, &u8) &&
-    u8 == 0xb &&
-    !CBS_get_u8(&data, &u8) &&
-    !CBS_get_last_u8(&data, &u8);
+  ASSERT_TRUE(CBS_get_u8(&data, &u8));
+  EXPECT_EQ(1u, u8);
+  ASSERT_TRUE(CBS_get_u16(&data, &u16));
+  EXPECT_EQ(0x203u, u16);
+  ASSERT_TRUE(CBS_get_u24(&data, &u32));
+  EXPECT_EQ(0x40506u, u32);
+  ASSERT_TRUE(CBS_get_u32(&data, &u32));
+  EXPECT_EQ(0x708090au, u32);
+  ASSERT_TRUE(CBS_get_last_u8(&data, &u8));
+  EXPECT_EQ(0xcu, u8);
+  ASSERT_TRUE(CBS_get_last_u8(&data, &u8));
+  EXPECT_EQ(0xbu, u8);
+  EXPECT_FALSE(CBS_get_u8(&data, &u8));
+  EXPECT_FALSE(CBS_get_last_u8(&data, &u8));
 }
 
-static bool TestGetPrefixed() {
+TEST(CBSTest, GetPrefixed) {
   static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
   uint8_t u8;
   uint16_t u16;
@@ -72,45 +77,37 @@
   CBS data, prefixed;
 
   CBS_init(&data, kData, sizeof(kData));
-  return CBS_get_u8_length_prefixed(&data, &prefixed) &&
-    CBS_len(&prefixed) == 1 &&
-    CBS_get_u8(&prefixed, &u8) &&
-    u8 == 2 &&
-    CBS_get_u16_length_prefixed(&data, &prefixed) &&
-    CBS_len(&prefixed) == 2 &&
-    CBS_get_u16(&prefixed, &u16) &&
-    u16 == 0x304 &&
-    CBS_get_u24_length_prefixed(&data, &prefixed) &&
-    CBS_len(&prefixed) == 3 &&
-    CBS_get_u24(&prefixed, &u32) &&
-    u32 == 0x30201;
+  ASSERT_TRUE(CBS_get_u8_length_prefixed(&data, &prefixed));
+  EXPECT_EQ(1u, CBS_len(&prefixed));
+  ASSERT_TRUE(CBS_get_u8(&prefixed, &u8));
+  EXPECT_EQ(2u, u8);
+  ASSERT_TRUE(CBS_get_u16_length_prefixed(&data, &prefixed));
+  EXPECT_EQ(2u, CBS_len(&prefixed));
+  ASSERT_TRUE(CBS_get_u16(&prefixed, &u16));
+  EXPECT_EQ(0x304u, u16);
+  ASSERT_TRUE(CBS_get_u24_length_prefixed(&data, &prefixed));
+  EXPECT_EQ(3u, CBS_len(&prefixed));
+  ASSERT_TRUE(CBS_get_u24(&prefixed, &u32));
+  EXPECT_EQ(0x30201u, u32);
 }
 
-static bool TestGetPrefixedBad() {
+TEST(CBSTest, GetPrefixedBad) {
   static const uint8_t kData1[] = {2, 1};
   static const uint8_t kData2[] = {0, 2, 1};
   static const uint8_t kData3[] = {0, 0, 2, 1};
   CBS data, prefixed;
 
   CBS_init(&data, kData1, sizeof(kData1));
-  if (CBS_get_u8_length_prefixed(&data, &prefixed)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_u8_length_prefixed(&data, &prefixed));
 
   CBS_init(&data, kData2, sizeof(kData2));
-  if (CBS_get_u16_length_prefixed(&data, &prefixed)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_u16_length_prefixed(&data, &prefixed));
 
   CBS_init(&data, kData3, sizeof(kData3));
-  if (CBS_get_u24_length_prefixed(&data, &prefixed)) {
-    return false;
-  }
-
-  return true;
+  EXPECT_FALSE(CBS_get_u24_length_prefixed(&data, &prefixed));
 }
 
-static bool TestGetASN1() {
+TEST(CBSTest, GetASN1) {
   static const uint8_t kData1[] = {0x30, 2, 1, 2};
   static const uint8_t kData2[] = {0x30, 3, 1, 2};
   static const uint8_t kData3[] = {0x30, 0x80};
@@ -126,133 +123,101 @@
   uint64_t value;
 
   CBS_init(&data, kData1, sizeof(kData1));
-  if (CBS_peek_asn1_tag(&data, 0x1) ||
-      !CBS_peek_asn1_tag(&data, 0x30)) {
-    return false;
-  }
-  if (!CBS_get_asn1(&data, &contents, 0x30) ||
-      CBS_len(&contents) != 2 ||
-      OPENSSL_memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_peek_asn1_tag(&data, 0x1));
+  EXPECT_TRUE(CBS_peek_asn1_tag(&data, 0x30));
+
+  ASSERT_TRUE(CBS_get_asn1(&data, &contents, 0x30));
+  EXPECT_EQ(Bytes("\x01\x02"), Bytes(CBS_data(&contents), CBS_len(&contents)));
 
   CBS_init(&data, kData2, sizeof(kData2));
   // data is truncated
-  if (CBS_get_asn1(&data, &contents, 0x30)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
 
   CBS_init(&data, kData3, sizeof(kData3));
   // zero byte length of length
-  if (CBS_get_asn1(&data, &contents, 0x30)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
 
   CBS_init(&data, kData4, sizeof(kData4));
   // long form mistakenly used.
-  if (CBS_get_asn1(&data, &contents, 0x30)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
 
   CBS_init(&data, kData5, sizeof(kData5));
   // length takes too many bytes.
-  if (CBS_get_asn1(&data, &contents, 0x30)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x30));
 
   CBS_init(&data, kData1, sizeof(kData1));
   // wrong tag.
-  if (CBS_get_asn1(&data, &contents, 0x31)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_asn1(&data, &contents, 0x31));
 
   CBS_init(&data, NULL, 0);
   // peek at empty data.
-  if (CBS_peek_asn1_tag(&data, 0x30)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_peek_asn1_tag(&data, 0x30));
 
   CBS_init(&data, NULL, 0);
   // optional elements at empty data.
-  if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
-      present ||
-      !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) ||
-      present ||
-      CBS_len(&contents) != 0 ||
-      !CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0) ||
-      CBS_len(&contents) != 0 ||
-      !CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
-      value != 42) {
-    return false;
-  }
+  ASSERT_TRUE(CBS_get_optional_asn1(&data, &contents, &present, 0xa0));
+  EXPECT_FALSE(present);
+  ASSERT_TRUE(
+      CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0));
+  EXPECT_FALSE(present);
+  EXPECT_EQ(0u, CBS_len(&contents));
+  ASSERT_TRUE(CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0));
+  EXPECT_EQ(0u, CBS_len(&contents));
+  ASSERT_TRUE(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42));
+  EXPECT_EQ(42u, value);
 
   CBS_init(&data, kData6, sizeof(kData6));
   // optional element.
-  if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
-      present ||
-      !CBS_get_optional_asn1(&data, &contents, &present, 0xa1) ||
-      !present ||
-      CBS_len(&contents) != 3 ||
-      OPENSSL_memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) {
-    return false;
-  }
+  ASSERT_TRUE(CBS_get_optional_asn1(&data, &contents, &present, 0xa0));
+  EXPECT_FALSE(present);
+  ASSERT_TRUE(CBS_get_optional_asn1(&data, &contents, &present, 0xa1));
+  EXPECT_TRUE(present);
+  EXPECT_EQ(Bytes("\x04\x01\x01"),
+            Bytes(CBS_data(&contents), CBS_len(&contents)));
 
   CBS_init(&data, kData6, sizeof(kData6));
   // optional octet string.
-  if (!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) ||
-      present ||
-      CBS_len(&contents) != 0 ||
-      !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1) ||
-      !present ||
-      CBS_len(&contents) != 1 ||
-      CBS_data(&contents)[0] != 1) {
-    return false;
-  }
+  ASSERT_TRUE(
+      CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0));
+  EXPECT_FALSE(present);
+  EXPECT_EQ(0u, CBS_len(&contents));
+  ASSERT_TRUE(
+      CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1));
+  EXPECT_TRUE(present);
+  EXPECT_EQ(Bytes("\x01"), Bytes(CBS_data(&contents), CBS_len(&contents)));
 
   CBS_init(&data, kData7, sizeof(kData7));
   // invalid optional octet string.
-  if (CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1)) {
-    return false;
-  }
+  EXPECT_FALSE(
+      CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1));
 
   CBS_init(&data, kData8, sizeof(kData8));
-  // optional octet string.
-  if (!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
-      value != 42 ||
-      !CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42) ||
-      value != 1) {
-    return false;
-  }
+  // optional integer.
+  ASSERT_TRUE(CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42));
+  EXPECT_EQ(42u, value);
+  ASSERT_TRUE(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42));
+  EXPECT_EQ(1u, value);
 
   CBS_init(&data, kData9, sizeof(kData9));
   // invalid optional integer.
-  if (CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)) {
-    return false;
-  }
+  EXPECT_FALSE(CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42));
 
   unsigned tag;
   CBS_init(&data, kData1, sizeof(kData1));
-  if (!CBS_get_any_asn1(&data, &contents, &tag) ||
-      tag != CBS_ASN1_SEQUENCE ||
-      CBS_len(&contents) != 2 ||
-      OPENSSL_memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) {
-    return false;
-  }
+  ASSERT_TRUE(CBS_get_any_asn1(&data, &contents, &tag));
+  EXPECT_EQ(CBS_ASN1_SEQUENCE, tag);
+  EXPECT_EQ(Bytes("\x01\x02"), Bytes(CBS_data(&contents), CBS_len(&contents)));
 
   size_t header_len;
   CBS_init(&data, kData1, sizeof(kData1));
-  if (!CBS_get_any_asn1_element(&data, &contents, &tag, &header_len) ||
-      tag != CBS_ASN1_SEQUENCE ||
-      header_len != 2 ||
-      CBS_len(&contents) != 4 ||
-      OPENSSL_memcmp(CBS_data(&contents), "\x30\x02\x01\x02", 2) != 0) {
-    return false;
-  }
-
-  return true;
+  ASSERT_TRUE(CBS_get_any_asn1_element(&data, &contents, &tag, &header_len));
+  EXPECT_EQ(CBS_ASN1_SEQUENCE, tag);
+  EXPECT_EQ(2u, header_len);
+  EXPECT_EQ(Bytes("\x30\x02\x01\x02"),
+            Bytes(CBS_data(&contents), CBS_len(&contents)));
 }
 
-static bool TestGetOptionalASN1Bool() {
+TEST(CBSTest, GetOptionalASN1Bool) {
   static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff};
   static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00};
   static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01};
@@ -260,183 +225,156 @@
   CBS data;
   CBS_init(&data, NULL, 0);
   int val = 2;
-  if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) ||
-      val != 0) {
-    return false;
-  }
+  ASSERT_TRUE(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0));
+  EXPECT_EQ(0, val);
 
   CBS_init(&data, kTrue, sizeof(kTrue));
   val = 2;
-  if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) ||
-      val != 1) {
-    return false;
-  }
+  ASSERT_TRUE(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0));
+  EXPECT_EQ(1, val);
 
   CBS_init(&data, kFalse, sizeof(kFalse));
   val = 2;
-  if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1) ||
-      val != 0) {
-    return false;
-  }
+  ASSERT_TRUE(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1));
+  EXPECT_EQ(0, val);
 
   CBS_init(&data, kInvalid, sizeof(kInvalid));
-  if (CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)) {
-    return false;
-  }
-
-  return true;
+  EXPECT_FALSE(CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1));
 }
 
-static bool TestCBBBasic() {
+// Test that CBB_init may be used on an uninitialized input.
+TEST(CBBTest, InitUninitialized) {
+  CBB cbb;
+  ASSERT_TRUE(CBB_init(&cbb, 100));
+  CBB_cleanup(&cbb);
+}
+
+TEST(CBBTest, Basic) {
   static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc};
   uint8_t *buf;
   size_t buf_len;
-  CBB cbb;
 
-  if (!CBB_init(&cbb, 100)) {
-    return false;
-  }
-  CBB_cleanup(&cbb);
+  bssl::ScopedCBB cbb;
+  ASSERT_TRUE(CBB_init(cbb.get(), 100));
+  cbb.Reset();
 
-  if (!CBB_init(&cbb, 0)) {
-    return false;
-  }
-  if (!CBB_add_u8(&cbb, 1) ||
-      !CBB_add_u16(&cbb, 0x203) ||
-      !CBB_add_u24(&cbb, 0x40506) ||
-      !CBB_add_u32(&cbb, 0x708090a) ||
-      !CBB_add_bytes(&cbb, (const uint8_t*) "\x0b\x0c", 2) ||
-      !CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_u8(cbb.get(), 1));
+  ASSERT_TRUE(CBB_add_u16(cbb.get(), 0x203));
+  ASSERT_TRUE(CBB_add_u24(cbb.get(), 0x40506));
+  ASSERT_TRUE(CBB_add_u32(cbb.get(), 0x708090a));
+  ASSERT_TRUE(CBB_add_bytes(cbb.get(), (const uint8_t *)"\x0b\x0c", 2));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
 
   bssl::UniquePtr<uint8_t> scoper(buf);
-  return buf_len == sizeof(kExpected) &&
-         OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
+  EXPECT_EQ(Bytes(kExpected), Bytes(buf, buf_len));
 }
 
-static bool TestCBBFixed() {
+TEST(CBBTest, Fixed) {
   bssl::ScopedCBB cbb;
   uint8_t buf[1];
   uint8_t *out_buf;
   size_t out_size;
 
-  if (!CBB_init_fixed(cbb.get(), NULL, 0) ||
-      !CBB_finish(cbb.get(), &out_buf, &out_size) ||
-      out_buf != NULL ||
-      out_size != 0) {
-    return false;
-  }
+  ASSERT_TRUE(CBB_init_fixed(cbb.get(), NULL, 0));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &out_buf, &out_size));
+  EXPECT_EQ(NULL, out_buf);
+  EXPECT_EQ(0u, out_size);
 
   cbb.Reset();
-  if (!CBB_init_fixed(cbb.get(), buf, 1) ||
-      !CBB_add_u8(cbb.get(), 1) ||
-      !CBB_finish(cbb.get(), &out_buf, &out_size) ||
-      out_buf != buf ||
-      out_size != 1 ||
-      buf[0] != 1) {
-    return false;
-  }
+  ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, 1));
+  ASSERT_TRUE(CBB_add_u8(cbb.get(), 1));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &out_buf, &out_size));
+  EXPECT_EQ(buf, out_buf);
+  EXPECT_EQ(1u, out_size);
+  EXPECT_EQ(1u, buf[0]);
 
   cbb.Reset();
-  if (!CBB_init_fixed(cbb.get(), buf, 1) ||
-      !CBB_add_u8(cbb.get(), 1) ||
-      CBB_add_u8(cbb.get(), 2)) {
-    return false;
-  }
-
-  return true;
+  ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, 1));
+  ASSERT_TRUE(CBB_add_u8(cbb.get(), 1));
+  EXPECT_FALSE(CBB_add_u8(cbb.get(), 2));
 }
 
-static bool TestCBBFinishChild() {
-  CBB cbb, child;
+// Test that calling CBB_finish on a child does nothing.
+TEST(CBBTest, FinishChild) {
+  CBB child;
   uint8_t *out_buf;
   size_t out_size;
 
-  if (!CBB_init(&cbb, 16)) {
-    return false;
-  }
-  if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
-      CBB_finish(&child, &out_buf, &out_size) ||
-      !CBB_finish(&cbb, &out_buf, &out_size)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  bssl::ScopedCBB cbb;
+  ASSERT_TRUE(CBB_init(cbb.get(), 16));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &child));
+
+  EXPECT_FALSE(CBB_finish(&child, &out_buf, &out_size));
+
+  ASSERT_TRUE(CBB_finish(cbb.get(), &out_buf, &out_size));
   bssl::UniquePtr<uint8_t> scoper(out_buf);
-  return out_size == 1 && out_buf[0] == 0;
+  ASSERT_EQ(1u, out_size);
+  EXPECT_EQ(0u, out_buf[0]);
 }
 
-static bool TestCBBPrefixed() {
+TEST(CBBTest, Prefixed) {
   static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
                                       4, 5, 6, 5, 4, 1, 0, 1, 2};
   uint8_t *buf;
   size_t buf_len;
-  CBB cbb, contents, inner_contents, inner_inner_contents;
-
-  if (!CBB_init(&cbb, 0) ||
-      CBB_len(&cbb) != 0 ||
-      !CBB_add_u8_length_prefixed(&cbb, &contents) ||
-      !CBB_add_u8_length_prefixed(&cbb, &contents) ||
-      !CBB_add_u8(&contents, 1) ||
-      CBB_len(&contents) != 1 ||
-      !CBB_flush(&cbb) ||
-      CBB_len(&cbb) != 3 ||
-      !CBB_add_u16_length_prefixed(&cbb, &contents) ||
-      !CBB_add_u16(&contents, 0x203) ||
-      !CBB_add_u24_length_prefixed(&cbb, &contents) ||
-      !CBB_add_u24(&contents, 0x40506) ||
-      !CBB_add_u8_length_prefixed(&cbb, &contents) ||
-      !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
-      !CBB_add_u8(&inner_contents, 1) ||
-      !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
-      !CBB_add_u8(&inner_inner_contents, 2) ||
-      !CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  bssl::ScopedCBB cbb;
+  CBB contents, inner_contents, inner_inner_contents;
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  EXPECT_EQ(0u, CBB_len(cbb.get()));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u8(&contents, 1));
+  EXPECT_EQ(1u, CBB_len(&contents));
+  ASSERT_TRUE(CBB_flush(cbb.get()));
+  EXPECT_EQ(3u, CBB_len(cbb.get()));
+  ASSERT_TRUE(CBB_add_u16_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u16(&contents, 0x203));
+  ASSERT_TRUE(CBB_add_u24_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u24(&contents, 0x40506));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(&contents, &inner_contents));
+  ASSERT_TRUE(CBB_add_u8(&inner_contents, 1));
+  ASSERT_TRUE(
+      CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents));
+  ASSERT_TRUE(CBB_add_u8(&inner_inner_contents, 2));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
 
   bssl::UniquePtr<uint8_t> scoper(buf);
-  return buf_len == sizeof(kExpected) &&
-         OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
+  EXPECT_EQ(Bytes(kExpected), Bytes(buf, buf_len));
 }
 
-static bool TestCBBDiscardChild() {
+TEST(CBBTest, DiscardChild) {
   bssl::ScopedCBB cbb;
   CBB contents, inner_contents, inner_inner_contents;
 
-  if (!CBB_init(cbb.get(), 0) ||
-      !CBB_add_u8(cbb.get(), 0xaa)) {
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_u8(cbb.get(), 0xaa));
 
   // Discarding |cbb|'s children preserves the byte written.
   CBB_discard_child(cbb.get());
 
-  if (!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
-      !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
-      !CBB_add_u8(&contents, 0xbb) ||
-      !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
-      !CBB_add_u16(&contents, 0xcccc) ||
-      !CBB_add_u24_length_prefixed(cbb.get(), &contents) ||
-      !CBB_add_u24(&contents, 0xdddddd) ||
-      !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
-      !CBB_add_u8(&contents, 0xff) ||
-      !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
-      !CBB_add_u8(&inner_contents, 0x42) ||
-      !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
-      !CBB_add_u8(&inner_inner_contents, 0x99)) {
-    return false;
-  }
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u8(&contents, 0xbb));
+  ASSERT_TRUE(CBB_add_u16_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u16(&contents, 0xcccc));
+  ASSERT_TRUE(CBB_add_u24_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u24(&contents, 0xdddddd));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &contents));
+  ASSERT_TRUE(CBB_add_u8(&contents, 0xff));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(&contents, &inner_contents));
+  ASSERT_TRUE(CBB_add_u8(&inner_contents, 0x42));
+  ASSERT_TRUE(
+      CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents));
+  ASSERT_TRUE(CBB_add_u8(&inner_inner_contents, 0x99));
 
   // Discard everything from |inner_contents| down.
   CBB_discard_child(&contents);
 
   uint8_t *buf;
   size_t buf_len;
-  if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
-    return false;
-  }
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   bssl::UniquePtr<uint8_t> scoper(buf);
 
   static const uint8_t kExpected[] = {
@@ -447,166 +385,105 @@
         0, 0, 3, 0xdd, 0xdd, 0xdd,
         1, 0xff,
   };
-  return buf_len == sizeof(kExpected) &&
-         OPENSSL_memcmp(buf, kExpected, buf_len) == 0;
+  EXPECT_EQ(Bytes(kExpected), Bytes(buf, buf_len));
 }
 
-static bool TestCBBMisuse() {
-  CBB cbb, child, contents;
+TEST(CBBTest, Misuse) {
+  bssl::ScopedCBB cbb;
+  CBB child, contents;
   uint8_t *buf;
   size_t buf_len;
 
-  if (!CBB_init(&cbb, 0)) {
-    return false;
-  }
-  if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
-      !CBB_add_u8(&child, 1) ||
-      !CBB_add_u8(&cbb, 2)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &child));
+  ASSERT_TRUE(CBB_add_u8(&child, 1));
+  ASSERT_TRUE(CBB_add_u8(cbb.get(), 2));
 
   // Since we wrote to |cbb|, |child| is now invalid and attempts to write to
   // it should fail.
-  if (CBB_add_u8(&child, 1) ||
-      CBB_add_u16(&child, 1) ||
-      CBB_add_u24(&child, 1) ||
-      CBB_add_u8_length_prefixed(&child, &contents) ||
-      CBB_add_u16_length_prefixed(&child, &contents) ||
-      CBB_add_asn1(&child, &contents, 1) ||
-      CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
-    fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  EXPECT_FALSE(CBB_add_u8(&child, 1));
+  EXPECT_FALSE(CBB_add_u16(&child, 1));
+  EXPECT_FALSE(CBB_add_u24(&child, 1));
+  EXPECT_FALSE(CBB_add_u8_length_prefixed(&child, &contents));
+  EXPECT_FALSE(CBB_add_u16_length_prefixed(&child, &contents));
+  EXPECT_FALSE(CBB_add_asn1(&child, &contents, 1));
+  EXPECT_FALSE(CBB_add_bytes(&child, (const uint8_t*) "a", 1));
 
-  if (!CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   bssl::UniquePtr<uint8_t> scoper(buf);
 
-  if (buf_len != 3 ||
-      OPENSSL_memcmp(buf, "\x01\x01\x02", 3) != 0) {
-    return false;
-  }
-  return true;
+  EXPECT_EQ(Bytes("\x01\x01\x02"), Bytes(buf, buf_len));
 }
 
-static bool TestCBBASN1() {
+TEST(CBBTest, ASN1) {
   static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
   uint8_t *buf;
   size_t buf_len;
-  CBB cbb, contents, inner_contents;
+  bssl::ScopedCBB cbb;
+  CBB contents, inner_contents;
 
-  if (!CBB_init(&cbb, 0)) {
-    return false;
-  }
-  if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
-      !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
-      !CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
+  ASSERT_TRUE(CBB_add_bytes(&contents, (const uint8_t *)"\x01\x02\x03", 3));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   bssl::UniquePtr<uint8_t> scoper(buf);
 
-  if (buf_len != sizeof(kExpected) ||
-      OPENSSL_memcmp(buf, kExpected, buf_len) != 0) {
-    return false;
-  }
+  EXPECT_EQ(Bytes(kExpected), Bytes(buf, buf_len));
 
   std::vector<uint8_t> test_data(100000, 0x42);
-
-  if (!CBB_init(&cbb, 0)) {
-    return false;
-  }
-  if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
-      !CBB_add_bytes(&contents, test_data.data(), 130) ||
-      !CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
+  ASSERT_TRUE(CBB_add_bytes(&contents, test_data.data(), 130));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   scoper.reset(buf);
 
-  if (buf_len != 3 + 130 ||
-      OPENSSL_memcmp(buf, "\x30\x81\x82", 3) != 0 ||
-      OPENSSL_memcmp(buf + 3, test_data.data(), 130) != 0) {
-    return false;
-  }
+  ASSERT_EQ(3u + 130u, buf_len);
+  EXPECT_EQ(Bytes("\x30\x81\x82"), Bytes(buf, 3));
+  EXPECT_EQ(Bytes(test_data.data(), 130), Bytes(buf + 3, 130));
 
-  if (!CBB_init(&cbb, 0)) {
-    return false;
-  }
-  if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
-      !CBB_add_bytes(&contents, test_data.data(), 1000) ||
-      !CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
+  ASSERT_TRUE(CBB_add_bytes(&contents, test_data.data(), 1000));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   scoper.reset(buf);
 
-  if (buf_len != 4 + 1000 ||
-      OPENSSL_memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
-      OPENSSL_memcmp(buf + 4, test_data.data(), 1000)) {
-    return false;
-  }
+  ASSERT_EQ(4u + 1000u, buf_len);
+  EXPECT_EQ(Bytes("\x30\x82\x03\xe8"), Bytes(buf, 4));
+  EXPECT_EQ(Bytes(test_data.data(), 1000), Bytes(buf + 4, 1000));
 
-  if (!CBB_init(&cbb, 0)) {
-    return false;
-  }
-  if (!CBB_add_asn1(&cbb, &contents, 0x30) ||
-      !CBB_add_asn1(&contents, &inner_contents, 0x30) ||
-      !CBB_add_bytes(&inner_contents, test_data.data(), 100000) ||
-      !CBB_finish(&cbb, &buf, &buf_len)) {
-    CBB_cleanup(&cbb);
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_asn1(cbb.get(), &contents, 0x30));
+  ASSERT_TRUE(CBB_add_asn1(&contents, &inner_contents, 0x30));
+  ASSERT_TRUE(CBB_add_bytes(&inner_contents, test_data.data(), 100000));
+  ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   scoper.reset(buf);
 
-  if (buf_len != 5 + 5 + 100000 ||
-      OPENSSL_memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) !=
-          0 ||
-      OPENSSL_memcmp(buf + 10, test_data.data(), 100000)) {
-    return false;
-  }
-
-  return true;
+  ASSERT_EQ(5u + 5u + 100000u, buf_len);
+  EXPECT_EQ(Bytes("\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0"), Bytes(buf, 10));
+  EXPECT_EQ(Bytes(test_data.data(), test_data.size()), Bytes(buf + 10, 100000));
 }
 
-static bool DoBerConvert(const char *name,
-                         const uint8_t *der_expected, size_t der_len,
-                         const uint8_t *ber, size_t ber_len) {
+static void ExpectBerConvert(const char *name, const uint8_t *der_expected,
+                             size_t der_len, const uint8_t *ber,
+                             size_t ber_len) {
+  SCOPED_TRACE(name);
   CBS in;
   uint8_t *out;
   size_t out_len;
 
   CBS_init(&in, ber, ber_len);
-  if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) {
-    fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
-    return false;
-  }
+  ASSERT_TRUE(CBS_asn1_ber_to_der(&in, &out, &out_len));
   bssl::UniquePtr<uint8_t> scoper(out);
 
   if (out == NULL) {
-    if (ber_len != der_len ||
-        OPENSSL_memcmp(der_expected, ber, ber_len) != 0) {
-      fprintf(stderr, "%s: incorrect unconverted result.\n", name);
-      return false;
-    }
-
-    return true;
+    EXPECT_EQ(Bytes(der_expected, der_len), Bytes(ber, ber_len));
+  } else {
+    EXPECT_NE(Bytes(der_expected, der_len), Bytes(ber, ber_len));
+    EXPECT_EQ(Bytes(der_expected, der_len), Bytes(out, out_len));
   }
-
-  if (out_len != der_len ||
-      OPENSSL_memcmp(out, der_expected, der_len) != 0) {
-    fprintf(stderr, "%s: incorrect converted result.\n", name);
-    return false;
-  }
-
-  return true;
 }
 
-static bool TestBerConvert() {
+TEST(CBSTest, BerConvert) {
   static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
 
   // kIndefBER contains a SEQUENCE with an indefinite length.
@@ -653,18 +530,17 @@
       0xa0, 0x08, 0x04, 0x02, 0x00, 0x01, 0x04, 0x02, 0x02, 0x03,
   };
 
-  return DoBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
-                      kSimpleBER, sizeof(kSimpleBER)) &&
-         DoBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
-                      sizeof(kIndefBER)) &&
-         DoBerConvert("kOctetStringBER", kOctetStringDER,
-                      sizeof(kOctetStringDER), kOctetStringBER,
-                      sizeof(kOctetStringBER)) &&
-         DoBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
-                      sizeof(kNSSBER)) &&
-         DoBerConvert("kConstructedStringBER", kConstructedStringDER,
-                      sizeof(kConstructedStringDER), kConstructedStringBER,
-                      sizeof(kConstructedStringBER));
+  ExpectBerConvert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), kSimpleBER,
+                   sizeof(kSimpleBER));
+  ExpectBerConvert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
+                   sizeof(kIndefBER));
+  ExpectBerConvert("kOctetStringBER", kOctetStringDER, sizeof(kOctetStringDER),
+                   kOctetStringBER, sizeof(kOctetStringBER));
+  ExpectBerConvert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
+                   sizeof(kNSSBER));
+  ExpectBerConvert("kConstructedStringBER", kConstructedStringDER,
+                   sizeof(kConstructedStringDER), kConstructedStringBER,
+                   sizeof(kConstructedStringBER));
 }
 
 struct ImplicitStringTest {
@@ -690,8 +566,9 @@
     {"\xa1\x09\x0c\x01\x61\x0c\x01\x61\x0c\x01\x61", 11, false, nullptr, 0},
 };
 
-static bool TestImplicitString() {
+TEST(CBSTest, ImplicitString) {
   for (const auto &test : kImplicitStringTests) {
+    SCOPED_TRACE(Bytes(test.in, test.in_len));
     uint8_t *storage = nullptr;
     CBS in, out;
     CBS_init(&in, reinterpret_cast<const uint8_t *>(test.in), test.in_len);
@@ -699,21 +576,13 @@
                                           CBS_ASN1_CONTEXT_SPECIFIC | 0,
                                           CBS_ASN1_OCTETSTRING);
     bssl::UniquePtr<uint8_t> scoper(storage);
+    EXPECT_EQ(test.ok, static_cast<bool>(ok));
 
-    if (static_cast<bool>(ok) != test.ok) {
-      fprintf(stderr, "CBS_get_asn1_implicit_string unexpectedly %s\n",
-              ok ? "succeeded" : "failed");
-      return false;
-    }
-
-    if (ok && (CBS_len(&out) != test.out_len ||
-               OPENSSL_memcmp(CBS_data(&out), test.out, test.out_len) != 0)) {
-      fprintf(stderr, "CBS_get_asn1_implicit_string gave the wrong output\n");
-      return false;
+    if (ok) {
+      EXPECT_EQ(Bytes(test.out, test.out_len),
+                Bytes(CBS_data(&out), CBS_len(&out)));
     }
   }
-
-  return true;
 }
 
 struct ASN1Uint64Test {
@@ -752,35 +621,26 @@
     {"\x02\x02\x00\x01", 4},
 };
 
-static bool TestASN1Uint64() {
+TEST(CBSTest, ASN1Uint64) {
   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Uint64Tests); i++) {
+    SCOPED_TRACE(i);
     const ASN1Uint64Test *test = &kASN1Uint64Tests[i];
     CBS cbs;
     uint64_t value;
-    CBB cbb;
     uint8_t *out;
     size_t len;
 
     CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
-    if (!CBS_get_asn1_uint64(&cbs, &value) ||
-        CBS_len(&cbs) != 0 ||
-        value != test->value) {
-      return false;
-    }
+    ASSERT_TRUE(CBS_get_asn1_uint64(&cbs, &value));
+    EXPECT_EQ(0u, CBS_len(&cbs));
+    EXPECT_EQ(test->value, value);
 
-    if (!CBB_init(&cbb, 0)) {
-      return false;
-    }
-    if (!CBB_add_asn1_uint64(&cbb, test->value) ||
-        !CBB_finish(&cbb, &out, &len)) {
-      CBB_cleanup(&cbb);
-      return false;
-    }
+    bssl::ScopedCBB cbb;
+    ASSERT_TRUE(CBB_init(cbb.get(), 0));
+    ASSERT_TRUE(CBB_add_asn1_uint64(cbb.get(), test->value));
+    ASSERT_TRUE(CBB_finish(cbb.get(), &out, &len));
     bssl::UniquePtr<uint8_t> scoper(out);
-    if (len != test->encoding_len ||
-        OPENSSL_memcmp(out, test->encoding, len) != 0) {
-      return false;
-    }
+    EXPECT_EQ(Bytes(test->encoding, test->encoding_len), Bytes(out, len));
   }
 
   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kASN1InvalidUint64Tests); i++) {
@@ -789,113 +649,76 @@
     uint64_t value;
 
     CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len);
-    if (CBS_get_asn1_uint64(&cbs, &value)) {
-      return false;
-    }
+    EXPECT_FALSE(CBS_get_asn1_uint64(&cbs, &value));
   }
-
-  return true;
 }
 
-static bool TestZero() {
+TEST(CBBTest, Zero) {
   CBB cbb;
   CBB_zero(&cbb);
   // Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
   CBB_cleanup(&cbb);
-  return true;
 }
 
-static bool TestCBBReserve() {
+TEST(CBBTest, Reserve) {
   uint8_t buf[10];
   uint8_t *ptr;
   size_t len;
   bssl::ScopedCBB cbb;
-  if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
-      // Too large.
-      CBB_reserve(cbb.get(), &ptr, 11)) {
-    return false;
-  }
+  ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, sizeof(buf)));
+  // Too large.
+  EXPECT_FALSE(CBB_reserve(cbb.get(), &ptr, 11));
 
   cbb.Reset();
-  if (!CBB_init_fixed(cbb.get(), buf, sizeof(buf)) ||
-      // Successfully reserve the entire space.
-      !CBB_reserve(cbb.get(), &ptr, 10) ||
-      ptr != buf ||
-      // Advancing under the maximum bytes is legal.
-      !CBB_did_write(cbb.get(), 5) ||
-      !CBB_finish(cbb.get(), NULL, &len) ||
-      len != 5) {
-    return false;
-  }
-  return true;
+  ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, sizeof(buf)));
+  // Successfully reserve the entire space.
+  ASSERT_TRUE(CBB_reserve(cbb.get(), &ptr, 10));
+  EXPECT_EQ(buf, ptr);
+  // Advancing under the maximum bytes is legal.
+  ASSERT_TRUE(CBB_did_write(cbb.get(), 5));
+  ASSERT_TRUE(CBB_finish(cbb.get(), NULL, &len));
+  EXPECT_EQ(5u, len);
 }
 
-static bool TestStickyError() {
+// Test that CBB errors are sticky; once on operation on CBB fails, all
+// subsequent ones do.
+TEST(CBBTest, StickyError) {
   // Write an input that exceeds the limit for its length prefix.
   bssl::ScopedCBB cbb;
   CBB child;
   static const uint8_t kZeros[256] = {0};
-  if (!CBB_init(cbb.get(), 0) ||
-      !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
-      !CBB_add_bytes(&child, kZeros, sizeof(kZeros))) {
-    return false;
-  }
-
-  if (CBB_flush(cbb.get())) {
-    fprintf(stderr, "CBB_flush unexpectedly succeeded.\n");
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &child));
+  ASSERT_TRUE(CBB_add_bytes(&child, kZeros, sizeof(kZeros)));
+  ASSERT_FALSE(CBB_flush(cbb.get()));
 
   // All future operations should fail.
   uint8_t *ptr;
   size_t len;
-  if (CBB_add_u8(cbb.get(), 0) ||
-      CBB_finish(cbb.get(), &ptr, &len)) {
-    fprintf(stderr, "Future operations unexpectedly succeeded.\n");
-    return false;
-  }
+  EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
+  EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
 
   // Write an input that cannot fit in a fixed CBB.
   cbb.Reset();
   uint8_t buf;
-  if (!CBB_init_fixed(cbb.get(), &buf, 1)) {
-    return false;
-  }
-
-  if (CBB_add_bytes(cbb.get(), kZeros, sizeof(kZeros))) {
-    fprintf(stderr, "CBB_add_bytes unexpectedly succeeded.\n");
-    return false;
-  }
+  ASSERT_TRUE(CBB_init_fixed(cbb.get(), &buf, 1));
+  ASSERT_FALSE(CBB_add_bytes(cbb.get(), kZeros, sizeof(kZeros)));
 
   // All future operations should fail.
-  if (CBB_add_u8(cbb.get(), 0) ||
-      CBB_finish(cbb.get(), &ptr, &len)) {
-    fprintf(stderr, "Future operations unexpectedly succeeded.\n");
-    return false;
-  }
+  EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
+  EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
 
   // Write a u32 that cannot fit in a u24.
   cbb.Reset();
-  if (!CBB_init(cbb.get(), 0)) {
-    return false;
-  }
-
-  if (CBB_add_u24(cbb.get(), 1u << 24)) {
-    fprintf(stderr, "CBB_add_u24 unexpectedly succeeded.\n");
-    return false;
-  }
+  ASSERT_TRUE(CBB_init(cbb.get(), 0));
+  ASSERT_FALSE(CBB_add_u24(cbb.get(), 1u << 24));
 
   // All future operations should fail.
-  if (CBB_add_u8(cbb.get(), 0) ||
-      CBB_finish(cbb.get(), &ptr, &len)) {
-    fprintf(stderr, "Future operations unexpectedly succeeded.\n");
-    return false;
-  }
-
-  return true;
+  EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
+  EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
 }
 
-static bool TestBitString() {
+TEST(CBSTest, BitString) {
   static const std::vector<uint8_t> kValidBitStrings[] = {
       {0x00},                                      // 0 bits
       {0x07, 0x80},                                // 1 bit
@@ -904,11 +727,10 @@
       {0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0},  // 42 bits
   };
   for (const auto& test : kValidBitStrings) {
+    SCOPED_TRACE(Bytes(test.data(), test.size()));
     CBS cbs;
     CBS_init(&cbs, test.data(), test.size());
-    if (!CBS_is_valid_asn1_bitstring(&cbs)) {
-      return false;
-    }
+    EXPECT_TRUE(CBS_is_valid_asn1_bitstring(&cbs));
   }
 
   static const std::vector<uint8_t> kInvalidBitStrings[] = {
@@ -923,16 +745,13 @@
       {0x06, 0xff, 0xc1},
   };
   for (const auto& test : kInvalidBitStrings) {
+    SCOPED_TRACE(Bytes(test.data(), test.size()));
     CBS cbs;
     CBS_init(&cbs, test.data(), test.size());
-    if (CBS_is_valid_asn1_bitstring(&cbs)) {
-      return false;
-    }
+    EXPECT_FALSE(CBS_is_valid_asn1_bitstring(&cbs));
 
     // CBS_asn1_bitstring_has_bit returns false on invalid inputs.
-    if (CBS_asn1_bitstring_has_bit(&cbs, 0)) {
-      return false;
-    }
+    EXPECT_FALSE(CBS_asn1_bitstring_has_bit(&cbs, 0));
   }
 
   static const struct {
@@ -960,43 +779,11 @@
       {{0x06, 0x0f, 0x40}, 1000, false},
   };
   for (const auto& test : kBitTests) {
+    SCOPED_TRACE(Bytes(test.in.data(), test.in.size()));
+    SCOPED_TRACE(test.bit);
     CBS cbs;
     CBS_init(&cbs, test.in.data(), test.in.size());
-    if (CBS_asn1_bitstring_has_bit(&cbs, test.bit) !=
-        static_cast<int>(test.bit_set)) {
-      return false;
-    }
+    EXPECT_EQ(static_cast<int>(test.bit_set),
+              CBS_asn1_bitstring_has_bit(&cbs, test.bit));
   }
-
-  return true;
-}
-
-int main() {
-  CRYPTO_library_init();
-
-  if (!TestSkip() ||
-      !TestGetUint() ||
-      !TestGetPrefixed() ||
-      !TestGetPrefixedBad() ||
-      !TestGetASN1() ||
-      !TestCBBBasic() ||
-      !TestCBBFixed() ||
-      !TestCBBFinishChild() ||
-      !TestCBBMisuse() ||
-      !TestCBBPrefixed() ||
-      !TestCBBDiscardChild() ||
-      !TestCBBASN1() ||
-      !TestBerConvert() ||
-      !TestImplicitString() ||
-      !TestASN1Uint64() ||
-      !TestGetOptionalASN1Bool() ||
-      !TestZero() ||
-      !TestCBBReserve() ||
-      !TestStickyError() ||
-      !TestBitString()) {
-    return 1;
-  }
-
-  printf("PASS\n");
-  return 0;
 }
diff --git a/include/openssl/bytestring.h b/include/openssl/bytestring.h
index 4aea6bf..1e74956 100644
--- a/include/openssl/bytestring.h
+++ b/include/openssl/bytestring.h
@@ -126,33 +126,33 @@
 /* Parsing ASN.1 */
 
 /* The following values are tag numbers for UNIVERSAL elements. */
-#define CBS_ASN1_BOOLEAN 0x1
-#define CBS_ASN1_INTEGER 0x2
-#define CBS_ASN1_BITSTRING 0x3
-#define CBS_ASN1_OCTETSTRING 0x4
-#define CBS_ASN1_NULL 0x5
-#define CBS_ASN1_OBJECT 0x6
-#define CBS_ASN1_ENUMERATED 0xa
-#define CBS_ASN1_UTF8STRING 0xc
-#define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
-#define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
-#define CBS_ASN1_NUMERICSTRING 0x12
-#define CBS_ASN1_PRINTABLESTRING 0x13
-#define CBS_ASN1_T61STRING 0x14
-#define CBS_ASN1_VIDEOTEXSTRING 0x15
-#define CBS_ASN1_IA5STRING 0x16
-#define CBS_ASN1_UTCTIME 0x17
-#define CBS_ASN1_GENERALIZEDTIME 0x18
-#define CBS_ASN1_GRAPHICSTRING 0x19
-#define CBS_ASN1_VISIBLESTRING 0x1a
-#define CBS_ASN1_GENERALSTRING 0x1b
-#define CBS_ASN1_UNIVERSALSTRING 0x1c
-#define CBS_ASN1_BMPSTRING 0x1e
+#define CBS_ASN1_BOOLEAN 0x1u
+#define CBS_ASN1_INTEGER 0x2u
+#define CBS_ASN1_BITSTRING 0x3u
+#define CBS_ASN1_OCTETSTRING 0x4u
+#define CBS_ASN1_NULL 0x5u
+#define CBS_ASN1_OBJECT 0x6u
+#define CBS_ASN1_ENUMERATED 0xau
+#define CBS_ASN1_UTF8STRING 0xcu
+#define CBS_ASN1_SEQUENCE (0x10u | CBS_ASN1_CONSTRUCTED)
+#define CBS_ASN1_SET (0x11u | CBS_ASN1_CONSTRUCTED)
+#define CBS_ASN1_NUMERICSTRING 0x12u
+#define CBS_ASN1_PRINTABLESTRING 0x13u
+#define CBS_ASN1_T61STRING 0x14u
+#define CBS_ASN1_VIDEOTEXSTRING 0x15u
+#define CBS_ASN1_IA5STRING 0x16u
+#define CBS_ASN1_UTCTIME 0x17u
+#define CBS_ASN1_GENERALIZEDTIME 0x18u
+#define CBS_ASN1_GRAPHICSTRING 0x19u
+#define CBS_ASN1_VISIBLESTRING 0x1au
+#define CBS_ASN1_GENERALSTRING 0x1bu
+#define CBS_ASN1_UNIVERSALSTRING 0x1cu
+#define CBS_ASN1_BMPSTRING 0x1eu
 
 /* CBS_ASN1_CONSTRUCTED may be ORed into a tag to toggle the constructed
  * bit. |CBS| and |CBB| APIs consider the constructed bit to be part of the
  * tag. */
-#define CBS_ASN1_CONSTRUCTED 0x20
+#define CBS_ASN1_CONSTRUCTED 0x20u
 
 /* The following values specify the constructed bit or tag class and may be ORed
  * into a tag number to produce the final tag. If none is used, the tag will be
@@ -161,15 +161,15 @@
  * Note that although they currently match the DER serialization, consumers must
  * use these bits rather than make assumptions about the representation. This is
  * to allow for tag numbers beyond 31 in the future. */
-#define CBS_ASN1_APPLICATION 0x40
-#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
-#define CBS_ASN1_PRIVATE 0xc0
+#define CBS_ASN1_APPLICATION 0x40u
+#define CBS_ASN1_CONTEXT_SPECIFIC 0x80u
+#define CBS_ASN1_PRIVATE 0xc0u
 
 /* CBS_ASN1_CLASS_MASK may be ANDed with a tag to query its class. */
-#define CBS_ASN1_CLASS_MASK 0xc0
+#define CBS_ASN1_CLASS_MASK 0xc0u
 
 /* CBS_ASN1_TAG_NUMBER_MASK may be ANDed with a tag to query its number. */
-#define CBS_ASN1_TAG_NUMBER_MASK 0x1f
+#define CBS_ASN1_TAG_NUMBER_MASK 0x1fu
 
 /* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
  * including tag and length bytes) and advances |cbs| over it. The ASN.1
diff --git a/util/all_tests.json b/util/all_tests.json
index 49c463a..ebc632d 100644
--- a/util/all_tests.json
+++ b/util/all_tests.json
@@ -1,7 +1,6 @@
 [
 	["crypto/fipsmodule/aes_test", "crypto/fipsmodule/aes/aes_tests.txt"],
 	["crypto/bn/bn_test", "crypto/bn/bn_tests.txt"],
-	["crypto/bytestring/bytestring_test"],
 	["crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"],
 	["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"],
 	["crypto/cipher/aead_test", "aes-128-gcm-siv", "crypto/cipher/test/aes_128_gcm_siv_tests.txt"],