Reset the error queue in some more typical cases where unit tests intend to fail.

This brings BoringSSL down to 60 `OPENSSL_PUT_ERROR` statement that seem
to both append to and create new error queues.

Likely more reduction possible in subsequent CLs.

Bug: 42290241
Change-Id: I6de5c44422f946b0926e5d6a9acac0aa6a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/99067
Reviewed-by: Xiangfei Ding <xfding@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc
index 6ef4881..8a1d2ec 100644
--- a/crypto/asn1/asn1_test.cc
+++ b/crypto/asn1/asn1_test.cc
@@ -381,6 +381,8 @@
       } else {
         uint64_t v;
         EXPECT_FALSE(ASN1_INTEGER_get_uint64(&v, obj));
+        EXPECT_TRUE(
+            ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_INTEGER}}));
       }
 
       if (fits_in_i64) {
@@ -390,6 +392,8 @@
       } else {
         int64_t v;
         EXPECT_FALSE(ASN1_INTEGER_get_int64(&v, obj));
+        EXPECT_TRUE(
+            ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_INTEGER}}));
       }
 
       if (fits_in_long) {
@@ -1029,12 +1033,22 @@
 
   // All unused bits must be zero.
   EXPECT_FALSE(set1(val.get(), {0xff}, 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}}));
   EXPECT_FALSE(set1(val.get(), {0xf0}, 5));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}}));
 
   // Invalid unused bit counts.
   EXPECT_FALSE(set1(val.get(), {0x00, 0x00}, 8));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}}));
   EXPECT_FALSE(set1(val.get(), {0x00, 0x00}, -1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}}));
   EXPECT_FALSE(set1(val.get(), {}, 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}}));
 
   // `ASN1_STRING_set` and `ASN1_STRING_set0` should clear the count of unused
   // bits, rather then carry it over.
@@ -2223,12 +2237,16 @@
   EXPECT_EQ(-1, name->type);
   // `name` should fail to encode.
   EXPECT_EQ(-1, i2d_GENERAL_NAME(name.get(), nullptr));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE}}));
 
   // The error should be propagated through types containing `name`.
   UniquePtr<GENERAL_NAMES> names(GENERAL_NAMES_new());
   ASSERT_TRUE(names);
   EXPECT_TRUE(PushToStack(names.get(), std::move(name)));
   EXPECT_EQ(-1, i2d_GENERAL_NAMES(names.get(), nullptr));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE}}));
 }
 
 // Encoding NID-only `ASN1_OBJECT`s should fail.
@@ -2251,6 +2269,7 @@
   ASSERT_TRUE(obj);
   EXPECT_EQ(-1, obj->type);
   EXPECT_EQ(-1, i2d_ASN1_TYPE(obj.get(), nullptr));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_WRONG_TYPE}}));
 
   // The historical in-memory representation of [UNIVERSAL 128] was for both
   // `obj->type` and `obj->value.asn1_string->type` to be 128. This is no longer
@@ -2261,6 +2280,7 @@
   obj->value.asn1_string = ASN1_STRING_type_new(128);
   ASSERT_TRUE(obj->value.asn1_string);
   EXPECT_EQ(-1, i2d_ASN1_TYPE(obj.get(), nullptr));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_WRONG_TYPE}}));
 }
 
 // Encoding invalid MSTRING types should fail. An MSTRING is a CHOICE of
@@ -2639,18 +2659,21 @@
   int tag_class;
   EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class,
                                   sizeof(kTruncated)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}}));
 
   // Indefinite-length encoding is not allowed in DER.
   static const uint8_t kIndefinite[] = {0x30, 0x80, 0x00, 0x00};
   ptr = kIndefinite;
   EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class,
                                   sizeof(kIndefinite)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}}));
 
   // DER requires lengths be minimally-encoded. This should be {0x30, 0x00}.
   static const uint8_t kNonMinimal[] = {0x30, 0x81, 0x00};
   ptr = kNonMinimal;
   EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class,
                                   sizeof(kNonMinimal)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}}));
 
   // This should be {0x04, 0x81, 0x80, ...}.
   std::vector<uint8_t> non_minimal = {0x04, 0x82, 0x00, 0x80};
@@ -2658,6 +2681,7 @@
   ptr = non_minimal.data();
   EXPECT_EQ(0x80, ASN1_get_object(&ptr, &length, &tag, &tag_class,
                                   non_minimal.size()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}}));
 }
 
 template <typename T>
@@ -2762,12 +2786,18 @@
       inp = t.in.data();
       UniquePtr<ASN1_STRING> str(t.d2i(nullptr, &inp, t.in.size()));
       EXPECT_EQ(t.valid, str != nullptr);
+      if (!t.valid) {
+        EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, std::nullopt}}));
+      }
     }
 
     // Also test with the ANY parser.
     inp = t.in.data();
     UniquePtr<ASN1_TYPE> any(d2i_ASN1_TYPE(nullptr, &inp, t.in.size()));
     EXPECT_EQ(t.valid, any != nullptr);
+    if (!t.valid) {
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, std::nullopt}}));
+    }
   }
 }
 
@@ -2827,11 +2857,13 @@
   // crashes, and actually allocating 512 MiB in a test is likely to break.
   char b = 0;
   EXPECT_FALSE(ASN1_STRING_set(str.get(), &b, INT_MAX / 4));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ERR_R_OVERFLOW}}));
 
 #if defined(OPENSSL_64_BIT)
   // `ASN1_STRING_set` should tolerate lengths that exceed `int` without
   // overflow.
   EXPECT_FALSE(ASN1_STRING_set(str.get(), &b, 1 + (ossl_ssize_t{1} << 48)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ERR_R_OVERFLOW}}));
 #endif
 }
 
@@ -3040,6 +3072,7 @@
 // the full combination of tagging and SEQUENCE OF.
 TEST(ASN1Test, MissingRequiredField) {
   EXPECT_EQ(-1, i2d_REQUIRED_FIELD(nullptr, nullptr));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}}));
 
   std::unique_ptr<REQUIRED_FIELD, decltype(&REQUIRED_FIELD_free)> obj(
       nullptr, REQUIRED_FIELD_free);
@@ -3050,6 +3083,7 @@
     ASN1_INTEGER_free((*obj).*field);
     (*obj).*field = nullptr;
     EXPECT_EQ(-1, i2d_REQUIRED_FIELD(obj.get(), nullptr));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}}));
   }
 
   for (auto field : {&REQUIRED_FIELD::seq, &REQUIRED_FIELD::seq_imp,
@@ -3059,6 +3093,7 @@
     sk_ASN1_INTEGER_pop_free((*obj).*field, ASN1_INTEGER_free);
     (*obj).*field = nullptr;
     EXPECT_EQ(-1, i2d_REQUIRED_FIELD(obj.get(), nullptr));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}}));
   }
 
   for (auto field : {&REQUIRED_FIELD::null, &REQUIRED_FIELD::null_imp,
@@ -3067,6 +3102,7 @@
     ASSERT_TRUE(obj);
     (*obj).*field = nullptr;
     EXPECT_EQ(-1, i2d_REQUIRED_FIELD(obj.get(), nullptr));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}}));
   }
 }
 
diff --git a/crypto/bio/bio_test.cc b/crypto/bio/bio_test.cc
index 8c05f81..ab58fbb 100644
--- a/crypto/bio/bio_test.cc
+++ b/crypto/bio/bio_test.cc
@@ -603,6 +603,7 @@
     int ok = BIO_read_asn1(bio.get(), &out, &out_len, t.max_len);
     if (!ok) {
       out = nullptr;
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, std::nullopt}}));
     }
     UniquePtr<uint8_t> out_storage(out);
 
diff --git a/crypto/bytestring/bytestring_test.cc b/crypto/bytestring/bytestring_test.cc
index fca6109..b93c0ca 100644
--- a/crypto/bytestring/bytestring_test.cc
+++ b/crypto/bytestring/bytestring_test.cc
@@ -481,6 +481,7 @@
   ASSERT_TRUE(CBB_init_fixed(&cbb, buf, 1));
   ASSERT_TRUE(CBB_add_u8(&cbb, 1));
   EXPECT_FALSE(CBB_add_u8(&cbb, 2));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
   // We do not need `CBB_cleanup` or |bssl::ScopedCBB| here because a fixed
   // `CBB` has no allocations. Leak-checking tools will confirm there was
   // nothing to clean up.
@@ -490,6 +491,7 @@
   ASSERT_TRUE(CBB_init_fixed(&cbb2, buf, 1));
   ASSERT_TRUE(CBB_add_u8(&cbb2, 1));
   EXPECT_FALSE(CBB_add_u8(&cbb2, 2));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
   CBB_cleanup(&cbb2);
 }
 
@@ -504,6 +506,8 @@
   ASSERT_TRUE(CBB_add_u8_length_prefixed(cbb.get(), &child));
 
   EXPECT_FALSE(CBB_finish(&child, &out_buf, &out_size));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
 
   ASSERT_TRUE(CBB_finish(cbb.get(), &out_buf, &out_size));
   UniquePtr<uint8_t> scoper(out_buf);
@@ -654,12 +658,26 @@
   // Since we wrote to `cbb`, `child` is now invalid and attempts to write to
   // it should fail.
   EXPECT_FALSE(CBB_add_u8(&child, 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_add_u16(&child, 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_add_u24(&child, 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_add_u8_length_prefixed(&child, &contents));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_add_u16_length_prefixed(&child, &contents));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_add_asn1(&child, &contents, 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_add_bytes(&child, (const uint8_t *)"a", 1));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
 
   ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
   UniquePtr<uint8_t> scoper(buf);
@@ -1324,6 +1342,7 @@
   ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, sizeof(buf)));
   // Too large.
   EXPECT_FALSE(CBB_reserve(cbb.get(), &ptr, 11));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
 
   cbb.Reset();
   ASSERT_TRUE(CBB_init_fixed(cbb.get(), buf, sizeof(buf)));
@@ -1347,40 +1366,59 @@
   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()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
 
   // All future operations should fail.
   uint8_t *ptr;
   size_t len;
   EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
 
   // Write an input that cannot fit in a fixed CBB.
   cbb.Reset();
   uint8_t buf;
   ASSERT_TRUE(CBB_init_fixed(cbb.get(), &buf, 1));
   ASSERT_FALSE(CBB_add_bytes(cbb.get(), kZeros, sizeof(kZeros)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
 
   // All future operations should fail.
   EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
 
   // Write a u32 that cannot fit in a u24.
   cbb.Reset();
   ASSERT_TRUE(CBB_init(cbb.get(), 0));
   ASSERT_FALSE(CBB_add_u24(cbb.get(), 1u << 24));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
 
   // All future operations should fail.
   EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
 
   // Write a u64 that cannot fit in a u48.
   cbb.Reset();
   ASSERT_TRUE(CBB_init(cbb.get(), 0));
   ASSERT_FALSE(CBB_add_u48(cbb.get(), uint64_t{1} << 48));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_OVERFLOW}}));
 
   // All future operations should fail.
   EXPECT_FALSE(CBB_add_u8(cbb.get(), 0));
   EXPECT_FALSE(CBB_finish(cbb.get(), &ptr, &len));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
 }
 
 TEST(CBSTest, BitString) {
@@ -1745,6 +1783,8 @@
     ASSERT_TRUE(CBB_add_asn1(cbb.get(), &child, CBS_ASN1_SET));
     ASSERT_TRUE(CBB_add_bytes(&child, t.data(), t.size()));
     EXPECT_FALSE(CBB_flush_asn1_set_of(&child));
+    EXPECT_TRUE(ErrorsAreAndClear(
+        {{ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED}}));
   }
 }
 
diff --git a/crypto/conf/conf_test.cc b/crypto/conf/conf_test.cc
index c347fd6..81c2b63 100644
--- a/crypto/conf/conf_test.cc
+++ b/crypto/conf/conf_test.cc
@@ -22,12 +22,13 @@
 
 #include <gtest/gtest.h>
 
+#include "../test/test_util.h"
 #include "internal.h"
 
-
 BSSL_NAMESPACE_BEGIN
 namespace {
 
+
 // A `CONF` is an unordered list of sections, where each section contains an
 // ordered list of (name, value) pairs.
 using ConfModel =
@@ -436,6 +437,7 @@
     UniquePtr<CONF> conf(NCONF_new(nullptr));
     ASSERT_TRUE(conf);
     EXPECT_FALSE(NCONF_load_bio(conf.get(), bio.get(), nullptr));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_CONF, std::nullopt}}));
   }
 }
 
diff --git a/crypto/dh/dh_test.cc b/crypto/dh/dh_test.cc
index a7280ab..745d0f9 100644
--- a/crypto/dh/dh_test.cc
+++ b/crypto/dh/dh_test.cc
@@ -428,15 +428,20 @@
   auto check_invalid_group = [](DH *dh) {
     // All operations on egregiously invalid groups should fail.
     EXPECT_FALSE(DH_generate_key(dh));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DH, DH_R_INVALID_PARAMETERS}}));
     int check_result;
     EXPECT_FALSE(DH_check(dh, &check_result));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DH, DH_R_INVALID_PARAMETERS}}));
     UniquePtr<BIGNUM> pub_key(BN_new());
     ASSERT_TRUE(pub_key);
     ASSERT_TRUE(BN_set_u64(pub_key.get(), 42));
     EXPECT_FALSE(DH_check_pub_key(dh, pub_key.get(), &check_result));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DH, DH_R_INVALID_PARAMETERS}}));
     uint8_t buf[1024];
     EXPECT_EQ(DH_compute_key(buf, pub_key.get(), dh), -1);
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DH, DH_R_INVALID_PARAMETERS}}));
     EXPECT_EQ(DH_compute_key_padded(buf, pub_key.get(), dh), -1);
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DH, DH_R_INVALID_PARAMETERS}}));
   };
 
   UniquePtr<BIGNUM> p(BN_get_rfc3526_prime_2048(nullptr));
diff --git a/crypto/digest/digest_test.cc b/crypto/digest/digest_test.cc
index 0672fef..26737fd 100644
--- a/crypto/digest/digest_test.cc
+++ b/crypto/digest/digest_test.cc
@@ -283,6 +283,7 @@
   ScopedCBB cbb;
   ASSERT_TRUE(CBB_init(cbb.get(), 0));
   EXPECT_FALSE(EVP_marshal_digest_algorithm(cbb.get(), EVP_md5_sha1()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DIGEST, DIGEST_R_UNKNOWN_HASH}}));
 
   static const uint8_t kSHA256NullParam[] = {0x30, 0x0d, 0x06, 0x09, 0x60,
                                              0x86, 0x48, 0x01, 0x65, 0x03,
@@ -319,6 +320,7 @@
   // Garbage parameters are not.
   CBS_init(&cbs, kSHA256GarbageParam, sizeof(kSHA256GarbageParam));
   EXPECT_FALSE(EVP_parse_digest_algorithm(&cbs));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DIGEST, DIGEST_R_DECODE_ERROR}}));
 }
 
 TEST(DigestTest, TransformBlocks) {
diff --git a/crypto/dsa/dsa_test.cc b/crypto/dsa/dsa_test.cc
index dbe479f..1c3334f 100644
--- a/crypto/dsa/dsa_test.cc
+++ b/crypto/dsa/dsa_test.cc
@@ -197,6 +197,7 @@
       dsa.get(), 10001, /*seed=*/nullptr, /*seed_len=*/0,
       /*out_counter=*/nullptr, /*out_h=*/nullptr,
       /*cb=*/nullptr));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS}}));
 }
 
 TEST(DSATest, GenerateKeyTooLarge) {
@@ -212,6 +213,7 @@
 
   // Don't generate DSA keys if the group is too large.
   EXPECT_FALSE(DSA_generate_key(dsa.get()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE}}));
 }
 
 TEST(DSATest, Verify) {
@@ -223,11 +225,14 @@
   EXPECT_EQ(-1,
             DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_negative,
                        sizeof(fips_sig_negative), dsa.get()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, BN_R_NEGATIVE_NUMBER}}));
   EXPECT_EQ(-1, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_extra,
                            sizeof(fips_sig_extra), dsa.get()));
+  EXPECT_EQ(0u, ERR_peek_error());
   EXPECT_EQ(-1,
             DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_bad_length,
                        sizeof(fips_sig_bad_length), dsa.get()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DSA, DSA_R_DECODE_ERROR}}));
   EXPECT_EQ(0, DSA_verify(0, fips_digest, sizeof(fips_digest), fips_sig_bad_r,
                           sizeof(fips_sig_bad_r), dsa.get()));
 }
@@ -257,6 +262,7 @@
                                    fips_sig_negative, sizeof(fips_sig_negative),
                                    dsa.get()));
   EXPECT_EQ(0, valid);
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, BN_R_NEGATIVE_NUMBER}}));
 
   // Extra data (error)
   valid = 42;
@@ -264,6 +270,7 @@
                                    fips_sig_extra, sizeof(fips_sig_extra),
                                    dsa.get()));
   EXPECT_EQ(0, valid);
+  EXPECT_EQ(0u, ERR_peek_error());
 
   // Bad length (error)
   valid = 42;
@@ -271,6 +278,7 @@
                                    fips_sig_bad_length,
                                    sizeof(fips_sig_bad_length), dsa.get()));
   EXPECT_EQ(0, valid);
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_DSA, DSA_R_DECODE_ERROR}}));
 }
 
 TEST(DSATest, InvalidGroup) {
diff --git a/crypto/ecdsa/ecdsa_p1363_test.cc b/crypto/ecdsa/ecdsa_p1363_test.cc
index bdc753f..5c93a5d 100644
--- a/crypto/ecdsa/ecdsa_p1363_test.cc
+++ b/crypto/ecdsa/ecdsa_p1363_test.cc
@@ -22,10 +22,12 @@
 #include <openssl/ec.h>
 #include <openssl/ec_key.h>
 #include <openssl/ecdsa.h>
+#include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 
 #include "../test/file_test.h"
+#include "../test/test_util.h"
 #include "../test/wycheproof_util.h"
 
 
@@ -63,6 +65,9 @@
     int ret = ECDSA_verify_p1363(digest, digest_len, sig.data(), sig.size(),
                                  key.get());
     EXPECT_EQ(ret, result.IsValid() ? 1 : 0);
+    if (!result.IsValid()) {
+      ERR_clear_error();
+    }
   });
 }
 
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index 9464418..0342669 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -1680,9 +1680,11 @@
   ScopedCBB cbb;
   ASSERT_TRUE(CBB_init(cbb.get(), 0));
   EXPECT_FALSE(EVP_marshal_public_key(cbb.get(), pkey.get()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EC, EC_R_UNKNOWN_GROUP}}));
   cbb.Reset();
   ASSERT_TRUE(CBB_init(cbb.get(), 0));
   EXPECT_FALSE(EVP_marshal_private_key(cbb.get(), pkey.get()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EC, EC_R_UNKNOWN_GROUP}}));
 }
 
 // APIs should avoid creating an `EVP_PKEY` that is missing its underlying data.
@@ -1693,21 +1695,25 @@
   ASSERT_TRUE(pkey);
 
   EXPECT_FALSE(EVP_PKEY_set_type(pkey.get(), EVP_PKEY_RSA));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}}));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
   EXPECT_FALSE(EVP_PKEY_set1_RSA(pkey.get(), nullptr));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
 
   EXPECT_FALSE(EVP_PKEY_set_type(pkey.get(), EVP_PKEY_EC));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}}));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
   EXPECT_FALSE(EVP_PKEY_set1_EC_KEY(pkey.get(), nullptr));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
 
   EXPECT_FALSE(EVP_PKEY_set_type(pkey.get(), EVP_PKEY_DH));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}}));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
   EXPECT_FALSE(EVP_PKEY_set1_DH(pkey.get(), nullptr));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
 
   EXPECT_FALSE(EVP_PKEY_set_type(pkey.get(), EVP_PKEY_DSA));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}}));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
   EXPECT_FALSE(EVP_PKEY_set1_DSA(pkey.get(), nullptr));
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
diff --git a/crypto/evp/evp_test.cc b/crypto/evp/evp_test.cc
index 5d477b8..b310bc0 100644
--- a/crypto/evp/evp_test.cc
+++ b/crypto/evp/evp_test.cc
@@ -1307,6 +1307,7 @@
     } else if (!result) {
       ADD_FAILURE() << "Operation unexpectedly failed.";
     }
+    ERR_clear_error();
   });
 }
 
@@ -1417,6 +1418,9 @@
       int ret = EVP_DigestVerify(ctx.get(), sig.data(), sig.size(), msg.data(),
                                  msg.size());
       EXPECT_EQ(ret, expect_valid ? 1 : 0);
+      if (!expect_valid) {
+        ERR_clear_error();
+      }
     }
   });
 }
diff --git a/crypto/evp/scrypt_test.cc b/crypto/evp/scrypt_test.cc
index 13485ed..3aaed12 100644
--- a/crypto/evp/scrypt_test.cc
+++ b/crypto/evp/scrypt_test.cc
@@ -79,24 +79,31 @@
   // p and r are non-zero.
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 1024 /* N */, 0 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 1024 /* N */, 8 /* r */,
                               0 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
 
   // N must be a power of 2 > 1.
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 0 /* N */, 8 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 1 /* N */, 8 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 1023 /* N */, 8 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
   EXPECT_TRUE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 1024 /* N */, 8 /* r */,
-                              1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+                             1 /* p */, 0 /* max_mem */, key, sizeof(key)));
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 1025 /* N */, 8 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
 
   // N must be below 2^(128 * r / 8).
   EXPECT_FALSE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 65536 /* N */, 1 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PARAMETERS}}));
   EXPECT_TRUE(EVP_PBE_scrypt(nullptr, 0, nullptr, 0, 32768 /* N */, 1 /* r */,
                              1 /* p */, 0 /* max_mem */, key, sizeof(key)));
 }
diff --git a/crypto/fipsmodule/bn/bn_test.cc b/crypto/fipsmodule/bn/bn_test.cc
index 775c727..b83db5a 100644
--- a/crypto/fipsmodule/bn/bn_test.cc
+++ b/crypto/fipsmodule/bn/bn_test.cc
@@ -889,8 +889,10 @@
   if (!BN_is_one(gcd.get())) {
     EXPECT_FALSE(BN_mod_inverse(ret.get(), a.get(), b.get(), ctx))
         << "A^-1 (mod B) computed, but it does not exist";
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, std::nullopt}}));
     EXPECT_FALSE(BN_mod_inverse(ret.get(), b.get(), a.get(), ctx))
         << "B^-1 (mod A) computed, but it does not exist";
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, std::nullopt}}));
 
     if (!BN_is_zero(b.get())) {
       UniquePtr<BIGNUM> a_reduced(BN_new());
@@ -901,6 +903,7 @@
                                             a_reduced.get(), b.get(), ctx))
           << "A^-1 (mod B) computed, but it does not exist";
       EXPECT_TRUE(no_inverse);
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, std::nullopt}}));
     }
 
     if (!BN_is_zero(a.get())) {
@@ -912,6 +915,7 @@
                                             b_reduced.get(), a.get(), ctx))
           << "B^-1 (mod A) computed, but it does not exist";
       EXPECT_TRUE(no_inverse);
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, std::nullopt}}));
     }
   }
 
@@ -2740,7 +2744,9 @@
   // infinite loop. (For some invalid inputs, it may even be non-deterministic.)
   // See CVE-2022-0778.
   BN_free(BN_mod_sqrt(nullptr, bn2140141.get(), bn4588033.get(), ctx()));
+  ERR_clear_error();
   BN_free(BN_mod_sqrt(nullptr, bn2140142.get(), bn4588033.get(), ctx()));
+  ERR_clear_error();
 }
 
 // Test that constructing Montgomery contexts for large bignums is not possible.
@@ -2754,6 +2760,7 @@
   UniquePtr<BN_MONT_CTX> mont(
       BN_MONT_CTX_new_for_modulus(large_bignum.get(), ctx()));
   EXPECT_FALSE(mont);
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG}}));
 
   // The same limit should apply when `BN_mod_exp_mont_consttime` internally
   // constructs a `BN_MONT_CTX`.
@@ -2762,6 +2769,7 @@
   EXPECT_FALSE(BN_mod_exp_mont_consttime(r.get(), BN_value_one(),
                                          large_bignum.get(), large_bignum.get(),
                                          ctx(), nullptr));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG}}));
 }
 
 TEST_F(BNTest, FormatWord) {
diff --git a/crypto/hpke/hpke_test.cc b/crypto/hpke/hpke_test.cc
index fa922cb..5bc2361 100644
--- a/crypto/hpke/hpke_test.cc
+++ b/crypto/hpke/hpke_test.cc
@@ -503,17 +503,20 @@
           sender_ctx.get(), enc, &enc_len, sizeof(enc),
           EVP_hpke_x25519_hkdf_sha256(), kdf(), aead(), kSmallOrderPoint,
           sizeof(kSmallOrderPoint), nullptr, 0));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY}}));
 
       // Likewise with auth.
       EXPECT_FALSE(EVP_HPKE_CTX_setup_auth_sender(
           sender_ctx.get(), enc, &enc_len, sizeof(enc), key.get(), kdf(),
           aead(), kSmallOrderPoint, sizeof(kSmallOrderPoint), nullptr, 0));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY}}));
 
       // Set up the recipient, passing in kSmallOrderPoint as `enc`.
       ScopedEVP_HPKE_CTX recipient_ctx;
       EXPECT_FALSE(EVP_HPKE_CTX_setup_recipient(
           recipient_ctx.get(), key.get(), kdf(), aead(), kSmallOrderPoint,
           sizeof(kSmallOrderPoint), nullptr, 0));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY}}));
 
       // Likewise with auth. With auth, a small-order point could appear as
       // either `enc` or the peer public key.
@@ -521,10 +524,12 @@
           recipient_ctx.get(), key.get(), kdf(), aead(), kSmallOrderPoint,
           sizeof(kSmallOrderPoint), nullptr, 0, kValidPoint,
           sizeof(kValidPoint)));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY}}));
       EXPECT_FALSE(EVP_HPKE_CTX_setup_auth_recipient(
           recipient_ctx.get(), key.get(), kdf(), aead(), kValidPoint,
           sizeof(kValidPoint), nullptr, 0, kSmallOrderPoint,
           sizeof(kSmallOrderPoint)));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY}}));
     }
   }
 }
diff --git a/crypto/rsa/rsa_test.cc b/crypto/rsa/rsa_test.cc
index 2172c83..79dc740 100644
--- a/crypto/rsa/rsa_test.cc
+++ b/crypto/rsa/rsa_test.cc
@@ -1479,10 +1479,15 @@
   // TODO(crbug.com/42290480): Raise the lower bound. 512-bit RSA was factored
   // in 1999.
   EXPECT_FALSE(generate_key(511u));
-  EXPECT_TRUE(
-      ErrorEquals(ERR_get_error(), ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL}}));
   EXPECT_FALSE(read_private_key("crypto/rsa/test/rsa511.pem"));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_DECODE_ERROR}}));
   EXPECT_FALSE(read_public_key("crypto/rsa/test/rsa511pub.pem"));
+  EXPECT_TRUE(ErrorsAreAndClear({
+      {ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL},
+      {ERR_LIB_RSA, RSA_R_BAD_RSA_PARAMETERS},
+      {ERR_LIB_RSA, RSA_R_BAD_ENCODING},
+  }));
 
   UniquePtr<RSA> rsa = read_private_key("crypto/rsa/test/rsa512.pem");
   ASSERT_TRUE(rsa);
@@ -1517,8 +1522,15 @@
   EXPECT_EQ(RSA_bits(rsa.get()), 16384u);
 
   EXPECT_FALSE(read_private_key("crypto/rsa/test/rsa16385.pem"));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_EVP, EVP_R_DECODE_ERROR}}));
   EXPECT_FALSE(read_public_key("crypto/rsa/test/rsa16385pub.pem"));
+  EXPECT_TRUE(ErrorsAreAndClear({
+      {ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE},
+      {ERR_LIB_RSA, RSA_R_BAD_RSA_PARAMETERS},
+      {ERR_LIB_RSA, RSA_R_BAD_ENCODING},
+  }));
   EXPECT_FALSE(generate_key(16385u));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE}}));
 }
 
 #if defined(OPENSSL_THREADS)
diff --git a/crypto/x509/x509_extension_test.cc b/crypto/x509/x509_extension_test.cc
index 7ca4db4..cb870cb 100644
--- a/crypto/x509/x509_extension_test.cc
+++ b/crypto/x509/x509_extension_test.cc
@@ -262,6 +262,7 @@
     const uint8_t *p = in.data();
     EXPECT_FALSE(UniquePtr<CERTIFICATEPOLICIES>(
         d2i_CERTIFICATEPOLICIES(nullptr, &p, in.size())));
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, std::nullopt}}));
   }
 }
 
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index e5d64a9..4b571d3 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -2576,6 +2576,7 @@
     UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert.get()));
     ASSERT_TRUE(pkey);
     EXPECT_FALSE(X509_verify(cert.get(), pkey.get()));
+    EXPECT_TRUE(ErrorsAreAndClear({{std::nullopt, std::nullopt}}));
   }
 }
 
@@ -3811,11 +3812,13 @@
   UniquePtr<STACK_OF(X509_INFO)> infos2(
       PEM_X509_INFO_read_bio(bio.get(), nullptr, nullptr, nullptr));
   EXPECT_FALSE(infos2);
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
 
   bio.reset(BIO_new_mem_buf(bad_pem.data(), bad_pem.size()));
   ASSERT_TRUE(bio);
   EXPECT_FALSE(
       PEM_X509_INFO_read_bio(bio.get(), infos.get(), nullptr, nullptr));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_EQ(2 * std::size(kExpected), sk_X509_INFO_num(infos.get()));
 }
 
@@ -4427,17 +4430,30 @@
   // https://crbug.com/42290225.
   EXPECT_TRUE(CertFromPEM(kExplicitDefaultVersionPEM));
   EXPECT_FALSE(CRLFromPEM(kExplicitDefaultVersionCRLPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(CertFromPEM(kNegativeVersionPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_FALSE(CertFromPEM(kFutureVersionPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(CertFromPEM(kOverflowVersionPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_FALSE(CertFromPEM(kV1WithExtensionsPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_FALSE(CertFromPEM(kV2WithExtensionsPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_FALSE(CertFromPEM(kV1WithIssuerUniqueIDPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_FALSE(CertFromPEM(kV1WithSubjectUniqueIDPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
   EXPECT_FALSE(CRLFromPEM(kV1CRLWithExtensionsPEM));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_FIELD_FOR_VERSION}}));
   EXPECT_FALSE(CRLFromPEM(kV1CRLWithEntryExtensionsPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(CRLFromPEM(kV3CRLPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(CSRFromPEM(kV2CSRPEM));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
 
   // kV3CSRPEM is invalid but, for now, we accept it. See
   // https://github.com/certbot/certbot/pull/9334
@@ -4446,14 +4462,20 @@
   UniquePtr<X509> x509(X509_new());
   ASSERT_TRUE(x509);
   EXPECT_FALSE(X509_set_version(x509.get(), -1));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(X509_set_version(x509.get(), X509_VERSION_3 + 1));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(X509_set_version(x509.get(), 9999));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
 
   UniquePtr<X509_CRL> crl(X509_CRL_new());
   ASSERT_TRUE(crl);
   EXPECT_FALSE(X509_CRL_set_version(crl.get(), -1));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(X509_CRL_set_version(crl.get(), X509_CRL_VERSION_2 + 1));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
   EXPECT_FALSE(X509_CRL_set_version(crl.get(), 9999));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_INVALID_VERSION}}));
 
   UniquePtr<X509_REQ> req(X509_REQ_new());
   ASSERT_TRUE(req);
@@ -4960,6 +4982,7 @@
       // `X509_ATTRIBUTE_get0_data` requires the type match.
       EXPECT_FALSE(
           X509_ATTRIBUTE_get0_data(attr, idx, V_ASN1_OCTET_STRING, nullptr));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_WRONG_TYPE}}));
       const ASN1_BMPSTRING *bmpstring = static_cast<const ASN1_BMPSTRING *>(
           X509_ATTRIBUTE_get0_data(attr, idx, V_ASN1_BMPSTRING, nullptr));
       ASSERT_TRUE(bmpstring);
@@ -5896,6 +5919,9 @@
       SCOPED_TRACE(dns);
       EXPECT_EQ(0, X509_check_host(cert.get(), dns.data(), dns.size(), t.flags,
                                    /*peername=*/nullptr));
+      if (t.cert_invalid_subject_alt_name) {
+        EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}}));
+      }
       EXPECT_EQ(t.cert_invalid_subject_alt_name ? X509_V_ERR_INVALID_EXTENSION
                                                 : X509_V_ERR_HOSTNAME_MISMATCH,
                 Verify(cert.get(), {root.get()}, /*intermediates=*/{},
@@ -6423,6 +6449,7 @@
   EXPECT_EQ(
       0, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic2_obj.get(),
                            /*crit=*/0, X509V3_ADD_DEFAULT));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509V3, X509V3_R_EXTENSION_EXISTS}}));
   expect_extensions({{NID_basic_constraints, true, basic1_der},
                      {NID_subject_key_identifier, false, skid1_der}});
 
@@ -6456,12 +6483,16 @@
   // Not finding an extension to delete is an error.
   EXPECT_EQ(0, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, nullptr, 0,
                                  X509V3_ADD_DELETE));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND}}));
   expect_extensions({{NID_subject_key_identifier, true, skid2_der}});
 
   // `X509V3_ADD_REPLACE_EXISTING` fails if it cannot find a match.
   EXPECT_EQ(
       0, X509_add1_ext_i2d(x509.get(), NID_basic_constraints, basic1_obj.get(),
                            /*crit=*/1, X509V3_ADD_REPLACE_EXISTING));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND}}));
   expect_extensions({{NID_subject_key_identifier, true, skid2_der}});
 
   // `X509V3_ADD_REPLACE` adds a new extension if not present.
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index b1a8941..03b67f1 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -614,6 +614,7 @@
     // Test strict mode.
     if (t.strict_fail) {
       EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
+      EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_INVALID_COMMAND}}));
     } else {
       ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
       EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
@@ -2708,6 +2709,8 @@
   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
                                 ech_config.data(), ech_config.size(),
                                 key.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG}}));
 
   // Invalid public names are rejected.
   ECHConfigParams invalid_public_name;
@@ -3088,9 +3091,11 @@
   EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
                                           buffer.size(), label, strlen(label),
                                           nullptr, 0, 0));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_HANDSHAKE_NOT_COMPLETE}}));
   EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(),
                                           buffer.size(), label, strlen(label),
                                           nullptr, 0, 0));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_HANDSHAKE_NOT_COMPLETE}}));
 
   // Send the client's first flight of handshake messages.
   int client_ret = SSL_do_handshake(client.get());
@@ -5512,17 +5517,24 @@
 
   // There is no key or certificate, so `SSL_CTX_check_private_key` fails.
   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}}));
 
   // With only a certificate, `SSL_CTX_check_private_key` still fails.
   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}}));
 
   // The private key does not match the certificate, so it should fail.
   EXPECT_FALSE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
+  EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH}}));
 
   // Checking the private key fails, but this is really because there is still
   // no private key.
   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}}));
   EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
 }
 
@@ -5537,10 +5549,14 @@
 
   // There is no key or certificate, so `SSL_CTX_check_private_key` fails.
   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}}));
 
   // With only a key, `SSL_CTX_check_private_key` still fails.
   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED}}));
 
   // If configuring a certificate that doesn't match the key, configuration
   // actually succeeds. We just silently drop the private key.
@@ -5552,6 +5568,8 @@
   // by way of noticing there is no private key. The actual consistency check
   // happened in `SSL_CTX_use_certificate`.
   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
+  EXPECT_TRUE(
+      ErrorsAreAndClear({{ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}}));
 }
 
 TEST(SSLTest, OverrideCertAndKey) {
@@ -11146,16 +11164,22 @@
   Span<const uint8_t> client_read, client_write, server_read, server_write;
   bool client_ok =
       SSL_get_traffic_secrets(client_.get(), &client_read, &client_write);
-  bool server_ok =
-      SSL_get_traffic_secrets(server_.get(), &server_read, &server_write);
   if (!is_dtls() && version() >= TLS1_3_VERSION) {
+    bool server_ok =
+        SSL_get_traffic_secrets(server_.get(), &server_read, &server_write);
     ASSERT_TRUE(client_ok);
     ASSERT_TRUE(server_ok);
     EXPECT_EQ(Bytes(client_read), Bytes(server_write));
     EXPECT_EQ(Bytes(server_read), Bytes(client_write));
   } else {
     EXPECT_FALSE(client_ok);
+    int expected_reason =
+        is_dtls() ? ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED : SSL_R_WRONG_SSL_VERSION;
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_SSL, expected_reason}}));
+    bool server_ok =
+        SSL_get_traffic_secrets(server_.get(), &server_read, &server_write);
     EXPECT_FALSE(server_ok);
+    EXPECT_TRUE(ErrorsAreAndClear({{ERR_LIB_SSL, expected_reason}}));
   }
 }