From e10349ab8dda8a3f11be6aa19f2b6e29fe814044 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Fri, 23 Feb 2018 11:04:39 +0100 Subject: Update NSS to 3.35-RTM --- security/nss/lib/softoken/fipstest.c | 9 + security/nss/lib/softoken/fipstokn.c | 33 +++- security/nss/lib/softoken/legacydb/keydb.c | 8 - security/nss/lib/softoken/legacydb/lgattr.c | 12 +- security/nss/lib/softoken/legacydb/lgcreate.c | 15 +- security/nss/lib/softoken/legacydb/lgfips.c | 4 + security/nss/lib/softoken/legacydb/lginit.c | 4 + security/nss/lib/softoken/legacydb/lowcert.c | 2 - security/nss/lib/softoken/legacydb/lowkey.c | 7 - security/nss/lib/softoken/legacydb/lowkeyi.h | 5 +- security/nss/lib/softoken/legacydb/lowkeyti.h | 2 - security/nss/lib/softoken/legacydb/pcertdb.c | 10 +- security/nss/lib/softoken/lowkey.c | 12 -- security/nss/lib/softoken/lowkeyi.h | 2 - security/nss/lib/softoken/lowkeyti.h | 2 - security/nss/lib/softoken/pkcs11.c | 66 ++++--- security/nss/lib/softoken/pkcs11c.c | 239 ++++++++++++++++++++++---- security/nss/lib/softoken/pkcs11i.h | 1 + security/nss/lib/softoken/pkcs11u.c | 8 - security/nss/lib/softoken/sdb.c | 105 +++++++---- security/nss/lib/softoken/sdb.h | 4 + security/nss/lib/softoken/sftkdb.c | 84 ++++++++- security/nss/lib/softoken/sftkdbti.h | 1 + security/nss/lib/softoken/sftkpwd.c | 7 + security/nss/lib/softoken/softkver.h | 10 +- security/nss/lib/softoken/softoknt.h | 3 + 26 files changed, 461 insertions(+), 194 deletions(-) (limited to 'security/nss/lib/softoken') diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c index 3563bd2d2..0cca74d6e 100644 --- a/security/nss/lib/softoken/fipstest.c +++ b/security/nss/lib/softoken/fipstest.c @@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef NSS_FIPS_DISABLED #include "seccomon.h" #include "blapi.h" #include "softoken.h" @@ -652,3 +653,11 @@ sftk_FIPSEntryOK() } return CKR_OK; } +#else +#include "pkcs11t.h" +CK_RV +sftk_FIPSEntryOK() +{ + return CKR_DEVICE_ERROR; +} +#endif /* NSS_FIPS_DISABLED */ diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c index fd4fd4207..ca7d7998a 100644 --- a/security/nss/lib/softoken/fipstokn.c +++ b/security/nss/lib/softoken/fipstokn.c @@ -540,7 +540,10 @@ FC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) crv = NSC_GetTokenInfo(slotID, pInfo); if (crv == CKR_OK) { - if ((pInfo->flags & CKF_LOGIN_REQUIRED) == 0) { + /* use the global database to figure out if we are running in + * FIPS 140 Level 1 or Level 2 */ + if (slotID == FIPS_SLOT_ID && + (pInfo->flags & CKF_LOGIN_REQUIRED) == 0) { isLevel2 = PR_FALSE; } } @@ -616,7 +619,8 @@ FC_InitPIN(CK_SESSION_HANDLE hSession, * we need to make sure the pin meets FIPS requirements */ if ((ulPinLen == 0) || ((rv = sftk_newPinCheck(pPin, ulPinLen)) == CKR_OK)) { rv = NSC_InitPIN(hSession, pPin, ulPinLen); - if (rv == CKR_OK) { + if ((rv == CKR_OK) && + (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) { isLevel2 = (ulPinLen > 0) ? PR_TRUE : PR_FALSE; } } @@ -644,7 +648,8 @@ FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, if ((rv = sftk_fipsCheck()) == CKR_OK && (rv = sftk_newPinCheck(pNewPin, usNewLen)) == CKR_OK) { rv = NSC_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen); - if (rv == CKR_OK) { + if ((rv == CKR_OK) && + (sftk_SlotIDFromSessionHandle(hSession) == FIPS_SLOT_ID)) { /* if we set the password in level1 we now go * to level2. NOTE: we don't allow the user to * go from level2 to level1 */ @@ -705,11 +710,23 @@ FC_GetSessionInfo(CK_SESSION_HANDLE hSession, rv = NSC_GetSessionInfo(hSession, pInfo); if (rv == CKR_OK) { - if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) { - pInfo->state = CKS_RO_USER_FUNCTIONS; - } - if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) { - pInfo->state = CKS_RW_USER_FUNCTIONS; + /* handle the case where the auxilary slot doesn't require login. + * piggy back on the main token's login state */ + if (isLoggedIn && + ((pInfo->state == CKS_RO_PUBLIC_SESSION) || + (pInfo->state == CKS_RW_PUBLIC_SESSION))) { + CK_RV crv; + CK_TOKEN_INFO tInfo; + crv = NSC_GetTokenInfo(sftk_SlotIDFromSessionHandle(hSession), + &tInfo); + /* if the token doesn't login, use our global login state */ + if ((crv == CKR_OK) && ((tInfo.flags & CKF_LOGIN_REQUIRED) == 0)) { + if (pInfo->state == CKS_RO_PUBLIC_SESSION) { + pInfo->state = CKS_RO_USER_FUNCTIONS; + } else { + pInfo->state = CKS_RW_USER_FUNCTIONS; + } + } } } return rv; diff --git a/security/nss/lib/softoken/legacydb/keydb.c b/security/nss/lib/softoken/legacydb/keydb.c index 178e333ec..b4aa7754b 100644 --- a/security/nss/lib/softoken/legacydb/keydb.c +++ b/security/nss/lib/softoken/legacydb/keydb.c @@ -1137,12 +1137,10 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer namekey.data = pubkey->u.dh.publicValue.data; namekey.size = pubkey->u.dh.publicValue.len; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: namekey.data = pubkey->u.ec.publicValue.data; namekey.size = pubkey->u.ec.publicValue.len; break; -#endif /* NSS_DISABLE_ECC */ default: /* XXX We don't do Fortezza or DH yet. */ return PR_FALSE; @@ -1467,12 +1465,10 @@ seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, SECItem *der_item = NULL; SECItem *cipherText = NULL; SECItem *dummy = NULL; -#ifndef NSS_DISABLE_ECC #ifdef EC_DEBUG SECItem *fordebug = NULL; #endif int savelen; -#endif temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if (temparena == NULL) @@ -1548,7 +1544,6 @@ seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, goto loser; } break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: lg_prepare_low_ec_priv_key_for_asn1(pk); /* Public value is encoded as a bit string so adjust length @@ -1589,7 +1584,6 @@ seckey_encrypt_private_key(PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, #endif break; -#endif /* NSS_DISABLE_ECC */ default: /* We don't support DH or Fortezza private keys yet */ PORT_Assert(PR_FALSE); @@ -1809,7 +1803,6 @@ seckey_decrypt_private_key(SECItem *epki, lg_nsslowkey_DHPrivateKeyTemplate, &newPrivateKey); break; -#ifndef NSS_DISABLE_ECC case SEC_OID_ANSIX962_EC_PUBLIC_KEY: pk->keyType = NSSLOWKEYECKey; lg_prepare_low_ec_priv_key_for_asn1(pk); @@ -1849,7 +1842,6 @@ seckey_decrypt_private_key(SECItem *epki, } break; -#endif /* NSS_DISABLE_ECC */ default: rv = SECFailure; break; diff --git a/security/nss/lib/softoken/legacydb/lgattr.c b/security/nss/lib/softoken/legacydb/lgattr.c index 5c2cbdbc6..542b0c968 100644 --- a/security/nss/lib/softoken/legacydb/lgattr.c +++ b/security/nss/lib/softoken/legacydb/lgattr.c @@ -133,7 +133,7 @@ lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, attr->ulValueLen = (CK_ULONG)-1; return CKR_BUFFER_TOO_SMALL; } - if (value != NULL) { + if (len > 0 && value != NULL) { PORT_Memcpy(attr->pValue, value, len); } attr->ulValueLen = len; @@ -421,11 +421,9 @@ lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) case NSSLOWKEYDHKey: pubItem = &pubKey->u.dh.publicValue; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: pubItem = &pubKey->u.ec.publicValue; break; -#endif /* NSS_DISABLE_ECC */ default: break; } @@ -544,7 +542,6 @@ lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, return lg_invalidAttribute(attribute); } -#ifndef NSS_DISABLE_ECC static CK_RV lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attribute) @@ -594,7 +591,6 @@ lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, } return lg_invalidAttribute(attribute); } -#endif /* NSS_DISABLE_ECC */ static CK_RV lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, @@ -645,10 +641,8 @@ lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, return lg_FindDSAPublicKeyAttribute(key, type, attribute); case NSSLOWKEYDHKey: return lg_FindDHPublicKeyAttribute(key, type, attribute); -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: return lg_FindECPublicKeyAttribute(key, type, attribute); -#endif /* NSS_DISABLE_ECC */ default: break; } @@ -935,7 +929,6 @@ lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, return lg_invalidAttribute(attribute); } -#ifndef NSS_DISABLE_ECC static CK_RV lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attribute, SDB *sdbpw) @@ -973,7 +966,6 @@ lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, } return lg_invalidAttribute(attribute); } -#endif /* NSS_DISABLE_ECC */ static CK_RV lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, @@ -1020,10 +1012,8 @@ lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, return lg_FindDSAPrivateKeyAttribute(key, type, attribute, obj->sdb); case NSSLOWKEYDHKey: return lg_FindDHPrivateKeyAttribute(key, type, attribute, obj->sdb); -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: return lg_FindECPrivateKeyAttribute(key, type, attribute, obj->sdb); -#endif /* NSS_DISABLE_ECC */ default: break; } diff --git a/security/nss/lib/softoken/legacydb/lgcreate.c b/security/nss/lib/softoken/legacydb/lgcreate.c index a0d2b2e57..f2b2aa634 100644 --- a/security/nss/lib/softoken/legacydb/lgcreate.c +++ b/security/nss/lib/softoken/legacydb/lgcreate.c @@ -398,21 +398,17 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, NSSLOWKEYPrivateKey *priv; SECItem pubKeySpace = { siBuffer, NULL, 0 }; SECItem *pubKey; -#ifndef NSS_DISABLE_ECC SECItem pubKey2Space = { siBuffer, NULL, 0 }; PLArenaPool *arena = NULL; -#endif /* NSS_DISABLE_ECC */ NSSLOWKEYDBHandle *keyHandle = NULL; switch (key_type) { case CKK_RSA: pubKeyAttr = CKA_MODULUS; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: pubKeyAttr = CKA_EC_POINT; break; -#endif /* NSS_DISABLE_ECC */ case CKK_DSA: case CKK_DH: break; @@ -425,7 +421,6 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, if (crv != CKR_OK) return crv; -#ifndef NSS_DISABLE_ECC if (key_type == CKK_EC) { SECStatus rv; /* @@ -448,7 +443,6 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, pubKey = &pubKey2Space; } } -#endif /* NSS_DISABLE_ECC */ PORT_Assert(pubKey->data); if (pubKey->data == NULL) { @@ -469,14 +463,12 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, /* make sure the associated private key already exists */ /* only works if we are logged in */ priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); -#ifndef NSS_DISABLE_ECC if (priv == NULL && pubKey == &pubKey2Space) { /* no match on the decoded key, match the original pubkey */ pubKey = &pubKeySpace; priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); } -#endif if (priv == NULL) { /* the legacy database can only 'store' public keys which already * have their corresponding private keys in the database */ @@ -490,10 +482,9 @@ lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, done: PORT_Free(pubKeySpace.data); -#ifndef NSS_DISABLE_ECC - if (arena) + if (arena) { PORT_FreeArena(arena, PR_FALSE); -#endif + } return crv; } @@ -613,7 +604,6 @@ lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count, } break; -#ifndef NSS_DISABLE_ECC case CKK_EC: privKey->keyType = NSSLOWKEYECKey; crv = lg_Attribute2SSecItem(arena, CKA_EC_PARAMS, templ, count, @@ -646,7 +636,6 @@ lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count, if (rv != SECSuccess) crv = CKR_HOST_MEMORY; break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; diff --git a/security/nss/lib/softoken/legacydb/lgfips.c b/security/nss/lib/softoken/legacydb/lgfips.c index b017424db..b991dcf8e 100644 --- a/security/nss/lib/softoken/legacydb/lgfips.c +++ b/security/nss/lib/softoken/legacydb/lgfips.c @@ -6,6 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* $Id: fipstest.c,v 1.31 2012/06/28 17:55:06 rrelyea%redhat.com Exp $ */ +#ifndef NSS_FIPS_DISABLED + #include "seccomon.h" #include "lgdb.h" #include "blapi.h" @@ -113,3 +115,5 @@ lg_FIPSEntryOK() #endif return lg_self_tests_success; } + +#endif /* NSS_FIPS_DISABLED */ diff --git a/security/nss/lib/softoken/legacydb/lginit.c b/security/nss/lib/softoken/legacydb/lginit.c index 6913eea50..4f0b53f52 100644 --- a/security/nss/lib/softoken/legacydb/lginit.c +++ b/security/nss/lib/softoken/legacydb/lginit.c @@ -586,11 +586,15 @@ legacy_Open(const char *configdir, const char *certPrefix, #define NSS_VERSION_VARIABLE __nss_dbm_version #include "verref.h" +#ifndef NSS_FIPS_DISABLED if (flags & SDB_FIPS) { + /* We shouldn't get here when FIPS is not enabled on the database. But + * we also don't care when this NSS build doesn't support FIPS. */ if (!lg_FIPSEntryOK()) { return CKR_DEVICE_ERROR; } } +#endif rv = SECOID_Init(); if (SECSuccess != rv) { diff --git a/security/nss/lib/softoken/legacydb/lowcert.c b/security/nss/lib/softoken/legacydb/lowcert.c index 2906120ee..5a349f0aa 100644 --- a/security/nss/lib/softoken/legacydb/lowcert.c +++ b/security/nss/lib/softoken/legacydb/lowcert.c @@ -823,7 +823,6 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) if (rv == SECSuccess) return pubk; break; -#ifndef NSS_DISABLE_ECC case SEC_OID_ANSIX962_EC_PUBLIC_KEY: pubk->keyType = NSSLOWKEYECKey; /* Since PKCS#11 directly takes the DER encoding of EC params @@ -845,7 +844,6 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) if (rv == SECSuccess) return pubk; break; -#endif /* NSS_DISABLE_ECC */ default: rv = SECFailure; break; diff --git a/security/nss/lib/softoken/legacydb/lowkey.c b/security/nss/lib/softoken/legacydb/lowkey.c index 7de4197a1..a9b7cce3d 100644 --- a/security/nss/lib/softoken/legacydb/lowkey.c +++ b/security/nss/lib/softoken/legacydb/lowkey.c @@ -99,8 +99,6 @@ const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[] = { { 0 } }; -#ifndef NSS_DISABLE_ECC - /* NOTE: The SECG specification allows the private key structure * to contain curve parameters but recommends that they be stored * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo @@ -193,7 +191,6 @@ LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams, loser: return SECFailure; } -#endif /* NSS_DISABLE_ECC */ /* * See bugzilla bug 125359 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, @@ -243,7 +240,6 @@ lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.dh.privateValue.type = siUnsignedInteger; } -#ifndef NSS_DISABLE_ECC void lg_prepare_low_ecparams_for_asn1(ECParams *params) { @@ -260,7 +256,6 @@ lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.ec.privateValue.type = siUnsignedInteger; key->u.ec.publicValue.type = siUnsignedInteger; } -#endif /* NSS_DISABLE_ECC */ void lg_nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) @@ -362,7 +357,6 @@ lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey)); @@ -383,7 +377,6 @@ lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#endif /* NSS_DISABLE_ECC */ /* No Fortezza in Low Key implementations (Fortezza keys aren't * stored in our data base */ default: diff --git a/security/nss/lib/softoken/legacydb/lowkeyi.h b/security/nss/lib/softoken/legacydb/lowkeyi.h index 5136b56a5..4a5bcfa91 100644 --- a/security/nss/lib/softoken/legacydb/lowkeyi.h +++ b/security/nss/lib/softoken/legacydb/lowkeyi.h @@ -26,10 +26,8 @@ extern void lg_prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void lg_prepare_low_pqg_params_for_asn1(PQGParams *params); extern void lg_prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -#ifndef NSS_DISABLE_ECC extern void lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void lg_prepare_low_ecparams_for_asn1(ECParams *params); -#endif /* NSS_DISABLE_ECC */ typedef char *(*NSSLOWKEYDBNameFunc)(void *arg, int dbVersion); @@ -134,7 +132,6 @@ extern char * nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus, SDB *sdb); -#ifndef NSS_DISABLE_ECC /* * smaller version of EC_FillParams. In this code, we only need * oid and DER data. @@ -145,7 +142,7 @@ SECStatus LGEC_FillParams(PLArenaPool *arena, const SECItem *encodedParams, /* Copy all of the fields from srcParams into dstParams */ SECStatus LGEC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif + SEC_END_PROTOS #endif /* _LOWKEYI_H_ */ diff --git a/security/nss/lib/softoken/legacydb/lowkeyti.h b/security/nss/lib/softoken/legacydb/lowkeyti.h index ef92689e0..2fd5d4e29 100644 --- a/security/nss/lib/softoken/legacydb/lowkeyti.h +++ b/security/nss/lib/softoken/legacydb/lowkeyti.h @@ -42,10 +42,8 @@ extern const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate2[]; extern const SEC_ASN1Template lg_nsslowkey_DSAPrivateKeyTemplate[]; extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[]; extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyExportTemplate[]; -#ifndef NSS_DISABLE_ECC #define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */ extern const SEC_ASN1Template lg_nsslowkey_ECPrivateKeyTemplate[]; -#endif /* NSS_DISABLE_ECC */ extern const SEC_ASN1Template lg_nsslowkey_PrivateKeyInfoTemplate[]; extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[]; diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c index f1444bf04..2e8b650ee 100644 --- a/security/nss/lib/softoken/legacydb/pcertdb.c +++ b/security/nss/lib/softoken/legacydb/pcertdb.c @@ -1854,6 +1854,8 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr) &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len], entry->smimeOptions.len); + } else { + entry->smimeOptions.data = NULL; } if (entry->optionsDate.len) { entry->optionsDate.data = @@ -1868,6 +1870,8 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr) entry->subjectName.len + entry->smimeOptions.len], entry->optionsDate.len); + } else { + entry->optionsDate.data = NULL; } /* both options and options date must either exist or not exist */ @@ -2014,7 +2018,7 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr) { PLArenaPool *arena = NULL; PLArenaPool *tmparena = NULL; - certDBEntrySMime *entry; + certDBEntrySMime *entry = NULL; SECItem dbkey; SECItem dbentry; SECStatus rv; @@ -2031,8 +2035,8 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr) goto loser; } - entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySMime)); + entry = (certDBEntrySMime *)PORT_ArenaZAlloc(arena, + sizeof(certDBEntrySMime)); if (entry == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c index 73b1dc971..295d55f40 100644 --- a/security/nss/lib/softoken/lowkey.c +++ b/security/nss/lib/softoken/lowkey.c @@ -8,10 +8,7 @@ #include "base64.h" #include "secasn1.h" #include "secerr.h" - -#ifndef NSS_DISABLE_ECC #include "softoken.h" -#endif SEC_ASN1_MKSUB(SEC_AnyTemplate) SEC_ASN1_MKSUB(SEC_BitStringTemplate) @@ -90,8 +87,6 @@ const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = { { 0 } }; -#ifndef NSS_DISABLE_ECC - /* NOTE: The SECG specification allows the private key structure * to contain curve parameters but recommends that they be stored * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo @@ -117,7 +112,6 @@ const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = { SEC_ASN1_SUB(SEC_BitStringTemplate) }, { 0 } }; -#endif /* NSS_DISABLE_ECC */ /* * See bugzilla bug 125359 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, @@ -173,7 +167,6 @@ prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.dh.privateValue.type = siUnsignedInteger; } -#ifndef NSS_DISABLE_ECC void prepare_low_ecparams_for_asn1(ECParams *params) { @@ -190,7 +183,6 @@ prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) key->u.ec.privateValue.type = siUnsignedInteger; key->u.ec.publicValue.type = siUnsignedInteger; } -#endif /* NSS_DISABLE_ECC */ void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) @@ -325,7 +317,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey)); @@ -346,7 +337,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) return pubk; } break; -#endif /* NSS_DISABLE_ECC */ /* No Fortezza in Low Key implementations (Fortezza keys aren't * stored in our data base */ default: @@ -463,7 +453,6 @@ nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) if (rv != SECSuccess) break; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version), &(privKey->u.ec.version)); @@ -484,7 +473,6 @@ nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) if (rv != SECSuccess) break; break; -#endif /* NSS_DISABLE_ECC */ default: rv = SECFailure; } diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h index a5878c2f6..f9ba3a75f 100644 --- a/security/nss/lib/softoken/lowkeyi.h +++ b/security/nss/lib/softoken/lowkeyi.h @@ -25,10 +25,8 @@ extern void prepare_low_pqg_params_for_asn1(PQGParams *params); extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key); extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -#ifndef NSS_DISABLE_ECC extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); extern void prepare_low_ecparams_for_asn1(ECParams *params); -#endif /* NSS_DISABLE_ECC */ /* ** Destroy a private key object. diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h index 2ef16405f..c048b33e7 100644 --- a/security/nss/lib/softoken/lowkeyti.h +++ b/security/nss/lib/softoken/lowkeyti.h @@ -20,10 +20,8 @@ extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[]; extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[]; extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[]; extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[]; -#ifndef NSS_DISABLE_ECC #define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */ extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[]; -#endif /* NSS_DISABLE_ECC */ extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[]; extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[]; diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index a594fd501..77882a274 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -282,13 +282,11 @@ static const struct mechanismList mechanisms[] = { /* no diffie hellman yet */ { CKM_DH_PKCS_KEY_PAIR_GEN, { DH_MIN_P_BITS, DH_MAX_P_BITS, CKF_GENERATE_KEY_PAIR }, PR_TRUE }, { CKM_DH_PKCS_DERIVE, { DH_MIN_P_BITS, DH_MAX_P_BITS, CKF_DERIVE }, PR_TRUE }, -#ifndef NSS_DISABLE_ECC /* -------------------- Elliptic Curve Operations --------------------- */ { CKM_EC_KEY_PAIR_GEN, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_GENERATE_KEY_PAIR | CKF_EC_BPNU }, PR_TRUE }, { CKM_ECDH1_DERIVE, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_DERIVE | CKF_EC_BPNU }, PR_TRUE }, { CKM_ECDSA, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE }, { CKM_ECDSA_SHA1, { EC_MIN_KEY_BITS, EC_MAX_KEY_BITS, CKF_SN_VR | CKF_EC_BPNU }, PR_TRUE }, -#endif /* NSS_DISABLE_ECC */ /* ------------------------- RC2 Operations --------------------------- */ { CKM_RC2_KEY_GEN, { 1, 128, CKF_GENERATE }, PR_TRUE }, { CKM_RC2_ECB, { 1, 128, CKF_EN_DE_WR_UN }, PR_TRUE }, @@ -423,11 +421,20 @@ static const struct mechanismList mechanisms[] = { #endif /* --------------------- Secret Key Operations ------------------------ */ { CKM_GENERIC_SECRET_KEY_GEN, { 1, 32, CKF_GENERATE }, PR_TRUE }, - { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_GENERATE }, PR_FALSE }, - { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE }, - { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_GENERATE }, PR_FALSE }, - { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_GENERATE }, PR_FALSE }, + { CKM_CONCATENATE_BASE_AND_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CONCATENATE_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CONCATENATE_DATA_AND_BASE, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_XOR_BASE_AND_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, { CKM_EXTRACT_KEY_FROM_KEY, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_DES3_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_DES3_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_AES_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_AES_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CAMELLIA_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_CAMELLIA_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_SEED_ECB_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + { CKM_SEED_CBC_ENCRYPT_DATA, { 1, 32, CKF_DERIVE }, PR_FALSE }, + /* ---------------------- SSL Key Derivations ------------------------- */ { CKM_SSL3_PRE_MASTER_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_FALSE }, { CKM_SSL3_MASTER_KEY_DERIVE, { 48, 48, CKF_DERIVE }, PR_FALSE }, @@ -931,7 +938,6 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, recover = CK_FALSE; wrap = CK_FALSE; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) { return CKR_TEMPLATE_INCOMPLETE; @@ -945,7 +951,6 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, recover = CK_FALSE; wrap = CK_FALSE; break; -#endif /* NSS_DISABLE_ECC */ default: return CKR_ATTRIBUTE_VALUE_INVALID; } @@ -1114,7 +1119,6 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP recover = CK_FALSE; wrap = CK_FALSE; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: if (!sftk_hasAttribute(object, CKA_EC_PARAMS)) { return CKR_TEMPLATE_INCOMPLETE; @@ -1127,7 +1131,6 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP recover = CK_FALSE; wrap = CK_FALSE; break; -#endif /* NSS_DISABLE_ECC */ case CKK_NSS_JPAKE_ROUND1: if (!sftk_hasAttribute(object, CKA_PRIME) || !sftk_hasAttribute(object, CKA_SUBPRIME) || @@ -1778,7 +1781,6 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, crv = sftk_Attribute2SSecItem(arena, &pubKey->u.dh.publicValue, object, CKA_VALUE); break; -#ifndef NSS_DISABLE_ECC case CKK_EC: pubKey->keyType = NSSLOWKEYECKey; crv = sftk_Attribute2SSecItem(arena, @@ -1837,7 +1839,6 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, crv = CKR_ATTRIBUTE_VALUE_INVALID; } break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; break; @@ -1947,7 +1948,6 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) * if we don't set it explicitly */ break; -#ifndef NSS_DISABLE_ECC case CKK_EC: privKey->keyType = NSSLOWKEYECKey; crv = sftk_Attribute2SSecItem(arena, @@ -1992,7 +1992,6 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) #endif } break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; @@ -2365,17 +2364,22 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all) return slot; } -SFTKSlot * -sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle) +CK_SLOT_ID +sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle) { CK_ULONG slotIDIndex = (handle >> 24) & 0x7f; CK_ULONG moduleIndex = (handle >> 31) & 1; if (slotIDIndex >= nscSlotCount[moduleIndex]) { - return NULL; + return (CK_SLOT_ID)-1; } + return nscSlotList[moduleIndex][slotIDIndex]; +} - return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex], PR_FALSE); +SFTKSlot * +sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle) +{ + return sftk_SlotFromID(sftk_SlotIDFromSessionHandle(handle), PR_FALSE); } static CK_RV @@ -3305,6 +3309,15 @@ NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) } } + /* If there is no key database, this is for example the case when NSS was + * initialized with NSS_NoDbInit(), then there won't be any point in + * requesting a PIN. Set the CKF_USER_PIN_INITIALIZED bit so that + * PK11_NeedUserInit() doesn't indicate that a PIN is needed. + */ + if (slot->keyDB == NULL) { + pInfo->flags |= CKF_USER_PIN_INITIALIZED; + } + /* ok we really should read it out of the keydb file. */ /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */ pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR; @@ -3566,7 +3579,6 @@ NSC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, { SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); SFTKDBHandle *handle; - SFTKDBHandle *certHandle; SECStatus rv; unsigned int i; SFTKObject *object; @@ -3614,19 +3626,16 @@ NSC_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, } rv = sftkdb_ResetKeyDB(handle); + /* clear the password */ + sftkdb_ClearPassword(handle); + /* update slot->needLogin (should be true now since no password is set) */ + sftk_checkNeedLogin(slot, handle); sftk_freeDB(handle); if (rv != SECSuccess) { return CKR_DEVICE_ERROR; } - /* finally mark all the user certs as non-user certs */ - certHandle = sftk_getCertDB(slot); - if (certHandle == NULL) - return CKR_OK; - - sftk_freeDB(certHandle); - - return CKR_OK; /*is this the right function for not implemented*/ + return CKR_OK; } /* NSC_InitPIN initializes the normal user's PIN. */ @@ -3792,7 +3801,10 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, /* Now update our local copy of the pin */ if (rv == SECSuccess) { + PZ_Lock(slot->slotLock); slot->needLogin = (PRBool)(ulNewLen != 0); + slot->isLoggedIn = (PRBool)(sftkdb_PWCached(handle) == SECSuccess); + PZ_Unlock(slot->slotLock); /* Reset login flags. */ if (ulNewLen == 0) { PRBool tokenRemoved = PR_FALSE; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 0234aa431..d675d7331 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -65,7 +65,6 @@ sftk_Null(void *data, PRBool freeit) return; } -#ifndef NSS_DISABLE_ECC #ifdef EC_DEBUG #define SEC_PRINT(str1, str2, num, sitem) \ printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \ @@ -78,7 +77,6 @@ sftk_Null(void *data, PRBool freeit) #undef EC_DEBUG #define SEC_PRINT(a, b, c, d) #endif -#endif /* NSS_DISABLE_ECC */ /* * free routines.... Free local type allocated data, and convert @@ -124,7 +122,6 @@ sftk_MapCryptError(int error) return CKR_KEY_SIZE_RANGE; /* the closest error code */ case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM: return CKR_TEMPLATE_INCONSISTENT; - /* EC functions set this error if NSS_DISABLE_ECC is defined */ case SEC_ERROR_UNSUPPORTED_KEYALG: return CKR_MECHANISM_INVALID; case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE: @@ -1527,8 +1524,7 @@ NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, maxout -= padoutlen; } /* now save the final block for the next decrypt or the final */ - PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - - context->blockSize], + PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize], context->blockSize); context->padDataLength = context->blockSize; ulEncryptedPartLen -= context->padDataLength; @@ -2417,7 +2413,6 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf, return rv; } -#ifndef NSS_DISABLE_ECC static SECStatus nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen, void *dataBuf, unsigned int dataLen) @@ -2452,7 +2447,6 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf, *sigLen = signature.len; return rv; } -#endif /* NSS_DISABLE_ECC */ /* NSC_SignInit setups up the signing operations. There are three basic * types of signing: @@ -2612,7 +2606,6 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, break; -#ifndef NSS_DISABLE_ECC case CKM_ECDSA_SHA1: context->multi = PR_TRUE; crv = sftk_doSubSHA1(context); @@ -2635,7 +2628,6 @@ NSC_SignInit(CK_SESSION_HANDLE hSession, context->maxLen = MAX_ECKEY_LEN * 2; break; -#endif /* NSS_DISABLE_ECC */ #define INIT_HMAC_MECH(mmm) \ case CKM_##mmm##_HMAC_GENERAL: \ @@ -3303,7 +3295,6 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, context->verify = (SFTKVerify)nsc_DSA_Verify_Stub; context->destroy = sftk_Null; break; -#ifndef NSS_DISABLE_ECC case CKM_ECDSA_SHA1: context->multi = PR_TRUE; crv = sftk_doSubSHA1(context); @@ -3324,7 +3315,6 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSession, context->verify = (SFTKVerify)nsc_ECDSAVerifyStub; context->destroy = sftk_Null; break; -#endif /* NSS_DISABLE_ECC */ INIT_HMAC_MECH(MD2) INIT_HMAC_MECH(MD5) @@ -4624,12 +4614,10 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, pairwise_digest_length = subPrimeLen; mech.mechanism = CKM_DSA; break; -#ifndef NSS_DISABLE_ECC case CKK_EC: signature_length = MAX_ECKEY_LEN * 2; mech.mechanism = CKM_ECDSA; break; -#endif default: return CKR_DEVICE_ERROR; } @@ -4746,12 +4734,10 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* Diffie Hellman */ DHPrivateKey *dhPriv; -#ifndef NSS_DISABLE_ECC /* Elliptic Curve Cryptography */ SECItem ecEncodedParams; /* DER Encoded parameters */ ECPrivateKey *ecPriv; ECParams *ecParams; -#endif /* NSS_DISABLE_ECC */ CHECK_FORK(); @@ -5097,7 +5083,6 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, PORT_FreeArena(dhPriv->arena, PR_TRUE); break; -#ifndef NSS_DISABLE_ECC case CKM_EC_KEY_PAIR_GEN: sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS); sftk_DeleteAttributeType(privateKey, CKA_VALUE); @@ -5166,7 +5151,6 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* should zeroize, since this function doesn't. */ PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE); break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_MECHANISM_INVALID; @@ -5296,12 +5280,10 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) void *dummy, *param = NULL; SECStatus rv = SECSuccess; SECItem *encodedKey = NULL; -#ifndef NSS_DISABLE_ECC #ifdef EC_DEBUG SECItem *fordebug; #endif int savelen; -#endif if (!key) { *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */ @@ -5353,7 +5335,6 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) nsslowkey_PQGParamsTemplate); algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE; break; -#ifndef NSS_DISABLE_ECC case NSSLOWKEYECKey: prepare_low_ec_priv_key_for_asn1(lk); /* Public value is encoded as a bit string so adjust length @@ -5382,7 +5363,6 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY; break; -#endif /* NSS_DISABLE_ECC */ case NSSLOWKEYDHKey: default: dummy = NULL; @@ -5641,8 +5621,7 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) prepare_low_dsa_priv_key_export_for_asn1(lpk); prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params); break; -/* case NSSLOWKEYDHKey: */ -#ifndef NSS_DISABLE_ECC + /* case NSSLOWKEYDHKey: */ case SEC_OID_ANSIX962_EC_PUBLIC_KEY: keyTemplate = nsslowkey_ECPrivateKeyTemplate; paramTemplate = NULL; @@ -5651,7 +5630,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) prepare_low_ec_priv_key_for_asn1(lpk); prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams); break; -#endif /* NSS_DISABLE_ECC */ default: keyTemplate = NULL; paramTemplate = NULL; @@ -5666,7 +5644,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) /* decode the private key and any algorithm parameters */ rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey); -#ifndef NSS_DISABLE_ECC if (lpk->keyType == NSSLOWKEYECKey) { /* convert length in bits to length in bytes */ lpk->u.ec.publicValue.len >>= 3; @@ -5677,7 +5654,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) goto loser; } } -#endif /* NSS_DISABLE_ECC */ if (rv != SECSuccess) { goto loser; @@ -5790,8 +5766,7 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) keyType = CKK_DH; break; #endif -/* what about fortezza??? */ -#ifndef NSS_DISABLE_ECC + /* what about fortezza??? */ case NSSLOWKEYECKey: keyType = CKK_EC; crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT; @@ -5823,7 +5798,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) break; /* XXX Do we need to decode the EC Params here ?? */ break; -#endif /* NSS_DISABLE_ECC */ default: crv = CKR_KEY_TYPE_INCONSISTENT; break; @@ -6153,7 +6127,6 @@ sftk_MapKeySize(CK_KEY_TYPE keyType) return 0; } -#ifndef NSS_DISABLE_ECC /* Inputs: * key_len: Length of derived key to be generated. * SharedSecret: a shared secret that is the output of a key agreement primitive. @@ -6266,7 +6239,43 @@ sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, else return CKR_MECHANISM_INVALID; } -#endif /* NSS_DISABLE_ECC */ + +/* + * Handle the derive from a block encryption cipher + */ +CK_RV +sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo, + int blockSize, SFTKObject *key, CK_ULONG keySize, + unsigned char *data, CK_ULONG len) +{ + /* large enough for a 512-bit key */ + unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE]; + SECStatus rv; + unsigned int outLen; + CK_RV crv; + + if ((len % blockSize) != 0) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (len > SFTK_MAX_DERIVE_KEY_SIZE) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (keySize && (len < keySize)) { + return CKR_MECHANISM_PARAM_INVALID; + } + if (keySize == 0) { + keySize = len; + } + + rv = (*encrypt)(cipherInfo, &tmpdata, &outLen, len, data, len); + if (rv != SECSuccess) { + crv = sftk_MapCryptError(PORT_GetError()); + return crv; + } + + crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize); + return crv; +} /* * SSL Key generation given pre master secret @@ -6926,6 +6935,172 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, break; } + case CKM_DES3_ECB_ENCRYPT_DATA: + case CKM_DES3_CBC_ENCRYPT_DATA: { + void *cipherInfo; + unsigned char des3key[MAX_DES3_KEY_SIZE]; + CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) { + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) + pMechanism->pParameter; + mode = NSS_DES_EDE3; + iv = NULL; + data = stringPtr->pData; + len = stringPtr->ulLen; + } else { + mode = NSS_DES_EDE3_CBC; + desEncryptPtr = + (CK_DES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + iv = desEncryptPtr->iv; + data = desEncryptPtr->pData; + len = desEncryptPtr->length; + } + if (att->attrib.ulValueLen == 16) { + PORT_Memcpy(des3key, att->attrib.pValue, 16); + PORT_Memcpy(des3key + 16, des3key, 8); + } else if (att->attrib.ulValueLen == 24) { + PORT_Memcpy(des3key, att->attrib.pValue, 24); + } else { + crv = CKR_KEY_SIZE_RANGE; + break; + } + cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE); + PORT_Memset(des3key, 0, 24); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)DES_Encrypt, + cipherInfo, 8, key, keySize, + data, len); + DES_DestroyContext(cipherInfo, PR_TRUE); + break; + } + + case CKM_AES_ECB_ENCRYPT_DATA: + case CKM_AES_CBC_ENCRYPT_DATA: { + void *cipherInfo; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) { + mode = NSS_AES; + iv = NULL; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; + data = stringPtr->pData; + len = stringPtr->ulLen; + } else { + aesEncryptPtr = + (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter; + mode = NSS_AES_CBC; + iv = aesEncryptPtr->iv; + data = aesEncryptPtr->pData; + len = aesEncryptPtr->length; + } + + cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue, + iv, mode, PR_TRUE, + att->attrib.ulValueLen, 16); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)AES_Encrypt, + cipherInfo, 16, key, keySize, + data, len); + AES_DestroyContext(cipherInfo, PR_TRUE); + break; + } + + case CKM_CAMELLIA_ECB_ENCRYPT_DATA: + case CKM_CAMELLIA_CBC_ENCRYPT_DATA: { + void *cipherInfo; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) { + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) + pMechanism->pParameter; + aesEncryptPtr = NULL; + mode = NSS_CAMELLIA; + data = stringPtr->pData; + len = stringPtr->ulLen; + iv = NULL; + } else { + stringPtr = NULL; + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + mode = NSS_CAMELLIA_CBC; + iv = aesEncryptPtr->iv; + data = aesEncryptPtr->pData; + len = aesEncryptPtr->length; + } + + cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue, + iv, mode, PR_TRUE, + att->attrib.ulValueLen); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)Camellia_Encrypt, + cipherInfo, 16, key, keySize, + data, len); + Camellia_DestroyContext(cipherInfo, PR_TRUE); + break; + } + + case CKM_SEED_ECB_ENCRYPT_DATA: + case CKM_SEED_CBC_ENCRYPT_DATA: { + void *cipherInfo; + CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; + int mode; + unsigned char *iv; + unsigned char *data; + CK_ULONG len; + + if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) { + mode = NSS_SEED; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) + pMechanism->pParameter; + aesEncryptPtr = NULL; + data = stringPtr->pData; + len = stringPtr->ulLen; + iv = NULL; + } else { + mode = NSS_SEED_CBC; + aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) + pMechanism->pParameter; + iv = aesEncryptPtr->iv; + data = aesEncryptPtr->pData; + len = aesEncryptPtr->length; + } + + cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue, + iv, mode, PR_TRUE); + if (cipherInfo == NULL) { + crv = CKR_HOST_MEMORY; + break; + } + crv = sftk_DeriveEncrypt((SFTKCipher)SEED_Encrypt, + cipherInfo, 16, key, keySize, + data, len); + SEED_DestroyContext(cipherInfo, PR_TRUE); + break; + } + case CKM_CONCATENATE_BASE_AND_KEY: { SFTKObject *newKey; @@ -7242,7 +7417,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, break; } -#ifndef NSS_DISABLE_ECC case CKM_ECDH1_DERIVE: case CKM_ECDH1_COFACTOR_DERIVE: { SECItem ecScalar, ecPoint; @@ -7382,7 +7556,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, } break; } -#endif /* NSS_DISABLE_ECC */ /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */ case CKM_NSS_HKDF_SHA1: diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index c5f21c30a..7e57dc5e5 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -667,6 +667,7 @@ extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session); extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all); extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle); +extern CK_SLOT_ID sftk_SlotIDFromSessionHandle(CK_SESSION_HANDLE handle); extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); extern void sftk_FreeSession(SFTKSession *session); extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index c51211b6c..27e411759 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -1261,13 +1261,11 @@ static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = { }; static const CK_ULONG dhPubKeyAttrsCount = sizeof(dhPubKeyAttrs) / sizeof(dhPubKeyAttrs[0]); -#ifndef NSS_DISABLE_ECC static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = { CKA_EC_PARAMS, CKA_EC_POINT }; static const CK_ULONG ecPubKeyAttrsCount = sizeof(ecPubKeyAttrs) / sizeof(ecPubKeyAttrs[0]); -#endif static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = { CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT, @@ -1294,13 +1292,11 @@ static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = { }; static const CK_ULONG dhPrivKeyAttrsCount = sizeof(dhPrivKeyAttrs) / sizeof(dhPrivKeyAttrs[0]); -#ifndef NSS_DISABLE_ECC static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = { CKA_EC_PARAMS, CKA_VALUE }; static const CK_ULONG ecPrivKeyAttrsCount = sizeof(ecPrivKeyAttrs) / sizeof(ecPrivKeyAttrs[0]); -#endif static const CK_ATTRIBUTE_TYPE certAttrs[] = { CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER @@ -1405,12 +1401,10 @@ stfk_CopyTokenPrivateKey(SFTKObject *destObject, SFTKTokenObject *src_to) crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs, dhPrivKeyAttrsCount); break; -#ifndef NSS_DISABLE_ECC case CKK_EC: crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs, ecPrivKeyAttrsCount); break; -#endif default: crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types * of token keys into our database. */ @@ -1467,12 +1461,10 @@ stfk_CopyTokenPublicKey(SFTKObject *destObject, SFTKTokenObject *src_to) crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs, dhPubKeyAttrsCount); break; -#ifndef NSS_DISABLE_ECC case CKK_EC: crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs, ecPubKeyAttrsCount); break; -#endif default: crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types * of token keys into our database. */ diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c index 8690df34c..96717cb26 100644 --- a/security/nss/lib/softoken/sdb.c +++ b/security/nss/lib/softoken/sdb.c @@ -37,6 +37,7 @@ #elif defined(XP_UNIX) #include #endif +#include "utilpars.h" #ifdef SQLITE_UNSAFE_THREADS #include "prlock.h" @@ -190,6 +191,34 @@ sdb_done(int err, int *count) return 0; } +#if defined(_WIN32) +/* + * NSPR functions and narrow CRT functions do not handle UTF-8 file paths that + * sqlite3 expects. + */ + +static int +sdb_chmod(const char *filename, int pmode) +{ + int result; + + if (!filename) { + return -1; + } + + wchar_t *filenameWide = _NSSUTIL_UTF8ToWide(filename); + if (!filenameWide) { + return -1; + } + result = _wchmod(filenameWide, pmode); + PORT_Free(filenameWide); + + return result; +} +#else +#define sdb_chmod(filename, pmode) chmod((filename), (pmode)) +#endif + /* * find out where sqlite stores the temp tables. We do this by replicating * the logic from sqlite. @@ -1600,7 +1629,7 @@ loser: return error; } -static const char RESET_CMD[] = "DROP TABLE IF EXISTS %s;"; +static const char RESET_CMD[] = "DELETE FROM %s;"; CK_RV sdb_Reset(SDB *sdb) { @@ -1621,17 +1650,19 @@ sdb_Reset(SDB *sdb) goto loser; } - /* delete the key table */ - newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); + if (tableExists(sqlDB, sdb_p->table)) { + /* delete the contents of the key table */ + newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table); + if (newStr == NULL) { + error = CKR_HOST_MEMORY; + goto loser; + } + sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); + sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) - goto loser; + if (sqlerr != SQLITE_OK) + goto loser; + } /* delete the password entry table */ sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;", @@ -1737,7 +1768,7 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * sqlite3 will always create it. */ LOCK_SQLITE(); - create = (PR_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS); + create = (_NSSUTIL_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS); if ((flags == SDB_RDONLY) && create) { error = sdb_mapSQLError(type, SQLITE_CANTOPEN); goto loser; @@ -1754,7 +1785,7 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * * NO NSPR call for chmod? :( */ - if (create && chmod(dbname, 0600) != 0) { + if (create && sdb_chmod(dbname, 0600) != 0) { error = sdb_mapSQLError(type, SQLITE_CANTOPEN); goto loser; } @@ -1866,30 +1897,29 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * so we use it for the cache (see sdb_buildCache for how it's done).*/ /* - * we decide whether or not to use the cache based on the following input. - * - * NSS_SDB_USE_CACHE environment variable is non-existant or set to - * anything other than "no" or "yes" ("auto", for instance). - * This is the normal case. NSS will measure the performance of access - * to the temp database versus the access to the users passed in - * database location. If the temp database location is "significantly" - * faster we will use the cache. - * - * NSS_SDB_USE_CACHE environment variable is set to "no": cache will not - * be used. - * - * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will - * always be used. - * - * It is expected that most applications would use the "auto" selection, - * the environment variable is primarily to simplify testing, and to - * correct potential corner cases where */ + * we decide whether or not to use the cache based on the following input. + * + * NSS_SDB_USE_CACHE environment variable is set to anything other than + * "yes" or "no" (for instance, "auto"): NSS will measure the performance + * of access to the temp database versus the access to the user's + * passed-in database location. If the temp database location is + * "significantly" faster we will use the cache. + * + * NSS_SDB_USE_CACHE environment variable is nonexistent or set to "no": + * cache will not be used. + * + * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will + * always be used. + * + * It is expected that most applications will not need this feature, and + * thus it is disabled by default. + */ env = PR_GetEnvSecure("NSS_SDB_USE_CACHE"); - if (env && PORT_Strcasecmp(env, "no") == 0) { + if (!env || PORT_Strcasecmp(env, "no") == 0) { enableCache = PR_FALSE; - } else if (env && PORT_Strcasecmp(env, "yes") == 0) { + } else if (PORT_Strcasecmp(env, "yes") == 0) { enableCache = PR_TRUE; } else { char *tempDir = NULL; @@ -2035,10 +2065,11 @@ s_open(const char *directory, const char *certPrefix, const char *keyPrefix, { char *env; env = PR_GetEnvSecure("NSS_SDB_USE_CACHE"); - /* If the environment variable is set to yes or no, sdb_init() will - * ignore the value of accessOps, and we can skip the measuring.*/ - if (!env || ((PORT_Strcasecmp(env, "no") != 0) && - (PORT_Strcasecmp(env, "yes") != 0))) { + /* If the environment variable is undefined or set to yes or no, + * sdb_init() will ignore the value of accessOps, and we can skip the + * measuring.*/ + if (env && PORT_Strcasecmp(env, "no") != 0 && + PORT_Strcasecmp(env, "yes") != 0) { accessOps = sdb_measureAccess(directory); } } diff --git a/security/nss/lib/softoken/sdb.h b/security/nss/lib/softoken/sdb.h index 04b873e02..8ff254bf7 100644 --- a/security/nss/lib/softoken/sdb.h +++ b/security/nss/lib/softoken/sdb.h @@ -83,6 +83,10 @@ CK_RV s_open(const char *directory, const char *certPrefix, int flags, SDB **certdb, SDB **keydb, int *newInit); CK_RV s_shutdown(); +#if defined(_WIN32) +wchar_t *sdb_UTF8ToWide(const char *buf); +#endif + /* flags */ #define SDB_RDONLY 1 #define SDB_RDWR 2 diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c index 52e516117..2ae084068 100644 --- a/security/nss/lib/softoken/sftkdb.c +++ b/security/nss/lib/softoken/sftkdb.c @@ -28,6 +28,9 @@ #include "utilpars.h" #include "secerr.h" #include "softoken.h" +#if defined(_WIN32) +#include +#endif /* * We want all databases to have the same binary representation independent of @@ -40,7 +43,7 @@ */ #define BBP 8 -static PRBool +PRBool sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type) { switch (type) { @@ -1370,7 +1373,8 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, } /* make sure we don't have attributes that conflict with the existing DB */ - crv = sftkdb_checkConflicts(db, object->objclass, template, count, objectID); + crv = sftkdb_checkConflicts(db, object->objclass, ntemplate, count, + objectID); if (crv != CKR_OK) { goto loser; } @@ -1386,8 +1390,8 @@ sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, goto loser; } inTransaction = PR_TRUE; - crv = sftkdb_setAttributeValue(arena, handle, db, - objectID, template, count); + crv = sftkdb_setAttributeValue(arena, handle, db, objectID, ntemplate, + count); if (crv != CKR_OK) { goto loser; } @@ -2311,6 +2315,13 @@ loser: crv = (*handle->update->sdb_GetMetaData)(handle->update, "password", &item1, &item2); if (crv != CKR_OK) { + /* if we get here, neither the source, nor the target has been initialized + * with a password entry. Create a metadata table now so that we don't + * mistake this for a partially updated database */ + item1.data[0] = 0; + item2.data[0] = 0; + item1.len = item2.len = 1; + crv = (*handle->db->sdb_PutMetaData)(handle->db, "empty", &item1, &item2); goto done; } crv = (*handle->db->sdb_PutMetaData)(handle->db, "password", &item1, @@ -2501,6 +2512,53 @@ sftk_oldVersionExists(const char *dir, int version) return PR_FALSE; } +#if defined(_WIN32) +/* + * Convert an sdb path (encoded in UTF-8) to a legacy path (encoded in the + * current system codepage). Fails if the path contains a character outside + * the current system codepage. + */ +static char * +sftk_legacyPathFromSDBPath(const char *confdir) +{ + wchar_t *confdirWide; + DWORD size; + char *nconfdir; + BOOL unmappable; + + if (!confdir) { + return NULL; + } + confdirWide = _NSSUTIL_UTF8ToWide(confdir); + if (!confdirWide) { + return NULL; + } + + size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1, + NULL, 0, NULL, &unmappable); + if (size == 0 || unmappable) { + PORT_Free(confdirWide); + return NULL; + } + nconfdir = PORT_Alloc(sizeof(char) * size); + if (!nconfdir) { + PORT_Free(confdirWide); + return NULL; + } + size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, confdirWide, -1, + nconfdir, size, NULL, &unmappable); + PORT_Free(confdirWide); + if (size == 0 || unmappable) { + PORT_Free(nconfdir); + return NULL; + } + + return nconfdir; +} +#else +#define sftk_legacyPathFromSDBPath(confdir) PORT_Strdup((confdir)) +#endif + static PRBool sftk_hasLegacyDB(const char *confdir, const char *certPrefix, const char *keyPrefix, int certVersion, int keyVersion) @@ -2560,6 +2618,7 @@ sftk_DBInit(const char *configdir, const char *certPrefix, int flags = SDB_RDONLY; PRBool newInit = PR_FALSE; PRBool needUpdate = PR_FALSE; + char *nconfdir = NULL; if (!readOnly) { flags = SDB_CREATE; @@ -2598,11 +2657,14 @@ sftk_DBInit(const char *configdir, const char *certPrefix, * the exists. */ if (crv != CKR_OK) { - if (((flags & SDB_RDONLY) == SDB_RDONLY) && - sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { + if ((flags & SDB_RDONLY) == SDB_RDONLY) { + nconfdir = sftk_legacyPathFromSDBPath(confdir); + } + if (nconfdir && + sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) { /* we have legacy databases, if we failed to open the new format * DB's read only, just use the legacy ones */ - crv = sftkdbCall_open(confdir, certPrefix, + crv = sftkdbCall_open(nconfdir, certPrefix, keyPrefix, 8, 3, flags, noCertDB ? NULL : &certSDB, noKeyDB ? NULL : &keySDB); } @@ -2631,7 +2693,10 @@ sftk_DBInit(const char *configdir, const char *certPrefix, /* if the new format DB was also a newly created DB, and we * succeeded, then need to update that new database with data * from the existing legacy DB */ - if (sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { + nconfdir = sftk_legacyPathFromSDBPath(confdir); + if (nconfdir && + sftk_hasLegacyDB(nconfdir, certPrefix, keyPrefix, 8, 3)) { + confdir = nconfdir; needUpdate = PR_TRUE; } } @@ -2704,6 +2769,9 @@ done: if (appName) { PORT_Free(appName); } + if (nconfdir) { + PORT_Free(nconfdir); + } return forceOpen ? CKR_OK : crv; } diff --git a/security/nss/lib/softoken/sftkdbti.h b/security/nss/lib/softoken/sftkdbti.h index 4942e1b12..7b1db4560 100644 --- a/security/nss/lib/softoken/sftkdbti.h +++ b/security/nss/lib/softoken/sftkdbti.h @@ -49,6 +49,7 @@ SECStatus sftkdb_VerifyAttribute(SECItem *passKey, CK_ATTRIBUTE_TYPE attrType, SECItem *plainText, SECItem *sigText); +PRBool sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type); void sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value); CK_RV sftkdb_Update(SFTKDBHandle *handle, SECItem *key); CK_RV sftkdb_PutAttributeSignature(SFTKDBHandle *handle, diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c index 0b8c91bfd..e0d2df9ab 100644 --- a/security/nss/lib/softoken/sftkpwd.c +++ b/security/nss/lib/softoken/sftkpwd.c @@ -926,6 +926,13 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, continue; } + if (authAttrs[i].ulValueLen == sizeof(CK_ULONG) && + sftkdb_isULONGAttribute(authAttrs[i].type)) { + CK_ULONG value = *(CK_ULONG *)authAttrs[i].pValue; + sftk_ULong2SDBULong(authAttrs[i].pValue, value); + authAttrs[i].ulValueLen = SDB_ULONG_SIZE; + } + plainText.data = authAttrs[i].pValue; plainText.len = authAttrs[i].ulValueLen; rv = sftkdb_SignAttribute(arena, newKey, id, diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index fb2e5bda5..9fd99a8e0 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -8,11 +8,7 @@ #ifndef _SOFTKVER_H_ #define _SOFTKVER_H_ -#ifndef NSS_DISABLE_ECC #define SOFTOKEN_ECC_STRING " Basic ECC" -#else -#define SOFTOKEN_ECC_STRING "" -#endif /* * Softoken's major version, minor version, patch level, build number, @@ -21,10 +17,10 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.32.1" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.35" SOFTOKEN_ECC_STRING #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 32 -#define SOFTOKEN_VPATCH 1 +#define SOFTOKEN_VMINOR 35 +#define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VBUILD 0 #define SOFTOKEN_BETA PR_FALSE diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h index 071689842..03c92361c 100644 --- a/security/nss/lib/softoken/softoknt.h +++ b/security/nss/lib/softoken/softoknt.h @@ -9,6 +9,9 @@ #define _SOFTOKNT_H_ #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048 +#define DES_BLOCK_SIZE 8 /* bytes */ +#define MAX_DES3_KEY_SIZE 24 /* DES_BLOCK_SIZE * 3 */ +#define SFTK_MAX_DERIVE_KEY_SIZE 64 /* * FIPS 140-2 auditing -- cgit v1.2.3