Bug 1724869 - land NSS 56238350052a UPGRADE_NSS_RELEASE, r=djackson

Differential Revision: https://phabricator.services.mozilla.com/D122202
This commit is contained in:
Benjamin Beurdouche 2021-08-10 09:52:10 +00:00
parent 3095d71dc7
commit 46e2563077
20 changed files with 690 additions and 22523 deletions

View File

@ -1 +1 @@
NSS_3_69_RTM
56238350052a

View File

@ -35,6 +35,7 @@ RUN apt-get update \
valgrind \
zlib1g-dev \
clang-format-3.9 \
sqlite3 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get autoremove -y && apt-get clean -y

View File

@ -11,6 +11,7 @@ RUN apt-get update \
make \
patch \
mercurial \
sqlite3 \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get autoremove -y && apt-get clean -y

View File

@ -20,6 +20,7 @@ RUN apt-get update \
mercurial \
ninja-build \
pkg-config \
sqlite3 \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get autoremove -y && apt-get clean -y

View File

@ -10,3 +10,4 @@
*/
#error "Do not include this header file."

View File

@ -8,6 +8,7 @@ Releases
:glob:
:hidden:
nss_3_69.rst
nss_3_68.rst
nss_3_67.rst
nss_3_66.rst
@ -16,22 +17,21 @@ Releases
.. note::
**NSS 3.68** is the latest version of NSS.
**NSS 3.69** is the latest version of NSS.
Complete release notes are available here: :ref:`mozilla_projects_nss_nss_3_68_release_notes`
Complete release notes are available here: :ref:`mozilla_projects_nss_nss_3_69_release_notes`
.. container::
Changes included in this release:
- Bug 1709654 - Update for NetBSD configuration.
- Bug 1709750 - Disable HPKE test when fuzzing.
- Bug 1566124 - Optimize AES-GCM for ppc64le.
- Bug 1699021 - Add AES-256-GCM to HPKE.
- Bug 1698419 - ECH -10 updates.
- Bug 1692930 - Update HPKE to final version.
- Bug 1707130 - NSS should use modern algorithms in PKCS#12 files by default.
- Bug 1703936 - New coverity/cpp scanner errors.
- Bug 1697303 - NSS needs to update it's csp clearing to FIPS 180-3 standards.
- Bug 1702663 - Need to support RSA PSS with Hashing PKCS #11 Mechanisms.
- Bug 1705119 - Deadlock when using GCM and non-thread safe tokens.
- Bug 1722613 - Disable DTLS 1.0 and 1.1 by default
- Bug 1720226 - integrity checks in key4.db not happening on private components with AES_CBC
- Bug 1720235 - SSL handling of signature algorithms ignores environmental invalid algorithms.
- Bug 1721476 - sqlite 3.34 changed it's open semantics, causing nss failures.
- Bug 1720230 - Gtest update changed the gtest reports, losing gtest details in all.sh reports.
- Bug 1720228 - NSS incorrectly accepting 1536 bit DH primes in FIPS mode
- Bug 1720232 - SQLite calls could timeout in starvation situations.
- Bug 1720225 - Coverity/cpp scanner errors found in nss 3.67
- Bug 1709817 - Import the NSS documentation from MDN in nss/doc.
- Bug 1720227 - NSS using a tempdir to measure sql performance not active

View File

@ -0,0 +1,64 @@
.. _mozilla_projects_nss_nss_3_69_release_notes:
NSS 3.69 release notes
======================
`Introduction <#introduction>`__
--------------------------------
.. container::
Network Security Services (NSS) 3.69 was released on **5 August 2021**.
.. _distribution_information:
`Distribution Information <#distribution_information>`__
--------------------------------------------------------
.. container::
The HG tag is NSS_3_69_RTM. NSS 3.69 requires NSPR 4.32 or newer.
NSS 3.69 source distributions are available on ftp.mozilla.org for secure HTTPS download:
- Source tarballs:
https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_69_RTM/src/
Other releases are available :ref:`mozilla_projects_nss_releases`.
.. _bugs_fixed_in_nss_3.69:
`Bugs fixed in NSS 3.69 <#bugs_fixed_in_nss_3.69>`__
----------------------------------------------------
.. container::
- Bug 1722613 - Disable DTLS 1.0 and 1.1 by default
- Bug 1720226 - integrity checks in key4.db not happening on private components with AES_CBC
- Bug 1720235 - SSL handling of signature algorithms ignores environmental invalid algorithms.
- Bug 1721476 - sqlite 3.34 changed it's open semantics, causing nss failures.
- Bug 1720230 - Gtest update changed the gtest reports, losing gtest details in all.sh reports.
- Bug 1720228 - NSS incorrectly accepting 1536 bit DH primes in FIPS mode
- Bug 1720232 - SQLite calls could timeout in starvation situations.
- Bug 1720225 - Coverity/cpp scanner errors found in nss 3.67
- Bug 1709817 - Import the NSS documentation from MDN in nss/doc.
- Bug 1720227 - NSS using a tempdir to measure sql performance not active
`Compatibility <#compatibility>`__
----------------------------------
.. container::
NSS 3.69 shared libraries are backwards-compatible with all older NSS 3.x shared libraries. A
program linked with older NSS 3.x shared libraries will work with NSS 3.69 shared libraries
without recompiling or relinking. Furthermore, applications that restrict their use of NSS APIs
to the functions listed in NSS Public Functions will remain compatible with future versions of
the NSS shared libraries.
`Feedback <#feedback>`__
------------------------
.. container::
Bugs discovered should be reported by filing a bug report on
`bugzilla.mozilla.org <https://bugzilla.mozilla.org/enter_bug.cgi?product=NSS>`__ (product NSS).

View File

@ -6,6 +6,15 @@
#define GTEST_HAS_RTTI 0
#include "gtest/gtest.h"
// Tests are passed the location of their source directory
// so that they can load extra resources from there.
std::string g_source_dir;
void usage(const char *progname) {
PR_fprintf(PR_STDERR, "Usage: %s [-s <dir>] [-d <dir> [-w]]\n", progname);
exit(2);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
@ -13,13 +22,18 @@ int main(int argc, char **argv) {
uint32_t flags = NSS_INIT_READONLY;
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], "-d")) {
if (!strcmp(argv[i], "-s")) {
if (i + 1 >= argc) {
PR_fprintf(PR_STDERR, "Usage: %s [-d <dir> [-w]]\n", argv[0]);
exit(2);
usage(argv[0]);
}
workdir = argv[i + 1];
i++;
g_source_dir = argv[i];
} else if (!strcmp(argv[i], "-d")) {
if (i + 1 >= argc) {
usage(argv[0]);
}
i++;
workdir = argv[i];
} else if (!strcmp(argv[i], "-w")) {
flags &= ~NSS_INIT_READONLY;
}

View File

@ -1,62 +0,0 @@
#!/usr/bin/env python3
# This script converts the test vectors referenced by the specification into
# a form that matches our implementation.
import json
import sys
def pkcs8(sk, pk):
print(
f'"3067020100301406072a8648ce3d020106092b06010401da470f01044c304a0201010420{sk}a123032100{pk}",'
)
i = 0
for tc in json.load(sys.stdin):
# Only mode_base and mode_psk
if tc["mode"] != 0 and tc["mode"] != 1:
continue
# X25519
if tc["kem_id"] != 32:
continue
# SHA-2 256, 384, and 512 (1..3)
if not tc["kdf_id"] in [1, 2, 3]:
continue
# AES-128-GCM, AES-256-GCM, and ChaCha20Poly1305 (1..3 also)
if not tc["aead_id"] in [1, 2, 3]:
continue
print(f"{{{i},")
print(f"static_cast<HpkeModeId>({tc['mode']}),")
print(f"static_cast<HpkeKemId>({tc['kem_id']}),")
print(f"static_cast<HpkeKdfId>({tc['kdf_id']}),")
print(f"static_cast<HpkeAeadId>({tc['aead_id']}),")
print(f'"{tc["info"]}", // info')
pkcs8(tc["skEm"], tc["pkEm"])
pkcs8(tc["skRm"], tc["pkRm"])
print(f'"{tc.get("psk", "")}", // psk')
print(f'"{tc.get("psk_id", "")}", // psk_id')
print(f'"{tc["enc"]}", // enc')
print(f'"{tc["key"]}", // key')
print(f'"{tc["base_nonce"]}", // nonce')
print("{ // Encryptions")
for e in tc["encryptions"]:
print("{")
print(f'"{e["plaintext"]}", // pt')
print(f'"{e["aad"]}", // aad')
print(f'"{e["ciphertext"]}", // ct')
print("},")
print("},")
print("{ // Exports")
for e in tc["exports"]:
print("{")
print(f'"{e["exporter_context"]}", // context')
print(f'{e["L"]}, // len')
print(f'"{e["exported_value"]}", // exported')
print("},")
print("},")
print("},")
i = i + 1

File diff suppressed because it is too large Load Diff

View File

@ -271,19 +271,3 @@ TEST_F(Blake2BTests, EmptyKeyTest) {
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
if (NSS_NoDB_Init(nullptr) != SECSuccess) {
return 1;
}
int rv = RUN_ALL_TESTS();
if (NSS_Shutdown() != SECSuccess) {
return 1;
}
return rv;
}

View File

@ -30,12 +30,14 @@
'target_name': 'freebl_gtest',
'type': 'executable',
'sources': [
'mpi_unittest.cc',
'blake2b_unittest.cc',
'cmac_unittests.cc',
'dh_unittest.cc',
'ecl_unittest.cc',
'ghash_unittest.cc',
'mpi_unittest.cc',
'prng_kat_unittest.cc',
'rsa_unittest.cc',
'cmac_unittests.cc',
'<(DEPTH)/gtests/common/gtests.cc'
],
'dependencies': [
@ -50,28 +52,6 @@
}],
],
},
{
'target_name': 'prng_gtest',
'type': 'executable',
'sources': [
'prng_kat_unittest.cc',
],
'dependencies': [
'freebl_gtest_deps',
'<(DEPTH)/exports.gyp:nss_exports',
],
},
{
'target_name': 'blake2b_gtest',
'type': 'executable',
'sources': [
'blake2b_unittest.cc',
],
'dependencies': [
'freebl_gtest_deps',
'<(DEPTH)/exports.gyp:nss_exports',
],
},
],
'target_defaults': {
'include_dirs': [

View File

@ -15,9 +15,11 @@
#include "blapi.h"
extern std::string g_source_dir;
namespace nss_test {
typedef struct PRNGTestValuesStr {
struct PRNGTestValues {
std::vector<uint8_t> entropy;
std::vector<uint8_t> nonce;
std::vector<uint8_t> personal;
@ -25,9 +27,7 @@ typedef struct PRNGTestValuesStr {
std::vector<uint8_t> additional_entropy;
std::vector<uint8_t> additional_input_reseed;
std::vector<std::vector<uint8_t>> additional_input;
} PRNGTestValues;
std::vector<PRNGTestValues> test_vector;
};
bool contains(std::string& s, const char* to_find) {
return s.find(to_find) != std::string::npos;
@ -59,8 +59,10 @@ void print_bytes(std::vector<uint8_t> bytes, std::string name) {
std::cout << std::endl;
}
static void ReadFile(const std::string file_name) {
static std::vector<PRNGTestValues> ReadFile(const std::string file_name) {
std::vector<PRNGTestValues> test_vector;
std::ifstream infile(file_name);
EXPECT_FALSE(infile.fail()) << "kat file: " << file_name;
std::string line;
// Variables holding the input for each test.
@ -123,11 +125,17 @@ static void ReadFile(const std::string file_name) {
test = {};
infile.seekg(pos);
}
return test_vector;
}
class PRNGTest : public ::testing::TestWithParam<PRNGTestValues> {
class PRNGTest : public ::testing::Test {
protected:
void RunTest(PRNGTestValues test) {
void SetUp() override {
test_vector_ = ReadFile(::g_source_dir + "/kat/Hash_DRBG.rsp");
ASSERT_FALSE(test_vector_.empty());
}
void RunTest(PRNGTestValues& test) {
ASSERT_EQ(2U, test.additional_input.size());
SECStatus rv = PRNGTEST_Instantiate_Kat(
test.entropy.data(), test.entropy.size(), test.nonce.data(),
@ -154,34 +162,15 @@ class PRNGTest : public ::testing::TestWithParam<PRNGTestValues> {
rv = PRNGTEST_Uninstantiate();
ASSERT_EQ(SECSuccess, rv);
}
protected:
std::vector<PRNGTestValues> test_vector_;
};
TEST_P(PRNGTest, HashDRBG) { RunTest(GetParam()); }
INSTANTIATE_TEST_SUITE_P(NISTTestVector, PRNGTest,
::testing::ValuesIn(test_vector));
} // nss_test
int main(int argc, char** argv) {
if (argc < 2) {
std::cout << "usage: prng_gtest <.rsp file>" << std::endl;
return 1;
TEST_F(PRNGTest, HashDRBG) {
for (auto& v : test_vector_) {
RunTest(v);
}
nss_test::ReadFile(argv[1]);
assert(!nss_test::test_vector.empty());
::testing::InitGoogleTest(&argc, argv);
if (NSS_NoDB_Init(nullptr) != SECSuccess) {
return 1;
}
int rv = RUN_ALL_TESTS();
if (NSS_Shutdown() != SECSuccess) {
return 1;
}
return rv;
}
} // namespace nss_test

File diff suppressed because one or more lines are too long

View File

@ -4,8 +4,6 @@
* 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 UNSAFE_FUZZER_MODE // See Bug 1709750
#include <memory>
#include "blapi.h"
#include "gtest/gtest.h"
@ -15,9 +13,10 @@
#include "pk11pub.h"
#include "secerr.h"
#include "sechash.h"
#include "testvectors/hpke-vectors.h"
#include "util.h"
extern std::string g_source_dir;
namespace nss_test {
/* See note in pk11pub.h. */
@ -75,8 +74,9 @@ class HpkeTest {
CheckEquality(expected_vec, actual);
}
void Seal(const ScopedHpkeContext &cx, std::vector<uint8_t> &aad_vec,
std::vector<uint8_t> &pt_vec, std::vector<uint8_t> &out_sealed) {
void Seal(const ScopedHpkeContext &cx, const std::vector<uint8_t> &aad_vec,
const std::vector<uint8_t> &pt_vec,
std::vector<uint8_t> *out_sealed) {
SECItem aad_item = {siBuffer, toUcharPtr(aad_vec.data()),
static_cast<unsigned int>(aad_vec.size())};
SECItem pt_item = {siBuffer, toUcharPtr(pt_vec.data()),
@ -87,11 +87,12 @@ class HpkeTest {
PK11_HPKE_Seal(cx.get(), &aad_item, &pt_item, &sealed_item));
ASSERT_NE(nullptr, sealed_item);
ScopedSECItem sealed(sealed_item);
out_sealed.assign(sealed->data, sealed->data + sealed->len);
out_sealed->assign(sealed->data, sealed->data + sealed->len);
}
void Open(const ScopedHpkeContext &cx, std::vector<uint8_t> &aad_vec,
std::vector<uint8_t> &ct_vec, std::vector<uint8_t> &out_opened) {
void Open(const ScopedHpkeContext &cx, const std::vector<uint8_t> &aad_vec,
const std::vector<uint8_t> &ct_vec,
std::vector<uint8_t> *out_opened) {
SECItem aad_item = {siBuffer, toUcharPtr(aad_vec.data()),
static_cast<unsigned int>(aad_vec.size())};
SECItem ct_item = {siBuffer, toUcharPtr(ct_vec.data()),
@ -101,19 +102,21 @@ class HpkeTest {
PK11_HPKE_Open(cx.get(), &aad_item, &ct_item, &opened_item));
ASSERT_NE(nullptr, opened_item);
ScopedSECItem opened(opened_item);
out_opened.assign(opened->data, opened->data + opened->len);
out_opened->assign(opened->data, opened->data + opened->len);
}
void SealOpen(const ScopedHpkeContext &sender,
const ScopedHpkeContext &receiver, std::vector<uint8_t> &msg,
std::vector<uint8_t> &aad, const std::vector<uint8_t> *expect) {
const ScopedHpkeContext &receiver,
const std::vector<uint8_t> &msg,
const std::vector<uint8_t> &aad,
const std::vector<uint8_t> *expect) {
std::vector<uint8_t> sealed;
std::vector<uint8_t> opened;
Seal(sender, aad, msg, sealed);
Seal(sender, aad, msg, &sealed);
if (expect) {
EXPECT_EQ(*expect, sealed);
}
Open(receiver, aad, sealed, opened);
Open(receiver, aad, sealed, &opened);
EXPECT_EQ(msg, opened);
}
@ -221,105 +224,441 @@ class HpkeTest {
}
};
class TestVectors : public HpkeTest,
public ::testing::TestWithParam<hpke_vector> {
protected:
void ReadVector(const hpke_vector &vec) {
ScopedPK11SymKey vec_psk;
if (!vec.psk.empty()) {
ASSERT_FALSE(vec.psk_id.empty());
vec_psk_id = hex_string_to_bytes(vec.psk_id);
std::vector<uint8_t> psk_bytes = hex_string_to_bytes(vec.psk);
SECItem psk_item = {siBuffer, toUcharPtr(psk_bytes.data()),
static_cast<unsigned int>(psk_bytes.size())};
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
ASSERT_TRUE(slot);
PK11SymKey *psk_key =
PK11_ImportSymKey(slot.get(), CKM_HKDF_KEY_GEN, PK11_OriginUnwrap,
CKA_WRAP, &psk_item, nullptr);
ASSERT_NE(nullptr, psk_key);
vec_psk_key.reset(psk_key);
}
vec_pkcs8_r = hex_string_to_bytes(vec.pkcs8_r);
vec_pkcs8_e = hex_string_to_bytes(vec.pkcs8_e);
vec_key = hex_string_to_bytes(vec.key);
vec_nonce = hex_string_to_bytes(vec.nonce);
vec_enc = hex_string_to_bytes(vec.enc);
vec_info = hex_string_to_bytes(vec.info);
vec_encryptions = vec.encrypt_vecs;
vec_exports = vec.export_vecs;
// If we make a few assumptions about the file, parsing JSON can be easy.
// This is not a full parser, it only works on a narrow set of inputs.
class JsonReader {
public:
JsonReader(const std::string &n) : buf_(), available_(0), i_(0) {
f_.reset(PR_Open(n.c_str(), PR_RDONLY, 00600));
EXPECT_TRUE(f_) << "error opening vectors from: " << n;
buf_[0] = 0;
}
void TestExports(const ScopedHpkeContext &sender,
const ScopedHpkeContext &receiver) {
for (auto &vec : vec_exports) {
std::vector<uint8_t> context = hex_string_to_bytes(vec.ctxt);
std::vector<uint8_t> expected = hex_string_to_bytes(vec.exported);
SECItem context_item = {siBuffer, toUcharPtr(context.data()),
static_cast<unsigned int>(context.size())};
PK11SymKey *actual_r = nullptr;
PK11SymKey *actual_s = nullptr;
ASSERT_EQ(SECSuccess, PK11_HPKE_ExportSecret(sender.get(), &context_item,
vec.len, &actual_s));
ASSERT_EQ(SECSuccess,
PK11_HPKE_ExportSecret(receiver.get(), &context_item, vec.len,
&actual_r));
ScopedPK11SymKey scoped_act_s(actual_s);
ScopedPK11SymKey scoped_act_r(actual_r);
CheckEquality(expected, scoped_act_s.get());
CheckEquality(expected, scoped_act_r.get());
void next() { i_++; }
uint8_t peek() {
TopUp();
return buf_[i_];
}
uint8_t take() {
uint8_t v = peek();
next();
return v;
}
// No input checking, overflow protection, or any safety.
// Returns 0 if there isn't a number here rather than aborting.
uint64_t ReadInt() {
SkipWhitespace();
uint8_t c = peek();
uint64_t v = 0;
while (c >= '0' && c <= '9') {
v = v * 10 + c - '0';
next();
c = peek();
}
return v;
}
// No input checking, no unicode, no escaping (not even \"), just read ASCII.
std::string ReadLabel() {
SkipWhitespace();
if (peek() != '"') {
return "";
}
next();
std::string s;
uint8_t c = take();
while (c != '"') {
s.push_back(c);
c = take();
}
SkipWhitespace();
EXPECT_EQ(take(), ':');
return s;
}
std::vector<uint8_t> ReadHex() {
SkipWhitespace();
uint8_t c = take();
EXPECT_EQ(c, '"');
std::vector<uint8_t> v;
c = take();
while (c != '"') {
v.push_back(JsonReader::Hex(c) << 4 | JsonReader::Hex(take()));
c = take();
}
return v;
}
bool NextItem(uint8_t h = '{', uint8_t t = '}') {
SkipWhitespace();
switch (uint8_t c = take()) {
case ',':
return true;
case '{':
case '[':
EXPECT_EQ(c, h);
SkipWhitespace();
if (peek() == t) {
next();
return false;
}
return true;
case '}':
case ']':
EXPECT_EQ(c, t);
return false;
default:
ADD_FAILURE() << "Unexpected '" << c << "'";
}
return false;
}
void SkipValue() {
uint8_t c = take();
if (c == '"') {
do {
c = take();
} while (c != '"');
} else if (c >= '0' && c <= '9') {
c = peek();
while (c >= '0' && c <= '9') {
next();
c = peek();
}
} else {
ADD_FAILURE() << "No idea how to skip'" << c << "'";
}
}
void TestEncryptions(const ScopedHpkeContext &sender,
const ScopedHpkeContext &receiver) {
for (auto &enc_vec : vec_encryptions) {
std::vector<uint8_t> msg = hex_string_to_bytes(enc_vec.pt);
std::vector<uint8_t> aad = hex_string_to_bytes(enc_vec.aad);
std::vector<uint8_t> expect_ct = hex_string_to_bytes(enc_vec.ct);
SealOpen(sender, receiver, msg, aad, &expect_ct);
}
}
void ImportKeyPairs(const ScopedHpkeContext &sender,
const ScopedHpkeContext &receiver) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
ADD_FAILURE() << "No slot";
private:
void TopUp() {
if (available_ > i_) {
return;
}
i_ = 0;
if (!f_) {
return;
}
PRInt32 res = PR_Read(f_.get(), buf_, sizeof(buf_));
if (res > 0) {
available_ = static_cast<size_t>(res);
} else {
available_ = 1;
f_.reset(nullptr);
buf_[0] = 0;
}
}
SECItem pkcs8_e_item = {siBuffer, toUcharPtr(vec_pkcs8_e.data()),
static_cast<unsigned int>(vec_pkcs8_e.size())};
SECKEYPrivateKey *sk_e = nullptr;
EXPECT_EQ(SECSuccess, PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8_e_item, nullptr, nullptr,
false, false, KU_ALL, &sk_e, nullptr));
skE_derived.reset(sk_e);
SECKEYPublicKey *pk_e = SECKEY_ConvertToPublicKey(skE_derived.get());
ASSERT_NE(nullptr, pk_e);
pkE_derived.reset(pk_e);
void SkipWhitespace() {
uint8_t c = peek();
while (c && (c == ' ' || c == '\t' || c == '\r' || c == '\n')) {
next();
c = peek();
}
}
SECItem pkcs8_r_item = {siBuffer, toUcharPtr(vec_pkcs8_r.data()),
static_cast<unsigned int>(vec_pkcs8_r.size())};
SECKEYPrivateKey *sk_r = nullptr;
EXPECT_EQ(SECSuccess, PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8_r_item, nullptr, nullptr,
false, false, KU_ALL, &sk_r, nullptr));
skR_derived.reset(sk_r);
SECKEYPublicKey *pk_r = SECKEY_ConvertToPublicKey(skR_derived.get());
ASSERT_NE(nullptr, pk_r);
pkR_derived.reset(pk_r);
// This only handles lowercase.
uint8_t Hex(uint8_t c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
EXPECT_TRUE(c >= 'a' && c <= 'f');
return c - 'a' + 10;
}
ScopedPRFileDesc f_;
uint8_t buf_[4096];
size_t available_;
size_t i_;
};
struct HpkeEncryptVector {
std::vector<uint8_t> pt;
std::vector<uint8_t> aad;
std::vector<uint8_t> ct;
static std::vector<HpkeEncryptVector> ReadVec(JsonReader &r) {
std::vector<HpkeEncryptVector> all;
while (r.NextItem('[', ']')) {
HpkeEncryptVector enc;
while (r.NextItem()) {
std::string n = r.ReadLabel();
if (n == "") {
break;
}
if (n == "plaintext") {
enc.pt = r.ReadHex();
} else if (n == "aad") {
enc.aad = r.ReadHex();
} else if (n == "ciphertext") {
enc.ct = r.ReadHex();
} else {
r.SkipValue();
}
}
all.push_back(enc);
}
return all;
}
};
struct HpkeExportVector {
std::vector<uint8_t> ctxt;
size_t len;
std::vector<uint8_t> exported;
static std::vector<HpkeExportVector> ReadVec(JsonReader &r) {
std::vector<HpkeExportVector> all;
while (r.NextItem('[', ']')) {
HpkeExportVector exp;
while (r.NextItem()) {
std::string n = r.ReadLabel();
if (n == "") {
break;
}
if (n == "exporter_context") {
exp.ctxt = r.ReadHex();
} else if (n == "L") {
exp.len = r.ReadInt();
} else if (n == "exported_value") {
exp.exported = r.ReadHex();
} else {
r.SkipValue();
}
}
all.push_back(exp);
}
return all;
}
};
struct HpkeVector {
uint32_t test_id;
HpkeModeId mode;
HpkeKemId kem_id;
HpkeKdfId kdf_id;
HpkeAeadId aead_id;
std::vector<uint8_t> info;
std::vector<uint8_t> pkcs8_e;
std::vector<uint8_t> pkcs8_r;
std::vector<uint8_t> psk;
std::vector<uint8_t> psk_id;
std::vector<uint8_t> enc;
std::vector<uint8_t> key;
std::vector<uint8_t> nonce;
std::vector<HpkeEncryptVector> encryptions;
std::vector<HpkeExportVector> exports;
static std::vector<uint8_t> Pkcs8(const std::vector<uint8_t> &sk,
const std::vector<uint8_t> &pk) {
// Only X25519 format.
std::vector<uint8_t> v(105);
v.assign({
0x30, 0x67, 0x02, 0x01, 0x00, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, 0x48,
0xce, 0x3d, 0x02, 0x01, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda,
0x47, 0x0f, 0x01, 0x04, 0x4c, 0x30, 0x4a, 0x02, 0x01, 0x01, 0x04, 0x20,
});
v.insert(v.end(), sk.begin(), sk.end());
v.insert(v.end(), {
0xa1, 0x23, 0x03, 0x21, 0x00,
});
v.insert(v.end(), pk.begin(), pk.end());
return v;
}
static std::vector<HpkeVector> Read(JsonReader &r) {
std::vector<HpkeVector> all_tests;
uint32_t test_id = 0;
while (r.NextItem('[', ']')) {
HpkeVector vec = { 0 };
uint32_t fields = 0;
enum class RequiredFields {
mode,
kem,
kdf,
aead,
skEm,
skRm,
pkEm,
pkRm,
all
};
std::vector<uint8_t> sk_e, pk_e, sk_r, pk_r;
test_id++;
while (r.NextItem()) {
std::string n = r.ReadLabel();
if (n == "") {
break;
}
if (n == "mode") {
vec.mode = static_cast<HpkeModeId>(r.ReadInt());
fields |= 1 << static_cast<uint32_t>(RequiredFields::mode);
} else if (n == "kem_id") {
vec.kem_id = static_cast<HpkeKemId>(r.ReadInt());
fields |= 1 << static_cast<uint32_t>(RequiredFields::kem);
} else if (n == "kdf_id") {
vec.kdf_id = static_cast<HpkeKdfId>(r.ReadInt());
fields |= 1 << static_cast<uint32_t>(RequiredFields::kdf);
} else if (n == "aead_id") {
vec.aead_id = static_cast<HpkeAeadId>(r.ReadInt());
fields |= 1 << static_cast<uint32_t>(RequiredFields::aead);
} else if (n == "info") {
vec.info = r.ReadHex();
} else if (n == "skEm") {
sk_e = r.ReadHex();
fields |= 1 << static_cast<uint32_t>(RequiredFields::skEm);
} else if (n == "pkEm") {
pk_e = r.ReadHex();
fields |= 1 << static_cast<uint32_t>(RequiredFields::pkEm);
} else if (n == "skRm") {
sk_r = r.ReadHex();
fields |= 1 << static_cast<uint32_t>(RequiredFields::skRm);
} else if (n == "pkRm") {
pk_r = r.ReadHex();
fields |= 1 << static_cast<uint32_t>(RequiredFields::pkRm);
} else if (n == "psk") {
vec.psk = r.ReadHex();
} else if (n == "psk_id") {
vec.psk_id = r.ReadHex();
} else if (n == "enc") {
vec.enc = r.ReadHex();
} else if (n == "key") {
vec.key = r.ReadHex();
} else if (n == "base_nonce") {
vec.nonce = r.ReadHex();
} else if (n == "encryptions") {
vec.encryptions = HpkeEncryptVector::ReadVec(r);
} else if (n == "exports") {
vec.exports = HpkeExportVector::ReadVec(r);
} else {
r.SkipValue();
}
}
if (fields != (1 << static_cast<uint32_t>(RequiredFields::all)) - 1) {
std::cerr << "Skipping entry " << test_id << " for missing fields"
<< std::endl;
continue;
}
// Skip modes and configurations we don't support.
if (vec.mode != HpkeModeBase && vec.mode != HpkeModePsk) {
continue;
}
SECStatus rv =
PK11_HPKE_ValidateParameters(vec.kem_id, vec.kdf_id, vec.aead_id);
if (rv != SECSuccess) {
continue;
}
vec.test_id = test_id;
vec.pkcs8_e = HpkeVector::Pkcs8(sk_e, pk_e);
vec.pkcs8_r = HpkeVector::Pkcs8(sk_r, pk_r);
all_tests.push_back(vec);
}
return all_tests;
}
};
class TestVectors : public HpkeTest, public ::testing::Test {
struct Endpoint {
bool init(const HpkeVector &vec, const std::vector<uint8_t> &sk_data) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
ADD_FAILURE() << "No slot";
return false;
}
cx_ = Endpoint::MakeContext(slot, vec);
SECItem item = {siBuffer, toUcharPtr(sk_data.data()),
static_cast<unsigned int>(sk_data.size())};
SECKEYPrivateKey *sk = nullptr;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &item, nullptr, nullptr, false, false, KU_ALL, &sk,
nullptr);
if (rv != SECSuccess) {
ADD_FAILURE() << "Failed to import secret";
return false;
}
sk_.reset(sk);
SECKEYPublicKey *pk = SECKEY_ConvertToPublicKey(sk_.get());
pk_.reset(pk);
return cx_ && sk_ && pk_;
}
static ScopedHpkeContext MakeContext(const ScopedPK11SlotInfo &slot,
const HpkeVector &vec) {
ScopedPK11SymKey psk = Endpoint::ReadPsk(slot, vec);
SECItem psk_id_item = {siBuffer, toUcharPtr(vec.psk_id.data()),
static_cast<unsigned int>(vec.psk_id.size())};
SECItem *psk_id = psk ? &psk_id_item : nullptr;
return ScopedHpkeContext(PK11_HPKE_NewContext(
vec.kem_id, vec.kdf_id, vec.aead_id, psk.get(), psk_id));
}
static ScopedPK11SymKey ReadPsk(const ScopedPK11SlotInfo &slot,
const HpkeVector &vec) {
ScopedPK11SymKey psk;
if (!vec.psk.empty()) {
SECItem psk_item = {siBuffer, toUcharPtr(vec.psk.data()),
static_cast<unsigned int>(vec.psk.size())};
PK11SymKey *psk_key =
PK11_ImportSymKey(slot.get(), CKM_HKDF_KEY_GEN, PK11_OriginUnwrap,
CKA_WRAP, &psk_item, nullptr);
EXPECT_NE(nullptr, psk_key);
psk.reset(psk_key);
}
return psk;
}
ScopedHpkeContext cx_;
ScopedSECKEYPublicKey pk_;
ScopedSECKEYPrivateKey sk_;
};
protected:
void TestExports(const HpkeVector &vec, const Endpoint &sender,
const Endpoint &receiver) {
for (auto &exp : vec.exports) {
SECItem context_item = {siBuffer, toUcharPtr(exp.ctxt.data()),
static_cast<unsigned int>(exp.ctxt.size())};
PK11SymKey *actual_r = nullptr;
PK11SymKey *actual_s = nullptr;
ASSERT_EQ(SECSuccess,
PK11_HPKE_ExportSecret(sender.cx_.get(), &context_item, exp.len,
&actual_s));
ASSERT_EQ(SECSuccess,
PK11_HPKE_ExportSecret(receiver.cx_.get(), &context_item,
exp.len, &actual_r));
ScopedPK11SymKey scoped_act_s(actual_s);
ScopedPK11SymKey scoped_act_r(actual_r);
CheckEquality(exp.exported, scoped_act_s.get());
CheckEquality(exp.exported, scoped_act_r.get());
}
}
void TestEncryptions(const HpkeVector &vec, const Endpoint &sender,
const Endpoint &receiver) {
for (auto &enc : vec.encryptions) {
SealOpen(sender.cx_, receiver.cx_, enc.pt, enc.aad, &enc.ct);
}
}
void SetupS(const ScopedHpkeContext &cx, const ScopedSECKEYPublicKey &pkE,
const ScopedSECKEYPrivateKey &skE,
const ScopedSECKEYPublicKey &pkR,
const std::vector<uint8_t> &info) {
SECItem info_item = {siBuffer, toUcharPtr(vec_info.data()),
static_cast<unsigned int>(vec_info.size())};
SECItem info_item = {siBuffer, toUcharPtr(info.data()),
static_cast<unsigned int>(info.size())};
EXPECT_EQ(SECSuccess, PK11_HPKE_SetupS(cx.get(), pkE.get(), skE.get(),
pkR.get(), &info_item));
}
@ -330,65 +669,43 @@ class TestVectors : public HpkeTest,
const std::vector<uint8_t> &info) {
SECItem enc_item = {siBuffer, toUcharPtr(enc.data()),
static_cast<unsigned int>(enc.size())};
SECItem info_item = {siBuffer, toUcharPtr(vec_info.data()),
static_cast<unsigned int>(vec_info.size())};
SECItem info_item = {siBuffer, toUcharPtr(info.data()),
static_cast<unsigned int>(info.size())};
EXPECT_EQ(SECSuccess, PK11_HPKE_SetupR(cx.get(), pkR.get(), skR.get(),
&enc_item, &info_item));
}
void SetupSenderReceiver(const ScopedHpkeContext &sender,
const ScopedHpkeContext &receiver) {
SetupS(sender, pkE_derived, skE_derived, pkR_derived, vec_info);
void SetupSenderReceiver(const HpkeVector &vec, const Endpoint &sender,
const Endpoint &receiver) {
SetupS(sender.cx_, sender.pk_, sender.sk_, receiver.pk_, vec.info);
uint8_t buf[32]; // Curve25519 only, fixed size.
SECItem encap_item = {siBuffer, const_cast<uint8_t *>(buf), sizeof(buf)};
ASSERT_EQ(SECSuccess,
PK11_HPKE_Serialize(pkE_derived.get(), encap_item.data,
&encap_item.len, encap_item.len));
CheckEquality(vec_enc, &encap_item);
SetupR(receiver, pkR_derived, skR_derived, vec_enc, vec_info);
ASSERT_EQ(SECSuccess, PK11_HPKE_Serialize(sender.pk_.get(), encap_item.data,
&encap_item.len, encap_item.len));
CheckEquality(vec.enc, &encap_item);
SetupR(receiver.cx_, receiver.pk_, receiver.sk_, vec.enc, vec.info);
}
void RunTestVector(const hpke_vector &vec) {
ReadVector(vec);
SECItem psk_id_item = {siBuffer, toUcharPtr(vec_psk_id.data()),
static_cast<unsigned int>(vec_psk_id.size())};
PK11SymKey *psk = vec_psk_key ? vec_psk_key.get() : nullptr;
SECItem *psk_id = psk ? &psk_id_item : nullptr;
void RunTestVector(const HpkeVector &vec) {
Endpoint sender;
ASSERT_TRUE(sender.init(vec, vec.pkcs8_e));
Endpoint receiver;
ASSERT_TRUE(receiver.init(vec, vec.pkcs8_r));
ScopedHpkeContext sender(
PK11_HPKE_NewContext(vec.kem_id, vec.kdf_id, vec.aead_id, psk, psk_id));
ScopedHpkeContext receiver(
PK11_HPKE_NewContext(vec.kem_id, vec.kdf_id, vec.aead_id, psk, psk_id));
ASSERT_TRUE(sender);
ASSERT_TRUE(receiver);
ImportKeyPairs(sender, receiver);
SetupSenderReceiver(sender, receiver);
TestEncryptions(sender, receiver);
TestExports(sender, receiver);
SetupSenderReceiver(vec, sender, receiver);
TestEncryptions(vec, sender, receiver);
TestExports(vec, sender, receiver);
}
private:
ScopedPK11SymKey vec_psk_key;
std::vector<uint8_t> vec_psk_id;
std::vector<uint8_t> vec_pkcs8_e;
std::vector<uint8_t> vec_pkcs8_r;
std::vector<uint8_t> vec_enc;
std::vector<uint8_t> vec_info;
std::vector<uint8_t> vec_key;
std::vector<uint8_t> vec_nonce;
std::vector<hpke_encrypt_vector> vec_encryptions;
std::vector<hpke_export_vector> vec_exports;
ScopedSECKEYPublicKey pkE_derived;
ScopedSECKEYPublicKey pkR_derived;
ScopedSECKEYPrivateKey skE_derived;
ScopedSECKEYPrivateKey skR_derived;
};
TEST_P(TestVectors, TestVectors) { RunTestVector(GetParam()); }
INSTANTIATE_TEST_SUITE_P(Pk11Hpke, TestVectors,
::testing::ValuesIn(kHpkeTestVectors));
TEST_F(TestVectors, HpkeVectors) {
JsonReader r(::g_source_dir + "/hpke-vectors.json");
auto all_tests = HpkeVector::Read(r);
for (auto &vec : all_tests) {
std::cout << "HPKE vector " << vec.test_id << std::endl;
RunTestVector(vec);
}
}
class ModeParameterizedTest
: public HpkeTest,
@ -685,5 +1002,3 @@ TEST_F(ModeParameterizedTest, InvalidReceiverKeyType) {
}
} // namespace nss_test
#endif

View File

@ -287,9 +287,12 @@ sftkdb_DecryptAttribute(SFTKDBHandle *handle, SECItem *passKey,
}
/* If we are using aes 256, we need to check authentication as well.*/
if ((type != CKT_INVALID_TYPE) && (cipherValue.alg == SEC_OID_AES_256_CBC)) {
if ((type != CKT_INVALID_TYPE) &&
(cipherValue.alg == SEC_OID_PKCS5_PBES2) &&
(cipherValue.param->encAlg == SEC_OID_AES_256_CBC)) {
SECItem signature;
unsigned char signData[SDB_MAX_META_DATA_LEN];
CK_RV crv;
/* if we get here from the old legacy db, there is clearly an
* error, don't return the plaintext */
@ -301,15 +304,28 @@ sftkdb_DecryptAttribute(SFTKDBHandle *handle, SECItem *passKey,
signature.data = signData;
signature.len = sizeof(signData);
rv = sftkdb_GetAttributeSignature(handle, handle, id, type,
&signature);
if (rv != SECSuccess) {
goto loser;
rv = SECFailure;
/* sign sftkdb_GetAttriibuteSignature returns a crv, not an rv */
crv = sftkdb_GetAttributeSignature(handle, handle, id, type,
&signature);
if (crv == CKR_OK) {
rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE,
type, *plain, &signature);
}
rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE, type,
*plain, &signature);
if (rv != SECSuccess) {
goto loser;
/* handle bug 1720226 where old versions of NSS misfiled the signature
* attribute on password update */
id |= SFTK_KEYDB_TYPE | SFTK_TOKEN_TYPE;
signature.len = sizeof(signData);
crv = sftkdb_GetAttributeSignature(handle, handle, id, type,
&signature);
if (crv != CKR_OK) {
rv = SECFailure;
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto loser;
}
rv = sftkdb_VerifyAttribute(handle, passKey, CK_INVALID_HANDLE,
type, *plain, &signature);
}
}
@ -1198,6 +1214,7 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
unsigned int i;
for (i = 0; i < privAttrCount; i++) {
// Read the old attribute in the clear.
CK_OBJECT_HANDLE sdbId = id & SFTK_OBJ_ID_MASK;
CK_ATTRIBUTE privAttr = { privAttrTypes[i], NULL, 0 };
CK_RV crv = sftkdb_GetAttributeValue(keydb, id, &privAttr, 1);
if (crv != CKR_OK) {
@ -1222,7 +1239,7 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
plainText.data = privAttr.pValue;
plainText.len = privAttr.ulValueLen;
if (sftkdb_EncryptAttribute(arena, keydb, keydb->db, newKey,
iterationCount, id, privAttr.type,
iterationCount, sdbId, privAttr.type,
&plainText, &result) != SECSuccess) {
return CKR_GENERAL_ERROR;
}
@ -1232,10 +1249,9 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
PORT_Memset(plainText.data, 0, plainText.len);
// Write the newly encrypted attributes out directly.
CK_OBJECT_HANDLE newId = id & SFTK_OBJ_ID_MASK;
keydb->newKey = newKey;
keydb->newDefaultIterationCount = iterationCount;
crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, newId, &privAttr, 1);
crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, sdbId, &privAttr, 1);
keydb->newKey = NULL;
if (crv != CKR_OK) {
return crv;

View File

@ -101,12 +101,12 @@ static sslOptions ssl_defaults = {
* default range of enabled SSL/TLS protocols
*/
static SSLVersionRange versions_defaults_stream = {
SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_2,
SSL_LIBRARY_VERSION_TLS_1_3
};
static SSLVersionRange versions_defaults_datagram = {
SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_2,
SSL_LIBRARY_VERSION_TLS_1_2
};

View File

@ -209,8 +209,6 @@
'gtests/cryptohi_gtest/cryptohi_gtest.gyp:cryptohi_gtest',
'gtests/der_gtest/der_gtest.gyp:der_gtest',
'gtests/certdb_gtest/certdb_gtest.gyp:certdb_gtest',
'gtests/freebl_gtest/freebl_gtest.gyp:prng_gtest',
'gtests/freebl_gtest/freebl_gtest.gyp:blake2b_gtest',
'gtests/freebl_gtest/freebl_gtest.gyp:freebl_gtest',
'gtests/mozpkix_gtest/mozpkix_gtest.gyp:mozpkix_gtest',
'gtests/nss_bogo_shim/nss_bogo_shim.gyp:nss_bogo_shim',

View File

@ -75,6 +75,7 @@ Echo()
echo "| $*"
echo "---------------------------------------------------------------"
}
dbtest_main()
{
cd ${HOSTDIR}
@ -249,9 +250,9 @@ dbtest_main()
${BINDIR}/certutil -L -n bob -d ${CONFLICT_DIR}
ret=$?
if [ $ret -ne 0 ]; then
html_failed "Nicknane conflict test-setting nickname conflict incorrectly worked"
html_failed "Nickname conflict test-setting nickname conflict incorrectly worked"
else
html_passed "Nicknane conflict test-setting nickname conflict was correctly rejected"
html_passed "Nickname conflict test-setting nickname conflict was correctly rejected"
fi
# import a token private key and make sure the corresponding public key is
# created
@ -262,6 +263,71 @@ dbtest_main()
else
html_passed "Importing Token Private Key correctly creates the corrresponding Public Key"
fi
#
# If we are testing an sqlite db, make sure we detect corrupted attributes.
# This test only runs if 1) we have sqlite3 (the command line sqlite diagnostic
# tool) and 2) we are using the sql database (rather than the dbm).
#
which sqlite3
ret=$?
KEYDB=${CONFLICT_DIR}/key4.db
# make sure sql database is bing used.
if [ ! -f ${KEYDB} ]; then
Echo "skipping key corruption test: requires sql database"
# make sure sqlite3 is installed.
elif [ $ret -ne 0 ]; then
Echo "skipping key corruption test: sqlite3 command not installed"
else
# we are going to mangle this key database in multiple tests, save a copy
# so that we can restore it later.
cp ${KEYDB} ${KEYDB}.save
# dump the keys in the log for diagnostic purposes
${BINDIR}/certutil -K -d ${CONFLICT_DIR} -f ${R_PWFILE}
# fetch the rsa and ec key ids
rsa_id=$(${BINDIR}/certutil -K -d ${CONFLICT_DIR} -f ${R_PWFILE} | grep rsa | awk '{ print $4}')
ec_id=$(${BINDIR}/certutil -K -d ${CONFLICT_DIR} -f ${R_PWFILE} | grep ' ec ' | awk '{ print $4}')
# now loop through all the private attributes and mangle them one at a time
for i in 120 122 123 124 125 126 127 128 011
do
Echo "testing if key corruption is detected in attribute $i"
cp ${KEYDB}.save ${KEYDB} # restore the saved keydb
# find all the hmacs for this key attribute and mangle each entry
sqlite3 ${KEYDB} ".dump metadata" | sed -e "/sig_key_.*_00000$i/{s/.*VALUES('\\(.*\\)',X'\\(.*\\)',NULL.*/\\1 \\2/;p;};d" | while read sig data
do
# mangle the last byte of the hmac
# The following increments the last nibble by 1 with both F and f
# mapping to 0. This mangles both upper and lower case results, so
# it will work on the mac.
last=$((${#data}-1))
newbyte=$(echo "${data:${last}}" | tr A-Fa-f0-9 B-F0b-f0-9a)
mangle=${data::${last}}${newbyte}
echo " amending ${sig} from ${data} to ${mangle}"
# write the mangled entry, inserting with a key matching an existing
# entry will overwrite the existing entry with the same key (${sig})
sqlite3 ${KEYDB} "BEGIN TRANSACTION; INSERT INTO metaData VALUES('${sig}',X'${mangle}',NULL); COMMIT"
done
# pick the key based on the attribute we are mangling,
# only CKA_VALUE (0x011) is not an RSA attribute, so we choose
# ec for 0x011 and rsa for all the rest. We could use the dsa
# key here, both CKA_VALUE attributes will be modifed in the loop above, but
# ec is more common than dsa these days.
if [ "$i" = "011" ]; then
key_id=$ec_id
else
key_id=$rsa_id
fi
# now try to use the mangled key (try to create a cert request with the key).
echo "${BINDIR}/certutil -R -k ${key_id} -s 'CN=BadTest, E=bad@mozilla.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US' -d ${CONFLICT_DIR} -f ${R_PWFILE} -a"
${BINDIR}/certutil -R -k ${key_id} -s 'CN=BadTest, E=bad@mozilla.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US' -d ${CONFLICT_DIR} -f ${R_PWFILE} -a
ret=$?
if [ ${ret} -eq 0 ]; then
html_failed "Key attribute $i corruption not detected"
else
html_passed "Corrupted key attribute $i correctly disabled key"
fi
done
cp ${KEYDB}.save ${KEYDB} # restore the saved keydb
fi
if [ "${NSS_DEFAULT_DB_TYPE}" = "sql" ] ; then

View File

@ -24,6 +24,8 @@ gtest_init()
{
cd "$(dirname "$1")"
pwd
SOURCE_DIR="$PWD"/../..
if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
cd ../common
. ./init.sh
@ -77,7 +79,7 @@ gtest_start()
fi
echo "executing $i"
ASAN_OPTIONS="$ASAN_OPTIONS:$EXTRA_ASAN_OPTIONS" "${BINDIR}/$i" \
"${SOURCE_DIR}/gtests/freebl_gtest/kat/Hash_DRBG.rsp" \
-s "${SOURCE_DIR}/gtests/$i" \
-d "$DIR" -w --gtest_output=xml:"${GTESTREPORT}" \
--gtest_filter="${GTESTFILTER:-*}"
html_msg $? 0 "$i run successfully"
@ -99,8 +101,7 @@ gtest_cleanup()
}
################## main #################################################
GTESTS="${GTESTS:-prng_gtest certhigh_gtest certdb_gtest der_gtest pk11_gtest util_gtest freebl_gtest softoken_gtest sysinit_gtest blake2b_gtest smime_gtest mozpkix_gtest}"
SOURCE_DIR="$PWD"/../..
GTESTS="${GTESTS:-certhigh_gtest certdb_gtest der_gtest pk11_gtest util_gtest freebl_gtest softoken_gtest sysinit_gtest smime_gtest mozpkix_gtest}"
gtest_init "$0"
gtest_start
gtest_cleanup