Bug 1280846 - tests: adjust gtests to compile under modular builds, r=franziskus
authorDaiki Ueno <dueno@redhat.com>
Thu, 01 Jun 2017 10:47:30 +0200
changeset 13434 a15755b99b544dc9643f6e3e7c3b36825112c5b2
parent 13433 d20ee6560caf7c8ed6640583791700451fe06921
child 13435 8445f247021a7cb13c08046698730aec77069b9f
push id2249
push userfranziskuskiefer@gmail.com
push dateMon, 12 Jun 2017 09:15:02 +0000
reviewersfranziskus
bugs1280846
Bug 1280846 - tests: adjust gtests to compile under modular builds, r=franziskus
cmd/platlibs.mk
cpputil/scoped_ptrs_util.h
gtests/certhigh_gtest/manifest.mn
gtests/common/gtests-util.cc
gtests/common/manifest.mn
gtests/der_gtest/der_getint_unittest.cc
gtests/der_gtest/der_gtest.gyp
gtests/der_gtest/der_quickder_unittest.cc
gtests/der_gtest/manifest.mn
gtests/manifest.mn
gtests/pk11_gtest/manifest.mn
gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
gtests/pk11_gtest/pk11_gtest.gyp
gtests/util_gtest/manifest.mn
gtests/util_gtest/util_b64_unittest.cc
gtests/util_gtest/util_pkcs11uri_unittest.cc
tests/gtests/gtests.sh
--- a/cmd/platlibs.mk
+++ b/cmd/platlibs.mk
@@ -27,16 +27,22 @@ endif
 endif # BUILD_SUN_PKG
 
 ifdef NSS_DISABLE_DBM
 DBMLIB = $(NULL)
 else
 DBMLIB = $(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) 
 endif
 
+ifeq ($(NSS_BUILD_UTIL_ONLY),1)
+SECTOOL_LIB = $(NULL)
+else
+SECTOOL_LIB = $(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX)
+endif
+
 ifdef USE_STATIC_LIBS
 
 DEFINES += -DNSS_USE_STATIC_LIBS
 # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 ifndef NSS_USE_SYSTEM_FREEBL
 CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
 SOFTOKENLIB=$(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX)
 else
@@ -65,30 +71,20 @@ PKIXLIB = \
 	$(DIST)/lib/$(LIB_PREFIX)pkixpki.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX)
 endif
 endif
 
 NSS_LIBS_1=
-SECTOOL_LIB=
 NSS_LIBS_2=
 NSS_LIBS_3=
 NSS_LIBS_4=
 
-ifneq ($(NSS_BUILD_UTIL_ONLY),1)
-SECTOOL_LIB = \
-	$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
-	$(NULL)
-else
-SECTOOL_LIB = \
-	$(NULL)
-endif
-
 ifneq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
 ifeq ($(OS_ARCH), WINNT)
 # breakdown for windows
 NSS_LIBS_1 = \
 	$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
 	$(NULL)
@@ -116,19 +112,16 @@ NSS_LIBS_4 = \
 	$(NULL)
 else
 # breakdown for others
 NSS_LIBS_1 = \
 	$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
 	$(NULL)
-SECTOOL_LIB = \
-	$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
-	$(NULL)
 NSS_LIBS_2 = \
 	$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
 	$(NULL)
 NSS_LIBS_3 = \
@@ -196,17 +189,17 @@ EXTRA_SHARED_LIBS += \
 endif
 
 else # USE_STATIC_LIBS
 # can't do this in manifest.mn because OS_ARCH isn't defined there.
 ifeq ($(OS_ARCH), WINNT)
 
 # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 EXTRA_LIBS += \
-	$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
+	$(SECTOOL_LIB) \
 	$(NSSUTIL_LIB_DIR)/$(IMPORT_LIB_PREFIX)nssutil3$(IMPORT_LIB_SUFFIX) \
 	$(DIST)/lib/$(IMPORT_LIB_PREFIX)smime3$(IMPORT_LIB_SUFFIX) \
 	$(DIST)/lib/$(IMPORT_LIB_PREFIX)ssl3$(IMPORT_LIB_SUFFIX) \
 	$(DIST)/lib/$(IMPORT_LIB_PREFIX)nss3$(IMPORT_LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4$(IMPORT_LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4$(IMPORT_LIB_SUFFIX) \
 	$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4$(IMPORT_LIB_SUFFIX) \
 	$(NULL)
@@ -215,17 +208,17 @@ EXTRA_LIBS += \
 #OS_LIBS += \
 	wsock32.lib \
 	winmm.lib \
 	$(NULL)
 else
 
 # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 EXTRA_LIBS += \
-	$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
+	$(SECTOOL_LIB) \
 	$(NULL)
 
 ifeq ($(OS_ARCH), AIX) 
 EXTRA_SHARED_LIBS += -brtl 
 endif
 
 # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
 # $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
@@ -233,23 +226,25 @@ EXTRA_SHARED_LIBS += \
 	-L$(DIST)/lib \
 	-L$(NSSUTIL_LIB_DIR) \
 	-lnssutil3 \
 	-L$(NSPR_LIB_DIR) \
 	-lplc4 \
 	-lplds4 \
 	-lnspr4 \
 	$(NULL)
+ifndef NSS_BUILD_UTIL_ONLY
 ifndef NSS_BUILD_SOFTOKEN_ONLY
 EXTRA_SHARED_LIBS += \
 	-lssl3 \
 	-lsmime3 \
 	-lnss3
 endif
 endif
+endif
 
 ifdef SOFTOKEN_LIB_DIR
 ifdef NSS_USE_SYSTEM_FREEBL
 EXTRA_SHARED_LIBS += -L$(SOFTOKEN_LIB_DIR) -lsoftokn3
 endif
 endif
 
 endif # USE_STATIC_LIBS
new file mode 100644
--- /dev/null
+++ b/cpputil/scoped_ptrs_util.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef scoped_ptrs_util_h__
+#define scoped_ptrs_util_h__
+
+#include <memory>
+#include "pkcs11uri.h"
+#include "secoid.h"
+
+struct ScopedDelete {
+  void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); }
+  void operator()(SECItem* item) { SECITEM_FreeItem(item, true); }
+  void operator()(PK11URI* uri) { PK11URI_DestroyURI(uri); }
+  void operator()(PLArenaPool* arena) { PORT_FreeArena(arena, PR_FALSE); }
+};
+
+template <class T>
+struct ScopedMaybeDelete {
+  void operator()(T* ptr) {
+    if (ptr) {
+      ScopedDelete del;
+      del(ptr);
+    }
+  }
+};
+
+#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped##x
+
+SCOPED(SECAlgorithmID);
+SCOPED(SECItem);
+SCOPED(PK11URI);
+
+#undef SCOPED
+
+#endif  // scoped_ptrs_util_h__
--- a/gtests/certhigh_gtest/manifest.mn
+++ b/gtests/certhigh_gtest/manifest.mn
@@ -9,14 +9,14 @@ MODULE = nss
 CPPSRCS = \
       certhigh_unittest.cc \
       $(NULL)
 
 INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
             -I$(CORE_DEPTH)/gtests/common \
             -I$(CORE_DEPTH)/cpputil
 
-REQUIRES = nspr nss libdbm gtest
+REQUIRES = nspr gtest
 
 PROGRAM = certhigh_gtest
 
 EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \
-             ../common/$(OBJDIR)/gtests$(OBJ_SUFFIX)
+             $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX)
new file mode 100644
--- /dev/null
+++ b/gtests/common/gtests-util.cc
@@ -0,0 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nspr.h"
+#include "secoid.h"
+
+#include <cstdlib>
+
+#define GTEST_HAS_RTTI 0
+#include "gtest/gtest.h"
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+
+  if (SECOID_Init() != SECSuccess) {
+    return 1;
+  }
+  int rv = RUN_ALL_TESTS();
+
+  if (SECOID_Shutdown() != SECSuccess) {
+    return 1;
+  }
+
+  return rv;
+}
--- a/gtests/common/manifest.mn
+++ b/gtests/common/manifest.mn
@@ -1,22 +1,23 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 CORE_DEPTH = ../..
 DEPTH      = ../..
 MODULE = nss
 
-CPPSRCS = \
-      gtests.cc \
-      $(NULL)
+LIBRARY_NAME = gtestutil
+
+ifeq ($(NSS_BUILD_UTIL_ONLY),1)
+CPPSRCS = gtests-util.cc
+else
+CPPSRCS = gtests.cc
+endif
 
 INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
             -I$(CORE_DEPTH)/gtests/common \
             -I$(CORE_DEPTH)/cpputil
 
 REQUIRES = gtest
 
 EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX)
-
-# NOTE: this is not actually used but required to build gtests.o
-PROGRAM = gtests
--- a/gtests/der_gtest/der_getint_unittest.cc
+++ b/gtests/der_gtest/der_getint_unittest.cc
@@ -1,22 +1,21 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "secder.h"
+#include "secerr.h"
+
 #include <climits>
 #include <memory>
-#include "nss.h"
-#include "pk11pub.h"
-#include "secutil.h"
 
 #include "gtest/gtest.h"
-#include "scoped_ptrs.h"
 
 namespace nss_test {
 
 class DERIntegerDecodingTest : public ::testing::Test {
  public:
   void TestGetInteger(long number, unsigned char *der_number,
                       unsigned int len) {
     SECItem input = {siBuffer, der_number, len};
--- a/gtests/der_gtest/der_gtest.gyp
+++ b/gtests/der_gtest/der_gtest.gyp
@@ -7,17 +7,16 @@
     '../common/gtest.gypi',
   ],
   'targets': [
     {
       'target_name': 'der_gtest',
       'type': 'executable',
       'sources': [
         'der_getint_unittest.cc',
-        'der_private_key_import_unittest.cc',
         'der_quickder_unittest.cc',
         '<(DEPTH)/gtests/common/gtests.cc'
       ],
       'dependencies': [
         '<(DEPTH)/exports.gyp:nss_exports',
         '<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
         '<(DEPTH)/lib/util/util.gyp:nssutil3',
         '<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
--- a/gtests/der_gtest/der_quickder_unittest.cc
+++ b/gtests/der_gtest/der_quickder_unittest.cc
@@ -2,21 +2,22 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdint.h>
 
 #include "gtest/gtest.h"
-#include "scoped_ptrs.h"
+#include "scoped_ptrs_util.h"
 
 #include "nss.h"
 #include "prerror.h"
 #include "secasn1.h"
+#include "secder.h"
 #include "secerr.h"
 #include "secitem.h"
 
 const SEC_ASN1Template mySEC_NullTemplate[] = {
     {SEC_ASN1_NULL, 0, NULL, sizeof(SECItem)}};
 
 namespace nss_test {
 
--- a/gtests/der_gtest/manifest.mn
+++ b/gtests/der_gtest/manifest.mn
@@ -3,22 +3,21 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 CORE_DEPTH = ../..
 DEPTH      = ../..
 MODULE = nss
 
 CPPSRCS = \
       der_getint_unittest.cc \
-      der_private_key_import_unittest.cc \
       der_quickder_unittest.cc \
       $(NULL)
 
 INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
             -I$(CORE_DEPTH)/gtests/common \
             -I$(CORE_DEPTH)/cpputil
 
-REQUIRES = nspr nss libdbm gtest
+REQUIRES = nspr gtest
 
 PROGRAM = der_gtest
 
 EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \
-             ../common/$(OBJDIR)/gtests$(OBJ_SUFFIX)
+             $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX)
--- a/gtests/manifest.mn
+++ b/gtests/manifest.mn
@@ -1,18 +1,36 @@
 # 
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 CORE_DEPTH = ..
 DEPTH      = ..
 
-DIRS = \
+LIB_SRCDIRS = \
 	google_test \
 	common \
+	$(NULL)
+
+ifneq ($(NSS_BUILD_WITHOUT_UTIL),1)
+UTIL_SRCDIRS = \
+	util_gtest \
+	der_gtest \
+	$(NULL)
+endif
+
+ifneq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
+ifneq ($(NSS_BUILD_UTIL_ONLY),1)
+NSS_SRCDIRS = \
 	certdb_gtest \
 	certhigh_gtest \
-	der_gtest \
-	util_gtest \
 	pk11_gtest \
 	ssl_gtest \
         nss_bogo_shim \
 	$(NULL)
+endif
+endif
+
+DIRS = \
+	$(LIB_SRCDIRS) \
+	$(UTIL_SRCDIRS) \
+	$(NSS_SRCDIRS) \
+	$(NULL)
--- a/gtests/pk11_gtest/manifest.mn
+++ b/gtests/pk11_gtest/manifest.mn
@@ -11,21 +11,22 @@ CPPSRCS = \
       pk11_chacha20poly1305_unittest.cc \
       pk11_curve25519_unittest.cc \
       pk11_ecdsa_unittest.cc \
       pk11_export_unittest.cc \
       pk11_pbkdf2_unittest.cc \
       pk11_prf_unittest.cc \
       pk11_prng_unittest.cc \
       pk11_rsapss_unittest.cc \
+      pk11_der_private_key_import_unittest.cc \
       $(NULL)
 
 INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
             -I$(CORE_DEPTH)/gtests/common \
             -I$(CORE_DEPTH)/cpputil
 
 REQUIRES = nspr nss libdbm gtest
 
 PROGRAM = pk11_gtest
 
 EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \
-             ../common/$(OBJDIR)/gtests$(OBJ_SUFFIX)
+             $(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX)
 
new file mode 100644
--- /dev/null
+++ b/gtests/pk11_gtest/pk11_der_private_key_import_unittest.cc
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <climits>
+#include <memory>
+#include "nss.h"
+#include "pk11pub.h"
+#include "secutil.h"
+
+#include "gtest/gtest.h"
+#include "scoped_ptrs.h"
+
+namespace nss_test {
+
+const std::vector<uint8_t> kValidRSAKey = {
+    // 512-bit RSA private key (PKCS#8)
+    0x30, 0x82, 0x01, 0x54, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+    0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
+    0xa2, 0x40, 0xce, 0xb5, 0x4e, 0x70, 0xdc, 0x14, 0x82, 0x5b, 0x58, 0x7d,
+    0x2f, 0x5d, 0xfd, 0x46, 0x3c, 0x4b, 0x82, 0x50, 0xb6, 0x96, 0x00, 0x4a,
+    0x1a, 0xca, 0xaf, 0xe4, 0x9b, 0xcf, 0x38, 0x4a, 0x46, 0xaa, 0x9f, 0xb4,
+    0xd9, 0xc7, 0xee, 0x88, 0xe9, 0xef, 0x0a, 0x31, 0x5f, 0x53, 0x86, 0x8f,
+    0x63, 0x68, 0x0b, 0x58, 0x34, 0x72, 0x49, 0xba, 0xed, 0xd9, 0x34, 0x15,
+    0x16, 0xc4, 0xca, 0xb7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x34,
+    0xe6, 0xdc, 0x7e, 0xd0, 0xec, 0x8b, 0x55, 0x44, 0x8b, 0x73, 0xf6, 0x9d,
+    0x13, 0x10, 0x19, 0x6e, 0x5f, 0x50, 0x45, 0xf0, 0xc2, 0x47, 0xa5, 0xe1,
+    0xc6, 0x64, 0x43, 0x2d, 0x6a, 0x0a, 0xf7, 0xe7, 0xda, 0x40, 0xb8, 0x3a,
+    0xf0, 0x47, 0xdd, 0x01, 0xf5, 0xe0, 0xa9, 0x0e, 0x47, 0xc2, 0x24, 0xd7,
+    0xb5, 0x13, 0x3a, 0x35, 0x4d, 0x11, 0xaa, 0x50, 0x03, 0xb3, 0xe8, 0x54,
+    0x6c, 0x99, 0x01, 0x02, 0x21, 0x00, 0xcd, 0xb2, 0xd7, 0xa7, 0x43, 0x5b,
+    0xcb, 0x45, 0xe5, 0x0e, 0x86, 0xf6, 0xc1, 0x4e, 0x97, 0xed, 0x78, 0x1f,
+    0x09, 0x56, 0xcd, 0x26, 0xe6, 0xf7, 0x5e, 0xd9, 0xfc, 0x88, 0x12, 0x5f,
+    0x84, 0x07, 0x02, 0x21, 0x00, 0xc9, 0xee, 0x30, 0xaf, 0x6c, 0xb9, 0x5a,
+    0xc9, 0xc1, 0x14, 0x9e, 0xd8, 0x4b, 0x33, 0x38, 0x48, 0x17, 0x41, 0x35,
+    0x94, 0x09, 0xf3, 0x69, 0xc4, 0x97, 0xbe, 0x17, 0x7d, 0x95, 0x0f, 0xb7,
+    0xd1, 0x02, 0x21, 0x00, 0x8b, 0x0e, 0xf9, 0x8d, 0x61, 0x13, 0x20, 0x63,
+    0x9b, 0x0b, 0x6c, 0x20, 0x4a, 0xe4, 0xa7, 0xfe, 0xe8, 0xf3, 0x0a, 0x6c,
+    0x3c, 0xfa, 0xac, 0xaf, 0xd4, 0xd6, 0xc7, 0x4a, 0xf2, 0x28, 0xd2, 0x67,
+    0x02, 0x20, 0x6b, 0x0e, 0x1d, 0xbf, 0x93, 0x5b, 0xbd, 0x77, 0x43, 0x27,
+    0x24, 0x83, 0xb5, 0x72, 0xa5, 0x3f, 0x0b, 0x1d, 0x26, 0x43, 0xa2, 0xf6,
+    0xea, 0xb7, 0x30, 0x5f, 0xb6, 0x62, 0x7c, 0xf9, 0x85, 0x51, 0x02, 0x20,
+    0x3d, 0x22, 0x63, 0x15, 0x6b, 0x32, 0x41, 0x46, 0x44, 0x78, 0xb7, 0x13,
+    0xeb, 0x85, 0x4c, 0x4f, 0x6b, 0x3e, 0xf0, 0x52, 0xf0, 0x46, 0x3b, 0x65,
+    0xd8, 0x21, 0x7d, 0xae, 0xc0, 0x09, 0x98, 0x34};
+
+const std::vector<uint8_t> kInvalidLengthKey = {
+    0x30, 0x1b,        // SEQUENCE(len=27)
+    0x02, 0x01, 0x00,  // INT(len=1) = 0
+    0x30, 0x13,        // SEQUENCE(len=19)
+    0x06, 0x07,        // OID(len=7)
+    // dhPublicKey (1.2.840.10046.2.1)
+    0x2a, 0x86, 0x48, 0xce, 0x3e, 0x02, 0x01, 0x06, 0x08,  // OID(len=8)
+    // prime256v1 (1.2.840.10045.3.1.7) */
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04,
+    0x00  // OCTET STRING(len=0)
+};
+
+const std::vector<uint8_t> kInvalidZeroLengthKey = {
+    0x30, 0x1a,        // SEQUENCE(len=26)
+    0x02, 0x01, 0x00,  // INT(len=1) = 0
+    0x30, 0x13,        // SEQUENCE(len=19)
+    0x06, 0x07,        // OID(len=7)
+    // dhPublicKey (1.2.840.10046.2.1)
+    0x2a, 0x86, 0x48, 0xce, 0x3e, 0x02, 0x01, 0x06, 0x08,  // OID(len=8)
+    // prime256v1 (1.2.840.10045.3.1.7) */
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x04,
+    0x00  // OCTET STRING(len=0)
+};
+
+class DERPrivateKeyImportTest : public ::testing::Test {
+ public:
+  bool ParsePrivateKey(const std::vector<uint8_t>& data) {
+    ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
+    EXPECT_TRUE(slot);
+
+    SECKEYPrivateKey* key = nullptr;
+    SECItem item = {siBuffer, const_cast<unsigned char*>(data.data()),
+                    (unsigned int)data.size()};
+
+    SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+        slot.get(), &item, nullptr, nullptr, false, false, KU_ALL, &key,
+        nullptr);
+
+    EXPECT_EQ(rv == SECSuccess, key != nullptr);
+    SECKEY_DestroyPrivateKey(key);
+
+    return rv == SECSuccess;
+  }
+};
+
+TEST_F(DERPrivateKeyImportTest, ImportPrivateRSAKey) {
+  EXPECT_TRUE(ParsePrivateKey(kValidRSAKey));
+  EXPECT_FALSE(PORT_GetError());
+}
+
+TEST_F(DERPrivateKeyImportTest, ImportInvalidPrivateKey) {
+  EXPECT_FALSE(ParsePrivateKey(kInvalidLengthKey));
+  EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_DER);
+}
+
+TEST_F(DERPrivateKeyImportTest, ImportZeroLengthPrivateKey) {
+  EXPECT_FALSE(ParsePrivateKey(kInvalidZeroLengthKey));
+  EXPECT_EQ(PORT_GetError(), SEC_ERROR_BAD_KEY);
+}
+
+}  // namespace nss_test
--- a/gtests/pk11_gtest/pk11_gtest.gyp
+++ b/gtests/pk11_gtest/pk11_gtest.gyp
@@ -15,16 +15,17 @@
         'pk11_aes_gcm_unittest.cc',
         'pk11_chacha20poly1305_unittest.cc',
         'pk11_curve25519_unittest.cc',
         'pk11_ecdsa_unittest.cc',
         'pk11_pbkdf2_unittest.cc',
         'pk11_prf_unittest.cc',
         'pk11_prng_unittest.cc',
         'pk11_rsapss_unittest.cc',
+        'pk11_der_private_key_import_unittest.cc',
         '<(DEPTH)/gtests/common/gtests.cc'
       ],
       'dependencies': [
         '<(DEPTH)/exports.gyp:nss_exports',
         '<(DEPTH)/lib/util/util.gyp:nssutil3',
         '<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
       ],
       'conditions': [
--- a/gtests/util_gtest/manifest.mn
+++ b/gtests/util_gtest/manifest.mn
@@ -20,10 +20,10 @@ INCLUDES += \
 
 REQUIRES = nspr gtest
 
 PROGRAM = util_gtest
 
 EXTRA_LIBS = \
 	$(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \
 	$(DIST)/lib/$(LIB_PREFIX)nssutil.$(LIB_SUFFIX) \
-	../common/$(OBJDIR)/gtests$(OBJ_SUFFIX) \
+	$(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX) \
 	$(NULL)
--- a/gtests/util_gtest/util_b64_unittest.cc
+++ b/gtests/util_gtest/util_b64_unittest.cc
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <climits>
 #include <memory>
 #include "nssb64.h"
 
 #include "gtest/gtest.h"
-#include "scoped_ptrs.h"
+#include "scoped_ptrs_util.h"
 
 namespace nss_test {
 
 class B64EncodeDecodeTest : public ::testing::Test {
  public:
   void TestDecodeStr(const std::string &str) {
     ScopedSECItem tmp(
         NSSBase64_DecodeBuffer(nullptr, nullptr, str.c_str(), str.size()));
--- a/gtests/util_gtest/util_pkcs11uri_unittest.cc
+++ b/gtests/util_gtest/util_pkcs11uri_unittest.cc
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <climits>
 #include <memory>
 #include "pkcs11uri.h"
 
 #include "gtest/gtest.h"
-#include "scoped_ptrs.h"
+#include "scoped_ptrs_util.h"
 
 namespace nss_test {
 
 class PK11URITest : public ::testing::Test {
  public:
   bool TestCreate(const PK11URIAttribute *pattrs, size_t num_pattrs,
                   const PK11URIAttribute *qattrs, size_t num_qattrs) {
     ScopedPK11URI tmp(
--- a/tests/gtests/gtests.sh
+++ b/tests/gtests/gtests.sh
@@ -19,17 +19,17 @@
 
 ############################## gtest_init ##############################
 # local shell function to initialize this script
 ########################################################################
 gtest_init()
 {
   cd "$(dirname "$1")"
   if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
-      cd common
+      cd ../common
       . ./init.sh
   fi
 
   SCRIPTNAME=gtests.sh
 
   if [ -z "${CLEANUP}" ] ; then   # if nobody else is responsible for
     CLEANUP="${SCRIPTNAME}"       # cleaning this script will do it
   fi