Bug 1018642: Factor out reusable NSS GTest infrastructure into a new NSSTest class, r=cviecco
authorBrian Smith <brian@briansmith.org>
Fri, 30 May 2014 16:46:49 -0700
changeset 186231 d03cc4b6832c1dd5a2a7703d98e600b582796b21
parent 186230 c470f879b8c8b6534aad748ec930000dbd74a258
child 186232 a24472ea29d4554271b97075031f7b5bc131557e
push id26884
push usercbook@mozilla.com
push dateTue, 03 Jun 2014 12:40:39 +0000
treeherdermozilla-central@caff98d085ee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscviecco
bugs1018642
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1018642: Factor out reusable NSS GTest infrastructure into a new NSSTest class, r=cviecco
security/pkix/test/gtest/nssgtest.cpp
security/pkix/test/gtest/nssgtest.h
security/pkix/test/gtest/pkix_ocsp_request_tests.cpp
security/pkix/test/lib/pkixtestutil.cpp
security/pkix/test/lib/pkixtestutil.h
--- a/security/pkix/test/gtest/nssgtest.cpp
+++ b/security/pkix/test/gtest/nssgtest.cpp
@@ -18,16 +18,19 @@
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #include "nssgtest.h"
+#include "nss.h"
+#include "pkixtestutil.h"
+#include "prinit.h"
 
 using namespace std;
 using namespace testing;
 
 namespace mozilla { namespace pkix { namespace test {
 
 ostream&
 operator<<(ostream& os, SECStatusWithPRErrorCode const& value)
@@ -70,9 +73,33 @@ Pred_SECFailure(const char* expectedExpr
     return AssertionSuccess();
   }
 
   return AssertionFailure()
       << "Expected: (" << expectedExpr << ") == (" << actualExpr
       << "), actual: " << SECFailure << " != " << actual;
 }
 
+/*static*/ void
+NSSTest::SetUpTestCase()
+{
+  if (NSS_NoDB_Init(nullptr) != SECSuccess) {
+    PR_Abort();
+  }
+
+  now = PR_Now();
+  oneDayBeforeNow = now - ONE_DAY;
+  oneDayAfterNow = now + ONE_DAY;
+}
+
+NSSTest::NSSTest()
+  : arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE))
+{
+  if (!arena) {
+    PR_Abort();
+  }
+}
+
+/*static*/ PRTime NSSTest::now;
+/*static*/ PRTime NSSTest::oneDayBeforeNow;
+/*static*/ PRTime NSSTest::oneDayAfterNow;
+
 } } } // namespace mozilla::pkix::test
--- a/security/pkix/test/gtest/nssgtest.h
+++ b/security/pkix/test/gtest/nssgtest.h
@@ -22,17 +22,20 @@
  * limitations under the License.
  */
 
 #ifndef mozilla_pkix__nssgtest_h
 #define mozilla_pkix__nssgtest_h
 
 #include "stdint.h"
 #include "gtest/gtest.h"
+#include "pkix/pkixtypes.h"
+#include "pkixtestutil.h"
 #include "prerror.h"
+#include "prtime.h"
 #include "seccomon.h"
 
 namespace mozilla { namespace pkix { namespace test {
 
 class SECStatusWithPRErrorCode
 {
 public:
   SECStatusWithPRErrorCode(SECStatus rv, PRErrorCode errorCode)
@@ -60,27 +63,41 @@ private:
                                   SECStatusWithPRErrorCode const& value);
 
   void operator=(const SECStatusWithPRErrorCode&) /*delete*/;
 };
 
 ::std::ostream& operator<<(::std::ostream&,
                            SECStatusWithPRErrorCode const&);
 
-} } } // namespace mozilla::pkix::test
-
 #define ASSERT_SECSuccess(rv) \
   ASSERT_EQ(::mozilla::pkix::test::SECStatusWithPRErrorCode(SECSuccess, 0), \
             ::mozilla::pkix::test::SECStatusWithPRErrorCode(rv))
 #define EXPECT_SECSuccess(rv) \
   EXPECT_EQ(::mozilla::pkix::test::SECStatusWithPRErrorCode(SECSuccess, 0), \
             ::mozilla::pkix::test::SECStatusWithPRErrorCode(rv))
 
 #define ASSERT_SECFailure(expectedError, rv) \
   ASSERT_EQ(::mozilla::pkix::test::SECStatusWithPRErrorCode(SECFailure, \
                                                             expectedError), \
             ::mozilla::pkix::test::SECStatusWithPRErrorCode(rv))
 #define EXPECT_SECFailure(expectedError, rv) \
   EXPECT_EQ(::mozilla::pkix::test::SECStatusWithPRErrorCode(SECFailure, \
                                                             expectedError), \
             ::mozilla::pkix::test::SECStatusWithPRErrorCode(rv))
 
+class NSSTest : public ::testing::Test
+{
+public:
+  static void SetUpTestCase();
+
+protected:
+  NSSTest();
+
+  ScopedPLArenaPool arena;
+  static PRTime now;
+  static PRTime oneDayBeforeNow;
+  static PRTime oneDayAfterNow;
+};
+
+} } } // namespace mozilla::pkix::test
+
 #endif // mozilla_pkix__nssgtest_h
--- a/security/pkix/test/gtest/pkix_ocsp_request_tests.cpp
+++ b/security/pkix/test/gtest/pkix_ocsp_request_tests.cpp
@@ -17,45 +17,35 @@
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
-
-#include "nss.h"
+#include "nssgtest.h"
 #include "pkix/pkix.h"
 #include "pkixder.h"
-#include "pkixtestutil.h"
 #include "prerror.h"
 #include "secerr.h"
 
 using namespace mozilla::pkix;
 using namespace mozilla::pkix::test;
 
-class pkix_ocsp_request_tests : public ::testing::Test
+class pkix_ocsp_request_tests : public NSSTest
 {
 protected:
-  ScopedPLArenaPool arena;
   // These SECItems are allocated in arena, and so will be auto-cleaned.
   SECItem* unsupportedLongSerialNumber;
   SECItem* shortSerialNumber;
   SECItem* longestRequiredSerialNumber;
-  PRTime now;
-  PRTime oneDayBeforeNow;
-  PRTime oneDayAfterNow;
 
   void SetUp()
   {
-    NSS_NoDB_Init(nullptr);
-    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
     static const uint8_t UNSUPPORTED_LEN = 128; // must be larger than 127
     // tag + length + value is 1 + 2 + UNSUPPORTED_LEN
     unsupportedLongSerialNumber = SECITEM_AllocItem(arena.get(), nullptr,
                                                     1 + 2 + UNSUPPORTED_LEN);
     memset(unsupportedLongSerialNumber->data, 0,
            unsupportedLongSerialNumber->len);
     unsupportedLongSerialNumber->data[0] = der::INTEGER;
     // Encoding the length takes two bytes: one byte to indicate that a
@@ -74,47 +64,32 @@ protected:
     // tag + length + value is 1 + 1 + LONGEST_REQUIRED_LEN
     longestRequiredSerialNumber = SECITEM_AllocItem(arena.get(), nullptr,
                                     1 + 1 + LONGEST_REQUIRED_LEN);
     memset(longestRequiredSerialNumber->data, 0,
            longestRequiredSerialNumber->len);
     longestRequiredSerialNumber->data[0] = der::INTEGER;
     longestRequiredSerialNumber->data[1] = LONGEST_REQUIRED_LEN;
     longestRequiredSerialNumber->data[2] = 0x01; // value is 0x010000...00
-
-    now = PR_Now();
-    oneDayBeforeNow = now - ONE_DAY;
-    oneDayAfterNow = now + ONE_DAY;
-  }
-
-  const SECItem*
-  ASCIIToDERName(const char* cn)
-  {
-    ScopedPtr<CERTName, CERT_DestroyName> certName(CERT_AsciiToName(cn));
-    if (!certName) {
-      return nullptr;
-    }
-    return SEC_ASN1EncodeItem(arena.get(), nullptr, certName.get(),
-                              SEC_ASN1_GET(CERT_NameTemplate));
   }
 
   void MakeTwoCerts(const char* issuerCN, SECItem* issuerSerial,
                     /*out*/ ScopedCERTCertificate& issuer,
                     const char* childCN, SECItem* childSerial,
                     /*out*/ ScopedCERTCertificate& child)
   {
-    const SECItem* issuerNameDer = ASCIIToDERName(issuerCN);
+    const SECItem* issuerNameDer = ASCIIToDERName(arena.get(), issuerCN);
     ASSERT_TRUE(issuerNameDer);
     ScopedSECKEYPrivateKey issuerKey;
     SECItem* issuerCertDer(CreateEncodedCertificate(arena.get(), v3,
                              SEC_OID_SHA256, issuerSerial, issuerNameDer,
                              oneDayBeforeNow, oneDayAfterNow, issuerNameDer,
                              nullptr, nullptr, SEC_OID_SHA256, issuerKey));
     ASSERT_TRUE(issuerCertDer);
-    const SECItem* childNameDer = ASCIIToDERName(childCN);
+    const SECItem* childNameDer = ASCIIToDERName(arena.get(), childCN);
     ASSERT_TRUE(childNameDer);
     ScopedSECKEYPrivateKey childKey;
     SECItem* childDer(CreateEncodedCertificate(arena.get(), v3,
                         SEC_OID_SHA256, childSerial, issuerNameDer,
                         oneDayBeforeNow, oneDayAfterNow, childNameDer, nullptr,
                         issuerKey.get(), SEC_OID_SHA256, childKey));
     ASSERT_TRUE(childDer);
     issuer = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), issuerCertDer,
--- a/security/pkix/test/lib/pkixtestutil.cpp
+++ b/security/pkix/test/lib/pkixtestutil.cpp
@@ -629,29 +629,29 @@ GenerateKeyPair(/*out*/ ScopedSECKEYPubl
   return SECFailure;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // Certificates
 
 static SECItem* TBSCertificate(PLArenaPool* arena, long version,
-                               SECItem* serialNumber, SECOidTag signature,
+                               const SECItem* serialNumber, SECOidTag signature,
                                const SECItem* issuer, PRTime notBefore,
                                PRTime notAfter, const SECItem* subject,
                                const SECKEYPublicKey* subjectPublicKey,
                                /*optional*/ SECItem const* const* extensions);
 
 // Certificate  ::=  SEQUENCE  {
 //         tbsCertificate       TBSCertificate,
 //         signatureAlgorithm   AlgorithmIdentifier,
 //         signatureValue       BIT STRING  }
 SECItem*
 CreateEncodedCertificate(PLArenaPool* arena, long version,
-                         SECOidTag signature, SECItem* serialNumber,
+                         SECOidTag signature, const SECItem* serialNumber,
                          const SECItem* issuerNameDER, PRTime notBefore,
                          PRTime notAfter, const SECItem* subjectNameDER,
                          /*optional*/ SECItem const* const* extensions,
                          /*optional*/ SECKEYPrivateKey* issuerPrivateKey,
                          SECOidTag signatureHashAlg,
                          /*out*/ ScopedSECKEYPrivateKey& privateKey)
 {
   PR_ASSERT(arena);
@@ -692,17 +692,17 @@ CreateEncodedCertificate(PLArenaPool* ar
 //      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,
-               SECItem* serialNumber, SECOidTag signatureOidTag,
+               const SECItem* serialNumber, SECOidTag signatureOidTag,
                const SECItem* issuer, PRTime notBeforeTime,
                PRTime notAfterTime, const SECItem* subject,
                const SECKEYPublicKey* subjectPublicKey,
                /*optional*/ SECItem const* const* extensions)
 {
   PR_ASSERT(arena);
   PR_ASSERT(issuer);
   PR_ASSERT(subject);
@@ -812,16 +812,33 @@ TBSCertificate(PLArenaPool* arena, long 
     if (output.Add(extensionsWrapped) != der::Success) {
       return nullptr;
     }
   }
 
   return output.Squash(arena, der::SEQUENCE);
 }
 
+const SECItem*
+ASCIIToDERName(PLArenaPool* arena, const char* cn)
+{
+  ScopedPtr<CERTName, CERT_DestroyName> certName(CERT_AsciiToName(cn));
+  if (!certName) {
+    return nullptr;
+  }
+  return SEC_ASN1EncodeItem(arena, nullptr, certName.get(),
+                            SEC_ASN1_GET(CERT_NameTemplate));
+}
+
+SECItem*
+CreateEncodedSerialNumber(PLArenaPool* arena, long serialNumberValue)
+{
+  return Integer(arena, serialNumberValue);
+}
+
 // BasicConstraints ::= SEQUENCE {
 //         cA                      BOOLEAN DEFAULT FALSE,
 //         pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
 SECItem*
 CreateEncodedBasicConstraints(PLArenaPool* arena, bool isCA,
                               long pathLenConstraintValue,
                               ExtensionCriticality criticality)
 {
--- a/security/pkix/test/lib/pkixtestutil.h
+++ b/security/pkix/test/lib/pkixtestutil.h
@@ -57,16 +57,19 @@ typedef mozilla::pkix::ScopedPtr<SECKEYP
 
 FILE* OpenFile(const char* dir, const char* filename, const char* mode);
 
 extern const PRTime ONE_DAY;
 
 SECStatus GenerateKeyPair(/*out*/ ScopedSECKEYPublicKey& publicKey,
                           /*out*/ ScopedSECKEYPrivateKey& privateKey);
 
+// The result will be owned by the arena
+const SECItem* ASCIIToDERName(PLArenaPool* arena, const char* cn);
+
 ///////////////////////////////////////////////////////////////////////////////
 // Encode Certificates
 
 enum Version { v1 = 0, v2 = 1, v3 = 2 };
 
 // serialNumber is assumed to be the DER encoding of an INTEGER.
 //
 // If extensions is null, then no extensions will be encoded. Otherwise,
@@ -75,25 +78,28 @@ enum Version { v1 = 0, v2 = 1, v3 = 2 };
 //
 // If issuerPrivateKey is null, then the certificate will be self-signed.
 // Parameter order is based on the order of the attributes of the certificate
 // in RFC 5280.
 //
 // The return value, if non-null, is owned by the arena in the context and
 // MUST NOT be freed.
 SECItem* CreateEncodedCertificate(PLArenaPool* arena, long version,
-                                  SECOidTag signature, SECItem* serialNumber,
+                                  SECOidTag signature,
+                                  const SECItem* serialNumber,
                                   const SECItem* issuerNameDER,
                                   PRTime notBefore, PRTime notAfter,
                                   const SECItem* subjectNameDER,
                      /*optional*/ SECItem const* const* extensions,
                      /*optional*/ SECKEYPrivateKey* issuerPrivateKey,
                                   SECOidTag signatureHashAlg,
                           /*out*/ ScopedSECKEYPrivateKey& privateKey);
 
+SECItem* CreateEncodedSerialNumber(PLArenaPool* arena, long value);
+
 MOZILLA_PKIX_ENUM_CLASS ExtensionCriticality { NotCritical = 0, Critical = 1 };
 
 // The return value, if non-null, is owned by the arena and MUST NOT be freed.
 SECItem* CreateEncodedBasicConstraints(PLArenaPool* arena, bool isCA,
                                        long pathLenConstraint,
                                        ExtensionCriticality criticality);
 
 // ekus must be non-null and must must point to a SEC_OID_UNKNOWN-terminated