Bug 1705477 - land NSS c982fb957516 UPGRADE_NSS_RELEASE, r=beurdouche

Differential Revision: https://phabricator.services.mozilla.com/D114231
This commit is contained in:
Benjamin Beurdouche 2021-05-04 13:33:25 +00:00
parent 16d0bd0051
commit 37aa935e43
63 changed files with 1235 additions and 701 deletions

View File

@ -9,7 +9,7 @@ option("--with-system-nss", help="Use system NSS")
imply_option("--with-system-nspr", True, when="--with-system-nss")
nss_pkg = pkg_check_modules(
"NSS", "nss >= 3.64", when="--with-system-nss", config=False
"NSS", "nss >= 3.65", when="--with-system-nss", config=False
)
set_config("MOZ_SYSTEM_NSS", True, when="--with-system-nss")

View File

@ -1 +1 @@
NSS_3_64_RTM
c982fb957516

View File

@ -0,0 +1,15 @@
2 Added functions:
'function PK11Context* PK11_CreateContextByPrivKey(CK_MECHANISM_TYPE, CK_ATTRIBUTE_TYPE, SECKEYPrivateKey*, const SECItem*)' {PK11_CreateContextByPrivKey@@NSS_3.65}
'function PK11Context* PK11_CreateContextByPubKey(CK_MECHANISM_TYPE, CK_ATTRIBUTE_TYPE, SECKEYPublicKey*, const SECItem*, void*)' {PK11_CreateContextByPubKey@@NSS_3.65}
1 function with some indirect sub-type change:
[C]'function PK11Context* PK11_CreateContextBySymKey(CK_MECHANISM_TYPE, CK_ATTRIBUTE_TYPE, PK11SymKey*, SECItem*)' at pk11cxt.c:493:1 has some indirect sub-type changes:
parameter 4 of type 'SECItem*' changed:
in pointed to type 'typedef SECItem':
entity changed from 'typedef SECItem' to 'const SECItem'
type size hasn't changed

View File

@ -1 +1 @@
NSS_3_63_BRANCH
NSS_3_64_BRANCH

View File

@ -386,7 +386,6 @@ CreateModifiedCRLCopy(PLArenaPool *arena, CERTCertDBHandle *certHandle,
rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
if (rv != SECSuccess) {
SECU_PrintError(progName, "unable to read input file");
PORT_FreeArena(modArena, PR_FALSE);
goto loser;
}

View File

@ -1378,6 +1378,7 @@ secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level)
(pk->u.ec.DEREncodedParams.data[0] == 0x06)) {
curveOID.len = pk->u.ec.DEREncodedParams.data[1];
curveOID.data = pk->u.ec.DEREncodedParams.data + 2;
curveOID.len = PR_MIN(curveOID.len, pk->u.ec.DEREncodedParams.len - 2);
SECU_PrintObjectID(out, &curveOID, "Curve", level + 1);
}
}

View File

@ -1034,7 +1034,7 @@ Pk11Install_Info_Cleanup(Pk11Install_Info* _this)
for (i = 0; i < _this->numPlatforms; i++) {
Pk11Install_Platform_delete(&_this->platforms[i]);
}
PR_Free(&_this->platforms);
PR_Free(_this->platforms);
_this->platforms = NULL;
_this->numPlatforms = 0;
}
@ -1043,7 +1043,7 @@ Pk11Install_Info_Cleanup(Pk11Install_Info* _this)
for (i = 0; i < _this->numForwardCompatible; i++) {
Pk11Install_PlatformName_delete(&_this->forwardCompatible[i]);
}
PR_Free(&_this->forwardCompatible);
PR_Free(_this->forwardCompatible);
_this->numForwardCompatible = 0;
}
}

View File

@ -1338,13 +1338,15 @@ extract_js(char *filename)
if ((PL_strlen(archiveDir) < 4) ||
PL_strcasecmp((archiveDir + strlen(archiveDir) - 4),
".jar")) {
char *newArchiveDir = NULL;
PR_fprintf(errorFD,
"warning: ARCHIVE attribute should end in \".jar\" in tag"
" starting on %s:%d.\n",
filename, curitem->startLine);
warningCount++;
newArchiveDir = PR_smprintf("%s.arc", archiveDir);
PR_Free(archiveDir);
archiveDir = PR_smprintf("%s.arc", archiveDir);
archiveDir = newArchiveDir;
} else {
PL_strcpy(archiveDir + strlen(archiveDir) - 4, ".arc");
}
@ -1650,9 +1652,6 @@ loser:
if (entityListTail) {
PR_Free(entityListTail);
}
if (curitem) {
PR_Free(curitem);
}
if (basedir) {
PR_Free(basedir);
}

View File

@ -19,7 +19,6 @@ ListCerts(char *key, int list_certs)
{
int failed = 0;
SECStatus rv;
char *ugly_list;
CERTCertDBHandle *db;
CERTCertificate *cert;
@ -33,14 +32,6 @@ ListCerts(char *key, int list_certs)
errlog.tail = NULL;
errlog.count = 0;
ugly_list = PORT_ZAlloc(16);
if (ugly_list == NULL) {
out_of_memory();
}
*ugly_list = 0;
db = CERT_GetDefaultCertDB();
if (list_certs == 2) {

View File

@ -138,8 +138,10 @@ rm_dash_r(char *path)
/* Recursively delete all entries in the directory */
while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
sprintf(filename, "%s/%s", path, entry->name);
if (rm_dash_r(filename))
if (rm_dash_r(filename)) {
PR_CloseDir(dir);
return -1;
}
}
if (PR_CloseDir(dir) != PR_SUCCESS) {

View File

@ -311,40 +311,75 @@ sv_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
sv_PrintInteger(out, &pk->u.dsa.publicValue, "publicValue=");
}
void
sv_PrintECDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
{
SECItem curve = { siBuffer, NULL, 0 };
if ((pk->u.ec.DEREncodedParams.len > 2) &&
(pk->u.ec.DEREncodedParams.data[0] == 0x06)) {
/* strip to just the oid for the curve */
curve.len = pk->u.ec.DEREncodedParams.data[1];
curve.data = pk->u.ec.DEREncodedParams.data + 2;
/* don't overflow the buffer */
curve.len = PR_MIN(curve.len, pk->u.ec.DEREncodedParams.len - 2);
fprintf(out, "%s", m);
sv_PrintObjectID(out, &curve, "curve=");
}
fprintf(out, "%s", m);
sv_PrintInteger(out, &pk->u.ec.publicValue, "publicValue=");
}
int
sv_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena,
CERTSubjectPublicKeyInfo *i, char *msg)
{
SECKEYPublicKey *pk;
SECKEYPublicKey pk;
int rv;
char mm[200];
sprintf(mm, "%s.publicKeyAlgorithm=", msg);
sv_PrintAlgorithmID(out, &i->algorithm, mm);
pk = (SECKEYPublicKey *)PORT_ZAlloc(sizeof(SECKEYPublicKey));
if (!pk)
return PORT_GetError();
DER_ConvertBitString(&i->subjectPublicKey);
switch (SECOID_FindOIDTag(&i->algorithm.algorithm)) {
case SEC_OID_PKCS1_RSA_ENCRYPTION:
rv = SEC_ASN1DecodeItem(arena, pk,
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
rv = SEC_ASN1DecodeItem(arena, &pk,
SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate),
&i->subjectPublicKey);
if (rv)
return rv;
sprintf(mm, "%s.rsaPublicKey.", msg);
sv_PrintRSAPublicKey(out, pk, mm);
sv_PrintRSAPublicKey(out, &pk, mm);
break;
case SEC_OID_ANSIX9_DSA_SIGNATURE:
rv = SEC_ASN1DecodeItem(arena, pk,
rv = SEC_ASN1DecodeItem(arena, &pk,
SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate),
&i->subjectPublicKey);
if (rv)
return rv;
#ifdef notdef
/* SECKEY_PQGParamsTemplate is not yet exported form NSS */
rv = SEC_ASN1DecodeItem(arena, &pk.u.dsa.params,
SEC_ASN1_GET(SECKEY_PQGParamsTemplate),
&i->algorithm.parameters);
if (rv)
return rv;
#endif
sprintf(mm, "%s.dsaPublicKey.", msg);
sv_PrintDSAPublicKey(out, pk, mm);
sv_PrintDSAPublicKey(out, &pk, mm);
break;
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
rv = SECITEM_CopyItem(arena, &pk.u.ec.DEREncodedParams,
&i->algorithm.parameters);
if (rv)
return rv;
rv = SECITEM_CopyItem(arena, &pk.u.ec.publicValue,
&i->subjectPublicKey);
if (rv)
return rv;
sprintf(mm, "%s.ecdsaPublicKey.", msg);
sv_PrintECDSAPublicKey(out, &pk, mm);
break;
default:
fprintf(out, "%s=bad SPKI algorithm type\n", msg);

View File

@ -303,6 +303,7 @@ PrintKey(PK11SymKey *symKey)
printf("<restricted>");
}
printf("\n");
PORT_Free(name);
}
SECStatus

View File

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

View File

@ -38,6 +38,7 @@ CPPSRCS = \
pk11_rsaoaep_unittest.cc \
pk11_rsapkcs1_unittest.cc \
pk11_rsapss_unittest.cc \
pk11_signature_test.cc \
pk11_seed_cbc_unittest.cc \
$(NULL)

View File

@ -6,12 +6,14 @@
#include <memory>
#include "nss.h"
#include "prerror.h"
#include "pk11pub.h"
#include "sechash.h"
#include "cryptohi.h"
#include "cpputil.h"
#include "databuffer.h"
#include "pk11_signature_test.h"
#include "gtest/gtest.h"
#include "nss_scoped_ptrs.h"
@ -19,59 +21,59 @@
#include "testvectors/dsa-vectors.h"
namespace nss_test {
CK_MECHANISM_TYPE
DsaHashToComboMech(SECOidTag hash) {
switch (hash) {
case SEC_OID_SHA1:
return CKM_DSA_SHA1;
case SEC_OID_SHA224:
return CKM_DSA_SHA224;
case SEC_OID_SHA256:
return CKM_DSA_SHA256;
case SEC_OID_SHA384:
return CKM_DSA_SHA384;
case SEC_OID_SHA512:
return CKM_DSA_SHA512;
default:
break;
}
return CKM_INVALID_MECHANISM;
}
class Pkcs11DsaTest : public ::testing::TestWithParam<DsaTestVector> {
class Pkcs11DsaTestBase : public Pk11SignatureTest {
protected:
void Derive(const uint8_t* sig, size_t sig_len, const uint8_t* spki,
size_t spki_len, const uint8_t* data, size_t data_len,
bool expect_success, const uint32_t test_id,
const SECOidTag hash_oid) {
std::stringstream s;
s << "Test with original ID #" << test_id << " failed.\n";
s << "Expected Success: " << expect_success << "\n";
std::string msg = s.str();
Pkcs11DsaTestBase(SECOidTag hashOid)
: Pk11SignatureTest(CKM_DSA, hashOid, DsaHashToComboMech(hashOid)) {}
SECItem spki_item = {siBuffer, toUcharPtr(spki),
static_cast<unsigned int>(spki_len)};
ScopedCERTSubjectPublicKeyInfo cert_spki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
ASSERT_TRUE(cert_spki) << msg;
ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get()));
ASSERT_TRUE(pub_key) << msg;
SECItem sig_item = {siBuffer, toUcharPtr(sig),
static_cast<unsigned int>(sig_len)};
ScopedSECItem decoded_sig_item(
DSAU_DecodeDerSigToLen(&sig_item, SECKEY_SignatureLen(pub_key.get())));
if (!decoded_sig_item) {
ASSERT_FALSE(expect_success) << msg;
void Verify(const DsaTestVector vec) {
/* DSA vectors encode the signature in DER, we need to unwrap it before
* we can send the raw signatures to PKCS #11. */
DataBuffer pubKeyBuffer(vec.public_key.data(), vec.public_key.size());
ScopedSECKEYPublicKey nssPubKey(ImportPublicKey(pubKeyBuffer));
SECItem sigItem = {siBuffer, toUcharPtr(vec.sig.data()),
static_cast<unsigned int>(vec.sig.size())};
ScopedSECItem decodedSigItem(
DSAU_DecodeDerSigToLen(&sigItem, SECKEY_SignatureLen(nssPubKey.get())));
if (!decodedSigItem) {
ASSERT_FALSE(vec.valid) << "Failed to decode DSA signature Error: "
<< PORT_ErrorToString(PORT_GetError()) << "\n";
return;
}
DataBuffer hash;
hash.Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(hash_oid)));
SECStatus rv = PK11_HashBuf(hash_oid, toUcharPtr(hash.data()),
toUcharPtr(data), data_len);
ASSERT_EQ(SECSuccess, rv) << msg;
// Verify.
SECItem hash_item = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};
rv = PK11_VerifyWithMechanism(pub_key.get(), CKM_DSA, nullptr,
decoded_sig_item.get(), &hash_item, nullptr);
EXPECT_EQ(expect_success ? SECSuccess : SECFailure, rv);
};
void Derive(const DsaTestVector vector) {
Derive(vector.sig.data(), vector.sig.size(), vector.public_key.data(),
vector.public_key.size(), vector.msg.data(), vector.msg.size(),
vector.valid, vector.id, vector.hash_oid);
};
Pkcs11SignatureTestParams params = {
DataBuffer(), pubKeyBuffer, DataBuffer(vec.msg.data(), vec.msg.size()),
DataBuffer(decodedSigItem.get()->data, decodedSigItem.get()->len)};
Pk11SignatureTest::Verify(params, (bool)vec.valid);
}
};
TEST_P(Pkcs11DsaTest, WycheproofVectors) { Derive(GetParam()); }
class Pkcs11DsaTest : public Pkcs11DsaTestBase,
public ::testing::WithParamInterface<DsaTestVector> {
public:
Pkcs11DsaTest() : Pkcs11DsaTestBase(GetParam().hash_oid) {}
};
TEST_P(Pkcs11DsaTest, WycheproofVectors) { Verify(GetParam()); }
INSTANTIATE_TEST_SUITE_P(DsaTest, Pkcs11DsaTest,
::testing::ValuesIn(kDsaWycheproofVectors));

View File

@ -8,6 +8,7 @@
#include "sechash.h"
#include "cryptohi.h"
#include "cpputil.h"
#include "gtest/gtest.h"
#include "nss_scoped_ptrs.h"
@ -19,10 +20,29 @@
namespace nss_test {
CK_MECHANISM_TYPE
EcHashToComboMech(SECOidTag hash) {
switch (hash) {
case SEC_OID_SHA1:
return CKM_ECDSA_SHA1;
case SEC_OID_SHA224:
return CKM_ECDSA_SHA224;
case SEC_OID_SHA256:
return CKM_ECDSA_SHA256;
case SEC_OID_SHA384:
return CKM_ECDSA_SHA384;
case SEC_OID_SHA512:
return CKM_ECDSA_SHA512;
default:
break;
}
return CKM_INVALID_MECHANISM;
}
class Pkcs11EcdsaTestBase : public Pk11SignatureTest {
protected:
Pkcs11EcdsaTestBase(SECOidTag hash_oid)
: Pk11SignatureTest(CKM_ECDSA, hash_oid) {}
: Pk11SignatureTest(CKM_ECDSA, hash_oid, EcHashToComboMech(hash_oid)) {}
};
struct Pkcs11EcdsaTestParams {
@ -88,7 +108,8 @@ TEST_F(Pkcs11EcdsaSha256Test, ImportOnlyAlgorithmParams) {
sizeof(kP256Pkcs8OnlyAlgorithmParams));
DataBuffer data(kP256Data, sizeof(kP256Data));
DataBuffer sig;
EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig));
DataBuffer sig2;
EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig, &sig2));
};
// Importing a private key in PKCS#8 format must succeed when the outer AlgID
@ -99,7 +120,8 @@ TEST_F(Pkcs11EcdsaSha256Test, ImportMatchingCurveOIDAndAlgorithmParams) {
sizeof(kP256Pkcs8MatchingCurveOIDAndAlgorithmParams));
DataBuffer data(kP256Data, sizeof(kP256Data));
DataBuffer sig;
EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig));
DataBuffer sig2;
EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig, &sig2));
};
// Importing a private key in PKCS#8 format must succeed when the outer AlgID
@ -110,7 +132,8 @@ TEST_F(Pkcs11EcdsaSha256Test, ImportDissimilarCurveOIDAndAlgorithmParams) {
sizeof(kP256Pkcs8DissimilarCurveOIDAndAlgorithmParams));
DataBuffer data(kP256Data, sizeof(kP256Data));
DataBuffer sig;
EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig));
DataBuffer sig2;
EXPECT_TRUE(ImportPrivateKeyAndSignHashedData(k, data, &sig, &sig2));
};
// Importing a private key in PKCS#8 format must fail when the outer ASN.1

View File

@ -44,6 +44,7 @@
'pk11_rsapkcs1_unittest.cc',
'pk11_rsapss_unittest.cc',
'pk11_seed_cbc_unittest.cc',
'pk11_signature_test.cc',
'<(DEPTH)/gtests/common/gtests.cc'
],
'dependencies': [

View File

@ -15,6 +15,7 @@
#include "pk11pub.h"
#include "secerr.h"
#include "sechash.h"
#include "pk11_signature_test.h"
#include "testvectors/rsa_signature_2048_sha224-vectors.h"
#include "testvectors/rsa_signature_2048_sha256-vectors.h"
@ -28,10 +29,46 @@
namespace nss_test {
class Pkcs11RsaPkcs1WycheproofTest
: public ::testing::TestWithParam<RsaSignatureTestVector> {
CK_MECHANISM_TYPE RsaHashToComboMech(SECOidTag hash) {
switch (hash) {
case SEC_OID_SHA1:
return CKM_SHA1_RSA_PKCS;
case SEC_OID_SHA224:
return CKM_SHA224_RSA_PKCS;
case SEC_OID_SHA256:
return CKM_SHA256_RSA_PKCS;
case SEC_OID_SHA384:
return CKM_SHA384_RSA_PKCS;
case SEC_OID_SHA512:
return CKM_SHA512_RSA_PKCS;
default:
break;
}
return CKM_INVALID_MECHANISM;
}
class Pkcs11RsaBaseTest : public Pk11SignatureTest {
protected:
void Derive(const RsaSignatureTestVector vec) {
Pkcs11RsaBaseTest(SECOidTag hashOid)
: Pk11SignatureTest(CKM_RSA_PKCS, hashOid, RsaHashToComboMech(hashOid)) {}
void Verify(const RsaSignatureTestVector vec) {
Pkcs11SignatureTestParams params = {
DataBuffer(), DataBuffer(vec.public_key.data(), vec.public_key.size()),
DataBuffer(vec.msg.data(), vec.msg.size()),
DataBuffer(vec.sig.data(), vec.sig.size())};
Pk11SignatureTest::Verify(params, (bool)vec.valid);
}
};
class Pkcs11RsaPkcs1WycheproofTest
: public Pkcs11RsaBaseTest,
public ::testing::WithParamInterface<RsaSignatureTestVector> {
public:
Pkcs11RsaPkcs1WycheproofTest() : Pkcs11RsaBaseTest(GetParam().hash_oid) {}
protected:
void Verify1(const RsaSignatureTestVector vec) {
SECItem spki_item = {siBuffer, toUcharPtr(vec.public_key.data()),
static_cast<unsigned int>(vec.public_key.size())};
@ -210,7 +247,13 @@ TEST(RsaPkcs1Test, RequireNullParameter) {
#endif
}
TEST_P(Pkcs11RsaPkcs1WycheproofTest, Verify) { Derive(GetParam()); }
TEST_P(Pkcs11RsaPkcs1WycheproofTest, Verify) {
/* Using VFY_ interface */
Verify1(GetParam());
/* Using PKCS #11 interface */
setSkipRaw(true);
Verify(GetParam());
}
INSTANTIATE_TEST_SUITE_P(
Wycheproof2048RsaSignatureSha224Test, Pkcs11RsaPkcs1WycheproofTest,

View File

@ -9,7 +9,6 @@
#include "pk11pub.h"
#include "sechash.h"
#include "cpputil.h"
#include "databuffer.h"
#include "gtest/gtest.h"
@ -28,83 +27,68 @@
namespace nss_test {
class Pkcs11RsaPssTestWycheproof
: public ::testing::TestWithParam<RsaPssTestVector> {
CK_MECHANISM_TYPE RsaPssMapCombo(SECOidTag hashOid) {
switch (hashOid) {
case SEC_OID_SHA1:
return CKM_SHA1_RSA_PKCS_PSS;
case SEC_OID_SHA224:
return CKM_SHA224_RSA_PKCS_PSS;
case SEC_OID_SHA256:
return CKM_SHA256_RSA_PKCS_PSS;
case SEC_OID_SHA384:
return CKM_SHA384_RSA_PKCS_PSS;
case SEC_OID_SHA512:
return CKM_SHA512_RSA_PKCS_PSS;
default:
break;
}
return CKM_INVALID_MECHANISM;
}
class Pkcs11RsaPssTestBase : public Pk11SignatureTest {
protected:
void TestPss(const RsaPssTestVector& vec) {
SECItem spki_item = {siBuffer, toUcharPtr(vec.public_key.data()),
static_cast<unsigned int>(vec.public_key.size())};
ScopedCERTSubjectPublicKeyInfo cert_spki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
ASSERT_TRUE(cert_spki);
ScopedSECKEYPublicKey pub_key(SECKEY_ExtractPublicKey(cert_spki.get()));
ASSERT_TRUE(pub_key);
DataBuffer hash;
hash.Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(vec.hash_oid)));
SECStatus rv = PK11_HashBuf(vec.hash_oid, toUcharPtr(hash.data()),
toUcharPtr(vec.msg.data()), vec.msg.size());
ASSERT_EQ(rv, SECSuccess);
// Verify.
SECItem hash_item = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};
SECItem sig_item = {siBuffer, toUcharPtr(vec.sig.data()),
static_cast<unsigned int>(vec.sig.size())};
CK_MECHANISM_TYPE hash_mech = 0;
switch (vec.hash_oid) {
case SEC_OID_SHA1:
hash_mech = CKM_SHA_1;
break;
case SEC_OID_SHA224:
hash_mech = CKM_SHA224;
break;
case SEC_OID_SHA256:
hash_mech = CKM_SHA256;
break;
case SEC_OID_SHA384:
hash_mech = CKM_SHA384;
break;
case SEC_OID_SHA512:
hash_mech = CKM_SHA512;
break;
default:
ASSERT_TRUE(hash_mech);
return;
}
CK_RSA_PKCS_PSS_PARAMS pss_params = {hash_mech, vec.mgf_hash, vec.sLen};
SECItem params = {siBuffer, reinterpret_cast<unsigned char*>(&pss_params),
sizeof(pss_params)};
rv = PK11_VerifyWithMechanism(pub_key.get(), CKM_RSA_PKCS_PSS, &params,
&sig_item, &hash_item, nullptr);
EXPECT_EQ(vec.valid ? SECSuccess : SECFailure, rv);
};
};
class Pkcs11RsaPssTest : public Pk11SignatureTest {
public:
Pkcs11RsaPssTest() : Pk11SignatureTest(CKM_RSA_PKCS_PSS, SEC_OID_SHA1) {
pss_params_.hashAlg = CKM_SHA_1;
pss_params_.mgf = CKG_MGF1_SHA1;
pss_params_.sLen = HASH_ResultLenByOidTag(SEC_OID_SHA1);
Pkcs11RsaPssTestBase(SECOidTag hashOid, CK_RSA_PKCS_MGF_TYPE mgf, int sLen)
: Pk11SignatureTest(CKM_RSA_PKCS_PSS, hashOid, RsaPssMapCombo(hashOid)) {
pss_params_.hashAlg = PK11_AlgtagToMechanism(hashOid);
pss_params_.mgf = mgf;
pss_params_.sLen = sLen;
params_.type = siBuffer;
params_.data = reinterpret_cast<unsigned char*>(&pss_params_);
params_.len = sizeof(pss_params_);
}
protected:
const SECItem* parameters() const { return &params_; }
void Verify(const RsaPssTestVector& vec) {
Pkcs11SignatureTestParams params = {
DataBuffer(), DataBuffer(vec.public_key.data(), vec.public_key.size()),
DataBuffer(vec.msg.data(), vec.msg.size()),
DataBuffer(vec.sig.data(), vec.sig.size())};
Pk11SignatureTest::Verify(params, vec.valid);
}
private:
CK_RSA_PKCS_PSS_PARAMS pss_params_;
SECItem params_;
};
class Pkcs11RsaPssTest : public Pkcs11RsaPssTestBase {
public:
Pkcs11RsaPssTest()
: Pkcs11RsaPssTestBase(SEC_OID_SHA1, CKG_MGF1_SHA1, SHA1_LENGTH) {}
};
class Pkcs11RsaPssTestWycheproof
: public Pkcs11RsaPssTestBase,
public ::testing::WithParamInterface<RsaPssTestVector> {
public:
Pkcs11RsaPssTestWycheproof()
: Pkcs11RsaPssTestBase(GetParam().hash_oid, GetParam().mgf_hash,
GetParam().sLen) {}
};
TEST_F(Pkcs11RsaPssTest, GenerateAndSignAndVerify) {
// Sign data with a 1024-bit RSA key, using PSS/SHA-256.
SECOidTag hashOid = SEC_OID_SHA256;
@ -179,7 +163,9 @@ class Pkcs11RsaPssVectorTest
: public Pkcs11RsaPssTest,
public ::testing::WithParamInterface<Pkcs11SignatureTestParams> {};
TEST_P(Pkcs11RsaPssVectorTest, Verify) { Verify(GetParam()); }
TEST_P(Pkcs11RsaPssVectorTest, Verify) {
Pk11SignatureTest::Verify(GetParam());
}
TEST_P(Pkcs11RsaPssVectorTest, SignAndVerify) { SignAndVerify(GetParam()); }
@ -227,7 +213,7 @@ static const Pkcs11SignatureTestParams kRsaPssVectors[] = {
INSTANTIATE_TEST_SUITE_P(RsaPssSignVerify, Pkcs11RsaPssVectorTest,
::testing::ValuesIn(kRsaPssVectors));
TEST_P(Pkcs11RsaPssTestWycheproof, Verify) { TestPss(GetParam()); }
TEST_P(Pkcs11RsaPssTestWycheproof, Verify) { Verify(GetParam()); }
INSTANTIATE_TEST_SUITE_P(
Wycheproof2048RsaPssSha120Test, Pkcs11RsaPssTestWycheproof,

View File

@ -0,0 +1,181 @@
/* 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 <memory>
#include "nss.h"
#include "pk11pub.h"
#include "sechash.h"
#include "prerror.h"
#include "cpputil.h"
#include "nss_scoped_ptrs.h"
#include "databuffer.h"
#include "gtest/gtest.h"
#include "pk11_signature_test.h"
namespace nss_test {
ScopedSECKEYPrivateKey Pk11SignatureTest::ImportPrivateKey(
const DataBuffer& pkcs8) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
ADD_FAILURE() << "No slot";
return nullptr;
}
SECItem pkcs8Item = {siBuffer, toUcharPtr(pkcs8.data()),
static_cast<unsigned int>(pkcs8.len())};
SECKEYPrivateKey* key = nullptr;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8Item, nullptr, nullptr, false, false, KU_ALL, &key,
nullptr);
if (rv != SECSuccess) {
return nullptr;
}
return ScopedSECKEYPrivateKey(key);
}
ScopedSECKEYPublicKey Pk11SignatureTest::ImportPublicKey(
const DataBuffer& spki) {
SECItem spkiItem = {siBuffer, toUcharPtr(spki.data()),
static_cast<unsigned int>(spki.len())};
ScopedCERTSubjectPublicKeyInfo certSpki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
if (!certSpki) {
return nullptr;
}
return ScopedSECKEYPublicKey(SECKEY_ExtractPublicKey(certSpki.get()));
}
bool Pk11SignatureTest::SignHashedData(ScopedSECKEYPrivateKey& privKey,
const DataBuffer& hash,
DataBuffer* sig) {
SECItem hashItem = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};
unsigned int sigLen = PK11_SignatureLen(privKey.get());
EXPECT_LT(0, (int)sigLen);
sig->Allocate(static_cast<size_t>(sigLen));
SECItem sigItem = {siBuffer, toUcharPtr(sig->data()),
static_cast<unsigned int>(sig->len())};
SECStatus rv = PK11_SignWithMechanism(privKey.get(), mechanism_, parameters(),
&sigItem, &hashItem);
EXPECT_EQ(sigLen, sigItem.len);
return rv == SECSuccess;
}
bool Pk11SignatureTest::SignData(ScopedSECKEYPrivateKey& privKey,
const DataBuffer& data, DataBuffer* sig) {
unsigned int sigLen = PK11_SignatureLen(privKey.get());
bool result = true;
EXPECT_LT(0, (int)sigLen);
sig->Allocate(static_cast<size_t>(sigLen));
// test the hash and verify interface */
PK11Context* context = PK11_CreateContextByPrivKey(
combo_, CKA_SIGN, privKey.get(), parameters());
if (context == NULL) {
ADD_FAILURE() << "Failed to sign data: couldn't create context"
<< "\n"
<< "mech=0x" << std::hex << combo_ << "\n"
<< "Error: " << PORT_ErrorToString(PORT_GetError());
return false;
}
SECStatus rv = PK11_DigestOp(context, data.data(), data.len());
if (rv != SECSuccess) {
ADD_FAILURE() << "Failed to sign data: Update failed\n"
<< "Error: " << PORT_ErrorToString(PORT_GetError());
PK11_DestroyContext(context, PR_TRUE);
return false;
}
unsigned int len = sigLen;
rv = PK11_DigestFinal(context, sig->data(), &len, sigLen);
if (rv != SECSuccess) {
ADD_FAILURE() << "Failed to sign data: final failed\n"
<< "Error: " << PORT_ErrorToString(PORT_GetError());
result = false;
}
if (len != sigLen) {
ADD_FAILURE() << "sign data: unexpected len " << len << "expected"
<< sigLen;
result = false;
}
PK11_DestroyContext(context, PR_TRUE);
return result;
}
bool Pk11SignatureTest::ImportPrivateKeyAndSignHashedData(
const DataBuffer& pkcs8, const DataBuffer& data, DataBuffer* sig,
DataBuffer* sig2) {
ScopedSECKEYPrivateKey privKey(ImportPrivateKey(pkcs8));
if (!privKey) {
return false;
}
DataBuffer hash;
if (!ComputeHash(data, &hash)) {
ADD_FAILURE() << "Failed to compute hash";
return false;
}
if (!SignHashedData(privKey, hash, sig)) {
ADD_FAILURE() << "Failed to sign hashed data";
return false;
}
if (!SignData(privKey, data, sig2)) {
/* failure was already added by SignData, with an error message */
return false;
}
return true;
}
void Pk11SignatureTest::Verify(const Pkcs11SignatureTestParams& params,
const DataBuffer& sig, bool valid) {
ScopedSECKEYPublicKey pubKey(ImportPublicKey(params.spki_));
ASSERT_TRUE(pubKey);
SECStatus rv;
DataBuffer hash;
SECItem sigItem = {siBuffer, toUcharPtr(sig.data()),
static_cast<unsigned int>(sig.len())};
/* RSA single shot requires encoding the hash before calling
* VerifyWithMechanism. We already check that mechanism
* with the VFY_ interface, so just do the combined hash/Verify
* in that case */
if (!skip_raw_) {
ASSERT_TRUE(ComputeHash(params.data_, &hash));
// Verify.
SECItem hashItem = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};
rv = PK11_VerifyWithMechanism(pubKey.get(), mechanism_, parameters(),
&sigItem, &hashItem, nullptr);
EXPECT_EQ(rv, valid ? SECSuccess : SECFailure);
}
// test the hash and verify interface */
PK11Context* context = PK11_CreateContextByPubKey(
combo_, CKA_VERIFY, pubKey.get(), parameters(), NULL);
/* we assert here because we'll crash if we try to continue
* without a context. */
ASSERT_NE((void*)context, (void*)NULL)
<< "CreateContext failed Error:" << PORT_ErrorToString(PORT_GetError())
<< "\n";
rv = PK11_DigestOp(context, params.data_.data(), params.data_.len());
/* expect success unconditionally here */
EXPECT_EQ(rv, SECSuccess);
unsigned int len;
rv = PK11_DigestFinal(context, sigItem.data, &len, sigItem.len);
EXPECT_EQ(rv, valid ? SECSuccess : SECFailure)
<< "verify failed Error:" << PORT_ErrorToString(PORT_GetError()) << "\n";
PK11_DestroyContext(context, PR_TRUE);
}
} // namespace nss_test

View File

@ -7,7 +7,6 @@
#include "pk11pub.h"
#include "sechash.h"
#include "cpputil.h"
#include "nss_scoped_ptrs.h"
#include "databuffer.h"
@ -25,46 +24,18 @@ struct Pkcs11SignatureTestParams {
class Pk11SignatureTest : public ::testing::Test {
protected:
Pk11SignatureTest(CK_MECHANISM_TYPE mech, SECOidTag hash_oid)
: mechanism_(mech), hash_oid_(hash_oid) {}
Pk11SignatureTest(CK_MECHANISM_TYPE mech, SECOidTag hash_oid,
CK_MECHANISM_TYPE combo)
: mechanism_(mech), hash_oid_(hash_oid), combo_(combo) {
skip_raw_ = false;
}
virtual const SECItem* parameters() const { return nullptr; }
CK_MECHANISM_TYPE mechanism() const { return mechanism_; }
void setSkipRaw(bool skip_raw) { skip_raw_ = true; }
ScopedSECKEYPrivateKey ImportPrivateKey(const DataBuffer& pkcs8) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
if (!slot) {
ADD_FAILURE() << "No slot";
return nullptr;
}
SECItem pkcs8Item = {siBuffer, toUcharPtr(pkcs8.data()),
static_cast<unsigned int>(pkcs8.len())};
SECKEYPrivateKey* key = nullptr;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8Item, nullptr, nullptr, false, false, KU_ALL, &key,
nullptr);
if (rv != SECSuccess) {
return nullptr;
}
return ScopedSECKEYPrivateKey(key);
}
ScopedSECKEYPublicKey ImportPublicKey(const DataBuffer& spki) {
SECItem spkiItem = {siBuffer, toUcharPtr(spki.data()),
static_cast<unsigned int>(spki.len())};
ScopedCERTSubjectPublicKeyInfo certSpki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
if (!certSpki) {
return nullptr;
}
return ScopedSECKEYPublicKey(SECKEY_ExtractPublicKey(certSpki.get()));
}
ScopedSECKEYPrivateKey ImportPrivateKey(const DataBuffer& pkcs8);
ScopedSECKEYPublicKey ImportPublicKey(const DataBuffer& spki);
bool ComputeHash(const DataBuffer& data, DataBuffer* hash) {
hash->Allocate(static_cast<size_t>(HASH_ResultLenByOidTag(hash_oid_)));
@ -74,66 +45,37 @@ class Pk11SignatureTest : public ::testing::Test {
}
bool SignHashedData(ScopedSECKEYPrivateKey& privKey, const DataBuffer& hash,
DataBuffer* sig) {
SECItem hashItem = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};
int sigLen = PK11_SignatureLen(privKey.get());
EXPECT_LT(0, sigLen);
sig->Allocate(static_cast<size_t>(sigLen));
SECItem sigItem = {siBuffer, toUcharPtr(sig->data()),
static_cast<unsigned int>(sig->len())};
SECStatus rv = PK11_SignWithMechanism(privKey.get(), mechanism_,
parameters(), &sigItem, &hashItem);
return rv == SECSuccess;
}
DataBuffer* sig);
bool SignData(ScopedSECKEYPrivateKey& privKey, const DataBuffer& data,
DataBuffer* sig);
bool ImportPrivateKeyAndSignHashedData(const DataBuffer& pkcs8,
const DataBuffer& data,
DataBuffer* sig) {
ScopedSECKEYPrivateKey privKey(ImportPrivateKey(pkcs8));
if (!privKey) {
return false;
}
DataBuffer* sig, DataBuffer* sig2);
void Verify(const Pkcs11SignatureTestParams& params, const DataBuffer& sig,
bool valid);
DataBuffer hash;
if (!ComputeHash(data, &hash)) {
ADD_FAILURE() << "Failed to compute hash";
return false;
}
return SignHashedData(privKey, hash, sig);
}
void Verify(const Pkcs11SignatureTestParams& params, const DataBuffer& sig) {
ScopedSECKEYPublicKey pubKey(ImportPublicKey(params.spki_));
ASSERT_TRUE(pubKey);
DataBuffer hash;
ASSERT_TRUE(ComputeHash(params.data_, &hash));
// Verify.
SECItem hashItem = {siBuffer, toUcharPtr(hash.data()),
static_cast<unsigned int>(hash.len())};
SECItem sigItem = {siBuffer, toUcharPtr(sig.data()),
static_cast<unsigned int>(sig.len())};
SECStatus rv = PK11_VerifyWithMechanism(
pubKey.get(), mechanism_, parameters(), &sigItem, &hashItem, nullptr);
EXPECT_EQ(rv, SECSuccess);
void Verify(const Pkcs11SignatureTestParams& params, bool valid) {
Verify(params, params.signature_, valid);
}
void Verify(const Pkcs11SignatureTestParams& params) {
Verify(params, params.signature_);
Verify(params, params.signature_, true);
}
void SignAndVerify(const Pkcs11SignatureTestParams& params) {
DataBuffer sig;
ASSERT_TRUE(
ImportPrivateKeyAndSignHashedData(params.pkcs8_, params.data_, &sig));
Verify(params, sig);
DataBuffer sig2;
ASSERT_TRUE(ImportPrivateKeyAndSignHashedData(params.pkcs8_, params.data_,
&sig, &sig2));
Verify(params, sig, true);
Verify(params, sig2, true);
}
private:
CK_MECHANISM_TYPE mechanism_;
SECOidTag hash_oid_;
CK_MECHANISM_TYPE combo_;
bool skip_raw_;
};
} // namespace nss_test

View File

@ -98,4 +98,14 @@ PRBool arm_sha1_support();
PRBool arm_sha2_support();
PRBool ppc_crypto_support();
#ifdef NSS_FIPS_DISABLED
#define BLAPI_CLEAR_STACK(stack_size)
#else
#define BLAPI_CLEAR_STACK(stack_size) \
{ \
volatile char _stkclr[stack_size]; \
PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
}
#endif
#endif /* _BLAPII_H_ */

View File

@ -145,6 +145,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
requested_bytes += hash_return_len;
no_of_bytes_to_return -= hash_return_len;
}
SHA256_DestroyContext(&ctx, PR_FALSE);
return SECSuccess;
}
@ -197,6 +198,7 @@ prng_initEntropy(void)
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
sizeof(globalrng->previousEntropyHash));
PORT_Memset(block, 0, sizeof(block));
SHA256_DestroyContext(&ctx, PR_FALSE);
return PR_SUCCESS;
}
@ -244,6 +246,7 @@ prng_getEntropy(PRUint8 *buffer, size_t requestLength)
}
out:
PORT_Memset(hash, 0, sizeof hash);
PORT_Memset(block, 0, sizeof block);
return rv;
}
@ -388,6 +391,7 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
* This increments data if no_of_returned_bytes is not zero */
carry = no_of_returned_bytes;
PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
SHA256_DestroyContext(&ctx, PR_FALSE);
}
PORT_Memset(data, 0, sizeof data);
PORT_Memset(thisHash, 0, sizeof thisHash);
@ -430,6 +434,7 @@ prng_generateNewBytes(RNGContext *rng,
SHA256_End(&ctx, w, NULL, sizeof w);
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
PORT_Memset(w, 0, sizeof w);
SHA256_DestroyContext(&ctx, PR_FALSE);
#undef w
}
@ -450,6 +455,7 @@ prng_generateNewBytes(RNGContext *rng,
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
/* if the prng failed, don't return any output, signal softoken */
PORT_Memset(H, 0, sizeof H);
if (!rng->isValid) {
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);

View File

@ -260,7 +260,7 @@ DSA_NewRandom(PLArenaPool *arena, const SECItem *q, SECItem *seed)
PORT_SetError(SEC_ERROR_NEED_RANDOM);
loser:
if (arena != NULL) {
SECITEM_FreeItem(seed, PR_FALSE);
SECITEM_ZfreeItem(seed, PR_FALSE);
}
return SECFailure;
}
@ -295,7 +295,7 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
rv = dsa_NewKeyExtended(params, &seed, privKey);
}
}
SECITEM_FreeItem(&seed, PR_FALSE);
SECITEM_ZfreeItem(&seed, PR_FALSE);
return rv;
}
@ -403,6 +403,8 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
CHECK_MPI_OK(mp_exptmod(&g, &t, &p, &r)); /* r = g**t mod p */
/* r is now g**(k+q*fuzz) == g**k mod p */
CHECK_MPI_OK(mp_mod(&r, &q, &r)); /* r = r mod q */
/* make sure fuzz is cleared off the stack and not optimized away */
*(volatile mp_digit *)&fuzz = 0;
/*
** FIPS 186-1, Section 5, Step 2
@ -415,14 +417,14 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
goto cleanup;
}
SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
SECITEM_FreeItem(&t2, PR_FALSE);
SECITEM_ZfreeItem(&t2, PR_FALSE);
if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
rv = SECFailure;
goto cleanup;
}
SECITEM_TO_MPINT(t2, &ar); /* ar <-$ Zq */
SECITEM_FreeItem(&t2, PR_FALSE);
SECITEM_ZfreeItem(&t2, PR_FALSE);
/* Using mp_invmod on k directly would leak bits from k. */
CHECK_MPI_OK(mp_mul(&k, &ar, &k)); /* k = k * ar */
@ -530,6 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
PORT_Memset(kSeed, 0, sizeof kSeed);
return rv;
}
@ -670,6 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
verified = SECSuccess; /* Signature verified. */
}
cleanup:
PORT_Memset(localDigestData, 0, sizeof localDigestData);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);

View File

@ -7,6 +7,7 @@
#endif
#include "blapi.h"
#include "blapii.h"
#include "prerr.h"
#include "secerr.h"
#include "secmpi.h"
@ -146,6 +147,10 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
CHECK_MPI_OK(ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy));
}
/* our ECC codes uses large stack variables to store intermediate results,
* clear our stack before returning to prevent CSP leakage */
BLAPI_CLEAR_STACK(2048)
/* Construct the SECItem representation of point Q */
pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
CHECK_MPI_OK(mp_to_fixlen_octets(&Qx, pointQ->data + 1,
@ -531,7 +536,6 @@ ECDH_Derive(SECItem *publicValue,
unsigned int len = 0;
SECItem pointQ = { siBuffer, NULL, 0 };
mp_int k; /* to hold the private value */
mp_int cofactor;
mp_err err = MP_OKAY;
#if EC_DEBUG
int i;
@ -596,11 +600,13 @@ ECDH_Derive(SECItem *publicValue,
(mp_size)privateValue->len));
if (withCofactor && (ecParams->cofactor != 1)) {
mp_int cofactor;
/* multiply k with the cofactor */
MP_DIGITS(&cofactor) = 0;
CHECK_MPI_OK(mp_init(&cofactor));
mp_set(&cofactor, ecParams->cofactor);
CHECK_MPI_OK(mp_mul(&k, &cofactor, &k));
mp_clear(&cofactor);
}
/* Multiply our private key and peer's public point */
@ -858,7 +864,7 @@ cleanup:
mp_clear(&ar);
if (t2) {
PORT_Free(t2);
PORT_ZFree(t2, 2 * ecParams->order.len);
}
if (kGpoint.data) {

View File

@ -192,7 +192,7 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
mp_int raz4;
mp_int scratch[MAX_SCRATCH];
signed char *naf = NULL;
int i, orderBitSize;
int i, orderBitSize = 0;
MP_DIGITS(&rz) = 0;
MP_DIGITS(&raz4) = 0;
@ -289,6 +289,9 @@ CLEANUP:
mp_clear(&tpy);
mp_clear(&rz);
mp_clear(&raz4);
if (naf) {
memset(naf, 0, orderBitSize + 1);
}
free(naf);
return res;
}

View File

@ -593,15 +593,19 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
if (rv != SECSuccess) {
goto loser;
}
PORT_Memset(H, 0, AES_BLOCK_SIZE);
gcm->ctr_context_init = PR_TRUE;
return gcm;
loser:
PORT_Memset(H, 0, AES_BLOCK_SIZE);
if (ghash && ghash->mem) {
PORT_Free(ghash->mem);
void *mem = ghash->mem;
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
PORT_Free(mem);
}
if (gcm) {
PORT_Free(gcm);
PORT_ZFree(gcm, sizeof(GCMContext));
}
return NULL;
}
@ -675,9 +679,11 @@ gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen,
goto loser;
}
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
return SECSuccess;
loser:
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
if (freeCtr) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
@ -687,13 +693,15 @@ loser:
void
GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
{
/* these two are statically allocated and will be freed when we free
void *mem = gcm->ghash_context->mem;
/* ctr_context is statically allocated and will be freed when we free
* gcm. call their destroy functions to free up any locally
* allocated data (like mp_int's) */
if (gcm->ctr_context_init) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
PORT_Free(gcm->ghash_context->mem);
PORT_Memset(gcm->ghash_context, 0, sizeof(gcmHashContext));
PORT_Free(mem);
PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
if (freeit) {

View File

@ -274,6 +274,11 @@ MAC(unsigned char *mdOut,
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
hashObj->destroy(mdState, PR_TRUE);
PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
PORT_Memset(hmacPad, 0, sizeof hmacPad);
PORT_Memset(firstBlock, 0, sizeof firstBlock);
PORT_Memset(macOut, 0, sizeof macOut);
return SECSuccess;
}

View File

@ -1006,7 +1006,11 @@ CLEANUP:
mp_clear(&accum[2]);
mp_clear(&accum[3]);
mp_clear(&tmp);
/* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */
/* zero required by FIPS here, can't use PORT_ZFree
* because mpi doesn't link with util */
if (powers) {
PORT_Memset(powers, 0, num_powers * sizeof(mp_digit));
}
free(powersArray);
return res;
}

View File

@ -711,7 +711,7 @@ cleanup:
if (rv == SECFailure) {
mp_zero(prime);
if (prime_seed->data) {
SECITEM_FreeItem(prime_seed, PR_FALSE);
SECITEM_ZfreeItem(prime_seed, PR_FALSE);
}
*prime_gen_counter = 0;
}
@ -867,7 +867,7 @@ cleanup:
if (rv == SECFailure) {
mp_zero(prime);
if (prime_seed->data) {
SECITEM_FreeItem(prime_seed, PR_FALSE);
SECITEM_ZfreeItem(prime_seed, PR_FALSE);
}
*prime_gen_counter = 0;
}
@ -905,6 +905,7 @@ findQfromSeed(
*typePtr = FIPS186_1_TYPE;
return SECSuccess;
}
mp_zero(Q_);
return SECFailure;
}
/* 1024 could use FIPS186_1 or FIPS186_3 algorithms, we need to try
@ -954,21 +955,23 @@ findQfromSeed(
if ((offset < 0) ||
(PORT_Memcmp(&seed->data[offset], qseed.data, qseed.len) != 0)) {
/* we found q, but the seeds don't match. This isn't an
* accident, someone has been tweeking with the seeds, just
* fail a this point. */
* accident, someone has been tweeking with the seeds, just
* fail a this point. */
SECITEM_FreeItem(&qseed, PR_FALSE);
mp_zero(Q_);
return SECFailure;
}
*qseed_len = qseed.len;
*hashtypePtr = hashtype;
*typePtr = FIPS186_3_ST_TYPE;
*qgen_counter = count;
SECITEM_FreeItem(&qseed, PR_FALSE);
SECITEM_ZfreeItem(&qseed, PR_FALSE);
return SECSuccess;
}
SECITEM_FreeItem(&qseed, PR_FALSE);
SECITEM_ZfreeItem(&qseed, PR_FALSE);
}
/* no hash algorithms found which match seed to Q, fail */
mp_zero(Q_);
return SECFailure;
}
@ -1069,6 +1072,7 @@ makePfromQandSeed(
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
cleanup:
PORT_Memset(V_j, 0, sizeof V_j);
mp_clear(&W);
mp_clear(&X);
mp_clear(&c);
@ -1077,8 +1081,12 @@ cleanup:
mp_clear(&tmp);
if (err) {
MP_TO_SEC_ERROR(err);
mp_zero(P);
return SECFailure;
}
if (rv != SECSuccess) {
mp_zero(P);
}
return rv;
}
@ -1128,6 +1136,9 @@ cleanup:
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
if (rv != SECSuccess) {
mp_zero(G);
}
return rv;
}
@ -1534,10 +1545,10 @@ generate_G:
*pVfy = verify;
cleanup:
if (pseed.data) {
PORT_Free(pseed.data);
SECITEM_ZfreeItem(&pseed, PR_FALSE);
}
if (qseed.data) {
PORT_Free(qseed.data);
SECITEM_ZfreeItem(&qseed, PR_FALSE);
}
mp_clear(&P);
mp_clear(&Q);
@ -1558,7 +1569,7 @@ cleanup:
}
}
if (hit.data) {
SECITEM_FreeItem(&hit, PR_FALSE);
SECITEM_ZfreeItem(&hit, PR_FALSE);
}
return rv;
}
@ -1869,7 +1880,7 @@ cleanup:
mp_clear(&r);
mp_clear(&h);
if (pseed_.data) {
SECITEM_FreeItem(&pseed_, PR_FALSE);
SECITEM_ZfreeItem(&pseed_, PR_FALSE);
}
if (err) {
MP_TO_SEC_ERROR(err);
@ -1887,11 +1898,11 @@ PQG_DestroyParams(PQGParams *params)
if (params == NULL)
return;
if (params->arena != NULL) {
PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
PORT_FreeArena(params->arena, PR_TRUE);
} else {
SECITEM_FreeItem(&params->prime, PR_FALSE); /* don't free prime */
SECITEM_FreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
SECITEM_FreeItem(&params->base, PR_FALSE); /* don't free base */
SECITEM_ZfreeItem(&params->prime, PR_FALSE); /* don't free prime */
SECITEM_ZfreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
SECITEM_ZfreeItem(&params->base, PR_FALSE); /* don't free base */
PORT_Free(params);
}
}
@ -1906,10 +1917,10 @@ PQG_DestroyVerify(PQGVerify *vfy)
if (vfy == NULL)
return;
if (vfy->arena != NULL) {
PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
PORT_FreeArena(vfy->arena, PR_TRUE);
} else {
SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
SECITEM_ZfreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
SECITEM_ZfreeItem(&vfy->h, PR_FALSE); /* don't free h */
PORT_Free(vfy);
}
}

View File

@ -957,6 +957,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
} else {
rijndael_invkey_expansion(cx, key, Nk);
}
BLAPI_CLEAR_STACK(256)
}
cx->worker_cx = cx;
cx->destroy = NULL;
@ -1118,6 +1119,7 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
const unsigned char *input, unsigned int inputLen)
{
/* Check args */
SECStatus rv;
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@ -1152,8 +1154,10 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
}
#endif
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
rv = (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
BLAPI_CLEAR_STACK(256)
return rv;
}
/*
@ -1167,6 +1171,7 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
SECStatus rv;
/* Check args */
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -1181,8 +1186,10 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
return SECFailure;
}
*outputLen = inputLen;
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
rv = (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, AES_BLOCK_SIZE);
BLAPI_CLEAR_STACK(256)
return rv;
}
/*
@ -1197,6 +1204,7 @@ AES_AEAD(AESContext *cx, unsigned char *output,
void *params, unsigned int paramsLen,
const unsigned char *aad, unsigned int aadLen)
{
SECStatus rv;
/* Check args */
if (cx == NULL || output == NULL || (input == NULL && inputLen != 0) || (aad == NULL && aadLen != 0) || params == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -1232,7 +1240,9 @@ AES_AEAD(AESContext *cx, unsigned char *output,
}
#endif
return (*cx->worker_aead)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, params, paramsLen, aad, aadLen,
AES_BLOCK_SIZE);
rv = (*cx->worker_aead)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, params, paramsLen, aad, aadLen,
AES_BLOCK_SIZE);
BLAPI_CLEAR_STACK(256)
return rv;
}

View File

@ -1593,7 +1593,7 @@ RSA_Cleanup(void)
mp_clear(&bp->f);
mp_clear(&bp->g);
}
SECITEM_FreeItem(&rsabp->modulus, PR_FALSE);
SECITEM_ZfreeItem(&rsabp->modulus, PR_FALSE);
PORT_Free(rsabp);
}

View File

@ -147,7 +147,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
padLen = modulusLen - data->len - 3;
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
PORT_Free(block);
PORT_ZFree(block, modulusLen);
return NULL;
}
PORT_Memset(bp, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
@ -176,7 +176,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
padLen = modulusLen - (data->len + 3);
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
PORT_Free(block);
PORT_ZFree(block, modulusLen);
return NULL;
}
j = modulusLen - 2;
@ -205,7 +205,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
}
}
if (rv != SECSuccess) {
PORT_Free(block);
PORT_ZFree(block, modulusLen);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
@ -216,7 +216,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
default:
PORT_Assert(0);
PORT_Free(block);
PORT_ZFree(block, modulusLen);
return NULL;
}

View File

@ -18,6 +18,7 @@
#include "hasht.h"
#include "pqg.h"
#include "blapii.h"
#include "secitem.h"
#ifndef NSS_FIPS_DISABLED
@ -494,6 +495,8 @@ blapi_SHVerifyFile(const char *shName, PRBool self)
#endif /* DEBUG_SHVERIFY */
loser:
PORT_Memset(buf, 0, sizeof buf);
PORT_Memset(hashBuf, 0, sizeof hashBuf);
if (checkName != NULL) {
PORT_Free(checkName);
}
@ -509,19 +512,19 @@ loser:
}
}
if (signature.data != NULL) {
PORT_Free(signature.data);
SECITEM_ZfreeItem(&signature, PR_FALSE);
}
if (key.params.prime.data != NULL) {
PORT_Free(key.params.prime.data);
SECITEM_ZfreeItem(&key.params.prime, PR_FALSE);
}
if (key.params.subPrime.data != NULL) {
PORT_Free(key.params.subPrime.data);
SECITEM_ZfreeItem(&key.params.subPrime, PR_FALSE);
}
if (key.params.base.data != NULL) {
PORT_Free(key.params.base.data);
SECITEM_ZfreeItem(&key.params.base, PR_FALSE);
}
if (key.publicValue.data != NULL) {
PORT_Free(key.publicValue.data);
SECITEM_ZfreeItem(&key.publicValue, PR_FALSE);
}
return result;

View File

@ -22,6 +22,7 @@ RNG_SystemInfoForRNG(void)
return;
}
RNG_RandomUpdate(bytes, numBytes);
PORT_Memset(bytes, 0, sizeof bytes);
}
size_t

View File

@ -829,10 +829,15 @@ pkix_pl_CertNameConstraints_Create(
if (nssNameConstraints == NULL) {
*pNameConstraints = NULL;
/* we free the arnea here because PKIX_ERROR_RECEIVED
* may not be set. Setting arena to NULL makes sure
* we don't try to free it again (and makes scanners
* happy). */
if (arena){
PKIX_CERTNAMECONSTRAINTS_DEBUG
("\t\tCalling PORT_FreeArena).\n");
PORT_FreeArena(arena, PR_FALSE);
arena = NULL;
}
goto cleanup;
}

View File

@ -439,7 +439,8 @@ PKIX_PL_Sprintf(
tempString = va_arg(args, PKIX_PL_String *);
if (tempString != NULL) {
PKIX_CHECK(PKIX_PL_String_GetEncoded
PKIX_CHECK_NO_GOTO(
PKIX_PL_String_GetEncoded
((PKIX_PL_String*)
tempString,
PKIX_ESCASCII,
@ -447,6 +448,12 @@ PKIX_PL_Sprintf(
&dummyLen,
plContext),
PKIX_STRINGGETENCODEDFAILED);
/* need to cleanup var args before
* we ditch out to cleanup. */
if (pkixErrorResult) {
va_end(args);
goto cleanup;
}
} else {
/* there may be a NULL in var_args */
pArg = NULL;

View File

@ -1219,4 +1219,11 @@ PK11_HPKE_ExportContext;
PK11_HPKE_ImportContext;
;+ local:
;+ *;
;+};
;+};
;+NSS_3.65 { # NSS 3.65 release
;+ global:
PK11_CreateContextByPubKey;
PK11_CreateContextByPrivKey;
;+ local:
;+ *;
;+};

View File

@ -22,12 +22,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define NSS_VERSION "3.64" _NSS_CUSTOMIZED
#define NSS_VERSION "3.65" _NSS_CUSTOMIZED " Beta"
#define NSS_VMAJOR 3
#define NSS_VMINOR 64
#define NSS_VMINOR 65
#define NSS_VPATCH 0
#define NSS_VBUILD 0
#define NSS_BETA PR_FALSE
#define NSS_BETA PR_TRUE
#ifndef RC_INVOKED

View File

@ -125,7 +125,7 @@ SECStatus
pk11_restoreContext(PK11Context *context, void *space, unsigned long savedLength)
{
CK_RV crv;
CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID : CK_INVALID_HANDLE;
CK_OBJECT_HANDLE objectID = context->objectID;
PORT_Assert(space != NULL);
if (space == NULL) {
@ -150,7 +150,7 @@ SECStatus pk11_Finalize(PK11Context *context);
*/
static CK_RV
pk11_contextInitMessage(PK11Context *context, CK_MECHANISM_PTR mech,
PK11SymKey *key, CK_C_MessageEncryptInit initFunc,
CK_C_MessageEncryptInit initFunc,
CK_FLAGS flags, CK_RV scrv)
{
PK11SlotInfo *slot = context->slot;
@ -173,7 +173,9 @@ pk11_contextInitMessage(PK11Context *context, CK_MECHANISM_PTR mech,
* if those cases */
if ((version.major >= 3) &&
PK11_DoesMechanismFlag(slot, (mech)->mechanism, flags)) {
crv = (*initFunc)((context)->session, (mech), (key)->objectID);
PK11_EnterContextMonitor(context);
crv = (*initFunc)((context)->session, (mech), (context)->objectID);
PK11_ExitContextMonitor(context);
if ((crv == CKR_FUNCTION_NOT_SUPPORTED) ||
(crv == CKR_MECHANISM_INVALID)) {
/* we have a 3.0 interface, and the flag was set (or ignored)
@ -195,54 +197,72 @@ static SECStatus
pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
{
CK_RV crv;
PK11SymKey *symKey = context->key;
SECStatus rv = SECSuccess;
context->simulate_message = PR_FALSE;
switch (context->operation) {
case CKA_ENCRYPT:
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, symKey->objectID);
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
break;
case CKA_DECRYPT:
PK11_EnterContextMonitor(context);
if (context->fortezzaHack) {
CK_ULONG count = 0;
/* generate the IV for fortezza */
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, symKey->objectID);
if (crv != CKR_OK)
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, context->objectID);
if (crv != CKR_OK) {
PK11_ExitContextMonitor(context);
break;
}
PK11_GETTAB(context->slot)
->C_EncryptFinal(context->session,
NULL, &count);
}
crv = PK11_GETTAB(context->slot)->C_DecryptInit(context->session, mech_info, symKey->objectID);
crv = PK11_GETTAB(context->slot)->C_DecryptInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
break;
case CKA_SIGN:
crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, symKey->objectID);
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
break;
case CKA_VERIFY:
crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, symKey->objectID);
/* NOTE: we previously has this set to C_SignInit for Macing.
* It turns out now one could possibly use it that way, though,
* because PK11_HashOp() always called C_VerifyUpdate on CKA_VERIFY,
* which would have failed. So everyone just calls us with CKA_SIGN
* when Macing even when they are verifying, no need to 'do it
* for them'. It needs to be VerifyInit now so that we can do
* PKCS #11 hash/Verify combo operations. */
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_VerifyInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
break;
case CKA_DIGEST:
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_DigestInit(context->session, mech_info);
PK11_ExitContextMonitor(context);
break;
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
crv = pk11_contextInitMessage(context, mech_info, symKey,
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageEncryptInit,
CKF_MESSAGE_ENCRYPT, CKR_OK);
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
crv = pk11_contextInitMessage(context, mech_info, symKey,
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageDecryptInit,
CKF_MESSAGE_DECRYPT, CKR_OK);
break;
case CKA_NSS_MESSAGE | CKA_SIGN:
crv = pk11_contextInitMessage(context, mech_info, symKey,
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageSignInit,
CKF_MESSAGE_SIGN, CKR_FUNCTION_NOT_SUPPORTED);
break;
case CKA_NSS_MESSAGE | CKA_VERIFY:
crv = pk11_contextInitMessage(context, mech_info, symKey,
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageVerifyInit,
CKF_MESSAGE_VERIFY, CKR_FUNCTION_NOT_SUPPORTED);
break;
@ -272,12 +292,14 @@ pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
* handle session starvation case.. use our last session to multiplex
*/
if (!context->ownSession) {
PK11_EnterContextMonitor(context);
context->savedData = pk11_saveContext(context, context->savedData,
&context->savedLength);
if (context->savedData == NULL)
rv = SECFailure;
/* clear out out session for others to use */
pk11_Finalize(context);
PK11_ExitContextMonitor(context);
}
return rv;
}
@ -332,16 +354,17 @@ _PK11_ContextGetAEADSimulation(PK11Context *context)
*/
static PK11Context *
pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey,
SECItem *param)
PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
PK11SymKey *symKey, CK_OBJECT_HANDLE objectID,
const SECItem *param, void *pwArg)
{
CK_MECHANISM mech_info;
PK11Context *context;
SECStatus rv;
PORT_Assert(slot != NULL);
if (!slot || (!symKey && ((operation != CKA_DIGEST) ||
(type == CKM_SKIPJACK_CBC64)))) {
if (!slot || ((objectID == CK_INVALID_HANDLE) && ((operation != CKA_DIGEST) ||
(type == CKM_SKIPJACK_CBC64)))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
@ -366,10 +389,16 @@ pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
/* initialize the critical fields of the context */
context->operation = operation;
/* If we were given a symKey, keep our own reference to it so
* that the key doesn't disappear in the middle of the operation
* if the caller frees it. Public and Private keys are not reference
* counted, so the caller just has to keep his copies around until
* the operation completes */
context->key = symKey ? PK11_ReferenceSymKey(symKey) : NULL;
context->objectID = objectID;
context->slot = PK11_ReferenceSlot(slot);
context->session = pk11_GetNewSession(slot, &context->ownSession);
context->cx = symKey ? symKey->cx : NULL;
context->pwArg = pwArg;
/* get our session */
context->savedData = NULL;
@ -396,9 +425,7 @@ pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
mech_info.mechanism = type;
mech_info.pParameter = param->data;
mech_info.ulParameterLen = param->len;
PK11_EnterContextMonitor(context);
rv = pk11_context_init(context, &mech_info);
PK11_ExitContextMonitor(context);
if (rv != SECSuccess) {
PK11_DestroyContext(context, PR_TRUE);
@ -460,11 +487,11 @@ PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
/*
* Create a context from a key. We really should make sure we aren't using
* the same key in multiple session!
* the same key in multiple sessions!
*/
PK11Context *
PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
PK11SymKey *symKey, SECItem *param)
PK11SymKey *symKey, const SECItem *param)
{
PK11SymKey *newKey;
PK11Context *context;
@ -477,13 +504,72 @@ PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
symKey = newKey;
}
/* Context Adopts the symKey.... */
/* Context keeps its reference to the symKey, so it's safe to
* free our reference we we are through, even though we may have
* created the key using pk11_ForceSlot. */
context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey,
param);
symKey->objectID, param, symKey->cx);
PK11_FreeSymKey(symKey);
return context;
}
/* To support multipart public key operations (like hash/verify operations),
* we need to create contexts with public keys. */
PK11Context *
PK11_CreateContextByPubKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
SECKEYPublicKey *pubKey, const SECItem *param,
void *pwArg)
{
PK11SlotInfo *slot = pubKey->pkcs11Slot;
SECItem nullparam = { 0, 0, 0 };
/* if this slot doesn't support the mechanism, go to a slot that does */
/* public keys have all their data in the public key data structure,
* so there's no need to export the old key, just import this one. The
* import manages consistancy of the public key data structure */
if (slot == NULL || !PK11_DoesMechanism(slot, type)) {
CK_OBJECT_HANDLE objectID;
slot = PK11_GetBestSlot(type, NULL);
if (slot == NULL) {
return NULL;
}
objectID = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
PK11_FreeSlot(slot);
if (objectID == CK_INVALID_HANDLE) {
return NULL;
}
}
/* unlike symkeys, we accept a NULL parameter. map a null parameter
* to the empty parameter. This matches the semantics of
* PK11_VerifyWithMechanism */
return pk11_CreateNewContextInSlot(type, pubKey->pkcs11Slot, operation,
NULL, pubKey->pkcs11ID,
param ? param : &nullparam, pwArg);
}
/* To support multipart private key operations (like hash/sign operations),
* we need to create contexts with private keys. */
PK11Context *
PK11_CreateContextByPrivKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
SECKEYPrivateKey *privKey, const SECItem *param)
{
SECItem nullparam = { 0, 0, 0 };
/* Private keys are generally not movable. If the token the
* private key lives on can't do the operation, generally we are
* stuck anyway. So no need to try to manipulate the key into
* another token */
/* if this slot doesn't support the mechanism, go to a slot that does */
/* unlike symkeys, we accept a NULL parameter. map a null parameter
* to the empty parameter. This matches the semantics of
* PK11_SignWithMechanism */
return pk11_CreateNewContextInSlot(type, privKey->pkcs11Slot, operation,
NULL, privKey->pkcs11ID,
param ? param : &nullparam,
privKey->wincx);
}
/*
* Digest contexts don't need keys, but the do need to find a slot.
* Macing should use PK11_CreateContextBySymKey.
@ -509,7 +595,8 @@ PK11_CreateDigestContext(SECOidTag hashAlg)
param.len = 0;
param.type = 0;
context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL, &param);
context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL,
CK_INVALID_HANDLE, &param, NULL);
PK11_FreeSlot(slot);
return context;
}
@ -527,7 +614,8 @@ PK11_CloneContext(PK11Context *old)
unsigned long len;
newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation,
old->key, old->param);
old->key, old->objectID, old->param,
old->pwArg);
if (newcx == NULL)
return NULL;
@ -703,12 +791,12 @@ PK11_DigestBegin(PK11Context *cx)
*/
PK11_EnterContextMonitor(cx);
pk11_Finalize(cx);
PK11_ExitContextMonitor(cx);
mech_info.mechanism = cx->type;
mech_info.pParameter = cx->param->data;
mech_info.ulParameterLen = cx->param->len;
rv = pk11_context_init(cx, &mech_info);
PK11_ExitContextMonitor(cx);
if (rv != SECSuccess) {
return SECFailure;

View File

@ -528,7 +528,10 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
}
#endif
mod->isThreadSafe = PR_TRUE;
/* This test operation makes sure our locking system is
* consistent even if we are using non-thread safe tokens by
* simulating unsafe tokens with safe ones. */
mod->isThreadSafe = !PR_GetEnvSecure("NSS_FORCE_TOKEN_LOCK");
/* Now we initialize the module */
rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);

View File

@ -1038,8 +1038,8 @@ secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
* try to expand the buffer with Realloc.
*/
static char *
secmod_doDescCopy(char *target, int *targetLen, const char *desc,
int descLen, char *value)
secmod_doDescCopy(char *target, char **base, int *baseLen,
const char *desc, int descLen, char *value)
{
int diff, esc_len;
@ -1048,12 +1048,14 @@ secmod_doDescCopy(char *target, int *targetLen, const char *desc,
if (diff > 0) {
/* we need to escape... expand newSpecPtr as well to make sure
* we don't overflow it */
char *newPtr = PORT_Realloc(target, *targetLen * diff);
int offset = target - *base;
char *newPtr = PORT_Realloc(*base, *baseLen + diff);
if (!newPtr) {
return target; /* not enough space, just drop the whole copy */
}
*targetLen += diff;
target = newPtr;
*baseLen += diff;
target = newPtr + offset;
*base = newPtr;
value = NSSUTIL_Escape(value, '\"');
if (value == NULL) {
return target; /* couldn't escape value, just drop the copy */
@ -1158,7 +1160,7 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
modulePrev = moduleSpec;
if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
&newSpec, &newSpecLen,
SECMOD_TOKEN_DESCRIPTION,
sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
@ -1169,7 +1171,7 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
modulePrev = moduleSpec; /* skip copying */
if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
&newSpec, &newSpecLen,
SECMOD_SLOT_DESCRIPTION,
sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
@ -1180,7 +1182,7 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
modulePrev = moduleSpec; /* skip copying */
if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
&newSpec, &newSpecLen,
SECMOD_TOKEN_DESCRIPTION,
sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
@ -1191,7 +1193,7 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
modulePrev = moduleSpec; /* skip copying */
if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
&newSpec, &newSpecLen,
SECMOD_SLOT_DESCRIPTION,
sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);

View File

@ -811,7 +811,17 @@ SECStatus PK11_VerifyWithMechanism(SECKEYPublicKey *key,
**********************************************************************/
void PK11_DestroyContext(PK11Context *context, PRBool freeit);
PK11Context *PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param);
CK_ATTRIBUTE_TYPE operation,
PK11SymKey *symKey,
const SECItem *param);
PK11Context *PK11_CreateContextByPubKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation,
SECKEYPublicKey *pubKey,
const SECItem *param, void *pwArg);
PK11Context *PK11_CreateContextByPrivKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation,
SECKEYPrivateKey *privKey,
const SECItem *param);
PK11Context *PK11_CreateDigestContext(SECOidTag hashAlg);
PK11Context *PK11_CloneContext(PK11Context *old);
SECStatus PK11_DigestBegin(PK11Context *cx);
@ -1007,7 +1017,7 @@ PRBool SECMOD_HasRootCerts(void);
/**********************************************************************
* Other Utilities
**********************************************************************/
/*
/*
* Get the state of the system FIPS mode -
* NSS uses this to force FIPS mode if the system bit is on. This returns
* the system state independent of the database state and can be called

View File

@ -368,6 +368,7 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
int series, void *wincx)
{
PK11SymKey *symKey = NULL;
CK_OBJECT_HANDLE keyHandle;
PK11_EnterSlotMonitor(slot);
if (slot->series != series ||
@ -380,9 +381,10 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
type = slot->wrapMechanism;
}
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
keyHandle = slot->refKeys[wrap];
PK11_ExitSlotMonitor(slot);
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
slot->wrapMechanism, keyHandle, PR_FALSE, wincx);
return symKey;
}

View File

@ -149,12 +149,13 @@ struct PK11ContextStr {
* doing (CKA_ENCRYPT, CKA_SIGN,
* CKA_HASH, etc.) */
PK11SymKey *key; /* symetric key for this context */
CK_OBJECT_HANDLE objectID; /* object handle to key */
PK11SlotInfo *slot; /* slot this context is using */
CK_SESSION_HANDLE session; /* session this context is using */
PZLock *sessionLock; /* lock before accessing a PKCS #11
* session */
PRBool ownSession; /* do we own the session? */
void *cx; /* window context for login */
void *pwArg; /* applicaton specific passwd arg */
void *savedData; /* save data when we are
* multiplexing on a single context */
unsigned long savedLength; /* length of the saved context */

View File

@ -306,6 +306,10 @@ NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type)
cinfo = &(c.genericData->contentInfo);
}
}
/* We are using a union as a form of 'safe casting'. This
* syntax confuses cppcheck, so tell it it's OK (and any human
* who happens along to verify any other scanner warnings) */
/* cppcheck-suppress returnDanglingLifetime */
return cinfo;
}

View File

@ -650,7 +650,7 @@ FC_GetMechanismList(CK_SLOT_ID slotID,
CHECK_FORK();
SFTK_FIPSFATALCHECK();
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
}
/* FIPS Slots support all functions */
@ -666,7 +666,7 @@ FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CHECK_FORK();
SFTK_FIPSFATALCHECK();
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
}
/* FIPS Slots support all functions */
@ -682,7 +682,7 @@ FC_GetMechanismInfoV2(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CHECK_FORK();
SFTK_FIPSFATALCHECK();
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
slotID = NETSCAPE_SLOT_ID;
}
/* FIPS Slots support all functions */

View File

@ -220,7 +220,7 @@ void
nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
{
if (pubk && pubk->arena) {
PORT_FreeArena(pubk->arena, PR_FALSE);
PORT_FreeArena(pubk->arena, PR_TRUE);
}
}
unsigned
@ -310,7 +310,7 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
break;
}
rv = SECITEM_CopyItem(privk->arena, &privk->u.dsa.publicValue, &publicValue);
SECITEM_FreeItem(&publicValue, PR_FALSE);
SECITEM_ZfreeItem(&publicValue, PR_FALSE);
if (rv != SECSuccess) {
break;
}
@ -349,7 +349,7 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
break;
}
rv = SECITEM_CopyItem(privk->arena, &privk->u.dh.publicValue, &publicValue);
SECITEM_FreeItem(&publicValue, PR_FALSE);
SECITEM_ZfreeItem(&publicValue, PR_FALSE);
if (rv != SECSuccess) {
break;
}
@ -394,7 +394,7 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
break;
}
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
return NULL;
}

View File

@ -164,11 +164,11 @@ nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
}
if (pre_hash != NULL) {
SECITEM_FreeItem(pre_hash, PR_TRUE);
SECITEM_ZfreeItem(pre_hash, PR_TRUE);
}
if ((rv != SECSuccess) && (hash != NULL)) {
SECITEM_FreeItem(hash, PR_TRUE);
SECITEM_ZfreeItem(hash, PR_TRUE);
hash = NULL;
}
@ -297,7 +297,7 @@ nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj,
newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed);
if (hash != newHash)
SECITEM_FreeItem(hash, PR_TRUE);
SECITEM_ZfreeItem(hash, PR_TRUE);
return newHash;
}
@ -403,7 +403,7 @@ loser:
PORT_ZFree(T, hLen);
}
if (rv != SECSuccess) {
SECITEM_FreeItem(result, PR_TRUE);
SECITEM_ZfreeItem(result, PR_TRUE);
result = NULL;
} else {
result->len = dkLen;
@ -598,7 +598,7 @@ sftk_clearPBECommonCacheItemsLocked(KDFCacheItem *item)
item->hash = NULL;
}
if (item->salt) {
SECITEM_FreeItem(item->salt, PR_TRUE);
SECITEM_ZfreeItem(item->salt, PR_TRUE);
item->salt = NULL;
}
if (item->pwItem) {
@ -1159,6 +1159,7 @@ nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
}
loser:
PORT_Memset(&pbev2_param, 0, sizeof(pbev2_param));
if (rv == SECSuccess) {
pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
} else {
@ -1177,7 +1178,7 @@ void
nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
{
if (pbe_param != NULL) {
PORT_FreeArena(pbe_param->poolp, PR_FALSE);
PORT_FreeArena(pbe_param->poolp, PR_TRUE);
}
}
@ -1213,7 +1214,7 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
dummy = CBC_PadBuffer(NULL, dup_src->data,
dup_src->len, &dup_src->len, DES_BLOCK_SIZE);
if (dummy == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
return NULL;
}
dup_src->data = (unsigned char *)dummy;
@ -1247,13 +1248,13 @@ sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
loser:
if (crv != CKR_OK) {
if (dest != NULL) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
}
dest = NULL;
}
if (dup_src != NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
}
return dest;
@ -1289,7 +1290,7 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
dummy = CBC_PadBuffer(NULL, dup_src->data,
dup_src->len, &dup_src->len, AES_BLOCK_SIZE);
if (dummy == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
return NULL;
}
dup_src->data = (unsigned char *)dummy;
@ -1322,13 +1323,13 @@ sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
loser:
if (crv != CKR_OK) {
if (dest != NULL) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
}
dest = NULL;
}
if (dup_src != NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
}
return dest;
@ -1364,7 +1365,7 @@ sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_de
dummy = CBC_PadBuffer(NULL, dup_src->data,
dup_src->len, &dup_src->len, AES_BLOCK_SIZE);
if (dummy == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
return NULL;
}
dup_src->data = (unsigned char *)dummy;
@ -1398,13 +1399,13 @@ sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_de
loser:
if (crv != CKR_OK) {
if (dest != NULL) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
}
dest = NULL;
}
if (dup_src != NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
}
return dest;
@ -1438,7 +1439,7 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
v = CBC_PadBuffer(NULL, dup_src->data,
dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */);
if (v == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
return NULL;
}
dup_src->data = (unsigned char *)v;
@ -1478,12 +1479,12 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
}
if ((rv != SECSuccess) && (dest != NULL)) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
dest = NULL;
}
if (dup_src != NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
SECITEM_ZfreeItem(dup_src, PR_TRUE);
}
return dest;
@ -1521,7 +1522,7 @@ sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op,
}
if ((rv != SECSuccess) && (dest)) {
SECITEM_FreeItem(dest, PR_TRUE);
SECITEM_ZfreeItem(dest, PR_TRUE);
dest = NULL;
}

View File

@ -318,6 +318,11 @@ static const struct mechanismList mechanisms[] = {
{ CKM_SHA256_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA384_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA512_RSA_PKCS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA1_RSA_PKCS_PSS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA224_RSA_PKCS_PSS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA256_RSA_PKCS_PSS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA384_RSA_PKCS_PSS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
{ CKM_SHA512_RSA_PKCS_PSS, { RSA_MIN_MODULUS_BITS, CK_MAX, CKF_SN_VR }, PR_TRUE },
/* ------------------------- DSA Operations --------------------------- */
{ CKM_DSA_KEY_PAIR_GEN, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
{ CKM_DSA, { DSA_MIN_P_BITS, DSA_MAX_P_BITS, CKF_SN_VR }, PR_TRUE },
@ -1172,7 +1177,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP
crv = sftk_forceAttribute(object, CKA_NSS_DB,
sftk_item_expand(&mod));
if (mod.data)
PORT_Free(mod.data);
SECITEM_ZfreeItem(&mod, PR_FALSE);
if (crv != CKR_OK)
return crv;
@ -1492,7 +1497,7 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
case CKO_SECRET_KEY:
/* make sure the required fields exist */
return sftk_handleSecretKeyObject(session, object, key_type,
(PRBool)(session->slot->slotID == FIPS_SLOT_ID));
(PRBool)(sftk_isFIPS(session->slot->slotID)));
default:
break;
}
@ -1934,7 +1939,7 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type,
}
*crvp = crv;
if (crv != CKR_OK) {
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
return NULL;
}
@ -2094,7 +2099,7 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
}
*crvp = crv;
if (crv != CKR_OK) {
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
return NULL;
}
return privKey;
@ -2599,7 +2604,7 @@ static PLHashTable *nscSlotHashTable[2] = { NULL, NULL };
static unsigned int
sftk_GetModuleIndex(CK_SLOT_ID slotID)
{
if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
if (sftk_isFIPS(slotID)) {
return NSC_FIPS_MODULE;
}
return NSC_NON_FIPS_MODULE;
@ -2671,6 +2676,9 @@ sftk_RegisterSlot(SFTKSlot *slot, unsigned int moduleIndex)
nscSlotList[index] = (CK_SLOT_ID *)PORT_Realloc(oldNscSlotList,
nscSlotListSize[index] * sizeof(CK_SLOT_ID));
if (nscSlotList[index] == NULL) {
/* evidently coverity doesn't know realloc does not
* free var if it fails ! */
/* coverity [use_after_free : FALSE] */
nscSlotList[index] = oldNscSlotList;
nscSlotListSize[index] = oldNscSlotListSize;
return CKR_HOST_MEMORY;
@ -4026,6 +4034,7 @@ NSC_InitPIN(CK_SESSION_HANDLE hSession,
if (tokenRemoved) {
sftk_CloseAllSessions(slot, PR_FALSE);
}
PORT_Memset(newPinStr, 0, ulPinLen);
sftk_freeDB(handle);
handle = NULL;
@ -4117,10 +4126,12 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
/* change the data base password */
PR_Lock(slot->pwCheckLock);
rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr, &tokenRemoved);
PORT_Memset(newPinStr, 0, ulNewLen);
PORT_Memset(oldPinStr, 0, ulOldLen);
if (tokenRemoved) {
sftk_CloseAllSessions(slot, PR_FALSE);
}
if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
if ((rv != SECSuccess) && (sftk_isFIPS(slot->slotID))) {
PR_Sleep(loginWaitTime);
}
PR_Unlock(slot->pwCheckLock);
@ -4356,6 +4367,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
handle = sftk_getKeyDB(slot);
if (handle == NULL) {
PORT_Memset(pinStr, 0, ulPinLen);
return CKR_USER_TYPE_INVALID;
}
@ -4370,7 +4382,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
* key database */
if (((userType == CKU_SO) && (sessionFlags & CKF_RW_SESSION))
/* fips always needs to authenticate, even if there isn't a db */
|| (slot->slotID == FIPS_SLOT_ID)) {
|| (sftk_isFIPS(slot->slotID))) {
/* should this be a fixed password? */
if (ulPinLen == 0) {
sftkdb_ClearPassword(handle);
@ -4401,7 +4413,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
if (tokenRemoved) {
sftk_CloseAllSessions(slot, PR_FALSE);
}
if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
if ((rv != SECSuccess) && (sftk_isFIPS(slot->slotID))) {
PR_Sleep(loginWaitTime);
}
PR_Unlock(slot->pwCheckLock);
@ -4422,6 +4434,7 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
crv = CKR_PIN_INCORRECT;
done:
PORT_Memset(pinStr, 0, ulPinLen);
if (handle) {
sftk_freeDB(handle);
}

File diff suppressed because it is too large Load Diff

View File

@ -105,8 +105,9 @@ typedef struct SFTKSessionContextStr SFTKSessionContext;
typedef struct SFTKSearchResultsStr SFTKSearchResults;
typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo;
typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
typedef struct SFTKOAEPInfoStr SFTKOAEPInfo;
typedef struct SFTKPSSSignInfoStr SFTKPSSSignInfo;
typedef struct SFTKPSSVerifyInfoStr SFTKPSSVerifyInfo;
typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
typedef struct SFTKChaCha20CtrInfoStr SFTKChaCha20CtrInfo;
@ -388,21 +389,33 @@ struct SFTKHashSignInfoStr {
NSSLOWKEYPrivateKey *key;
};
/**
* Contexts for RSA-OAEP
*/
struct SFTKOAEPEncryptInfoStr {
CK_RSA_PKCS_OAEP_PARAMS *params;
struct SFTKPSSVerifyInfoStr {
size_t size; /* must be first */
CK_RSA_PKCS_PSS_PARAMS params;
NSSLOWKEYPublicKey *key;
};
struct SFTKOAEPDecryptInfoStr {
CK_RSA_PKCS_OAEP_PARAMS *params;
struct SFTKPSSSignInfoStr {
size_t size; /* must be first */
CK_RSA_PKCS_PSS_PARAMS params;
NSSLOWKEYPrivateKey *key;
};
/**
* Contexts for RSA-OAEP
*/
struct SFTKOAEPInfoStr {
CK_RSA_PKCS_OAEP_PARAMS params;
PRBool isEncrypt;
union {
NSSLOWKEYPublicKey *pub;
NSSLOWKEYPrivateKey *priv;
} key;
};
/* context for the Final SSLMAC message */
struct SFTKSSLMACInfoStr {
size_t size; /* must be first */
void *hashContext;
SFTKBegin begin;
SFTKHash update;
@ -481,6 +494,8 @@ struct SFTKItemTemplateStr {
/* slot helper macros */
#define sftk_SlotFromSession(sp) ((sp)->slot)
#define sftk_isToken(id) (((id)&SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC)
#define sftk_isFIPS(id) \
(((id) == FIPS_SLOT_ID) || ((id) >= SFTK_MIN_FIPS_USER_SLOT_ID))
/* the session hash multiplier (see bug 201081) */
#define SHMULTIPLIER 1791398085

View File

@ -155,16 +155,19 @@ sftk_NewAttribute(SFTKObject *object,
static void
sftk_DestroyAttribute(SFTKAttribute *attribute)
{
if (attribute->freeData) {
if (attribute->attrib.pValue) {
/* clear out the data in the attribute value... it may have been
* sensitive data */
PORT_Memset(attribute->attrib.pValue, 0,
attribute->attrib.ulValueLen);
if (attribute->attrib.pValue) {
/* clear out the data in the attribute value... it may have been
* sensitive data */
PORT_Memset(attribute->attrib.pValue, 0, attribute->attrib.ulValueLen);
if (attribute->freeData) {
PORT_Free(attribute->attrib.pValue);
attribute->attrib.pValue = NULL;
attribute->freeData = PR_FALSE;
}
PORT_Free(attribute->attrib.pValue);
}
PORT_Free(attribute);
if (attribute->freeAttr) {
PORT_Free(attribute);
}
}
/*
@ -864,7 +867,7 @@ sftk_DeleteAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
if (attribute == NULL)
return;
sftk_DeleteAttribute(object, attribute);
sftk_FreeAttribute(attribute);
sftk_DestroyAttribute(attribute);
}
CK_RV

View File

@ -162,7 +162,7 @@ sftk_SDBULong2ULong(unsigned char *data)
*/
static CK_ATTRIBUTE *
sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
unsigned char **dataOut)
unsigned char **dataOut, int *dataOutSize)
{
int i;
int ulongCount = 0;
@ -170,6 +170,7 @@ sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
CK_ATTRIBUTE *ntemplate;
*dataOut = NULL;
*dataOutSize = 0;
/* first count the number of CK_ULONG attributes */
for (i = 0; i < count; i++) {
@ -201,6 +202,7 @@ sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
return NULL;
}
*dataOut = data;
*dataOutSize = SDB_ULONG_SIZE * ulongCount;
/* copy the old template, fixup the actual ulongs */
for (i = 0; i < count; i++) {
ntemplate[i] = template[i];
@ -400,7 +402,7 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
}
PORT_Assert(template[i].ulValueLen >= plainText->len);
if (template[i].ulValueLen < plainText->len) {
SECITEM_FreeItem(plainText, PR_TRUE);
SECITEM_ZfreeItem(plainText, PR_TRUE);
PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
template[i].ulValueLen = -1;
crv = CKR_GENERAL_ERROR;
@ -410,7 +412,7 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
/* copy the plain text back into the template */
PORT_Memcpy(template[i].pValue, plainText->data, plainText->len);
template[i].ulValueLen = plainText->len;
SECITEM_FreeItem(plainText, PR_TRUE);
SECITEM_ZfreeItem(plainText, PR_TRUE);
}
/* make sure signed attributes are valid */
if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) {
@ -1293,7 +1295,7 @@ loser:
}
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
}
if (crv == CKR_OK) {
*objectID |= (handle->type | SFTK_TOKEN_TYPE);
@ -1308,6 +1310,7 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
unsigned char *data = NULL;
CK_ATTRIBUTE *ntemplate = NULL;
CK_RV crv;
int dataSize;
SDB *db;
if (handle == NULL) {
@ -1316,7 +1319,7 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
db = SFTK_GET_SDB(handle);
if (count != 0) {
ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
ntemplate = sftkdb_fixupTemplateIn(template, count, &data, &dataSize);
if (ntemplate == NULL) {
return CKR_HOST_MEMORY;
}
@ -1326,7 +1329,7 @@ sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
count, find);
if (data) {
PORT_Free(ntemplate);
PORT_Free(data);
PORT_ZFree(data, dataSize);
}
return crv;
}
@ -1373,6 +1376,7 @@ sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID,
CK_RV crv, crv2;
CK_ATTRIBUTE *ntemplate;
unsigned char *data = NULL;
int dataSize = 0;
SDB *db;
if (handle == NULL) {
@ -1413,7 +1417,7 @@ sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID,
if (count == 0) {
return CKR_OK;
}
ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
ntemplate = sftkdb_fixupTemplateIn(template, count, &data, &dataSize);
if (ntemplate == NULL) {
return CKR_HOST_MEMORY;
}
@ -1426,7 +1430,7 @@ sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID,
crv = crv2;
if (data) {
PORT_Free(ntemplate);
PORT_Free(data);
PORT_ZFree(data, dataSize);
}
return crv;
}
@ -1442,6 +1446,7 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
CK_RV crv = CKR_OK;
CK_OBJECT_HANDLE objectID = (object->handle & SFTK_OBJ_ID_MASK);
PRBool inTransaction = PR_FALSE;
int dataSize;
if (handle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
@ -1463,7 +1468,7 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
return CKR_USER_NOT_LOGGED_IN;
}
ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
ntemplate = sftkdb_fixupTemplateIn(template, count, &data, &dataSize);
if (ntemplate == NULL) {
return CKR_HOST_MEMORY;
}
@ -1498,7 +1503,7 @@ loser:
}
if (data) {
PORT_Free(ntemplate);
PORT_Free(data);
PORT_ZFree(data, dataSize);
}
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
@ -1602,13 +1607,13 @@ sftkdb_CloseDB(SFTKDBHandle *handle)
(*handle->db->sdb_Close)(handle->db);
}
if (handle->passwordKey.data) {
PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
SECITEM_ZfreeItem(&handle->passwordKey, PR_FALSE);
}
if (handle->passwordLock) {
SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
}
if (handle->updatePasswordKey) {
SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE);
SECITEM_ZfreeItem(handle->updatePasswordKey, PR_TRUE);
}
if (handle->updateID) {
PORT_Free(handle->updateID);
@ -2690,6 +2695,10 @@ sftkdb_ResetKeyDB(SFTKDBHandle *handle)
/* set error */
return SECFailure;
}
if (handle->passwordKey.data) {
SECITEM_ZfreeItem(&handle->passwordKey, PR_FALSE);
handle->passwordKey.data = NULL;
}
return SECSuccess;
}

View File

@ -69,6 +69,7 @@ SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key)
ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx));
if (!ctx) {
PORT_Memset(secret, 0, secretLength);
return NULL;
}
@ -76,6 +77,7 @@ SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key)
ctx->secretLength = secretLength;
ctx->hash = HASH_GetRawHashObject(alg);
ctx->totalLength = params->ulBodyTotalLen;
PORT_Memset(secret, 0, secretLength);
return ctx;
}
@ -188,7 +190,7 @@ sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength,
void
sftk_MACConstantTime_DestroyContext(void *pctx, PRBool free)
{
PORT_Free(pctx);
PORT_ZFree(pctx, sizeof(sftk_MACConstantTimeCtx));
}
CK_RV
@ -217,7 +219,7 @@ CK_RV
sftk_MAC_Init(sftk_MACCtx *ctx, CK_MECHANISM_TYPE mech, SFTKObject *key)
{
SFTKAttribute *keyval = NULL;
PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);
PRBool isFIPS = sftk_isFIPS(key->slot->slotID);
CK_RV ret = CKR_OK;
/* Find the actual value of the key. */

View File

@ -465,7 +465,7 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey,
SFTKObject *newKeyObj = NULL;
unsigned char outKeyData[HASH_LENGTH_MAX];
unsigned char *newInKey = NULL;
unsigned int newInKeySize;
unsigned int newInKeySize = 0;
unsigned int macSize;
CK_RV crv = CKR_OK;
prfContext context;
@ -545,7 +545,7 @@ sftk_ike_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey,
crv = sftk_forceAttribute(outKey, CKA_VALUE, outKeyData, macSize);
fail:
if (newInKey) {
PORT_Free(newInKey);
PORT_ZFree(newInKey, newInKeySize);
}
if (newKeyValue) {
sftk_FreeAttribute(newKeyValue);

View File

@ -252,7 +252,7 @@ sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue,
loser:
if (localArena) {
PORT_FreeArena(localArena, PR_FALSE);
PORT_FreeArena(localArena, PR_TRUE);
}
return rv;
@ -419,7 +419,7 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SFTKDBHandle *handle, SDB *db,
loser:
if ((arena == NULL) && signature) {
SECITEM_FreeItem(cipher, PR_TRUE);
SECITEM_ZfreeItem(signature, PR_TRUE);
}
if (cipher) {
SECITEM_FreeItem(cipher, PR_TRUE);
@ -486,7 +486,7 @@ loser:
HMAC_Destroy(hashCx, PR_TRUE);
}
if (key) {
SECITEM_FreeItem(key, PR_TRUE);
SECITEM_ZfreeItem(key, PR_TRUE);
}
return rv;
}
@ -526,11 +526,12 @@ sftkdb_VerifyAttribute(SFTKDBHandle *handle,
}
loser:
PORT_Memset(signData, 0, sizeof signData);
if (signValue.param) {
nsspkcs5_DestroyPBEParameter(signValue.param);
}
if (signValue.arena) {
PORT_FreeArena(signValue.arena, PR_FALSE);
PORT_FreeArena(signValue.arena, PR_TRUE);
}
return rv;
}
@ -608,6 +609,7 @@ sftkdb_SignAttribute(PLArenaPool *arena, SFTKDBHandle *keyDB, SDB *db,
}
loser:
PORT_Memset(signData, 0, sizeof signData);
if (param) {
nsspkcs5_DestroyPBEParameter(param);
}
@ -1079,7 +1081,7 @@ sftkdb_finishPasswordCheck(SFTKDBHandle *keydb, SECItem *key, const char *pw,
done:
if (result) {
SECITEM_FreeItem(result, PR_TRUE);
SECITEM_ZfreeItem(result, PR_TRUE);
}
return rv;
}
@ -1273,8 +1275,7 @@ sftk_convertAttributes(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
}
/* free up our mess */
/* NOTE: at this point we know we've cleared out any unencrypted data */
PORT_FreeArena(arena, PR_FALSE);
PORT_FreeArena(arena, PR_TRUE);
return CKR_OK;
loser:

View File

@ -17,11 +17,11 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define SOFTOKEN_VERSION "3.64" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VERSION "3.65" SOFTOKEN_ECC_STRING " Beta"
#define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 64
#define SOFTOKEN_VMINOR 65
#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE
#define SOFTOKEN_BETA PR_TRUE
#endif /* _SOFTKVER_H_ */

View File

@ -174,7 +174,7 @@ sftk_TLSPRFInit(SFTKSessionContext *context,
prf_cx->cxDataLen = 0;
prf_cx->cxBufSize = blockSize - offsetof(TLSPRFContext, cxBuf);
prf_cx->cxRv = SECSuccess;
prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID);
prf_cx->cxIsFIPS = sftk_isFIPS(key->slot->slotID);
prf_cx->cxBufPtr = prf_cx->cxBuf;
prf_cx->cxHashAlg = hash_alg;
prf_cx->cxOutLen = out_len;

View File

@ -19,12 +19,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
#define NSSUTIL_VERSION "3.64"
#define NSSUTIL_VERSION "3.65 Beta"
#define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 64
#define NSSUTIL_VMINOR 65
#define NSSUTIL_VPATCH 0
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE
#define NSSUTIL_BETA PR_TRUE
SEC_BEGIN_PROTOS

View File

@ -110,7 +110,7 @@ SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *to,
void
SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit)
{
SECITEM_FreeItem(&algid->parameters, PR_FALSE);
SECITEM_ZfreeItem(&algid->parameters, PR_FALSE);
SECITEM_FreeItem(&algid->algorithm, PR_FALSE);
if (freeit == PR_TRUE)
PORT_Free(algid);

View File

@ -135,7 +135,7 @@ void
SGN_DestroyDigestInfo(SGNDigestInfo *di)
{
if (di && di->arena) {
PORT_FreeArena(di->arena, PR_FALSE);
PORT_FreeArena(di->arena, PR_TRUE);
}
return;

View File

@ -55,6 +55,9 @@
# sharedb - run test suites with shareable database format
# enabled (databases are created directly to this
# format). This is the default and doesn't need to be run separately.
# threadunsafe - run test suites with thread unsafe environment variable
# so simulate running NSS locking for PKCS #11 modules which
# are not thread safe.
#
# Mandatory environment variables (to be set before testing):
# -----------------------------------------------------------
@ -75,6 +78,7 @@
# NSS_TESTS - list of all test suites to run (separated by space
# character, without trailing .sh)
# - this list can be reduced for individual test cycles
# NSS_THREAD_TESTS - list of test suites run in the threadunsafe cycle
#
# NSS_SSL_TESTS - list of ssl tests to run (see ssl.sh)
# NSS_SSL_RUN - list of ssl sub-tests to run (see ssl.sh)
@ -83,7 +87,7 @@
# ---------------
# all.sh ~ (main)
# | |
# +------------+------------+-----------+ ~ run_cycles
# +------------+------------+-----------+--- ~ run_cycles
# | | | | |
# standard pkix upgradedb sharedb ~ run_cycle_*
# ... | ... ... |
@ -249,6 +253,37 @@ run_cycle_shared_db()
run_tests
}
########################## run_thread_unsafe #########################
# run test suites with an non-thread safe softoken
# This simulates loading a non-threadsafe PKCS #11 module and makes
# Sure we don't have any deadlocks in our locking code
########################################################################
run_cycle_thread_unsafe()
{
TEST_MODE=THREAD_UNSAFE
TABLE_ARGS="bgcolor=lightgray"
html_head "Testing with non-threadsafe softoken"
html "</TABLE><BR>"
HOSTDIR="${HOSTDIR}/threadunsafe"
mkdir -p "${HOSTDIR}"
init_directories
NSS_FORCE_TOKEN_LOCK=1
export NSS_FORCE_TOKEN_LOCK
# run the tests for appropriate for thread unsafe
# basically it's the ssl tests right now.
TESTS="${THREAD_TESTS}"
TESTS_SKIP="dbupgrade"
export -n NSS_SSL_TESTS
export -n NSS_SSL_RUN
run_tests
}
############################# run_cycles ###############################
# run test cycles defined in CYCLES variable
########################################################################
@ -271,6 +306,9 @@ run_cycles()
"sharedb")
run_cycle_shared_db
;;
"threadunsafe")
run_cycle_thread_unsafe
;;
esac
. ${ENV_BACKUP}
done
@ -288,7 +326,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
. ./init.sh
fi
cycles="standard pkix"
cycles="standard pkix threadunsafe"
CYCLES=${NSS_CYCLES:-$cycles}
NO_INIT_SUPPORT=`certutil --build-flags |grep -cw NSS_NO_INIT_SUPPORT`
@ -297,6 +335,7 @@ if [ $NO_INIT_SUPPORT -eq 0 ]; then
fi
tests="cipher lowhash libpkix cert dbtests tools $RUN_FIPS sdr crmf smime ssl ocsp merge pkits ec gtests ssl_gtests policy"
thread_tests="ssl ssl_gtests"
# Don't run chains tests when we have a gyp build.
if [ "$OBJDIR" != "Debug" -a "$OBJDIR" != "Release" ]; then
tests="$tests chains"
@ -304,6 +343,17 @@ fi
TESTS=${NSS_TESTS:-$tests}
ALL_TESTS=${TESTS}
default_thread=""
for i in ${ALL_TESTS}
do
for j in ${thread_tests}
do
if [ $i = $j ]; then
default_thread="$default_thread $i"
fi
done
done
THREAD_TESTS=${NSS_THREAD_TESTS-$default_thread}
nss_ssl_tests="crl iopr policy normal_normal"
if [ $NO_INIT_SUPPORT -eq 0 ]; then