Bug 1077859: Make ENCODING_FAILED safe to use in static initializers, r=mmc
☠☠ backed out by 8847ac2e2a53 ☠ ☠
authorBrian Smith <brian@briansmith.org>
Fri, 03 Oct 2014 15:52:38 -0700
changeset 209123 76000f9f12dac768085ef3370c4717bb4178cf11
parent 209091 f65726bd726555bd7cab954c3347931f4c9d4c00
child 209124 16fe1b9eb9e6f66d787cbcc72cdfa5328f08f6fa
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmmc
bugs1077859
milestone35.0a1
Bug 1077859: Make ENCODING_FAILED safe to use in static initializers, r=mmc
security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
security/pkix/test/gtest/pkixbuild_tests.cpp
security/pkix/test/gtest/pkixcert_extension_tests.cpp
security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp
security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
security/pkix/test/lib/pkixtestnss.cpp
security/pkix/test/lib/pkixtestutil.cpp
security/pkix/test/lib/pkixtestutil.h
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
@@ -194,17 +194,17 @@ GetOCSPResponseForType(OCSPResponseType 
   }
   context.signerKeyPair = CreateTestKeyPairFromCert(*signerCert);
   if (!context.signerKeyPair) {
     PrintPRError("PK11_FindKeyByAnyCert failed");
     return nullptr;
   }
 
   ByteString response(CreateEncodedOCSPResponse(context));
-  if (response == ENCODING_FAILED) {
+  if (ENCODING_FAILED(response)) {
     PrintPRError("CreateEncodedOCSPResponse failed");
     return nullptr;
   }
 
   SECItem item = {
     siBuffer,
     const_cast<uint8_t*>(response.data()),
     static_cast<unsigned int>(response.length())
--- a/security/pkix/test/gtest/pkixbuild_tests.cpp
+++ b/security/pkix/test/gtest/pkixbuild_tests.cpp
@@ -42,39 +42,37 @@ CreateCert(const char* issuerCN,
            EndEntityOrCA endEntityOrCA,
            /*optional*/ TestKeyPair* issuerKey,
            /*out*/ ScopedTestKeyPair& subjectKey,
            /*out*/ ScopedCERTCertificate* subjectCert = nullptr)
 {
   static long serialNumberValue = 0;
   ++serialNumberValue;
   ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue));
-  EXPECT_NE(ENCODING_FAILED, serialNumber);
+  EXPECT_FALSE(ENCODING_FAILED(serialNumber));
 
   ByteString issuerDER(CNToDERName(issuerCN));
-  EXPECT_NE(ENCODING_FAILED, issuerDER);
   ByteString subjectDER(CNToDERName(subjectCN));
-  EXPECT_NE(ENCODING_FAILED, subjectDER);
 
   ByteString extensions[2];
   if (endEntityOrCA == EndEntityOrCA::MustBeCA) {
     extensions[0] =
       CreateEncodedBasicConstraints(true, nullptr,
                                     ExtensionCriticality::Critical);
-    EXPECT_NE(ENCODING_FAILED, extensions[0]);
+    EXPECT_FALSE(ENCODING_FAILED(extensions[0]));
   }
 
   ByteString certDER(CreateEncodedCertificate(
                        v3, sha256WithRSAEncryption,
                        serialNumber, issuerDER,
                        oneDayBeforeNow, oneDayAfterNow,
                        subjectDER, extensions, issuerKey,
                        SignatureAlgorithm::rsa_pkcs1_with_sha256,
                        subjectKey));
-  EXPECT_NE(ENCODING_FAILED, certDER);
+  EXPECT_FALSE(ENCODING_FAILED(certDER));
   if (subjectCert) {
     SECItem certDERItem = {
       siBuffer,
       const_cast<uint8_t*>(certDER.data()),
       static_cast<unsigned int>(certDER.length())
     };
     *subjectCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                            &certDERItem, nullptr, false, true);
@@ -240,17 +238,17 @@ TEST_F(pkixbuild, MaxAcceptableCertChain
   }
 
   {
     ScopedTestKeyPair unusedKeyPair;
     ScopedCERTCertificate cert;
     ByteString certDER(CreateCert("CA7", "Direct End-Entity",
                                   EndEntityOrCA::MustBeEndEntity,
                                   trustDomain.leafCAKey.get(), unusedKeyPair));
-    ASSERT_NE(ENCODING_FAILED, certDER);
+    ASSERT_FALSE(ENCODING_FAILED(certDER));
     Input certDERInput;
     ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length()));
     ASSERT_EQ(Success,
               BuildCertChain(trustDomain, certDERInput, Now(),
                              EndEntityOrCA::MustBeEndEntity,
                              KeyUsage::noParticularKeyUsageRequired,
                              KeyPurposeId::id_kp_serverAuth,
                              CertPolicyId::anyPolicy,
@@ -266,34 +264,34 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCer
   // We need a CERTCertificate for caCert so that the trustdomain's FindIssuer
   // method can find it through the NSS cert DB.
   ScopedCERTCertificate caCert;
 
   {
     ByteString certDER(CreateCert("CA7", caCertName, EndEntityOrCA::MustBeCA,
                                   trustDomain.leafCAKey.get(), caKeyPair,
                                   &caCert));
-    ASSERT_NE(ENCODING_FAILED, certDER);
+    ASSERT_FALSE(ENCODING_FAILED(certDER));
     Input certDERInput;
     ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length()));
     ASSERT_EQ(Result::ERROR_UNKNOWN_ISSUER,
               BuildCertChain(trustDomain, certDERInput, Now(),
                              EndEntityOrCA::MustBeCA,
                              KeyUsage::noParticularKeyUsageRequired,
                              KeyPurposeId::id_kp_serverAuth,
                              CertPolicyId::anyPolicy,
                              nullptr/*stapledOCSPResponse*/));
   }
 
   {
     ScopedTestKeyPair unusedKeyPair;
     ByteString certDER(CreateCert(caCertName, "End-Entity Too Far",
                                   EndEntityOrCA::MustBeEndEntity,
                                   caKeyPair.get(), unusedKeyPair));
-    ASSERT_NE(ENCODING_FAILED, certDER);
+    ASSERT_FALSE(ENCODING_FAILED(certDER));
     Input certDERInput;
     ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length()));
     ASSERT_EQ(Result::ERROR_UNKNOWN_ISSUER,
               BuildCertChain(trustDomain, certDERInput, Now(),
                              EndEntityOrCA::MustBeEndEntity,
                              KeyUsage::noParticularKeyUsageRequired,
                              KeyPurposeId::id_kp_serverAuth,
                              CertPolicyId::anyPolicy,
@@ -383,35 +381,33 @@ private:
 };
 
 TEST_F(pkixbuild, NoRevocationCheckingForExpiredCert)
 {
   const char* rootCN = "Root CA";
   ScopedTestKeyPair rootKey;
   ByteString rootDER(CreateCert(rootCN, rootCN, EndEntityOrCA::MustBeCA,
                                 nullptr, rootKey, nullptr));
-  EXPECT_NE(ENCODING_FAILED, rootDER);
+  EXPECT_FALSE(ENCODING_FAILED(rootDER));
   ExpiredCertTrustDomain expiredCertTrustDomain(rootDER);
 
   ByteString serialNumber(CreateEncodedSerialNumber(100));
-  EXPECT_NE(ENCODING_FAILED, serialNumber);
+  EXPECT_FALSE(ENCODING_FAILED(serialNumber));
   ByteString issuerDER(CNToDERName(rootCN));
-  EXPECT_NE(ENCODING_FAILED, issuerDER);
   ByteString subjectDER(CNToDERName("Expired End-Entity Cert"));
-  EXPECT_NE(ENCODING_FAILED, subjectDER);
   ScopedTestKeyPair unusedSubjectKey;
   ByteString certDER(CreateEncodedCertificate(
                        v3, sha256WithRSAEncryption,
                        serialNumber, issuerDER,
                        oneDayBeforeNow - Time::ONE_DAY_IN_SECONDS,
                        oneDayBeforeNow,
                        subjectDER, nullptr, rootKey.get(),
                        SignatureAlgorithm::rsa_pkcs1_with_sha256,
                        unusedSubjectKey));
-  EXPECT_NE(ENCODING_FAILED, certDER);
+  EXPECT_FALSE(ENCODING_FAILED(certDER));
 
   Input cert;
   ASSERT_EQ(Success, cert.Init(certDER.data(), certDER.length()));
   ASSERT_EQ(Result::ERROR_EXPIRED_CERTIFICATE,
             BuildCertChain(expiredCertTrustDomain, cert, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::id_kp_serverAuth,
--- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp
+++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp
@@ -33,21 +33,21 @@ using namespace mozilla::pkix::test;
 static ByteString
 CreateCert(const char* subjectCN,
            const ByteString* extensions, // empty-string-terminated array
            /*out*/ ScopedTestKeyPair& subjectKey)
 {
   static long serialNumberValue = 0;
   ++serialNumberValue;
   ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue));
-  EXPECT_NE(ENCODING_FAILED, serialNumber);
+  EXPECT_FALSE(ENCODING_FAILED(serialNumber));
   ByteString issuerDER(CNToDERName(subjectCN));
-  EXPECT_NE(ENCODING_FAILED, issuerDER);
+  EXPECT_FALSE(ENCODING_FAILED(issuerDER));
   ByteString subjectDER(CNToDERName(subjectCN));
-  EXPECT_NE(ENCODING_FAILED, subjectDER);
+  EXPECT_FALSE(ENCODING_FAILED(subjectDER));
   return CreateEncodedCertificate(v3, sha256WithRSAEncryption,
                                   serialNumber, issuerDER,
                                   oneDayBeforeNow, oneDayAfterNow,
                                   subjectDER, extensions,
                                   nullptr,
                                   SignatureAlgorithm::rsa_pkcs1_with_sha256,
                                   subjectKey);
 }
@@ -133,17 +133,17 @@ TEST_F(pkixcert_extension, UnknownCritic
       0x04, 0x00 // OCTET STRING (length = 0)
   };
   static const ByteString
     unknownCriticalExtension(unknownCriticalExtensionBytes,
                              sizeof(unknownCriticalExtensionBytes));
   const char* certCN = "Cert With Unknown Critical Extension";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, unknownCriticalExtension, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
@@ -163,17 +163,17 @@ TEST_F(pkixcert_extension, UnknownNonCri
       0x04, 0x00 // OCTET STRING (length = 0)
   };
   static const ByteString
     unknownNonCriticalExtension(unknownNonCriticalExtensionBytes,
                                 sizeof(unknownNonCriticalExtensionBytes));
   const char* certCN = "Cert With Unknown NonCritical Extension";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, unknownNonCriticalExtension, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Success,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
@@ -194,17 +194,17 @@ TEST_F(pkixcert_extension, WrongOIDCriti
       0x04, 0x00 // OCTET STRING (length = 0)
   };
   static const ByteString
     wrongOIDCriticalExtension(wrongOIDCriticalExtensionBytes,
                               sizeof(wrongOIDCriticalExtensionBytes));
   const char* certCN = "Cert With Critical Wrong OID Extension";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, wrongOIDCriticalExtension, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
@@ -227,17 +227,17 @@ TEST_F(pkixcert_extension, CriticalAIAEx
         0x30, 0x00, // SEQUENCE (length = 0)
   };
   static const ByteString
     criticalAIAExtension(criticalAIAExtensionBytes,
                          sizeof(criticalAIAExtensionBytes));
   const char* certCN = "Cert With Critical AIA Extension";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, criticalAIAExtension, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Success,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
@@ -257,17 +257,17 @@ TEST_F(pkixcert_extension, UnknownCritic
       0x04, 0x00 // OCTET STRING (length = 0)
   };
   static const ByteString
     unknownCriticalCEExtension(unknownCriticalCEExtensionBytes,
                                sizeof(unknownCriticalCEExtensionBytes));
   const char* certCN = "Cert With Unknown Critical id-ce Extension";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, unknownCriticalCEExtension, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
@@ -287,17 +287,17 @@ TEST_F(pkixcert_extension, KnownCritical
         0x02, 0x01, 0x00, // INTEGER (length = 1, value = 0)
   };
   static const ByteString
     criticalCEExtension(criticalCEExtensionBytes,
                         sizeof(criticalCEExtensionBytes));
   const char* certCN = "Cert With Known Critical id-ce Extension";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, criticalCEExtension, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Success,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
@@ -316,17 +316,17 @@ TEST_F(pkixcert_extension, DuplicateSubj
           0x82, 11, // [2] (dNSName) (length = 11)
             'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'
   };
   static const ByteString DER(DER_BYTES, sizeof(DER_BYTES));
   static const ByteString extensions[] = { DER, DER, ByteString() };
   static const char* certCN = "Cert With Duplicate subjectAltName";
   ScopedTestKeyPair key;
   ByteString cert(CreateCert(certCN, extensions, key));
-  ASSERT_NE(ENCODING_FAILED, cert);
+  ASSERT_FALSE(ENCODING_FAILED(cert));
   Input certInput;
   ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
   ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID,
             BuildCertChain(trustDomain, certInput, Now(),
                            EndEntityOrCA::MustBeEndEntity,
                            KeyUsage::noParticularKeyUsageRequired,
                            KeyPurposeId::anyExtendedKeyUsage,
                            CertPolicyId::anyPolicy,
--- a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp
+++ b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp
@@ -82,17 +82,17 @@ private:
 class pkixocsp_CreateEncodedOCSPRequest : public ::testing::Test
 {
 protected:
   void MakeIssuerCertIDComponents(const char* issuerASCII,
                                   /*out*/ ByteString& issuerDER,
                                   /*out*/ ByteString& issuerSPKI)
   {
     issuerDER = CNToDERName(issuerASCII);
-    ASSERT_NE(ENCODING_FAILED, issuerDER);
+    ASSERT_FALSE(ENCODING_FAILED(issuerDER));
 
     ScopedTestKeyPair keyPair(GenerateKeyPair());
     ASSERT_TRUE(keyPair);
     issuerSPKI = keyPair->subjectPublicKeyInfo;
   }
 
   CreateEncodedOCSPRequestTrustDomain trustDomain;
 };
--- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
+++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
@@ -105,27 +105,27 @@ public:
     if (!rootKeyPair) {
       abort();
     }
   }
 
   void SetUp()
   {
     rootNameDER = CNToDERName(rootName);
-    if (rootNameDER == ENCODING_FAILED) {
+    if (ENCODING_FAILED(rootNameDER)) {
       abort();
     }
     Input rootNameDERInput;
     if (rootNameDERInput.Init(rootNameDER.data(), rootNameDER.length())
           != Success) {
       abort();
     }
 
     serialNumberDER = CreateEncodedSerialNumber(++rootIssuedCount);
-    if (serialNumberDER == ENCODING_FAILED) {
+    if (ENCODING_FAILED(serialNumberDER)) {
       abort();
     }
     Input serialNumberDERInput;
     if (serialNumberDERInput.Init(serialNumberDER.data(),
                                   serialNumberDER.length()) != Success) {
       abort();
     }
 
@@ -243,17 +243,17 @@ public:
                     const TestKeyPair& signerKeyPair,
                     time_t producedAt, time_t thisUpdate,
                     /*optional*/ const time_t* nextUpdate,
                     /*optional*/ const ByteString* certs = nullptr)
   {
     OCSPResponseContext context(certID, producedAt);
     if (signerName) {
       context.signerNameDER = CNToDERName(signerName);
-      EXPECT_NE(ENCODING_FAILED, context.signerNameDER);
+      EXPECT_FALSE(ENCODING_FAILED(context.signerNameDER));
     }
     context.signerKeyPair = signerKeyPair.Clone();
     EXPECT_TRUE(context.signerKeyPair);
     context.responseStatus = OCSPResponseContext::successful;
     context.producedAt = producedAt;
     context.certs = certs;
 
     context.certStatus = certStatus;
@@ -393,25 +393,25 @@ protected:
       ByteString()
     };
     ScopedTestKeyPair signerKeyPair;
     ByteString signerDER(CreateEncodedCertificate(
                            ++rootIssuedCount, rootName,
                            oneDayBeforeNow, oneDayAfterNow, certSubjectName,
                            signerEKUDER ? extensions : nullptr,
                            rootKeyPair.get(), signerKeyPair));
-    EXPECT_NE(ENCODING_FAILED, signerDER);
+    EXPECT_FALSE(ENCODING_FAILED(signerDER));
     if (signerDEROut) {
       *signerDEROut = signerDER;
     }
 
     ByteString signerNameDER;
     if (signerName) {
       signerNameDER = CNToDERName(signerName);
-      EXPECT_NE(ENCODING_FAILED, signerNameDER);
+      EXPECT_FALSE(ENCODING_FAILED(signerNameDER));
     }
     ByteString certs[] = { signerDER, ByteString() };
     return CreateEncodedOCSPSuccessfulResponse(certStatus, *endEntityCertID,
                                                signerName, *signerKeyPair,
                                                oneDayBeforeNow,
                                                oneDayBeforeNow,
                                                &oneDayAfterNow, certs);
   }
@@ -421,26 +421,26 @@ protected:
                                              time_t notBefore,
                                              time_t notAfter,
                                              const char* subject,
                                 /*optional*/ const ByteString* extensions,
                                 /*optional*/ TestKeyPair* signerKeyPair,
                                      /*out*/ ScopedTestKeyPair& keyPair)
   {
     ByteString serialNumberDER(CreateEncodedSerialNumber(serialNumber));
-    if (serialNumberDER == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(serialNumberDER)) {
+      return ByteString();
     }
     ByteString issuerDER(CNToDERName(issuer));
-    if (issuerDER == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(issuerDER)) {
+      return ByteString();
     }
     ByteString subjectDER(CNToDERName(subject));
-    if (subjectDER == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(subjectDER)) {
+      return ByteString();
     }
     return ::mozilla::pkix::test::CreateEncodedCertificate(
                                     v3,
                                     sha256WithRSAEncryption,
                                     serialNumberDER, issuerDER, notBefore,
                                     notAfter, subjectDER, extensions,
                                     signerKeyPair,
                                     SignatureAlgorithm::rsa_pkcs1_with_sha256,
@@ -542,17 +542,17 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
 
   ScopedTestKeyPair signerKeyPair;
   ByteString signerDER(CreateEncodedCertificate(
                           ++rootIssuedCount, rootName,
                           now - (10 * Time::ONE_DAY_IN_SECONDS),
                           now - (2 * Time::ONE_DAY_IN_SECONDS),
                           signerName, extensions, rootKeyPair.get(),
                           signerKeyPair));
-  ASSERT_NE(ENCODING_FAILED, signerDER);
+  ASSERT_FALSE(ENCODING_FAILED(signerDER));
 
   ByteString certs[] = { signerDER, ByteString() };
   ByteString responseString(
                CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, *signerKeyPair, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
   Input response;
@@ -577,17 +577,17 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
 
   ScopedTestKeyPair signerKeyPair;
   ByteString signerDER(CreateEncodedCertificate(
                          ++rootIssuedCount, rootName,
                          now + (2 * Time::ONE_DAY_IN_SECONDS),
                          now + (10 * Time::ONE_DAY_IN_SECONDS),
                          signerName, extensions, rootKeyPair.get(),
                          signerKeyPair));
-  ASSERT_NE(ENCODING_FAILED, signerDER);
+  ASSERT_FALSE(ENCODING_FAILED(signerDER));
 
   ByteString certs[] = { signerDER, ByteString() };
   ByteString responseString(
                CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, *signerKeyPair, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
   Input response;
@@ -677,17 +677,17 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
                               ExtensionCriticality::NotCritical),
     ByteString()
   };
   ScopedTestKeyPair signerKeyPair;
   ByteString signerDER(CreateEncodedCertificate(
                          1, subCAName, oneDayBeforeNow, oneDayAfterNow,
                          signerName, extensions, unknownKeyPair.get(),
                          signerKeyPair));
-  ASSERT_NE(ENCODING_FAILED, signerDER);
+  ASSERT_FALSE(ENCODING_FAILED(signerDER));
 
   // OCSP response signed by that delegated responder
   ByteString certs[] = { signerDER, ByteString() };
   ByteString responseString(
                CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, *signerKeyPair, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
@@ -717,30 +717,30 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
     ByteString()
   };
   ScopedTestKeyPair subCAKeyPair;
   ByteString subCADER(CreateEncodedCertificate(
                         ++rootIssuedCount, rootName,
                         oneDayBeforeNow, oneDayAfterNow,
                         subCAName, subCAExtensions, rootKeyPair.get(),
                         subCAKeyPair));
-  ASSERT_NE(ENCODING_FAILED, subCADER);
+  ASSERT_FALSE(ENCODING_FAILED(subCADER));
 
   // Delegated responder cert signed by that sub-CA
   const ByteString extensions[] = {
     CreateEncodedEKUExtension(OCSPSigningEKUDER,
                               ExtensionCriticality::NotCritical),
     ByteString(),
   };
   ScopedTestKeyPair signerKeyPair;
   ByteString signerDER(CreateEncodedCertificate(
                          1, subCAName, oneDayBeforeNow, oneDayAfterNow,
                          signerName, extensions, subCAKeyPair.get(),
                          signerKeyPair));
-  ASSERT_NE(ENCODING_FAILED, signerDER);
+  ASSERT_FALSE(ENCODING_FAILED(signerDER));
 
   // OCSP response signed by the delegated responder issued by the sub-CA
   // that is trying to impersonate the root.
   ByteString certs[] = { subCADER, signerDER, ByteString() };
   ByteString responseString(
                CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, *signerKeyPair, oneDayBeforeNow,
@@ -771,30 +771,30 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
     ByteString()
   };
   ScopedTestKeyPair subCAKeyPair;
   ByteString subCADER(CreateEncodedCertificate(++rootIssuedCount, rootName,
                                                oneDayBeforeNow, oneDayAfterNow,
                                                subCAName, subCAExtensions,
                                                rootKeyPair.get(),
                                                subCAKeyPair));
-  ASSERT_NE(ENCODING_FAILED, subCADER);
+  ASSERT_FALSE(ENCODING_FAILED(subCADER));
 
   // Delegated responder cert signed by that sub-CA
   const ByteString extensions[] = {
     CreateEncodedEKUExtension(OCSPSigningEKUDER,
                               ExtensionCriticality::NotCritical),
     ByteString()
   };
   ScopedTestKeyPair signerKeyPair;
   ByteString signerDER(CreateEncodedCertificate(
                          1, subCAName, oneDayBeforeNow, oneDayAfterNow,
                          signerName, extensions, subCAKeyPair.get(),
                          signerKeyPair));
-  ASSERT_NE(ENCODING_FAILED, signerDER);
+  ASSERT_FALSE(ENCODING_FAILED(signerDER));
 
   // OCSP response signed by the delegated responder issued by the sub-CA
   // that is trying to impersonate the root.
   ByteString certs[] = { signerDER, subCADER, ByteString() };
   ByteString responseString(
                  CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, *signerKeyPair, oneDayBeforeNow,
@@ -816,17 +816,17 @@ public:
   void SetUp()
   {
     pkixocsp_VerifyEncodedResponse_DelegatedResponder::SetUp();
 
     responseString =
         CreateEncodedIndirectOCSPSuccessfulResponse(
           "OCSPGetCertTrustTest Signer", OCSPResponseContext::good,
           byKey, &OCSPSigningEKUDER, &signerCertDER);
-    if (responseString == ENCODING_FAILED) {
+    if (ENCODING_FAILED(responseString)) {
       abort();
     }
     if (response.Init(responseString.data(), responseString.length())
           != Success) {
       abort();
     }
     if (signerCertDER.length() == 0) {
       abort();
--- a/security/pkix/test/lib/pkixtestnss.cpp
+++ b/security/pkix/test/lib/pkixtestnss.cpp
@@ -186,24 +186,24 @@ GenerateKeyPair()
 
   return nullptr;
 }
 
 ByteString
 SHA1(const ByteString& toHash)
 {
   if (InitNSSIfNeeded() != Success) {
-    return ENCODING_FAILED;
+    return ByteString();
   }
 
   uint8_t digestBuf[SHA1_LENGTH];
   SECStatus srv = PK11_HashBuf(SEC_OID_SHA1, digestBuf, toHash.data(),
                                static_cast<int32_t>(toHash.length()));
   if (srv != SECSuccess) {
-    return ENCODING_FAILED;
+    return ByteString();
   }
   return ByteString(digestBuf, sizeof(digestBuf));
 }
 
 Result
 TestCheckPublicKey(Input subjectPublicKeyInfo)
 {
   Result rv = InitNSSIfNeeded();
--- a/security/pkix/test/lib/pkixtestutil.cpp
+++ b/security/pkix/test/lib/pkixtestutil.cpp
@@ -92,38 +92,36 @@ TamperOnce(/*in/out*/ ByteString& item, 
   }
   if (item.find(from, pos + from.length()) != string::npos) {
     return Result::FATAL_ERROR_INVALID_ARGS; // More than once match.
   }
   item.replace(pos, from.length(), to);
   return Success;
 }
 
-// An empty string returned from an encoding function signifies failure.
-const ByteString ENCODING_FAILED;
-
 // Given a tag and a value, generates a DER-encoded tag-length-value item.
-static ByteString
+ByteString
 TLV(uint8_t tag, const ByteString& value)
 {
   ByteString result;
   result.push_back(tag);
 
   if (value.length() < 128) {
     result.push_back(value.length());
   } else if (value.length() < 256) {
     result.push_back(0x81u);
     result.push_back(value.length());
   } else if (value.length() < 65536) {
     result.push_back(0x82u);
     result.push_back(static_cast<uint8_t>(value.length() / 256));
     result.push_back(static_cast<uint8_t>(value.length() % 256));
   } else {
-    assert(false);
-    return ENCODING_FAILED;
+    // It is MUCH more convenient for TLV to be infallible than for it to have
+    // "proper" error handling.
+    abort();
   }
   result.append(value);
   return result;
 }
 
 OCSPResponseContext::OCSPResponseContext(const CertID& certID, time_t time)
   : certID(certID)
   , responseStatus(successful)
@@ -150,18 +148,18 @@ static ByteString KeyHash(const ByteStri
 static ByteString SingleResponse(OCSPResponseContext& context);
 static ByteString CertID(OCSPResponseContext& context);
 static ByteString CertStatus(OCSPResponseContext& context);
 
 static ByteString
 HashedOctetString(const ByteString& bytes)
 {
   ByteString digest(SHA1(bytes));
-  if (digest == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(digest)) {
+    return ByteString();
   }
   return TLV(der::OCTET_STRING, digest);
 }
 
 static ByteString
 BitString(const ByteString& rawBytes, bool corrupt)
 {
   ByteString prefixed;
@@ -185,17 +183,19 @@ Boolean(bool value)
   return TLV(der::BOOLEAN, encodedValue);
 }
 
 static ByteString
 Integer(long value)
 {
   if (value < 0 || value > 127) {
     // TODO: add encoding of larger values
-    return ENCODING_FAILED;
+    // It is MUCH more convenient for Integer to be infallible than for it to
+    // have "proper" error handling.
+    abort();
   }
 
   ByteString encodedValue;
   encodedValue.push_back(static_cast<uint8_t>(value));
   return TLV(der::INTEGER, encodedValue);
 }
 
 enum TimeEncoding { UTCTime = 0, GeneralizedTime = 1 };
@@ -220,29 +220,29 @@ gmtime_r(const time_t* t, /*out*/ tm* ex
 // the number of seconds since the Unix epoch.
 static ByteString
 TimeToEncodedTime(time_t time, TimeEncoding encoding)
 {
   assert(encoding == UTCTime || encoding == GeneralizedTime);
 
   tm exploded;
   if (!gmtime_r(&time, &exploded)) {
-    return ENCODING_FAILED;
+    return ByteString();
   }
 
   if (exploded.tm_sec >= 60) {
     // round down for leap seconds
     exploded.tm_sec = 59;
   }
 
   // exploded.tm_year is the year offset by 1900.
   int year = exploded.tm_year + 1900;
 
   if (encoding == UTCTime && (year < 1950 || year >= 2050)) {
-    return ENCODING_FAILED;
+    return ByteString();
   }
 
   ByteString value;
 
   if (encoding == GeneralizedTime) {
     value.push_back('0' + (year / 1000));
     value.push_back('0' + ((year % 1000) / 100));
   }
@@ -276,17 +276,17 @@ TimeToGeneralizedTime(time_t time)
 // as UTCTime; certificate validity dates in 2050 or later MUST be encoded as
 // GeneralizedTime." (This is a special case of the rule that we must always
 // use the shortest possible encoding.)
 static ByteString
 TimeToTimeChoice(time_t time)
 {
   tm exploded;
   if (!gmtime_r(&time, &exploded)) {
-    return ENCODING_FAILED;
+    return ByteString();
   }
   TimeEncoding encoding = (exploded.tm_year + 1900 >= 1950 &&
                            exploded.tm_year + 1900 < 2050)
                         ? UTCTime
                         : GeneralizedTime;
 
   return TimeToEncodedTime(time, encoding);
 }
@@ -336,58 +336,55 @@ YMDHMS(int16_t year, int16_t month, int1
   totalSeconds += hour * 60 * 60;
   totalSeconds += minutes * 60;
   totalSeconds += seconds;
   return TimeFromElapsedSecondsAD(totalSeconds);
 }
 
 static ByteString
 SignedData(const ByteString& tbsData,
-           TestKeyPair& keyPair,
+           /*optional*/ TestKeyPair* keyPair,
            SignatureAlgorithm signatureAlgorithm,
            bool corrupt, /*optional*/ const ByteString* certs)
 {
   ByteString signature;
-  if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) {
-     return ENCODING_FAILED;
-   }
+  if (keyPair) {
+    if (keyPair->SignData(tbsData, signatureAlgorithm, signature)
+          != Success) {
+       return ByteString();
+     }
+  }
 
   ByteString signatureAlgorithmDER;
   switch (signatureAlgorithm) {
     case SignatureAlgorithm::rsa_pkcs1_with_sha256:
       signatureAlgorithmDER.assign(alg_sha256WithRSAEncryption,
                                    sizeof(alg_sha256WithRSAEncryption));
       break;
     default:
-      return ENCODING_FAILED;
+      return ByteString();
   }
 
   // TODO: add ability to have signatures of bit length not divisible by 8,
   // resulting in unused bits in the bitstring encoding
   ByteString signatureNested(BitString(signature, corrupt));
-  if (signatureNested == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(signatureNested)) {
+    return ByteString();
   }
 
   ByteString certsNested;
   if (certs) {
     ByteString certsSequenceValue;
     while (!(*certs).empty()) {
       certsSequenceValue.append(*certs);
       ++certs;
     }
     ByteString certsSequence(TLV(der::SEQUENCE, certsSequenceValue));
-    if (certsSequence == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     certsNested = TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
                       certsSequence);
-    if (certsNested == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
   }
 
   ByteString value;
   value.append(tbsData);
   value.append(signatureAlgorithmDER);
   value.append(signatureNested);
   value.append(certsNested);
   return TLV(der::SEQUENCE, value);
@@ -406,30 +403,21 @@ Extension(Input extnID, ExtensionCritica
           const ByteString& extnValueBytes)
 {
   ByteString encoded;
 
   encoded.append(ByteString(extnID.UnsafeGetData(), extnID.GetLength()));
 
   if (criticality == ExtensionCriticality::Critical) {
     ByteString critical(Boolean(true));
-    if (critical == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     encoded.append(critical);
   }
 
   ByteString extnValueSequence(TLV(der::SEQUENCE, extnValueBytes));
-  if (extnValueBytes == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
   ByteString extnValue(TLV(der::OCTET_STRING, extnValueSequence));
-  if (extnValue == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
   encoded.append(extnValue);
   return TLV(der::SEQUENCE, encoded);
 }
 
 void
 MaybeLogOutput(const ByteString& result, const char* suffix)
 {
   assert(suffix);
@@ -482,34 +470,34 @@ CreateEncodedCertificate(long version, I
                          SignatureAlgorithm signatureAlgorithm,
                          /*out*/ ScopedTestKeyPair& keyPairResult)
 {
   // It may be the case that privateKeyResult references the same TestKeyPair
   // as issuerKeyPair. Thus, we can't set keyPairResult until after we're done
   // with issuerKeyPair.
   ScopedTestKeyPair subjectKeyPair(GenerateKeyPair());
   if (!subjectKeyPair) {
-    return ENCODING_FAILED;
+    return ByteString();
   }
 
   ByteString tbsCertificate(TBSCertificate(version, serialNumber,
                                            signature, issuerNameDER, notBefore,
                                            notAfter, subjectNameDER,
                                            subjectKeyPair->subjectPublicKeyInfo,
                                            extensions));
-  if (tbsCertificate == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(tbsCertificate)) {
+    return ByteString();
   }
 
   ByteString result(SignedData(tbsCertificate,
-                               issuerKeyPair ? *issuerKeyPair
-                                             : *subjectKeyPair,
+                               issuerKeyPair ? issuerKeyPair
+                                             : subjectKeyPair.get(),
                                signatureAlgorithm, false, nullptr));
-  if (result == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(result)) {
+    return ByteString();
   }
 
   MaybeLogOutput(result, "cert");
 
   keyPairResult = subjectKeyPair.release();
 
   return result;
 }
@@ -535,72 +523,66 @@ TBSCertificate(long versionValue,
                time_t notAfterTime, const ByteString& subject,
                const ByteString& subjectPublicKeyInfo,
                /*optional*/ const ByteString* extensions)
 {
   ByteString value;
 
   if (versionValue != static_cast<long>(der::Version::v1)) {
     ByteString versionInteger(Integer(versionValue));
-    if (versionInteger == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     ByteString version(TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
                            versionInteger));
-    if (version == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     value.append(version);
   }
 
   value.append(serialNumber);
   value.append(signature.UnsafeGetData(), signature.GetLength());
   value.append(issuer);
 
   // Validity ::= SEQUENCE {
   //       notBefore      Time,
   //       notAfter       Time }
   ByteString validity;
   {
     ByteString notBefore(TimeToTimeChoice(notBeforeTime));
-    if (notBefore == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(notBefore)) {
+      return ByteString();
     }
     ByteString notAfter(TimeToTimeChoice(notAfterTime));
-    if (notAfter == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(notAfter)) {
+      return ByteString();
     }
     ByteString validityValue;
     validityValue.append(notBefore);
     validityValue.append(notAfter);
     validity = TLV(der::SEQUENCE, validityValue);
-    if (validity == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(validity)) {
+      return ByteString();
     }
   }
   value.append(validity);
 
   value.append(subject);
 
   value.append(subjectPublicKeyInfo);
 
   if (extensions) {
     ByteString extensionsValue;
     while (!(*extensions).empty()) {
       extensionsValue.append(*extensions);
       ++extensions;
     }
     ByteString extensionsSequence(TLV(der::SEQUENCE, extensionsValue));
-    if (extensionsSequence == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(extensionsSequence)) {
+      return ByteString();
     }
     ByteString extensionsWrapped(
       TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 3, extensionsSequence));
-    if (extensionsWrapped == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(extensionsWrapped)) {
+      return ByteString();
     }
     value.append(extensionsWrapped);
   }
 
   return TLV(der::SEQUENCE, value);
 }
 
 ByteString
@@ -639,25 +621,17 @@ CNToDERName(const char* cn)
 
   ByteString value(reinterpret_cast<const ByteString::value_type*>(cn));
   value = TLV(der::UTF8String, value);
 
   ByteString ava;
   ava.append(tlv_id_at_commonName, sizeof(tlv_id_at_commonName));
   ava.append(value);
   ava = TLV(der::SEQUENCE, ava);
-  if (ava == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
-
   ByteString rdn(TLV(der::SET, ava));
-  if (rdn == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
-
   return TLV(der::SEQUENCE, rdn);
 }
 
 ByteString
 CreateEncodedSerialNumber(long serialNumberValue)
 {
   return Integer(serialNumberValue);
 }
@@ -669,27 +643,21 @@ ByteString
 CreateEncodedBasicConstraints(bool isCA,
                               /*optional*/ long* pathLenConstraintValue,
                               ExtensionCriticality criticality)
 {
   ByteString value;
 
   if (isCA) {
     ByteString cA(Boolean(true));
-    if (cA == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     value.append(cA);
   }
 
   if (pathLenConstraintValue) {
     ByteString pathLenConstraint(Integer(*pathLenConstraintValue));
-    if (pathLenConstraint == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     value.append(pathLenConstraint);
   }
 
   // python DottedOIDToCode.py --tlv id-ce-basicConstraints 2.5.29.19
   static const uint8_t tlv_id_ce_basicConstraints[] = {
     0x06, 0x03, 0x55, 0x1d, 0x13
   };
   return Extension(Input(tlv_id_ce_basicConstraints), criticality, value);
@@ -713,17 +681,17 @@ CreateEncodedEKUExtension(Input ekuOID, 
 ///////////////////////////////////////////////////////////////////////////////
 // OCSP responses
 
 ByteString
 CreateEncodedOCSPResponse(OCSPResponseContext& context)
 {
   if (!context.skipResponseBytes) {
     if (!context.signerKeyPair) {
-      return ENCODING_FAILED;
+      return ByteString();
     }
   }
 
   // OCSPResponse ::= SEQUENCE {
   //    responseStatus          OCSPResponseStatus,
   //    responseBytes       [0] EXPLICIT ResponseBytes OPTIONAL }
 
   // OCSPResponseStatus ::= ENUMERATED {
@@ -733,41 +701,32 @@ CreateEncodedOCSPResponse(OCSPResponseCo
   //    tryLater            (3),  -- Try again later
   //                              -- (4) is not used
   //    sigRequired         (5),  -- Must sign the request
   //    unauthorized        (6)   -- Request unauthorized
   // }
   ByteString reponseStatusValue;
   reponseStatusValue.push_back(context.responseStatus);
   ByteString responseStatus(TLV(der::ENUMERATED, reponseStatusValue));
-  if (responseStatus == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
 
   ByteString responseBytesNested;
   if (!context.skipResponseBytes) {
     ByteString responseBytes(ResponseBytes(context));
-    if (responseBytes == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(responseBytes)) {
+      return ByteString();
     }
 
     responseBytesNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC,
                               responseBytes);
-    if (responseBytesNested == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
   }
 
   ByteString value;
   value.append(responseStatus);
   value.append(responseBytesNested);
   ByteString result(TLV(der::SEQUENCE, value));
-  if (result == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
 
   MaybeLogOutput(result, "ocsp");
 
   return result;
 }
 
 // ResponseBytes ::= SEQUENCE {
 //    responseType            OBJECT IDENTIFIER,
@@ -775,23 +734,20 @@ CreateEncodedOCSPResponse(OCSPResponseCo
 ByteString
 ResponseBytes(OCSPResponseContext& context)
 {
   // Includes tag and length
   static const uint8_t id_pkix_ocsp_basic_encoded[] = {
     0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
   };
   ByteString response(BasicOCSPResponse(context));
-  if (response == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(response)) {
+    return ByteString();
   }
   ByteString responseNested = TLV(der::OCTET_STRING, response);
-  if (responseNested == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
 
   ByteString value;
   value.append(id_pkix_ocsp_basic_encoded,
                sizeof(id_pkix_ocsp_basic_encoded));
   value.append(responseNested);
   return TLV(der::SEQUENCE, value);
 }
 
@@ -799,98 +755,86 @@ ResponseBytes(OCSPResponseContext& conte
 //   tbsResponseData          ResponseData,
 //   signatureAlgorithm       AlgorithmIdentifier,
 //   signature                BIT STRING,
 //   certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
 ByteString
 BasicOCSPResponse(OCSPResponseContext& context)
 {
   ByteString tbsResponseData(ResponseData(context));
-  if (tbsResponseData == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(tbsResponseData)) {
+    return ByteString();
   }
 
   // TODO(bug 980538): certs
-  return SignedData(tbsResponseData, *context.signerKeyPair,
+  return SignedData(tbsResponseData, context.signerKeyPair.get(),
                     SignatureAlgorithm::rsa_pkcs1_with_sha256,
                     context.badSignature, context.certs);
 }
 
 // Extension ::= SEQUENCE {
 //   id               OBJECT IDENTIFIER,
 //   critical         BOOLEAN DEFAULT FALSE
 //   value            OCTET STRING
 // }
 static ByteString
 OCSPExtension(OCSPResponseContext& context, OCSPResponseExtension& extension)
 {
   ByteString encoded;
   encoded.append(extension.id);
   if (extension.critical) {
     ByteString critical(Boolean(true));
-    if (critical == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
     encoded.append(critical);
   }
   ByteString value(TLV(der::OCTET_STRING, extension.value));
-  if (value == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
   encoded.append(value);
   return TLV(der::SEQUENCE, encoded);
 }
 
 // Extensions ::= [1] {
 //   SEQUENCE OF Extension
 // }
 static ByteString
 Extensions(OCSPResponseContext& context)
 {
   ByteString value;
   for (OCSPResponseExtension* extension = context.extensions;
        extension; extension = extension->next) {
     ByteString extensionEncoded(OCSPExtension(context, *extension));
-    if (extensionEncoded == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(extensionEncoded)) {
+      return ByteString();
     }
     value.append(extensionEncoded);
   }
   ByteString sequence(TLV(der::SEQUENCE, value));
-  if (sequence == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
   return TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1, sequence);
 }
 
 // ResponseData ::= SEQUENCE {
 //    version             [0] EXPLICIT Version DEFAULT v1,
 //    responderID             ResponderID,
 //    producedAt              GeneralizedTime,
 //    responses               SEQUENCE OF SingleResponse,
 //    responseExtensions  [1] EXPLICIT Extensions OPTIONAL }
 ByteString
 ResponseData(OCSPResponseContext& context)
 {
   ByteString responderID(ResponderID(context));
-  if (responderID == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(responderID)) {
+    return ByteString();
   }
   ByteString producedAtEncoded(TimeToGeneralizedTime(context.producedAt));
-  if (producedAtEncoded == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(producedAtEncoded)) {
+    return ByteString();
   }
   ByteString response(SingleResponse(context));
-  if (response == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(response)) {
+    return ByteString();
   }
   ByteString responses(TLV(der::SEQUENCE, response));
-  if (responses == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
   ByteString responseExtensions;
   if (context.extensions || context.includeEmptyExtensions) {
     responseExtensions = Extensions(context);
   }
 
   ByteString value;
   value.append(responderID);
   value.append(producedAtEncoded);
@@ -908,18 +852,18 @@ ResponderID(OCSPResponseContext& context
 {
   ByteString contents;
   uint8_t responderIDType;
   if (!context.signerNameDER.empty()) {
     contents = context.signerNameDER;
     responderIDType = 1; // byName
   } else {
     contents = KeyHash(context.signerKeyPair->subjectPublicKey);
-    if (contents == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(contents)) {
+      return ByteString();
     }
     responderIDType = 2; // byKey
   }
 
   return TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | responderIDType,
              contents);
 }
 
@@ -939,38 +883,35 @@ KeyHash(const ByteString& subjectPublicK
 //    certStatus              CertStatus,
 //    thisUpdate              GeneralizedTime,
 //    nextUpdate          [0] EXPLICIT GeneralizedTime OPTIONAL,
 //    singleExtensions    [1] EXPLICIT Extensions OPTIONAL }
 ByteString
 SingleResponse(OCSPResponseContext& context)
 {
   ByteString certID(CertID(context));
-  if (certID == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(certID)) {
+    return ByteString();
   }
   ByteString certStatus(CertStatus(context));
-  if (certStatus == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(certStatus)) {
+    return ByteString();
   }
   ByteString thisUpdateEncoded(TimeToGeneralizedTime(context.thisUpdate));
-  if (thisUpdateEncoded == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(thisUpdateEncoded)) {
+    return ByteString();
   }
   ByteString nextUpdateEncodedNested;
   if (context.includeNextUpdate) {
     ByteString nextUpdateEncoded(TimeToGeneralizedTime(context.nextUpdate));
-    if (nextUpdateEncoded == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(nextUpdateEncoded)) {
+      return ByteString();
     }
     nextUpdateEncodedNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
                                   nextUpdateEncoded);
-    if (nextUpdateEncodedNested == ENCODING_FAILED) {
-      return ENCODING_FAILED;
-    }
   }
 
   ByteString value;
   value.append(certID);
   value.append(certStatus);
   value.append(thisUpdateEncoded);
   value.append(nextUpdateEncodedNested);
   return TLV(der::SEQUENCE, value);
@@ -982,52 +923,49 @@ SingleResponse(OCSPResponseContext& cont
 //        issuerKeyHash       OCTET STRING, -- Hash of issuer's public key
 //        serialNumber        CertificateSerialNumber }
 ByteString
 CertID(OCSPResponseContext& context)
 {
   ByteString issuerName(context.certID.issuer.UnsafeGetData(),
                         context.certID.issuer.GetLength());
   ByteString issuerNameHash(HashedOctetString(issuerName));
-  if (issuerNameHash == ENCODING_FAILED) {
-    return ENCODING_FAILED;
+  if (ENCODING_FAILED(issuerNameHash)) {
+    return ByteString();
   }
 
   ByteString issuerKeyHash;
   {
     // context.certID.issuerSubjectPublicKeyInfo is the entire
     // SubjectPublicKeyInfo structure, but we need just the subjectPublicKey
     // part.
     Reader input(context.certID.issuerSubjectPublicKeyInfo);
     Reader contents;
     if (der::ExpectTagAndGetValue(input, der::SEQUENCE, contents) != Success) {
-      return ENCODING_FAILED;
+      return ByteString();
     }
     // Skip AlgorithmIdentifier
     if (der::ExpectTagAndSkipValue(contents, der::SEQUENCE) != Success) {
-      return ENCODING_FAILED;
+      return ByteString();
     }
     Input subjectPublicKey;
     if (der::BitStringWithNoUnusedBits(contents, subjectPublicKey)
           != Success) {
-      return ENCODING_FAILED;
+      return ByteString();
     }
     issuerKeyHash = KeyHash(ByteString(subjectPublicKey.UnsafeGetData(),
                                        subjectPublicKey.GetLength()));
-    if (issuerKeyHash == ENCODING_FAILED) {
-      return ENCODING_FAILED;
+    if (ENCODING_FAILED(issuerKeyHash)) {
+      return ByteString();
     }
   }
 
   ByteString serialNumberValue(context.certID.serialNumber.UnsafeGetData(),
                                context.certID.serialNumber.GetLength());
   ByteString serialNumber(TLV(der::INTEGER, serialNumberValue));
-  if (serialNumber == ENCODING_FAILED) {
-    return ENCODING_FAILED;
-  }
 
   // python DottedOIDToCode.py --alg id-sha1 1.3.14.3.2.26
   static const uint8_t alg_id_sha1[] = {
     0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a
   };
 
   ByteString value;
   value.append(alg_id_sha1, sizeof(alg_id_sha1));
@@ -1057,22 +995,22 @@ CertStatus(OCSPResponseContext& context)
     case 0:
     case 2:
     {
       return TLV(der::CONTEXT_SPECIFIC | context.certStatus, ByteString());
     }
     case 1:
     {
       ByteString revocationTime(TimeToGeneralizedTime(context.revocationTime));
-      if (revocationTime == ENCODING_FAILED) {
-        return ENCODING_FAILED;
+      if (ENCODING_FAILED(revocationTime)) {
+        return ByteString();
       }
       // TODO(bug 980536): add support for revocationReason
       return TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1, revocationTime);
     }
     default:
       assert(false);
       // fall through
   }
-  return ENCODING_FAILED;
+  return ByteString();
 }
 
 } } } // namespace mozilla::pkix::test
--- a/security/pkix/test/lib/pkixtestutil.h
+++ b/security/pkix/test/lib/pkixtestutil.h
@@ -31,17 +31,18 @@
 
 #include "pkix/enumclass.h"
 #include "pkix/pkixtypes.h"
 #include "pkix/ScopedPtr.h"
 
 namespace mozilla { namespace pkix { namespace test {
 
 typedef std::basic_string<uint8_t> ByteString;
-extern const ByteString ENCODING_FAILED;
+
+inline bool ENCODING_FAILED(const ByteString& bs) { return bs.empty(); }
 
 // XXX: Ideally, we should define this instead:
 //
 //   template <typename T, std::size_t N>
 //   constexpr inline std::size_t
 //   ArrayLength(T (&)[N])
 //   {
 //     return N;
@@ -74,17 +75,16 @@ static const uint8_t tlv_id_kp_serverAut
 };
 
 extern const Input sha256WithRSAEncryption;
 
 // e.g. YMDHMS(2016, 12, 31, 1, 23, 45) => 2016-12-31:01:23:45 (GMT)
 mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day,
                            int16_t hour, int16_t minutes, int16_t seconds);
 
-
 ByteString CNToDERName(const char* cn);
 
 class TestKeyPair
 {
 public:
   virtual ~TestKeyPair() { }
 
   // The DER encoding of the entire SubjectPublicKeyInfo structure. This is