summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/softoken
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-08-14 07:52:35 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-08-14 16:42:52 +0200
commitab1060037931158d3a8bf4c8f9f6cb4dbfe916e9 (patch)
tree5e4677e52b9a349602f04135a44b3000c8baa97b /security/nss/lib/softoken
parentf44e99950fc25d16a3cdaffe26dadf7b58a9d38c (diff)
downloadUXP-ab1060037931158d3a8bf4c8f9f6cb4dbfe916e9.tar
UXP-ab1060037931158d3a8bf4c8f9f6cb4dbfe916e9.tar.gz
UXP-ab1060037931158d3a8bf4c8f9f6cb4dbfe916e9.tar.lz
UXP-ab1060037931158d3a8bf4c8f9f6cb4dbfe916e9.tar.xz
UXP-ab1060037931158d3a8bf4c8f9f6cb4dbfe916e9.zip
Update NSS to 3.38
- Added HACL*Poly1305 32-bit (INRIA/Microsoft) - Updated to final TLS 1.3 draft version (28) - Removed TLS 1.3 prerelease draft limit check - Removed NPN code - Enabled dev/urandom-only RNG on Linux with NSS_SEED_ONLY_DEV_URANDOM for non-standard environments - Fixed several bugs with TLS 1.3 negotiation - Updated internal certificate store - Added support for the TLS Record Size Limit Extension. - Fixed CVE-2018-0495 - Various security fixes in the ASN.1 code.
Diffstat (limited to 'security/nss/lib/softoken')
-rw-r--r--security/nss/lib/softoken/legacydb/pcertdb.c3
-rw-r--r--security/nss/lib/softoken/lowkey.c24
-rw-r--r--security/nss/lib/softoken/lowkeyi.h1
-rw-r--r--security/nss/lib/softoken/lowkeyti.h9
-rw-r--r--security/nss/lib/softoken/lowpbe.c10
-rw-r--r--security/nss/lib/softoken/pkcs11.c72
-rw-r--r--security/nss/lib/softoken/pkcs11c.c116
-rw-r--r--security/nss/lib/softoken/pkcs11u.c4
-rw-r--r--security/nss/lib/softoken/sdb.c69
-rw-r--r--security/nss/lib/softoken/sftkdb.c3
-rw-r--r--security/nss/lib/softoken/sftkpars.c34
-rw-r--r--security/nss/lib/softoken/sftkpwd.c6
-rw-r--r--security/nss/lib/softoken/softkver.h6
13 files changed, 271 insertions, 86 deletions
diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c
index 2e8b650ee..47778190d 100644
--- a/security/nss/lib/softoken/legacydb/pcertdb.c
+++ b/security/nss/lib/softoken/legacydb/pcertdb.c
@@ -2577,14 +2577,13 @@ ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
SECItem dbentry;
SECStatus rv;
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
}
- PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
-
entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
sizeof(certDBEntrySubject));
if (entry == NULL) {
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
index 295d55f40..a28a3a55e 100644
--- a/security/nss/lib/softoken/lowkey.c
+++ b/security/nss/lib/softoken/lowkey.c
@@ -45,6 +45,23 @@ const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
{ 0 }
};
+const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYSubjectPublicKeyInfo) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSLOWKEYSubjectPublicKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_BIT_STRING,
+ offsetof(NSSLOWKEYSubjectPublicKeyInfo, subjectPublicKey) },
+ { 0 }
+};
+
+const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.modulus) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent) },
+ { 0 }
+};
+
const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
{ SEC_ASN1_INTEGER, offsetof(PQGParams, prime) },
@@ -135,6 +152,13 @@ prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
}
void
+prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key)
+{
+ key->u.rsa.modulus.type = siUnsignedInteger;
+ key->u.rsa.publicExponent.type = siUnsignedInteger;
+}
+
+void
prepare_low_pqg_params_for_asn1(PQGParams *params)
{
params->prime.type = siUnsignedInteger;
diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h
index f9ba3a75f..e599f01fa 100644
--- a/security/nss/lib/softoken/lowkeyi.h
+++ b/security/nss/lib/softoken/lowkeyi.h
@@ -27,6 +27,7 @@ extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key);
extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
extern void prepare_low_ecparams_for_asn1(ECParams *params);
+extern void prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key);
/*
** Destroy a private key object.
diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h
index c048b33e7..7e77592c5 100644
--- a/security/nss/lib/softoken/lowkeyti.h
+++ b/security/nss/lib/softoken/lowkeyti.h
@@ -25,6 +25,8 @@ extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[];
extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[];
extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
+extern const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[];
+extern const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[];
/*
* PKCS #8 attributes
@@ -48,6 +50,13 @@ struct NSSLOWKEYPrivateKeyInfoStr {
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
+struct NSSLOWKEYSubjectPublicKeyInfoStr {
+ PLArenaPool *arena;
+ SECAlgorithmID algorithm;
+ SECItem subjectPublicKey;
+};
+typedef struct NSSLOWKEYSubjectPublicKeyInfoStr NSSLOWKEYSubjectPublicKeyInfo;
+
typedef enum {
NSSLOWKEYNullKey = 0,
NSSLOWKEYRSAKey = 1,
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
index 0a47804bf..4a101c68c 100644
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -1073,15 +1073,15 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
}
if (encrypt != PR_FALSE) {
- void *dummy;
+ void *v;
- dummy = CBC_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */);
- if (dummy == NULL) {
+ 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);
return NULL;
}
- dup_src->data = (unsigned char *)dummy;
+ dup_src->data = (unsigned char *)v;
}
dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 77882a274..34f25a9d0 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -1343,7 +1343,6 @@ sftk_handleSecretKeyObject(SFTKSession *session, SFTKObject *object,
if (sftk_isTrue(object, CKA_TOKEN)) {
SFTKSlot *slot = session->slot;
SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
- CK_RV crv;
if (keyHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
@@ -3807,12 +3806,12 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
PZ_Unlock(slot->slotLock);
/* Reset login flags. */
if (ulNewLen == 0) {
- PRBool tokenRemoved = PR_FALSE;
PZ_Lock(slot->slotLock);
slot->isLoggedIn = PR_FALSE;
slot->ssoLoggedIn = PR_FALSE;
PZ_Unlock(slot->slotLock);
+ tokenRemoved = PR_FALSE;
rv = sftkdb_CheckPassword(handle, "", &tokenRemoved);
if (tokenRemoved) {
sftk_CloseAllSessions(slot, PR_FALSE);
@@ -4422,6 +4421,44 @@ NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
return CKR_OK;
}
+static CK_RV
+nsc_GetTokenAttributeValue(SFTKSession *session, CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ SFTKSlot *slot = sftk_SlotFromSession(session);
+ SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
+ SFTKDBHandle *keydb = NULL;
+ CK_RV crv;
+
+ if (dbHandle == NULL) {
+ return CKR_OBJECT_HANDLE_INVALID;
+ }
+
+ crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
+
+ /* make sure we don't export any sensitive information */
+ keydb = sftk_getKeyDB(slot);
+ if (dbHandle == keydb) {
+ CK_ULONG i;
+ for (i = 0; i < ulCount; i++) {
+ if (sftk_isSensitive(pTemplate[i].type, CKO_PRIVATE_KEY)) {
+ crv = CKR_ATTRIBUTE_SENSITIVE;
+ if (pTemplate[i].pValue && (pTemplate[i].ulValueLen != -1)) {
+ PORT_Memset(pTemplate[i].pValue, 0,
+ pTemplate[i].ulValueLen);
+ }
+ pTemplate[i].ulValueLen = -1;
+ }
+ }
+ }
+
+ sftk_freeDB(dbHandle);
+ if (keydb) {
+ sftk_freeDB(keydb);
+ }
+ return crv;
+}
+
/* NSC_GetAttributeValue obtains the value of one or more object attributes. */
CK_RV
NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
@@ -4450,37 +4487,8 @@ NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
/* short circuit everything for token objects */
if (sftk_isToken(hObject)) {
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
- SFTKDBHandle *keydb = NULL;
-
- if (dbHandle == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
-
- /* make sure we don't export any sensitive information */
- keydb = sftk_getKeyDB(slot);
- if (dbHandle == keydb) {
- for (i = 0; i < (int)ulCount; i++) {
- if (sftk_isSensitive(pTemplate[i].type, CKO_PRIVATE_KEY)) {
- crv = CKR_ATTRIBUTE_SENSITIVE;
- if (pTemplate[i].pValue && (pTemplate[i].ulValueLen != -1)) {
- PORT_Memset(pTemplate[i].pValue, 0,
- pTemplate[i].ulValueLen);
- }
- pTemplate[i].ulValueLen = -1;
- }
- }
- }
-
+ crv = nsc_GetTokenAttributeValue(session, hObject, pTemplate, ulCount);
sftk_FreeSession(session);
- sftk_freeDB(dbHandle);
- if (keydb) {
- sftk_freeDB(keydb);
- }
return crv;
}
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index d675d7331..385d3c144 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -5324,7 +5324,52 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
prepare_low_rsa_priv_key_for_asn1(lk);
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
nsslowkey_RSAPrivateKeyTemplate);
- algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
+
+ /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */
+ attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO);
+ if (attribute) {
+ NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo;
+ SECItem spki;
+
+ spki.data = attribute->attrib.pValue;
+ spki.len = attribute->attrib.ulValueLen;
+
+ publicKeyInfo = PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYSubjectPublicKeyInfo));
+ if (!publicKeyInfo) {
+ sftk_FreeAttribute(attribute);
+ *crvp = CKR_HOST_MEMORY;
+ rv = SECFailure;
+ goto loser;
+ }
+ rv = SEC_QuickDERDecodeItem(arena, publicKeyInfo,
+ nsslowkey_SubjectPublicKeyInfoTemplate,
+ &spki);
+ if (rv != SECSuccess) {
+ sftk_FreeAttribute(attribute);
+ *crvp = CKR_KEY_TYPE_INCONSISTENT;
+ goto loser;
+ }
+ algorithm = SECOID_GetAlgorithmTag(&publicKeyInfo->algorithm);
+ if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION &&
+ algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
+ sftk_FreeAttribute(attribute);
+ rv = SECFailure;
+ *crvp = CKR_KEY_TYPE_INCONSISTENT;
+ goto loser;
+ }
+ param = SECITEM_DupItem(&publicKeyInfo->algorithm.parameters);
+ if (!param) {
+ sftk_FreeAttribute(attribute);
+ rv = SECFailure;
+ *crvp = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ sftk_FreeAttribute(attribute);
+ } else {
+ /* default to PKCS #1 */
+ algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
+ }
break;
case NSSLOWKEYDSAKey:
prepare_low_dsa_priv_key_export_for_asn1(lk);
@@ -5803,6 +5848,53 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
break;
}
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ /* For RSA-PSS, record the original algorithm parameters so
+ * they can be encrypted altoghether when wrapping */
+ if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
+ NSSLOWKEYSubjectPublicKeyInfo spki;
+ NSSLOWKEYPublicKey pubk;
+ SECItem *publicKeyInfo;
+
+ memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo));
+ rv = SECOID_CopyAlgorithmID(arena, &spki.algorithm, &pki->algorithm);
+ if (rv != SECSuccess) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ prepare_low_rsa_pub_key_for_asn1(&pubk);
+
+ rv = SECITEM_CopyItem(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus);
+ if (rv != SECSuccess) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ rv = SECITEM_CopyItem(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent);
+ if (rv != SECSuccess) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ if (SEC_ASN1EncodeItem(arena, &spki.subjectPublicKey,
+ &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ publicKeyInfo = SEC_ASN1EncodeItem(arena, NULL,
+ &spki, nsslowkey_SubjectPublicKeyInfoTemplate);
+ if (!publicKeyInfo) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO,
+ sftk_item_expand(publicKeyInfo));
+ }
+
loser:
if (lpk) {
nsslowkey_DestroyPrivateKey(lpk);
@@ -7575,13 +7667,13 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
(const CK_NSS_HKDFParams *)pMechanism->pParameter;
const SECHashObject *rawHash;
unsigned hashLen;
- CK_BYTE buf[HASH_LENGTH_MAX];
+ CK_BYTE hashbuf[HASH_LENGTH_MAX];
CK_BYTE *prk; /* psuedo-random key */
CK_ULONG prkLen;
CK_BYTE *okm; /* output keying material */
rawHash = HASH_GetRawHashObject(hashType);
- if (rawHash == NULL || rawHash->length > sizeof buf) {
+ if (rawHash == NULL || rawHash->length > sizeof(hashbuf)) {
crv = CKR_FUNCTION_FAILED;
break;
}
@@ -7615,7 +7707,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
saltLen = params->ulSaltLen;
if (salt == NULL) {
saltLen = hashLen;
- salt = buf;
+ salt = hashbuf;
memset(salt, 0, saltLen);
}
hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
@@ -7626,10 +7718,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
HMAC_Begin(hmac);
HMAC_Update(hmac, (const unsigned char *)att->attrib.pValue,
att->attrib.ulValueLen);
- HMAC_Finish(hmac, buf, &bufLen, sizeof(buf));
+ HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf));
HMAC_Destroy(hmac, PR_TRUE);
PORT_Assert(bufLen == rawHash->length);
- prk = buf;
+ prk = hashbuf;
prkLen = bufLen;
} else {
/* PRK = base key value */
@@ -7646,24 +7738,24 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
* key material = T(1) | ... | T(n)
*/
HMACContext *hmac;
- CK_BYTE i;
+ CK_BYTE bi;
unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
if (hmac == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- for (i = 1; i <= iterations; ++i) {
+ for (bi = 1; bi <= iterations; ++bi) {
unsigned len;
HMAC_Begin(hmac);
- if (i > 1) {
- HMAC_Update(hmac, key_block + ((i - 2) * hashLen), hashLen);
+ if (bi > 1) {
+ HMAC_Update(hmac, key_block + ((bi - 2) * hashLen), hashLen);
}
if (params->ulInfoLen != 0) {
HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
}
- HMAC_Update(hmac, &i, 1);
- HMAC_Finish(hmac, key_block + ((i - 1) * hashLen), &len,
+ HMAC_Update(hmac, &bi, 1);
+ HMAC_Finish(hmac, key_block + ((bi - 1) * hashLen), &len,
hashLen);
PORT_Assert(len == hashLen);
}
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 27e411759..7b5fe732f 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -1193,7 +1193,7 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
/* Handle Token case */
if (so && so->session) {
- SFTKSession *session = so->session;
+ session = so->session;
PZ_Lock(session->objectLock);
sftkqueue_delete(&so->sessionList, 0, session->objects, 0);
PZ_Unlock(session->objectLock);
@@ -1269,7 +1269,7 @@ static const CK_ULONG ecPubKeyAttrsCount =
static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = {
CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT,
- CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB
+ CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB, CKA_PUBLIC_KEY_INFO
};
static const CK_ULONG commonPrivKeyAttrsCount =
sizeof(commonPrivKeyAttrs) / sizeof(commonPrivKeyAttrs[0]);
diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c
index 96717cb26..fb897d68c 100644
--- a/security/nss/lib/softoken/sdb.c
+++ b/security/nss/lib/softoken/sdb.c
@@ -37,6 +37,10 @@
#elif defined(XP_UNIX)
#include <unistd.h>
#endif
+#if defined(LINUX) && !defined(ANDROID)
+#include <linux/magic.h>
+#include <sys/vfs.h>
+#endif
#include "utilpars.h"
#ifdef SQLITE_UNSAFE_THREADS
@@ -154,7 +158,8 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
+ CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS,
+ CKA_PUBLIC_KEY_INFO
};
static int known_attributes_size = sizeof(known_attributes) /
@@ -643,13 +648,18 @@ static int
sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
{
int sqlerr;
- /*
- * in sqlite3 3.5.0, there is a new open call that allows us
- * to specify read only. Most new OS's are still on 3.3.x (including
- * NSS's internal version and the version shipped with Firefox).
- */
+ int openFlags;
+
*sqlDB = NULL;
- sqlerr = sqlite3_open(name, sqlDB);
+
+ if (flags & SDB_RDONLY) {
+ openFlags = SQLITE_OPEN_READONLY;
+ } else {
+ openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ }
+
+ /* Requires SQLite 3.5.0 or newer. */
+ sqlerr = sqlite3_open_v2(name, sqlDB, openFlags, NULL);
if (sqlerr != SQLITE_OK) {
return sqlerr;
}
@@ -1757,6 +1767,8 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
PRIntervalTime now = 0;
char *env;
PRBool enableCache = PR_FALSE;
+ PRBool checkFSType = PR_FALSE;
+ PRBool measureSpeed = PR_FALSE;
PRBool create;
int flags = inFlags & 0x7;
@@ -1917,11 +1929,48 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
- if (!env || PORT_Strcasecmp(env, "no") == 0) {
- enableCache = PR_FALSE;
+ /* Variables enableCache, checkFSType, measureSpeed are PR_FALSE by default,
+ * which is the expected behavior for NSS_SDB_USE_CACHE="no".
+ * We don't need to check for "no" here. */
+ if (!env) {
+ /* By default, with no variable set, we avoid expensive measuring for
+ * most FS types. We start with inexpensive FS type checking, and
+ * might perform measuring for some types. */
+ checkFSType = PR_TRUE;
} else if (PORT_Strcasecmp(env, "yes") == 0) {
enableCache = PR_TRUE;
- } else {
+ } else if (PORT_Strcasecmp(env, "no") != 0) { /* not "no" => "auto" */
+ measureSpeed = PR_TRUE;
+ }
+
+ if (checkFSType) {
+#if defined(LINUX) && !defined(ANDROID)
+ struct statfs statfs_s;
+ if (statfs(dbname, &statfs_s) == 0) {
+ switch (statfs_s.f_type) {
+ case SMB_SUPER_MAGIC:
+ case 0xff534d42: /* CIFS_MAGIC_NUMBER */
+ case NFS_SUPER_MAGIC:
+ /* We assume these are slow. */
+ enableCache = PR_TRUE;
+ break;
+ case CODA_SUPER_MAGIC:
+ case 0x65735546: /* FUSE_SUPER_MAGIC */
+ case NCP_SUPER_MAGIC:
+ /* It's uncertain if this FS is fast or slow.
+ * It seems reasonable to perform slow measuring for users
+ * with questionable FS speed. */
+ measureSpeed = PR_TRUE;
+ break;
+ case AFS_SUPER_MAGIC: /* Already implements caching. */
+ default:
+ break;
+ }
+ }
+#endif
+ }
+
+ if (measureSpeed) {
char *tempDir = NULL;
PRUint32 tempOps = 0;
/*
diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c
index 2ae084068..409c910f4 100644
--- a/security/nss/lib/softoken/sftkdb.c
+++ b/security/nss/lib/softoken/sftkdb.c
@@ -1591,7 +1591,8 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
+ CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS,
+ CKA_PUBLIC_KEY_INFO
};
static unsigned int known_attributes_size = sizeof(known_attributes) /
diff --git a/security/nss/lib/softoken/sftkpars.c b/security/nss/lib/softoken/sftkpars.c
index e972fe854..5e96a1c04 100644
--- a/security/nss/lib/softoken/sftkpars.c
+++ b/security/nss/lib/softoken/sftkpars.c
@@ -162,7 +162,7 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
}
if (parsed->tokens == NULL) {
int count = isFIPS ? 1 : 2;
- int index = count - 1;
+ int i = count - 1;
sftk_token_parameters *tokens = NULL;
tokens = (sftk_token_parameters *)
@@ -172,30 +172,30 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
}
parsed->tokens = tokens;
parsed->token_count = count;
- tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
- tokens[index].certPrefix = certPrefix;
- tokens[index].keyPrefix = keyPrefix;
- tokens[index].minPW = minPW ? atoi(minPW) : 0;
- tokens[index].readOnly = parsed->readOnly;
- tokens[index].noCertDB = parsed->noCertDB;
- tokens[index].noKeyDB = parsed->noCertDB;
- tokens[index].forceOpen = parsed->forceOpen;
- tokens[index].pwRequired = parsed->pwRequired;
- tokens[index].optimizeSpace = parsed->optimizeSpace;
+ tokens[i].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
+ tokens[i].certPrefix = certPrefix;
+ tokens[i].keyPrefix = keyPrefix;
+ tokens[i].minPW = minPW ? atoi(minPW) : 0;
+ tokens[i].readOnly = parsed->readOnly;
+ tokens[i].noCertDB = parsed->noCertDB;
+ tokens[i].noKeyDB = parsed->noCertDB;
+ tokens[i].forceOpen = parsed->forceOpen;
+ tokens[i].pwRequired = parsed->pwRequired;
+ tokens[i].optimizeSpace = parsed->optimizeSpace;
tokens[0].optimizeSpace = parsed->optimizeSpace;
certPrefix = NULL;
keyPrefix = NULL;
if (isFIPS) {
- tokens[index].tokdes = ftokdes;
- tokens[index].updtokdes = pupdtokdes;
- tokens[index].slotdes = fslotdes;
+ tokens[i].tokdes = ftokdes;
+ tokens[i].updtokdes = pupdtokdes;
+ tokens[i].slotdes = fslotdes;
fslotdes = NULL;
ftokdes = NULL;
pupdtokdes = NULL;
} else {
- tokens[index].tokdes = ptokdes;
- tokens[index].updtokdes = pupdtokdes;
- tokens[index].slotdes = pslotdes;
+ tokens[i].tokdes = ptokdes;
+ tokens[i].updtokdes = pupdtokdes;
+ tokens[i].slotdes = pslotdes;
tokens[0].slotID = NETSCAPE_SLOT_ID;
tokens[0].tokdes = tokdes;
tokens[0].slotdes = slotdes;
diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c
index e0d2df9ab..9834d3ba0 100644
--- a/security/nss/lib/softoken/sftkpwd.c
+++ b/security/nss/lib/softoken/sftkpwd.c
@@ -138,12 +138,14 @@ sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue)
SFTKDBEncryptedDataInfo edi;
SECStatus rv;
+ PORT_Assert(cipherValue);
+ cipherValue->arena = NULL;
+ cipherValue->param = NULL;
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
return SECFailure;
}
- cipherValue->arena = NULL;
- cipherValue->param = NULL;
rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate,
cipherText);
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
index f760ba21d..827bf2e22 100644
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -17,10 +17,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define SOFTOKEN_VERSION "3.36.4" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.38" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 36
-#define SOFTOKEN_VPATCH 4
+#define SOFTOKEN_VMINOR 38
+#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE