Commit 0534b472 authored by Martin Thomson's avatar Martin Thomson

Merge NSS trunk to NSS_TLS13_DRAFT19_BRANCH

--HG--
branch : NSS_TLS13_DRAFT19_BRANCH
parents 0f52cc48 c4b72458
......@@ -1590,3 +1590,4 @@ bdf702cc0f766757d8221b1bb9a8a5a12f0183da NSS_3_25_BETA1
cc982d5a9904b9ec478eced92a3eea8ee0ee313a NSS_3_27_BETA1
d36a5c8225914f92c12f8e182d83f5b4727d327b NSS_3_27_BETA2
06ed5314230a8abc5436bdca2cc79e7de7f2828f NSS_3_27_BETA3
32c9bbad265504522441f601333f0b89861a15d1 NSS_3_34_BETA1
......@@ -256,26 +256,41 @@ check_abi()
fi
popd
ABI_PROBLEM_FOUND=0
ABI_REPORT=${OUTPUTDIR}/abi-diff.txt
rm -f ${ABI_REPORT}
PREVDIST=${HGDIR}/baseline/dist
NEWDIST=${HGDIR}/dist
ALL_SOs="libfreebl3.so libfreeblpriv3.so libnspr4.so libnss3.so libnssckbi.so libnssdbm3.so libnsssysinit.so libnssutil3.so libplc4.so libplds4.so libsmime3.so libsoftokn3.so libssl3.so"
for SO in ${ALL_SOs}; do
if [ ! -f nss/automation/abi-check/expected-report-$SO.txt ]; then
touch nss/automation/abi-check/expected-report-$SO.txt
if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then
touch ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt
fi
abidiff --hd1 $PREVDIST/public/ --hd2 $NEWDIST/public \
$PREVDIST/*/lib/$SO $NEWDIST/*/lib/$SO \
> nss/automation/abi-check/new-report-$SO.txt
diff -u nss/automation/abi-check/expected-report-$SO.txt \
nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT}
> ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt
if [ $? -ne 0 ]; then
ABI_PROBLEM_FOUND=1
fi
if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then
ABI_PROBLEM_FOUND=1
fi
diff -wB -u ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt \
${HGDIR}/nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT}
if [ ! -f ${ABI_REPORT} ]; then
ABI_PROBLEM_FOUND=1
fi
done
if [ -s ${ABI_REPORT} ]; then
print_log "FAILED: there are new unexpected ABI changes"
cat ${ABI_REPORT}
return 1
elif [ $ABI_PROBLEM_FOUND -ne 0 ]; then
print_log "FAILED: failure executing the ABI checks"
cat ${ABI_REPORT}
return 1
fi
return 0
......
This diff is collapsed.
......@@ -1312,15 +1312,12 @@ SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level)
return;
}
if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1);
return;
}
if (a->parameters.len == 0 ||
(a->parameters.len == 2 &&
PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) {
/* No arguments or NULL argument */
} else if (algtag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
secu_PrintRSAPSSParams(out, &a->parameters, "Parameters", level + 1);
} else {
/* Print args to algorithm */
SECU_PrintAsHex(out, &a->parameters, "Args", level + 1);
......
......@@ -10,7 +10,9 @@
#include <errno.h>
#include <stdio.h>
#include "nss.h"
#include "secport.h"
#include "secutil.h"
#include "ssl.h"
int
......@@ -19,6 +21,43 @@ main(int argc, char **argv)
const PRUint16 *cipherSuites = SSL_ImplementedCiphers;
int i;
int errCount = 0;
SECStatus rv;
PRErrorCode err;
char *certDir = NULL;
/* load policy from $SSL_DIR/pkcs11.txt, for testing */
certDir = SECU_DefaultSSLDir();
if (certDir) {
rv = NSS_Init(certDir);
} else {
rv = NSS_NoDB_Init(NULL);
}
if (rv != SECSuccess) {
err = PR_GetError();
++errCount;
fprintf(stderr, "NSS_Init failed: %s\n", PORT_ErrorToString(err));
goto out;
}
/* apply policy */
rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0);
if (rv != SECSuccess) {
err = PR_GetError();
++errCount;
fprintf(stderr, "NSS_SetAlgorithmPolicy failed: %s\n",
PORT_ErrorToString(err));
goto out;
}
/* update the default cipher suites according to the policy */
rv = SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
if (rv != SECSuccess) {
err = PR_GetError();
++errCount;
fprintf(stderr, "SSL_OptionSetDefault failed: %s\n",
PORT_ErrorToString(err));
goto out;
}
fputs("This version of libSSL supports these cipher suites:\n\n", stdout);
......@@ -58,5 +97,14 @@ main(int argc, char **argv)
info.isFIPS ? "FIPS" : "",
info.nonStandard ? "nonStandard" : "");
}
out:
rv = NSS_Shutdown();
if (rv != SECSuccess) {
err = PR_GetError();
++errCount;
fprintf(stderr, "NSS_Shutdown failed: %s\n", PORT_ErrorToString(err));
}
return errCount;
}
......@@ -63,6 +63,7 @@ NSS_SRCDIRS = \
pp \
pwdecrypt \
rsaperf \
rsapoptst \
sdrtest \
selfserv \
signtool \
......
This diff is collapsed.
# 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/.
{
'includes': [
'../../coreconf/config.gypi',
'../../cmd/platlibs.gypi'
],
'targets': [
{
'target_name': 'rsapoptst',
'type': 'executable',
'sources': [
'rsapoptst.c'
],
'dependencies': [
'<(DEPTH)/exports.gyp:dbm_exports',
'<(DEPTH)/exports.gyp:nss_exports',
]
}
],
'variables': {
'module': 'nss',
}
}
......@@ -10,6 +10,7 @@
'target_name': 'cpputil',
'type': 'static_library',
'sources': [
'databuffer.cc',
'dummy_io.cc',
'dummy_io_fwd.cc',
'tls_parser.cc',
......
/* -*- 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 "databuffer.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <iostream>
#if defined(WIN32) || defined(WIN64)
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif
namespace nss_test {
void DataBuffer::Assign(const uint8_t* data, size_t len) {
if (data) {
Allocate(len);
memcpy(static_cast<void*>(data_), static_cast<const void*>(data), len);
} else {
assert(len == 0);
data_ = nullptr;
len_ = 0;
}
}
// Write will do a new allocation and expand the size of the buffer if needed.
// Returns the offset of the end of the write.
size_t DataBuffer::Write(size_t index, const uint8_t* val, size_t count) {
assert(val);
if (index + count > len_) {
size_t newlen = index + count;
uint8_t* tmp = new uint8_t[newlen]; // Always > 0.
if (data_) {
memcpy(static_cast<void*>(tmp), static_cast<const void*>(data_), len_);
}
if (index > len_) {
memset(static_cast<void*>(tmp + len_), 0, index - len_);
}
delete[] data_;
data_ = tmp;
len_ = newlen;
}
if (data_) {
memcpy(static_cast<void*>(data_ + index), static_cast<const void*>(val),
count);
}
return index + count;
}
// Write an integer, also performing host-to-network order conversion.
// Returns the offset of the end of the write.
size_t DataBuffer::Write(size_t index, uint32_t val, size_t count) {
assert(count <= sizeof(uint32_t));
uint32_t nvalue = htonl(val);
auto* addr = reinterpret_cast<const uint8_t*>(&nvalue);
return Write(index, addr + sizeof(uint32_t) - count, count);
}
void DataBuffer::Splice(const uint8_t* ins, size_t ins_len, size_t index,
size_t remove) {
assert(ins);
uint8_t* old_value = data_;
size_t old_len = len_;
// The amount of stuff remaining from the tail of the old.
size_t tail_len = old_len - (std::min)(old_len, index + remove);
// The new length: the head of the old, the new, and the tail of the old.
len_ = index + ins_len + tail_len;
data_ = new uint8_t[len_ ? len_ : 1];
// The head of the old.
if (old_value) {
Write(0, old_value, (std::min)(old_len, index));
}
// Maybe a gap.
if (old_value && index > old_len) {
memset(old_value + index, 0, index - old_len);
}
// The new.
Write(index, ins, ins_len);
// The tail of the old.
if (tail_len > 0) {
Write(index + ins_len, old_value + index + remove, tail_len);
}
delete[] old_value;
}
// This can't use the same trick as Write(), since we might be reading from a
// smaller data source.
bool DataBuffer::Read(size_t index, size_t count, uint64_t* val) const {
assert(count <= sizeof(uint64_t));
assert(val);
if ((index > len()) || (count > (len() - index))) {
return false;
}
*val = 0;
for (size_t i = 0; i < count; ++i) {
*val = (*val << 8) | data()[index + i];
}
return true;
}
bool DataBuffer::Read(size_t index, size_t count, uint32_t* val) const {
assert(count <= sizeof(uint32_t));
uint64_t tmp;
if (!Read(index, count, &tmp)) {
return false;
}
*val = tmp & 0xffffffff;
return true;
}
size_t DataBuffer::logging_limit = 32;
/* static */ void DataBuffer::SetLogLimit(size_t limit) {
DataBuffer::logging_limit = limit;
}
} // namespace nss_test
......@@ -8,17 +8,9 @@
#define databuffer_h__
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <iostream>
#if defined(WIN32) || defined(WIN64)
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif
extern bool g_ssl_gtest_verbose;
namespace nss_test {
......@@ -50,80 +42,18 @@ class DataBuffer {
void Assign(const DataBuffer& other) { Assign(other.data(), other.len()); }
void Assign(const uint8_t* data, size_t len) {
if (data) {
Allocate(len);
memcpy(static_cast<void*>(data_), static_cast<const void*>(data), len);
} else {
assert(len == 0);
data_ = nullptr;
len_ = 0;
}
}
void Assign(const uint8_t* data, size_t len);
// Write will do a new allocation and expand the size of the buffer if needed.
// Returns the offset of the end of the write.
size_t Write(size_t index, const uint8_t* val, size_t count) {
assert(val);
if (index + count > len_) {
size_t newlen = index + count;
uint8_t* tmp = new uint8_t[newlen]; // Always > 0.
if (data_) {
memcpy(static_cast<void*>(tmp), static_cast<const void*>(data_), len_);
}
if (index > len_) {
memset(static_cast<void*>(tmp + len_), 0, index - len_);
}
delete[] data_;
data_ = tmp;
len_ = newlen;
}
if (data_) {
memcpy(static_cast<void*>(data_ + index), static_cast<const void*>(val),
count);
}
return index + count;
}
size_t Write(size_t index, const uint8_t* val, size_t count);
size_t Write(size_t index, const DataBuffer& buf) {
return Write(index, buf.data(), buf.len());
}
// Write an integer, also performing host-to-network order conversion.
// Returns the offset of the end of the write.
size_t Write(size_t index, uint32_t val, size_t count) {
assert(count <= sizeof(uint32_t));
uint32_t nvalue = htonl(val);
auto* addr = reinterpret_cast<const uint8_t*>(&nvalue);
return Write(index, addr + sizeof(uint32_t) - count, count);
}
// This can't use the same trick as Write(), since we might be reading from a
// smaller data source.
bool Read(size_t index, size_t count, uint64_t* val) const {
assert(count <= sizeof(uint64_t));
assert(val);
if ((index > len()) || (count > (len() - index))) {
return false;
}
*val = 0;
for (size_t i = 0; i < count; ++i) {
*val = (*val << 8) | data()[index + i];
}
return true;
}
// Overload because we have a lot of places where we are doing uint32_t
bool Read(size_t index, size_t count, uint32_t* val) const {
assert(count <= sizeof(uint32_t));
uint64_t tmp;
if (!Read(index, count, &tmp)) {
return false;
}
*val = tmp & 0xffffffff;
return true;
}
size_t Write(size_t index, uint32_t val, size_t count);
// Starting at |index|, remove |remove| bytes and replace them with the
// contents of |buf|.
......@@ -132,53 +62,30 @@ class DataBuffer {
}
void Splice(const uint8_t* ins, size_t ins_len, size_t index,
size_t remove = 0) {
assert(ins);
uint8_t* old_value = data_;
size_t old_len = len_;
// The amount of stuff remaining from the tail of the old.
size_t tail_len = old_len - (std::min)(old_len, index + remove);
// The new length: the head of the old, the new, and the tail of the old.
len_ = index + ins_len + tail_len;
data_ = new uint8_t[len_ ? len_ : 1];
// The head of the old.
if (old_value) {
Write(0, old_value, (std::min)(old_len, index));
}
// Maybe a gap.
if (old_value && index > old_len) {
memset(old_value + index, 0, index - old_len);
}
// The new.
Write(index, ins, ins_len);
// The tail of the old.
if (tail_len > 0) {
Write(index + ins_len, old_value + index + remove, tail_len);
}
delete[] old_value;
}
size_t remove = 0);
void Append(const DataBuffer& buf) { Splice(buf, len_); }
bool Read(size_t index, size_t count, uint64_t* val) const;
bool Read(size_t index, size_t count, uint32_t* val) const;
const uint8_t* data() const { return data_; }
uint8_t* data() { return data_; }
size_t len() const { return len_; }
bool empty() const { return len_ == 0; }
static void SetLogLimit(size_t limit);
friend std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf);
private:
static size_t logging_limit;
uint8_t* data_;
size_t len_;
};
static const size_t kMaxBufferPrint = 32;
inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) {
stream << "[" << buf.len() << "] ";
for (size_t i = 0; i < buf.len(); ++i) {
if (!g_ssl_gtest_verbose && i >= kMaxBufferPrint) {
if (i >= DataBuffer::logging_limit) {
stream << "...";
break;
}
......
......@@ -13,6 +13,7 @@ CPPSRCS = \
$(NULL)
else
CPPSRCS = \
databuffer.cc \
dummy_io.cc \
dummy_io_fwd.cc \
tls_parser.cc \
......
......@@ -455,6 +455,16 @@ of the attribute codes:
<listitem><para>Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537. The available alternate values are 3 and 17.</para></listitem>
</varlistentry>
<varlistentry>
<term>--pss</term>
<listitem><para>Restrict the generated certificate (with the <option>-S</option> option) or certificate request (with the <option>-R</option> option) to be used with the RSA-PSS signature scheme. This only works when the private key of the certificate or certificate request is RSA.</para></listitem>
</varlistentry>
<varlistentry>
<term>--pss-sign</term>
<listitem><para>Sign the generated certificate with the RSA-PSS signature scheme (with the <option>-C</option> or <option>-S</option> option). This only works when the private key of the signer's certificate is RSA. If the signer's certificate is restricted to RSA-PSS, it is not necessary to specify this option.</para></listitem>
</varlistentry>
<varlistentry>
<term>-z noise-file</term>
<listitem><para>Read a seed value from the specified file to generate a new private and public key pair. This argument makes it possible to use hardware-generated seed values or manually create a value from the keyboard. The minimum file size is 20 bytes.</para></listitem>
......
This diff is collapsed.
This diff is collapsed.
'\" t
.\" Title: CERTUTIL
.\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 8 September 2016
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
.\" Date: 27 October 2017
.\" Manual: NSS Security Tools
.\" Source: nss-tools
.\" Language: English
.\"
.TH "CERTUTIL" "1" "8 September 2016" "nss-tools" "NSS Security Tools"
.TH "CERTUTIL" "1" "27 October 2017" "nss-tools" "NSS Security Tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
......@@ -371,7 +371,7 @@ Read an alternate PQG value from the specified file when generating DSA key pair
\fBcertutil\fR
generates its own PQG value\&. PQG files are created with a separate DSA utility\&.
.sp
Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519.
Elliptic curve name is one of the ones from nistp256, nistp384, nistp521, curve25519\&.
.sp
If a token is available that supports more curves, the foolowing curves are supported as well: sect163k1, nistk163, sect163r1, sect163r2, nistb163, sect193r1, sect193r2, sect233k1, nistk233, sect233r1, nistb233, sect239k1, sect283k1, nistk283, sect283r1, nistb283, sect409k1, nistk409, sect409r1, nistb409, sect571k1, nistk571, sect571r1, nistb571, secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, nistp192, secp224k1, secp224r1, nistp224, secp256k1, secp256r1, secp384r1, secp521r1, prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2pnb272w1, c2pnb304w1, c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, secp112r2, secp128r1, secp128r2, sect113r1, sect113r2, sect131r1, sect131r2
.RE
......@@ -609,6 +609,24 @@ to generate the signature for a certificate being created or added to a database
Set an alternate exponent value to use in generating a new RSA public key for the database, instead of the default value of 65537\&. The available alternate values are 3 and 17\&.
.RE
.PP
\-\-pss
.RS 4
Restrict the generated certificate (with the
\fB\-S\fR
option) or certificate request (with the
\fB\-R\fR
option) to be used with the RSA\-PSS signature scheme\&. This only works when the private key of the certificate or certificate request is RSA\&.
.RE
.PP
\-\-pss\-sign
.RS 4
Sign the generated certificate with the RSA\-PSS signature scheme (with the
\fB\-C\fR
or
\fB\-S\fR
option)\&. This only works when the private key of the signer\*(Aqs certificate is RSA\&. If the signer\*(Aqs certificate is restricted to RSA\-PSS, it is not necessary to specify this option\&.
.RE
.PP
\-z noise\-file
.RS 4
Read a seed value from the specified file to generate a new private and public key pair\&. This argument makes it possible to use hardware\-generated seed values or manually create a value from the keyboard\&. The minimum file size is 20 bytes\&.
......@@ -1512,7 +1530,8 @@ There are ways to narrow the keys listed in the search results:
.IP \(bu 2.3
.\}
To return a specific key, use the
\fB\-n\fR\fIname\fR
\fB\-n\fR
\fIname\fR
argument with the name of the key\&.
.RE
.sp
......@@ -1525,7 +1544,8 @@ argument with the name of the key\&.
.IP \(bu 2.3
.\}
If there are multiple security devices loaded, then the
\fB\-h\fR\fItokenname\fR
\fB\-h\fR
\fItokenname\fR
argument can search a specific token or all tokens\&.
.RE
.sp
......@@ -1538,7 +1558,8 @@ argument can search a specific token or all tokens\&.
.IP \(bu 2.3
.\}
If there are multiple key types available, then the
\fB\-k\fR\fIkey\-type\fR
\fB\-k\fR
\fIkey\-type\fR
argument can search a specific type of key, like RSA, DSA, or ECC\&.
.RE
.PP
......
This diff is collapsed.
This diff is collapsed.
......@@ -2,6 +2,7 @@
* 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 <algorithm>
#include "shared.h"
#include "tls_parser.h"
......
......@@ -10,7 +10,7 @@
#include <cassert>
#include <vector>
std::vector<uint8_t> hex_string_to_bytes(std::string s) {
static inline std::vector<uint8_t> hex_string_to_bytes(std::string s) {
std::vector<uint8_t> bytes;
for (size_t i = 0; i < s.length(); i += 2) {
bytes.push_back(std::stoul(s.substr(i, 2), nullptr, 16));
......
#! gmake
#
# 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/.
#######################################################################
# (1) Include initial platform-independent assignments (MANDATORY). #
#######################################################################
include manifest.mn
#######################################################################
# (2) Include "global" configuration information. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include ../common/gtest.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
# 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/.
{
'includes': [
'../../coreconf/config.gypi',
'../common/gtest.gypi',
],
'targets': [
{
'target_name': 'cryptohi_gtest',
'type': 'executable',
'sources': [
'cryptohi_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',
'<(DEPTH)/lib/nss/nss.gyp:nss3',
]
}
],
'variables': {
'module': 'nss'
}
}
This diff is collapsed.
#
# 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 = \
cryptohi_unittest.cc \
$(NULL)
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
-I$(CORE_DEPTH)/gtests/common \
-I$(CORE_DEPTH)/cpputil
REQUIRES = nspr gtest
PROGRAM = cryptohi_gtest
EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) $(EXTRA_OBJS) \
$(DIST)/lib/$(LIB_PREFIX)gtestutil.$(LIB_SUFFIX)
......@@ -21,6 +21,7 @@ ifneq ($(NSS_BUILD_UTIL_ONLY),1)
NSS_SRCDIRS = \
certdb_gtest \
certhigh_gtest \
cryptohi_gtest \
der_gtest \
pk11_gtest \
softoken_gtest \
......