mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1705477 - land NSS c982fb957516 UPGRADE_NSS_RELEASE, r=beurdouche
Differential Revision: https://phabricator.services.mozilla.com/D114231
This commit is contained in:
parent
16d0bd0051
commit
37aa935e43
@ -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")
|
||||
|
@ -1 +1 @@
|
||||
NSS_3_64_RTM
|
||||
c982fb957516
|
@ -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
|
||||
|
||||
|
@ -1 +1 @@
|
||||
NSS_3_63_BRANCH
|
||||
NSS_3_64_BRANCH
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -303,6 +303,7 @@ PrintKey(PK11SymKey *symKey)
|
||||
printf("<restricted>");
|
||||
}
|
||||
printf("\n");
|
||||
PORT_Free(name);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
@ -10,3 +10,4 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header 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)
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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': [
|
||||
|
@ -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,
|
||||
|
@ -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, ¶ms,
|
||||
&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 ¶ms_; }
|
||||
|
||||
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,
|
||||
|
181
security/nss/gtests/pk11_gtest/pk11_signature_test.cc
Normal file
181
security/nss/gtests/pk11_gtest/pk11_signature_test.cc
Normal 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
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(¶ms->prime, PR_FALSE); /* don't free prime */
|
||||
SECITEM_FreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */
|
||||
SECITEM_FreeItem(¶ms->base, PR_FALSE); /* don't free base */
|
||||
SECITEM_ZfreeItem(¶ms->prime, PR_FALSE); /* don't free prime */
|
||||
SECITEM_ZfreeItem(¶ms->subPrime, PR_FALSE); /* don't free subPrime */
|
||||
SECITEM_ZfreeItem(¶ms->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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -22,6 +22,7 @@ RNG_SystemInfoForRNG(void)
|
||||
return;
|
||||
}
|
||||
RNG_RandomUpdate(bytes, numBytes);
|
||||
PORT_Memset(bytes, 0, sizeof bytes);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1219,4 +1219,11 @@ PK11_HPKE_ExportContext;
|
||||
PK11_HPKE_ImportContext;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+};
|
||||
;+NSS_3.65 { # NSS 3.65 release
|
||||
;+ global:
|
||||
PK11_CreateContextByPubKey;
|
||||
PK11_CreateContextByPrivKey;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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, ¶m);
|
||||
context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL,
|
||||
CK_INVALID_HANDLE, ¶m, 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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user