Bug 1061021, Part 15: Stop using PLArenaPool in CreateEncodedOCSPResponse, r=keeler
authorBrian Smith <brian@briansmith.org>
Mon, 01 Sep 2014 19:23:01 -0700
changeset 14686 88a132d5b1ab3f40e7634f2fc8727e72eb6653ab
parent 14685 8743adefe38aa1f100d74405ab7fc76caec1ceaf
child 14687 101b4b6d8849b35e1fc1a0a2d2af560f311119a7
push id3202
push userfranziskuskiefer@gmail.com
push dateMon, 01 Oct 2018 08:30:12 +0000
reviewerskeeler
bugs1061021
Bug 1061021, Part 15: Stop using PLArenaPool in CreateEncodedOCSPResponse, r=keeler
lib/mozpkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
lib/mozpkix/test/lib/pkixtestutil.cpp
lib/mozpkix/test/lib/pkixtestutil.h
--- a/lib/mozpkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
+++ b/lib/mozpkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp
@@ -201,40 +201,34 @@ static const WithoutResponseBytes WITHOU
   },
 };
 
 class pkixocsp_VerifyEncodedResponse_WithoutResponseBytes
   : public pkixocsp_VerifyEncodedResponse
   , public ::testing::WithParamInterface<WithoutResponseBytes>
 {
 protected:
-  // The result is owned by the arena
-  Input CreateEncodedOCSPErrorResponse(uint8_t status)
+  ByteString CreateEncodedOCSPErrorResponse(uint8_t status)
   {
     static const Input EMPTY;
-    OCSPResponseContext context(arena.get(),
-                                CertID(EMPTY, EMPTY, EMPTY),
+    OCSPResponseContext context(CertID(EMPTY, EMPTY, EMPTY),
                                 oneDayBeforeNow);
     context.responseStatus = status;
     context.skipResponseBytes = true;
-    SECItem* response = CreateEncodedOCSPResponse(context);
-    EXPECT_TRUE(response);
-    // The result will be an empty Input on failure, but it doesn't
-    // matter because the test is going to fail anyway.
-    Input result;
-    EXPECT_EQ(Success, result.Init(response->data, response->len));
-    return result;
+    return CreateEncodedOCSPResponse(context);
   }
 };
 
 TEST_P(pkixocsp_VerifyEncodedResponse_WithoutResponseBytes, CorrectErrorCode)
 {
-  Input
-    response(CreateEncodedOCSPErrorResponse(GetParam().responseStatus));
-
+  ByteString
+    responseString(CreateEncodedOCSPErrorResponse(GetParam().responseStatus));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(GetParam().expectedError,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
 }
 
 INSTANTIATE_TEST_CASE_P(pkixocsp_VerifyEncodedResponse_WithoutResponseBytes,
@@ -260,112 +254,127 @@ public:
     pkixocsp_VerifyEncodedResponse::SetUp();
   }
 
   static void SetUpTestCase()
   {
     pkixocsp_VerifyEncodedResponse::SetUpTestCase();
   }
 
-  // The result is owned by the arena
-  Input CreateEncodedOCSPSuccessfulResponse(
+  ByteString CreateEncodedOCSPSuccessfulResponse(
                     OCSPResponseContext::CertStatus certStatus,
                     const CertID& certID,
                     /*optional*/ const char* signerName,
                     const ScopedSECKEYPrivateKey& signerPrivateKey,
                     time_t producedAt, time_t thisUpdate,
                     /*optional*/ const time_t* nextUpdate,
                     /*optional*/ const ByteString* certs = nullptr)
   {
-    OCSPResponseContext context(arena.get(), certID, producedAt);
+    OCSPResponseContext context(certID, producedAt);
     if (signerName) {
       context.signerNameDER = CNToDERName(signerName);
       EXPECT_NE(ENCODING_FAILED, context.signerNameDER);
     }
     context.signerPrivateKey = SECKEY_CopyPrivateKey(signerPrivateKey.get());
     EXPECT_TRUE(context.signerPrivateKey);
     context.responseStatus = OCSPResponseContext::successful;
     context.producedAt = producedAt;
     context.certs = certs;
 
     context.certStatus = certStatus;
     context.thisUpdate = thisUpdate;
     context.nextUpdate = nextUpdate ? *nextUpdate : 0;
     context.includeNextUpdate = nextUpdate != nullptr;
 
-    SECItem* response = CreateEncodedOCSPResponse(context);
-    EXPECT_TRUE(response);
-    Input result;
-    EXPECT_EQ(Success, result.Init(response->data, response->len));
-    return result;
+    return CreateEncodedOCSPResponse(context);
   }
 };
 
 TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byKey)
 {
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID, byKey,
                          rootPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Success,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID,
                                       Now(), END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byName)
 {
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID, rootName,
                          rootPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Success,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byKey_without_nextUpdate)
 {
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID, byKey,
                          rootPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, nullptr));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Success,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_successful, revoked)
 {
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::revoked, *endEntityCertID, byKey,
                          rootPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_successful, unknown)
 {
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::unknown, *endEntityCertID, byKey,
                          rootPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
@@ -385,22 +394,22 @@ protected:
   // signerName should be byKey to use the byKey ResponderID construction, or
   // another value (usually equal to certSubjectName) to use the byName
   // ResponderID construction.
   //
   // If signerEKU is omitted, then the certificate will have the
   // id-kp-OCSPSigning EKU. If signerEKU is SEC_OID_UNKNOWN then it will not
   // have any EKU extension. Otherwise, the certificate will have the given
   // EKU.
-  Input CreateEncodedIndirectOCSPSuccessfulResponse(
-              const char* certSubjectName,
-              OCSPResponseContext::CertStatus certStatus,
-              const char* signerName,
-              /*optional*/ const Input* signerEKUDER = &OCSPSigningEKUDER,
-              /*optional, out*/ ByteString* signerDEROut = nullptr)
+  ByteString CreateEncodedIndirectOCSPSuccessfulResponse(
+               const char* certSubjectName,
+               OCSPResponseContext::CertStatus certStatus,
+               const char* signerName,
+               /*optional*/ const Input* signerEKUDER = &OCSPSigningEKUDER,
+               /*optional, out*/ ByteString* signerDEROut = nullptr)
   {
     assert(certSubjectName);
 
     const ByteString extensions[] = {
       signerEKUDER
         ? CreateEncodedEKUExtension(*signerEKUDER,
                                     ExtensionCriticality::NotCritical)
         : ByteString(),
@@ -464,70 +473,86 @@ protected:
   static const Input OCSPSigningEKUDER;
 };
 
 /*static*/ const Input pkixocsp_VerifyEncodedResponse_DelegatedResponder::
   OCSPSigningEKUDER(tlv_id_kp_OCSPSigning);
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byKey)
 {
-  Input response(CreateEncodedIndirectOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedIndirectOCSPSuccessfulResponse(
                          "good_indirect_byKey", OCSPResponseContext::good,
                          byKey));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Success,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byName)
 {
-  Input response(CreateEncodedIndirectOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedIndirectOCSPSuccessfulResponse(
                          "good_indirect_byName", OCSPResponseContext::good,
                          "good_indirect_byName"));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Success,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
        good_byKey_missing_signer)
 {
   ScopedSECKEYPublicKey missingSignerPublicKey;
   ScopedSECKEYPrivateKey missingSignerPrivateKey;
   ASSERT_EQ(Success, GenerateKeyPair(missingSignerPublicKey,
                                      missingSignerPrivateKey));
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID, byKey,
                          missingSignerPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, nullptr));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
        good_byName_missing_signer)
 {
   ScopedSECKEYPublicKey missingSignerPublicKey;
   ScopedSECKEYPrivateKey missingSignerPrivateKey;
   ASSERT_EQ(Success, GenerateKeyPair(missingSignerPublicKey,
                                      missingSignerPrivateKey));
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          "missing", missingSignerPrivateKey,
                          oneDayBeforeNow, oneDayBeforeNow, nullptr));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
@@ -546,20 +571,24 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
                           ++rootIssuedCount, rootName,
                           now - (10 * Time::ONE_DAY_IN_SECONDS),
                           now - (2 * Time::ONE_DAY_IN_SECONDS),
                           signerName, extensions, rootPrivateKey.get(),
                           signerPrivateKey));
   ASSERT_NE(ENCODING_FAILED, signerDER);
 
   ByteString certs[] = { signerDER, ByteString() };
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, signerPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future)
@@ -577,66 +606,76 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
                          ++rootIssuedCount, rootName,
                          now + (2 * Time::ONE_DAY_IN_SECONDS),
                          now + (10 * Time::ONE_DAY_IN_SECONDS),
                          signerName, extensions, rootPrivateKey.get(),
                          signerPrivateKey));
   ASSERT_NE(ENCODING_FAILED, signerDER);
 
   ByteString certs[] = { signerDER, ByteString() };
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, signerPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_no_eku)
 {
-  Input response(CreateEncodedIndirectOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedIndirectOCSPSuccessfulResponse(
                          "good_indirect_wrong_eku",
                          OCSPResponseContext::good, byKey, nullptr));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 static const Input serverAuthEKUDER(tlv_id_kp_serverAuth);
 
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder,
        good_indirect_wrong_eku)
 {
-  Input response(CreateEncodedIndirectOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedIndirectOCSPSuccessfulResponse(
                         "good_indirect_wrong_eku",
                         OCSPResponseContext::good, byKey, &serverAuthEKUDER));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 // Test that signature of OCSP response signer cert is verified
 TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_tampered_eku)
 {
-  Input response(CreateEncodedIndirectOCSPSuccessfulResponse(
+  ByteString tamperedResponse(
+               CreateEncodedIndirectOCSPSuccessfulResponse(
                          "good_indirect_tampered_eku",
-                         OCSPResponseContext::good, byKey,
-                         &serverAuthEKUDER));
-  ByteString tamperedResponse(response.UnsafeGetData(),
-                              response.GetLength());
+                         OCSPResponseContext::good, byKey, &serverAuthEKUDER));
   ASSERT_EQ(Success,
             TamperOnce(tamperedResponse,
                        ByteString(tlv_id_kp_serverAuth,
                                   sizeof(tlv_id_kp_serverAuth)),
                        ByteString(tlv_id_kp_OCSPSigning,
                                   sizeof(tlv_id_kp_OCSPSigning))));
   Input tamperedResponseInput;
   ASSERT_EQ(Success, tamperedResponseInput.Init(tamperedResponse.data(),
@@ -669,20 +708,24 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
   ByteString signerDER(CreateEncodedCertificate(
                          1, subCAName, oneDayBeforeNow, oneDayAfterNow,
                          signerName, extensions, unknownPrivateKey.get(),
                          signerPrivateKey));
   ASSERT_NE(ENCODING_FAILED, signerDER);
 
   // OCSP response signed by that delegated responder
   ByteString certs[] = { signerDER, ByteString() };
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, signerPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
@@ -719,20 +762,24 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
                          1, subCAName, oneDayBeforeNow, oneDayAfterNow,
                          signerName, extensions, subCAPrivateKey.get(),
                          signerPrivateKey));
   ASSERT_NE(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() };
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+               CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, signerPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
@@ -769,45 +816,51 @@ TEST_F(pkixocsp_VerifyEncodedResponse_De
                          1, subCAName, oneDayBeforeNow, oneDayAfterNow,
                          signerName, extensions, subCAPrivateKey.get(),
                          signerPrivateKey));
   ASSERT_NE(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() };
-  Input response(CreateEncodedOCSPSuccessfulResponse(
+  ByteString responseString(
+                 CreateEncodedOCSPSuccessfulResponse(
                          OCSPResponseContext::good, *endEntityCertID,
                          signerName, signerPrivateKey, oneDayBeforeNow,
                          oneDayBeforeNow, &oneDayAfterNow, certs));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 class pkixocsp_VerifyEncodedResponse_GetCertTrust
   : public pkixocsp_VerifyEncodedResponse_DelegatedResponder {
 public:
   void SetUp()
   {
     pkixocsp_VerifyEncodedResponse_DelegatedResponder::SetUp();
 
-    Input
-      createdResponse(
+    responseString =
         CreateEncodedIndirectOCSPSuccessfulResponse(
           "OCSPGetCertTrustTest Signer", OCSPResponseContext::good,
-          byKey, &OCSPSigningEKUDER, &signerCertDER));
-    if (response.Init(createdResponse) != Success) {
+          byKey, &OCSPSigningEKUDER, &signerCertDER);
+    if (responseString == ENCODING_FAILED) {
       abort();
     }
-
-    if (response.GetLength() == 0 || signerCertDER.length() == 0) {
+    if (response.Init(responseString.data(), responseString.length())
+          != Success) {
+      abort();
+    }
+    if (signerCertDER.length() == 0) {
       abort();
     }
   }
 
   class TrustDomain : public OCSPTestTrustDomain
   {
   public:
     TrustDomain()
@@ -837,17 +890,18 @@ public:
     }
 
     ByteString certDER;
     TrustLevel certTrustLevel;
   };
 
   TrustDomain trustDomain;
   ByteString signerCertDER;
-  Input response; // owned by arena
+  ByteString responseString;
+  Input response; // references data in responseString
 };
 
 TEST_F(pkixocsp_VerifyEncodedResponse_GetCertTrust, InheritTrust)
 {
   ASSERT_TRUE(trustDomain.SetCertTrust(signerCertDER,
                                        TrustLevel::InheritsTrust));
   bool expired;
   ASSERT_EQ(Success,
@@ -868,15 +922,18 @@ TEST_F(pkixocsp_VerifyEncodedResponse_Ge
                                       response, expired));
   ASSERT_FALSE(expired);
 }
 
 TEST_F(pkixocsp_VerifyEncodedResponse_GetCertTrust, ActivelyDistrusted)
 {
   ASSERT_TRUE(trustDomain.SetCertTrust(signerCertDER,
                                        TrustLevel::ActivelyDistrusted));
+  Input response;
+  ASSERT_EQ(Success,
+            response.Init(responseString.data(), responseString.length()));
   bool expired;
   ASSERT_EQ(Result::ERROR_OCSP_INVALID_SIGNING_CERT,
             VerifyEncodedOCSPResponse(trustDomain, *endEntityCertID, Now(),
                                       END_ENTITY_MAX_LIFETIME_IN_DAYS,
                                       response, expired));
   ASSERT_FALSE(expired);
 }
--- a/lib/mozpkix/test/lib/pkixtestutil.cpp
+++ b/lib/mozpkix/test/lib/pkixtestutil.cpp
@@ -144,31 +144,18 @@ TLV(uint8_t tag, const ByteString& value
   } else {
     assert(false);
     return ENCODING_FAILED;
   }
   result.append(value);
   return result;
 }
 
-static SECItem*
-ArenaDupByteString(PLArenaPool* arena, const ByteString& value)
-{
-  SECItem* result = SECITEM_AllocItem(arena, nullptr, value.length());
-  if (!result) {
-    return nullptr;
-  }
-  memcpy(result->data, value.data(), value.length());
-  return result;
-}
-
-OCSPResponseContext::OCSPResponseContext(PLArenaPool* arena,
-                                         const CertID& certID, time_t time)
-  : arena(arena)
-  , certID(certID)
+OCSPResponseContext::OCSPResponseContext(const CertID& certID, time_t time)
+  : certID(certID)
   , responseStatus(successful)
   , skipResponseBytes(false)
   , producedAt(time)
   , extensions(nullptr)
   , includeEmptyExtensions(false)
   , badSignature(false)
   , certs(nullptr)
 
@@ -826,26 +813,22 @@ CreateEncodedEKUExtension(Input ekuOID, 
   };
 
   return Extension(Input(tlv_id_ce_extKeyUsage), criticality, value);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // OCSP responses
 
-SECItem*
+ByteString
 CreateEncodedOCSPResponse(OCSPResponseContext& context)
 {
-  if (!context.arena) {
-    return nullptr;
-  }
-
   if (!context.skipResponseBytes) {
     if (!context.signerPrivateKey) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
   }
 
   // OCSPResponse ::= SEQUENCE {
   //    responseStatus          OCSPResponseStatus,
   //    responseBytes       [0] EXPLICIT ResponseBytes OPTIONAL }
 
   // OCSPResponseStatus ::= ENUMERATED {
@@ -856,63 +839,63 @@ CreateEncodedOCSPResponse(OCSPResponseCo
   //                              -- (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 nullptr;
+    return ENCODING_FAILED;
   }
 
   ByteString responseBytesNested;
   if (!context.skipResponseBytes) {
     ByteString responseBytes(ResponseBytes(context));
     if (responseBytes == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
 
     responseBytesNested = TLV(der::CONSTRUCTED | der::CONTEXT_SPECIFIC,
                               responseBytes);
     if (responseBytesNested == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
   }
 
   ByteString value;
   value.append(responseStatus);
   value.append(responseBytesNested);
   ByteString result(TLV(der::SEQUENCE, value));
   if (result == ENCODING_FAILED) {
-    return nullptr;
+    return ENCODING_FAILED;
   }
 
   MaybeLogOutput(result, "ocsp");
 
-  return ArenaDupByteString(context.arena, result);
+  return result;
 }
 
 // ResponseBytes ::= SEQUENCE {
 //    responseType            OBJECT IDENTIFIER,
 //    response                OCTET STRING }
 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 nullptr;
+    return ENCODING_FAILED;
   }
   ByteString responseNested = TLV(der::OCTET_STRING, response);
   if (responseNested == ENCODING_FAILED) {
-    return nullptr;
+    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);
 }
--- a/lib/mozpkix/test/lib/pkixtestutil.h
+++ b/lib/mozpkix/test/lib/pkixtestutil.h
@@ -161,19 +161,18 @@ public:
   bool critical;
   ByteString value;
   OCSPResponseExtension* next;
 };
 
 class OCSPResponseContext
 {
 public:
-  OCSPResponseContext(PLArenaPool* arena, const CertID& certID, std::time_t time);
+  OCSPResponseContext(const CertID& certID, std::time_t time);
 
-  PLArenaPool* arena;
   const CertID& certID;
   // TODO(bug 980538): add a way to specify what certificates are included.
 
   // The fields below are in the order that they appear in an OCSP response.
 
   enum OCSPResponseStatus {
     successful = 0,
     malformedRequest = 1,
@@ -210,15 +209,13 @@ public:
   };
   uint8_t certStatus; // CertStatus or an invalid value
   std::time_t revocationTime; // For certStatus == revoked
   std::time_t thisUpdate;
   std::time_t nextUpdate;
   bool includeNextUpdate;
 };
 
-// The return value, if non-null, is owned by the arena in the context
-// and MUST NOT be freed. A null return value indicates an error occurred.
-SECItem* CreateEncodedOCSPResponse(OCSPResponseContext& context);
+ByteString CreateEncodedOCSPResponse(OCSPResponseContext& context);
 
 } } } // namespace mozilla::pkix::test
 
 #endif // mozilla_pkix_test__pkixtestutils_h