Introduce a test helper for asserting on the error

This produces slightly nicer output, is less code, and helps us remember
to check both the library and reason code.

Change-Id: Ic49508accb0bc8a25cbb5b94cc7e4aeb1bd8cbd0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66507
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/bio/bio_test.cc b/crypto/bio/bio_test.cc
index 65324d0..d44c9dd 100644
--- a/crypto/bio/bio_test.cc
+++ b/crypto/bio/bio_test.cc
@@ -813,10 +813,7 @@
   // A closed write end may not be written to.
   EXPECT_EQ(0u, BIO_ctrl_get_write_guarantee(bio1));
   EXPECT_EQ(-1, BIO_write(bio1, "_____", 5));
-
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_BIO, ERR_GET_LIB(err));
-  EXPECT_EQ(BIO_R_BROKEN_PIPE, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_BIO, BIO_R_BROKEN_PIPE));
 
   // The other end is still functional.
   EXPECT_EQ(5, BIO_write(bio2, "12345", 5));
diff --git a/crypto/cipher_extra/aead_test.cc b/crypto/cipher_extra/aead_test.cc
index 64c65e9..e16f5a2 100644
--- a/crypto/cipher_extra/aead_test.cc
+++ b/crypto/cipher_extra/aead_test.cc
@@ -381,7 +381,7 @@
 
     // Skip decryption for AEADs that don't implement open_gather().
     if (!ret) {
-      int err = ERR_peek_error();
+      uint32_t err = ERR_peek_error();
       if (ERR_GET_LIB(err) == ERR_LIB_CIPHER &&
           ERR_GET_REASON(err) == CIPHER_R_CTRL_NOT_IMPLEMENTED) {
           t->SkipCurrent();
@@ -709,10 +709,10 @@
                                    nonce.data(), nonce.size(), nullptr /* in */,
                                    0, kZeros /* ad */, ad_len));
     uint32_t err = ERR_get_error();
-    EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
     // TODO(davidben): Merge these errors. https://crbug.com/boringssl/129.
-    if (ERR_GET_REASON(err) != CIPHER_R_UNSUPPORTED_NONCE_SIZE) {
-      EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+    if (!ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE)) {
+      EXPECT_TRUE(
+          ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_INVALID_NONCE_SIZE));
     }
 
     ctx.Reset();
@@ -723,9 +723,9 @@
                                    nonce.data(), nonce.size(), kZeros /* in */,
                                    sizeof(kZeros), kZeros /* ad */, ad_len));
     err = ERR_get_error();
-    EXPECT_EQ(ERR_LIB_CIPHER, ERR_GET_LIB(err));
-    if (ERR_GET_REASON(err) != CIPHER_R_UNSUPPORTED_NONCE_SIZE) {
-      EXPECT_EQ(CIPHER_R_INVALID_NONCE_SIZE, ERR_GET_REASON(err));
+    if (!ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE)) {
+      EXPECT_TRUE(
+          ErrorEquals(err, ERR_LIB_CIPHER, CIPHER_R_INVALID_NONCE_SIZE));
     }
   }
 }
diff --git a/crypto/dsa/dsa_test.cc b/crypto/dsa/dsa_test.cc
index 22e9e13..3b83e18 100644
--- a/crypto/dsa/dsa_test.cc
+++ b/crypto/dsa/dsa_test.cc
@@ -267,9 +267,8 @@
   static const uint8_t kDigest[32] = {0};
   EXPECT_FALSE(
       DSA_sign(0, kDigest, sizeof(kDigest), sig.data(), &sig_len, dsa.get()));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_DSA, ERR_GET_LIB(err));
-  EXPECT_EQ(DSA_R_INVALID_PARAMETERS, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS));
 }
 
 // Signing and verifying should cleanly fail when the DSA object is empty.
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index 948bfb5..6468386 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -812,7 +812,8 @@
   bssl::ScopedCBB cbb;
   EXPECT_FALSE(EVP_marshal_public_key(cbb.get(), empty.get()))
       << "Marshalled empty public key.";
-  EXPECT_EQ(EVP_R_UNSUPPORTED_ALGORITHM, ERR_GET_REASON(ERR_peek_last_error()));
+  EXPECT_TRUE(ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP,
+                          EVP_R_UNSUPPORTED_ALGORITHM));
 }
 
 TEST(EVPExtraTest, d2i_PrivateKey) {
@@ -890,16 +891,14 @@
   // Passing too small of a buffer is noticed.
   len = 31;
   EXPECT_FALSE(EVP_PKEY_get_raw_public_key(pubkey.get(), buf, &len));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_BUFFER_TOO_SMALL, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL));
   ERR_clear_error();
 
   // There is no private key.
   EXPECT_FALSE(EVP_PKEY_get_raw_private_key(pubkey.get(), nullptr, &len));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_NOT_A_PRIVATE_KEY, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_NOT_A_PRIVATE_KEY));
   ERR_clear_error();
 
   // The public key must encode properly.
@@ -915,9 +914,8 @@
   // The public key must gracefully fail to encode as a private key.
   ASSERT_TRUE(CBB_init(cbb.get(), 0));
   EXPECT_FALSE(EVP_marshal_private_key(cbb.get(), pubkey.get()));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_NOT_A_PRIVATE_KEY, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_NOT_A_PRIVATE_KEY));
   ERR_clear_error();
   cbb.Reset();
 
@@ -940,9 +938,8 @@
   // Passing too small of a buffer is noticed.
   len = 31;
   EXPECT_FALSE(EVP_PKEY_get_raw_private_key(privkey.get(), buf, &len));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_BUFFER_TOO_SMALL, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL));
   ERR_clear_error();
   // The public key must be extractable.
   len = 32;
@@ -995,9 +992,8 @@
       EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, privkey.get()));
   len = 31;
   EXPECT_FALSE(EVP_DigestSign(ctx.get(), buf, &len, nullptr /* msg */, 0));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_BUFFER_TOO_SMALL, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL));
   ERR_clear_error();
 }
 
diff --git a/crypto/evp/scrypt_test.cc b/crypto/evp/scrypt_test.cc
index e957fd0..5a88386 100644
--- a/crypto/evp/scrypt_test.cc
+++ b/crypto/evp/scrypt_test.cc
@@ -69,9 +69,8 @@
                               reinterpret_cast<const uint8_t *>(kSalt),
                               strlen(kSalt), 1048576 /* N */, 8 /* r */,
                               1 /* p */, 0 /* max_mem */, key, sizeof(key)));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_MEMORY_LIMIT_EXCEEDED, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_MEMORY_LIMIT_EXCEEDED));
 }
 
 TEST(ScryptTest, InvalidParameters) {
diff --git a/crypto/fipsmodule/bn/bn_test.cc b/crypto/fipsmodule/bn/bn_test.cc
index d62f6e4..fcc59e0 100644
--- a/crypto/fipsmodule/bn/bn_test.cc
+++ b/crypto/fipsmodule/bn/bn_test.cc
@@ -884,9 +884,7 @@
   EXPECT_FALSE(BN_mod_sqrt(ret.get(), not_mod_square.get(), p.get(), ctx))
       << "BN_mod_sqrt unexpectedly succeeded.";
 
-  uint32_t err = ERR_peek_error();
-  EXPECT_EQ(ERR_LIB_BN, ERR_GET_LIB(err));
-  EXPECT_EQ(BN_R_NOT_A_SQUARE, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_peek_error(), ERR_LIB_BN, BN_R_NOT_A_SQUARE));
   ERR_clear_error();
 }
 
diff --git a/crypto/fipsmodule/service_indicator/service_indicator_test.cc b/crypto/fipsmodule/service_indicator/service_indicator_test.cc
index ee66fc3..9eac62e 100644
--- a/crypto/fipsmodule/service_indicator/service_indicator_test.cc
+++ b/crypto/fipsmodule/service_indicator/service_indicator_test.cc
@@ -657,7 +657,8 @@
                           encrypt_output.size(), nonce.data(), nonce.size(),
                           kPlaintext, sizeof(kPlaintext), nullptr, 0)));
     EXPECT_EQ(approved, FIPSStatus::NOT_APPROVED);
-    EXPECT_EQ(ERR_GET_REASON(ERR_get_error()), CIPHER_R_INVALID_NONCE);
+    EXPECT_TRUE(
+        ErrorEquals(ERR_get_error(), ERR_LIB_CIPHER, CIPHER_R_INVALID_NONCE));
   }
 }
 
diff --git a/crypto/hpke/hpke_test.cc b/crypto/hpke/hpke_test.cc
index 30593f9..ce68adc 100644
--- a/crypto/hpke/hpke_test.cc
+++ b/crypto/hpke/hpke_test.cc
@@ -554,9 +554,8 @@
       sender_ctx.get(), enc, &enc_len, sizeof(enc),
       EVP_hpke_x25519_hkdf_sha256(), EVP_hpke_hkdf_sha256(),
       EVP_hpke_aes_128_gcm(), public_key_r, sizeof(public_key_r), nullptr, 0));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_INVALID_BUFFER_SIZE, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_BUFFER_SIZE));
   ERR_clear_error();
 }
 
@@ -587,9 +586,8 @@
   ASSERT_FALSE(EVP_HPKE_CTX_setup_recipient(
       recipient_ctx.get(), key.get(), EVP_hpke_hkdf_sha256(),
       EVP_hpke_aes_128_gcm(), bogus_enc, sizeof(bogus_enc), nullptr, 0));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY));
   ERR_clear_error();
 }
 
@@ -603,9 +601,8 @@
       EVP_hpke_x25519_hkdf_sha256(), EVP_hpke_hkdf_sha256(),
       EVP_hpke_aes_128_gcm(), bogus_public_key_r, sizeof(bogus_public_key_r),
       nullptr, 0));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_EVP, ERR_GET_LIB(err));
-  EXPECT_EQ(EVP_R_INVALID_PEER_KEY, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_EVP, EVP_R_INVALID_PEER_KEY));
   ERR_clear_error();
 }
 
diff --git a/crypto/pem/pem_test.cc b/crypto/pem/pem_test.cc
index aed523c..117e000 100644
--- a/crypto/pem/pem_test.cc
+++ b/crypto/pem/pem_test.cc
@@ -20,6 +20,8 @@
 #include <openssl/err.h>
 #include <openssl/rsa.h>
 
+#include "../test/test_util.h"
+
 
 // Test that implausible ciphers, notably an IV-less RC4, aren't allowed in PEM.
 // This is a regression test for https://github.com/openssl/openssl/issues/6347,
@@ -39,7 +41,6 @@
   bssl::UniquePtr<RSA> rsa(PEM_read_bio_RSAPublicKey(
       bio.get(), nullptr, nullptr, const_cast<char *>("password")));
   EXPECT_FALSE(rsa);
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_PEM, ERR_GET_LIB(err));
-  EXPECT_EQ(PEM_R_UNSUPPORTED_ENCRYPTION, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_PEM, PEM_R_UNSUPPORTED_ENCRYPTION));
 }
diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc
index 4d34fc9..82c5aa9 100644
--- a/crypto/rsa_extra/rsa_test.cc
+++ b/crypto/rsa_extra/rsa_test.cc
@@ -712,9 +712,8 @@
   ASSERT_TRUE(BN_set_word(e.get(), RSA_F4));
 
   EXPECT_FALSE(RSA_generate_key_ex(rsa.get(), 255, e.get(), nullptr));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err));
-  EXPECT_EQ(RSA_R_KEY_SIZE_TOO_SMALL, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL));
 }
 
 // Attempting to generate an funny RSA key length should round down.
@@ -1175,17 +1174,13 @@
   std::vector<uint8_t> out(RSA_size(sample.get()));
   EXPECT_FALSE(RSA_sign(NID_sha256, kZeros, sizeof(kZeros), out.data(), &len_u,
                         rsa.get()));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err));
-  EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_RSA, RSA_R_VALUE_MISSING));
 
   size_t len;
   EXPECT_FALSE(RSA_decrypt(rsa.get(), &len, out.data(), out.size(),
                            kOAEPCiphertext1, sizeof(kOAEPCiphertext1),
                            RSA_PKCS1_OAEP_PADDING));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err));
-  EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_RSA, RSA_R_VALUE_MISSING));
 
   // A private key without e cannot perform public key operations.
   rsa.reset(RSA_new_private_key_no_e(RSA_get0_n(sample.get()),
@@ -1194,15 +1189,11 @@
 
   EXPECT_FALSE(RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig.data(),
                           sig.size(), rsa.get()));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err));
-  EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_RSA, RSA_R_VALUE_MISSING));
 
   EXPECT_FALSE(RSA_encrypt(rsa.get(), &len, out.data(), out.size(), kPlaintext,
                            sizeof(kPlaintext), RSA_PKCS1_OAEP_PADDING));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err));
-  EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_RSA, RSA_R_VALUE_MISSING));
 }
 
 TEST(RSATest, Negative) {
diff --git a/crypto/test/test_util.cc b/crypto/test/test_util.cc
index 23e8909..6f56476 100644
--- a/crypto/test/test_util.cc
+++ b/crypto/test/test_util.cc
@@ -16,6 +16,8 @@
 
 #include <ostream>
 
+#include <openssl/err.h>
+
 #include "../internal.h"
 
 
@@ -67,3 +69,16 @@
   return ret;
 }
 
+testing::AssertionResult ErrorEquals(uint32_t err, int lib, int reason) {
+  if (ERR_GET_LIB(err) == lib && ERR_GET_REASON(err) == reason) {
+    return testing::AssertionSuccess();
+  }
+
+  char buf[128], expected[128];
+  return testing::AssertionFailure()
+         << "Got \"" << ERR_error_string_n(err, buf, sizeof(buf))
+         << "\", wanted \""
+         << ERR_error_string_n(ERR_PACK(lib, reason), expected,
+                               sizeof(expected))
+         << "\"";
+}
diff --git a/crypto/test/test_util.h b/crypto/test/test_util.h
index 796c931..fff6cdb 100644
--- a/crypto/test/test_util.h
+++ b/crypto/test/test_util.h
@@ -24,6 +24,8 @@
 #include <string>
 #include <vector>
 
+#include <gtest/gtest.h>
+
 #include <openssl/span.h>
 
 #include "../internal.h"
@@ -67,5 +69,9 @@
 // EncodeHex returns |in| encoded in hexadecimal.
 std::string EncodeHex(bssl::Span<const uint8_t> in);
 
+// ErrorEquals asserts that |err| is an error with library |lib| and reason
+// |reason|.
+testing::AssertionResult ErrorEquals(uint32_t err, int lib, int reason);
+
 
 #endif  // OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index b25e8b3..8b20ade 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -2062,9 +2062,8 @@
 
   ASSERT_FALSE(X509_verify(cert.get(), pkey.get()));
 
-  uint32_t err = ERR_get_error();
-  ASSERT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
-  ASSERT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER));
   ERR_clear_error();
 }
 
@@ -2909,9 +2908,8 @@
   ASSERT_TRUE(pkey);
 
   EXPECT_FALSE(X509_verify(cert.get(), pkey.get()));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
-  EXPECT_EQ(X509_R_SIGNATURE_ALGORITHM_MISMATCH, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_X509,
+                          X509_R_SIGNATURE_ALGORITHM_MISMATCH));
 }
 
 TEST(X509Test, PEMX509Info) {
@@ -3044,9 +3042,8 @@
   // certificates.
   bssl::UniquePtr<X509> x509(d2i_X509_bio(bio.get(), nullptr));
   EXPECT_FALSE(x509);
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_ASN1, ERR_GET_LIB(err));
-  EXPECT_EQ(ASN1_R_HEADER_TOO_LONG, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG));
 }
 
 TEST(X509Test, ReadBIOOneByte) {
@@ -3058,9 +3055,8 @@
   // to signal EOF.
   bssl::UniquePtr<X509> x509(d2i_X509_bio(bio.get(), nullptr));
   EXPECT_FALSE(x509);
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_ASN1, ERR_GET_LIB(err));
-  EXPECT_EQ(ASN1_R_NOT_ENOUGH_DATA, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA));
 }
 
 TEST(X509Test, PartialBIOReturn) {
@@ -3773,9 +3769,8 @@
   cert = CertFromPEM(kP256InvalidParam);
   ASSERT_TRUE(cert);
   EXPECT_FALSE(X509_verify(cert.get(), key.get()));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
-  EXPECT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER));
 
   // RSA parameters should be NULL, but we accept omitted ones.
   key = PrivateKeyFromPEM(kRSAKey);
@@ -3792,9 +3787,8 @@
   cert = CertFromPEM(kRSAInvalidParam);
   ASSERT_TRUE(cert);
   EXPECT_FALSE(X509_verify(cert.get(), key.get()));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
-  EXPECT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_X509, X509_R_INVALID_PARAMETER));
 }
 
 TEST(X509Test, GeneralName)  {
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index d12d49c..d7953e5 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -3021,9 +3021,8 @@
   // The client processes the ServerHello and fails.
   EXPECT_EQ(-1, SSL_do_handshake(client.get()));
   EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
-  EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_SSL,
+                          SSL_R_WRONG_VERSION_ON_EARLY_DATA));
 
   // The client should have written an alert to the transport.
   const uint8_t *unused;
@@ -3035,9 +3034,8 @@
   // Writing should fail, with the same error as the handshake.
   EXPECT_EQ(-1, SSL_write(client.get(), "a", 1));
   EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
-  err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
-  EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
+  EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_SSL,
+                          SSL_R_WRONG_VERSION_ON_EARLY_DATA));
 
   // Nothing should be written to the transport.
   ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
@@ -5190,9 +5188,8 @@
   int ret = SSL_do_handshake(ssl.get());
   EXPECT_EQ(-1, ret);
   EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
-  EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_NO_CIPHERS_AVAILABLE));
 }
 
 TEST_P(SSLVersionTest, SessionVersion) {
@@ -7177,9 +7174,8 @@
   // EncryptedExtensions on key change.
   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
   ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
-  EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_EXCESS_HANDSHAKE_DATA));
 
   // The client sends an alert in response to this. The alert is sent at
   // handshake level because we install write secrets before read secrets and
@@ -7628,9 +7624,8 @@
       // The client handshake should terminate on a certificate verification
       // error.
       EXPECT_EQ(SSL_ERROR_SSL, client_err);
-      uint32_t err = ERR_peek_error();
-      EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
-      EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
+      EXPECT_TRUE(ErrorEquals(ERR_peek_error(), ERR_LIB_SSL,
+                              SSL_R_CERTIFICATE_VERIFY_FAILED));
       break;
     }
 
@@ -7906,9 +7901,8 @@
   // We never renegotiate as a server.
   ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
   ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
-  uint32_t err = ERR_get_error();
-  EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
-  EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
+  EXPECT_TRUE(
+      ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION));
 }
 
 TEST(SSLTest, ConnectionPropertiesDuringRenegotiate) {