Bug 1061021, Part 11: Stop using PLArenaPool for TBSCertificate and SignedData encoding, r=keeler
authorBrian Smith <brian@briansmith.org>
Sat, 30 Aug 2014 19:55:52 -0700
changeset 14682 86d4257c47bcafe5edd30bce4eea39cbdf4cb8ab
parent 14681 ae1e6fc28aecdc104cf827422ed3f95054bf83cc
child 14683 07b910800d29a8bd7552cfdca10b200eec54283f
push id3202
push userfranziskuskiefer@gmail.com
push dateMon, 01 Oct 2018 08:30:12 +0000
reviewerskeeler
bugs1061021
Bug 1061021, Part 11: Stop using PLArenaPool for TBSCertificate and SignedData encoding, r=keeler
lib/mozpkix/test/lib/pkixtestutil.cpp
--- a/lib/mozpkix/test/lib/pkixtestutil.cpp
+++ b/lib/mozpkix/test/lib/pkixtestutil.cpp
@@ -453,41 +453,40 @@ YMDHMS(int16_t year, int16_t month, int1
   uint64_t totalSeconds = days * Time::ONE_DAY_IN_SECONDS;
   totalSeconds += hour * 60 * 60;
   totalSeconds += minutes * 60;
   totalSeconds += seconds;
   return TimeFromElapsedSecondsAD(totalSeconds);
 }
 
 static ByteString
-SignedData(const SECItem* tbsData,
+SignedData(const ByteString& tbsData,
            SECKEYPrivateKey* privKey,
            SignatureAlgorithm signatureAlgorithm,
            bool corrupt, /*optional*/ SECItem const* const* certs)
 {
-  assert(tbsData);
   assert(privKey);
-  if (!tbsData || !privKey) {
+  if (!privKey) {
     return ENCODING_FAILED;
   }
 
   SECOidTag signatureAlgorithmOidTag;
   ByteString signatureAlgorithmDER;
   switch (signatureAlgorithm) {
     case SignatureAlgorithm::rsa_pkcs1_with_sha256:
       signatureAlgorithmOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
       signatureAlgorithmDER.assign(alg_sha256WithRSAEncryption,
                                    sizeof(alg_sha256WithRSAEncryption));
       break;
     default:
       return ENCODING_FAILED;
   }
 
   SECItem signature;
-  if (SEC_SignData(&signature, tbsData->data, tbsData->len, privKey,
+  if (SEC_SignData(&signature, tbsData.data(), tbsData.length(), privKey,
                    signatureAlgorithmOidTag) != SECSuccess)
   {
     return nullptr;
   }
   // TODO: add ability to have signatures of bit length not divisible by 8,
   // resulting in unused bits in the bitstring encoding
   ByteString signatureNested(BitString(ByteString(signature.data, signature.len),
                                        corrupt));
@@ -510,17 +509,17 @@ SignedData(const SECItem* tbsData,
     certsNested = TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
                       certsSequence);
     if (certsNested == ENCODING_FAILED) {
       return ENCODING_FAILED;
     }
   }
 
   ByteString value;
-  value.append(ByteString(tbsData->data, tbsData->len));
+  value.append(tbsData);
   value.append(signatureAlgorithmDER);
   value.append(signatureNested);
   value.append(certsNested);
   return TLV(der::SEQUENCE, value);
 }
 
 // Extension  ::=  SEQUENCE  {
 //      extnID      OBJECT IDENTIFIER,
@@ -628,22 +627,22 @@ GenerateKeyPair(/*out*/ ScopedSECKEYPubl
 
   return MapPRErrorCodeToResult(PR_GetError());
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // Certificates
 
-static SECItem* TBSCertificate(PLArenaPool* arena, long version,
-                               const ByteString& serialNumber, Input signature,
-                               const ByteString& issuer, time_t notBefore,
-                               time_t notAfter, const ByteString& subject,
-                               const SECKEYPublicKey* subjectPublicKey,
-                               /*optional*/ const ByteString* extensions);
+static ByteString TBSCertificate(long version, const ByteString& serialNumber,
+                                 Input signature, const ByteString& issuer,
+                                 time_t notBefore, time_t notAfter,
+                                 const ByteString& subject,
+                                 const SECKEYPublicKey* subjectPublicKey,
+                                 /*optional*/ const ByteString* extensions);
 
 // Certificate  ::=  SEQUENCE  {
 //         tbsCertificate       TBSCertificate,
 //         signatureAlgorithm   AlgorithmIdentifier,
 //         signatureValue       BIT STRING  }
 SECItem*
 CreateEncodedCertificate(PLArenaPool* arena, long version, Input signature,
                          const ByteString& serialNumber,
@@ -664,21 +663,21 @@ CreateEncodedCertificate(PLArenaPool* ar
   // ScopedSECKEYPrivateKey that owns issuerPrivateKey; thus, we can't set
   // privateKeyResult until after we're done with issuerPrivateKey.
   ScopedSECKEYPublicKey publicKey;
   ScopedSECKEYPrivateKey privateKeyTemp;
   if (GenerateKeyPair(publicKey, privateKeyTemp) != Success) {
     return nullptr;
   }
 
-  SECItem* tbsCertificate(TBSCertificate(arena, version, serialNumber,
-                                         signature, issuerNameDER, notBefore,
-                                         notAfter, subjectNameDER,
-                                         publicKey.get(), extensions));
-  if (!tbsCertificate) {
+  ByteString tbsCertificate(TBSCertificate(version, serialNumber,
+                                           signature, issuerNameDER, notBefore,
+                                           notAfter, subjectNameDER,
+                                           publicKey.get(), extensions));
+  if (tbsCertificate == ENCODING_FAILED) {
     return nullptr;
   }
 
   ByteString result(SignedData(tbsCertificate,
                                issuerPrivateKey ? issuerPrivateKey
                                                 : privateKeyTemp.get(),
                                signatureAlgorithm, false, nullptr));
   if (result == ENCODING_FAILED) {
@@ -701,110 +700,102 @@ CreateEncodedCertificate(PLArenaPool* ar
 //      subject              Name,
 //      subjectPublicKeyInfo SubjectPublicKeyInfo,
 //      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 //                           -- If present, version MUST be v2 or v3
 //      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
 //                           -- If present, version MUST be v2 or v3
 //      extensions      [3]  Extensions OPTIONAL
 //                           -- If present, version MUST be v3 --  }
-static SECItem*
-TBSCertificate(PLArenaPool* arena, long versionValue,
+static ByteString
+TBSCertificate(long versionValue,
                const ByteString& serialNumber, Input signature,
                const ByteString& issuer, time_t notBeforeTime,
                time_t notAfterTime, const ByteString& subject,
                const SECKEYPublicKey* subjectPublicKey,
                /*optional*/ const ByteString* extensions)
 {
-  assert(arena);
   assert(subjectPublicKey);
-  if (!arena || !subjectPublicKey) {
-    return nullptr;
+  if (!subjectPublicKey) {
+    return ENCODING_FAILED;
   }
 
-  Output output;
+  ByteString value;
 
   if (versionValue != static_cast<long>(der::Version::v1)) {
     ByteString versionInteger(Integer(versionValue));
     if (versionInteger == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
     ByteString version(TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
                            versionInteger));
     if (version == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
-    output.Add(version);
+    value.append(version);
   }
 
-  output.Add(serialNumber);
-
-  SECItem signatureItem = UnsafeMapInputToSECItem(signature);
-  if (output.Add(&signatureItem) != Success) {
-    return nullptr;
-  }
-
-  output.Add(issuer);
+  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 nullptr;
+      return ENCODING_FAILED;
     }
     ByteString notAfter(TimeToTimeChoice(notAfterTime));
     if (notAfter == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
     ByteString validityValue;
     validityValue.append(notBefore);
     validityValue.append(notAfter);
     validity = TLV(der::SEQUENCE, validityValue);
     if (validity == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
   }
-  output.Add(validity);
+  value.append(validity);
 
-  output.Add(subject);
+  value.append(subject);
 
   // SubjectPublicKeyInfo  ::=  SEQUENCE  {
   //       algorithm            AlgorithmIdentifier,
   //       subjectPublicKey     BIT STRING  }
   ScopedSECItem subjectPublicKeyInfo(
     SECKEY_EncodeDERSubjectPublicKeyInfo(subjectPublicKey));
   if (!subjectPublicKeyInfo) {
-    return nullptr;
+    return ENCODING_FAILED;
   }
-  if (output.Add(subjectPublicKeyInfo.get()) != Success) {
-    return nullptr;
-  }
+  value.append(subjectPublicKeyInfo->data, subjectPublicKeyInfo->len);
 
   if (extensions) {
     ByteString extensionsValue;
     while (!(*extensions).empty()) {
       extensionsValue.append(*extensions);
       ++extensions;
     }
     ByteString extensionsSequence(TLV(der::SEQUENCE, extensionsValue));
     if (extensionsSequence == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
     ByteString extensionsWrapped(
       TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 3, extensionsSequence));
     if (extensionsWrapped == ENCODING_FAILED) {
-      return nullptr;
+      return ENCODING_FAILED;
     }
-    output.Add(extensionsWrapped);
+    value.append(extensionsWrapped);
   }
 
-  return output.Squash(arena, der::SEQUENCE);
+  return TLV(der::SEQUENCE, value);
 }
 
 ByteString
 CNToDERName(const char* cn)
 {
   // Name ::= CHOICE { -- only one possibility for now --
   //   rdnSequence  RDNSequence }
   //
@@ -1007,17 +998,18 @@ ByteString
 BasicOCSPResponse(OCSPResponseContext& context)
 {
   SECItem* tbsResponseData = ResponseData(context);
   if (!tbsResponseData) {
     return nullptr;
   }
 
   // TODO(bug 980538): certs
-  return SignedData(tbsResponseData, context.signerPrivateKey.get(),
+  return SignedData(ByteString(tbsResponseData->data, tbsResponseData->len),
+                    context.signerPrivateKey.get(),
                     SignatureAlgorithm::rsa_pkcs1_with_sha256,
                     context.badSignature, context.certs);
 }
 
 // Extension ::= SEQUENCE {
 //   id               OBJECT IDENTIFIER,
 //   critical         BOOLEAN DEFAULT FALSE
 //   value            OCTET STRING