diff options
Diffstat (limited to 'nss/lib/softoken/sftkpwd.c')
-rw-r--r-- | nss/lib/softoken/sftkpwd.c | 843 |
1 files changed, 416 insertions, 427 deletions
diff --git a/nss/lib/softoken/sftkpwd.c b/nss/lib/softoken/sftkpwd.c index d8ce857..0b8c91b 100644 --- a/nss/lib/softoken/sftkpwd.c +++ b/nss/lib/softoken/sftkpwd.c @@ -1,28 +1,28 @@ /* 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/. */ -/* +/* * The following code handles the storage of PKCS 11 modules used by the * NSS. For the rest of NSS, only one kind of database handle exists: * * SFTKDBHandle * - * There is one SFTKDBHandle for the each key database and one for each cert + * There is one SFTKDBHandle for the each key database and one for each cert * database. These databases are opened as associated pairs, one pair per * slot. SFTKDBHandles are reference counted objects. * * Each SFTKDBHandle points to a low level database handle (SDB). This handle - * represents the underlying physical database. These objects are not + * represents the underlying physical database. These objects are not * reference counted, an are 'owned' by their respective SFTKDBHandles. * - * + * */ #include "sftkdb.h" #include "sftkdbti.h" #include "pkcs11t.h" #include "pkcs11i.h" #include "sdb.h" -#include "prprf.h" +#include "prprf.h" #include "secasn1.h" #include "pratom.h" #include "blapi.h" @@ -33,9 +33,9 @@ #include "lgglue.h" #include "secerr.h" #include "softoken.h" - + /****************************************************************** - * + * * Key DB password handling functions * * These functions manage the key db password (set, reset, initialize, use). @@ -46,45 +46,44 @@ * in the database is no longer considered 'plain text'. */ - /* take string password and turn it into a key. The key is dependent * on a global salt entry acquired from the database. This salted * value will be based to a pkcs5 pbe function before it is used * in an actual encryption */ static SECStatus sftkdb_passwordToKey(SFTKDBHandle *keydb, SECItem *salt, - const char *pw, SECItem *key) + const char *pw, SECItem *key) { SHA1Context *cx = NULL; SECStatus rv = SECFailure; key->data = PORT_Alloc(SHA1_LENGTH); if (key->data == NULL) { - goto loser; + goto loser; } key->len = SHA1_LENGTH; cx = SHA1_NewContext(); - if ( cx == NULL) { - goto loser; + if (cx == NULL) { + goto loser; } SHA1_Begin(cx); - if (salt && salt->data ) { - SHA1_Update(cx, salt->data, salt->len); + if (salt && salt->data) { + SHA1_Update(cx, salt->data, salt->len); } SHA1_Update(cx, (unsigned char *)pw, PORT_Strlen(pw)); SHA1_End(cx, key->data, &key->len, key->len); rv = SECSuccess; - + loser: if (cx) { - SHA1_DestroyContext(cx, PR_TRUE); + SHA1_DestroyContext(cx, PR_TRUE); } if (rv != SECSuccess) { - if (key->data != NULL) { - PORT_ZFree(key->data,key->len); - } - key->data = NULL; + if (key->data != NULL) { + PORT_ZFree(key->data, key->len); + } + key->data = NULL; } return rv; } @@ -101,10 +100,10 @@ loser: typedef struct sftkCipherValueStr sftkCipherValue; struct sftkCipherValueStr { PLArenaPool *arena; - SECOidTag alg; + SECOidTag alg; NSSPKCS5PBEParameter *param; - SECItem salt; - SECItem value; + SECItem salt; + SECItem value; }; #define SFTK_CIPHERTEXT_VERSION 3 @@ -119,12 +118,12 @@ SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) const SEC_ASN1Template sftkdb_EncryptedDataInfoTemplate[] = { { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SFTKDBEncryptedDataInfo) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN , - offsetof(SFTKDBEncryptedDataInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + 0, NULL, sizeof(SFTKDBEncryptedDataInfo) }, + { SEC_ASN1_INLINE | SEC_ASN1_XTRN, + offsetof(SFTKDBEncryptedDataInfo, algorithm), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_OCTET_STRING, - offsetof(SFTKDBEncryptedDataInfo,encryptedData) }, + offsetof(SFTKDBEncryptedDataInfo, encryptedData) }, { 0 } }; @@ -141,20 +140,20 @@ sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue) arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { - return SECFailure; + return SECFailure; } cipherValue->arena = NULL; cipherValue->param = NULL; rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate, - cipherText); + cipherText); if (rv != SECSuccess) { - goto loser; + goto loser; } cipherValue->alg = SECOID_GetAlgorithmTag(&edi.algorithm); cipherValue->param = nsspkcs5_AlgidToParam(&edi.algorithm); if (cipherValue->param == NULL) { - goto loser; + goto loser; } cipherValue->value = edi.encryptedData; cipherValue->arena = arena; @@ -162,24 +161,22 @@ sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue) return SECSuccess; loser: if (cipherValue->param) { - nsspkcs5_DestroyPBEParameter(cipherValue->param); - cipherValue->param = NULL; + nsspkcs5_DestroyPBEParameter(cipherValue->param); + cipherValue->param = NULL; } if (arena) { - PORT_FreeArena(arena,PR_FALSE); + PORT_FreeArena(arena, PR_FALSE); } return SECFailure; } - - -/* +/* * unlike decode, Encode actually allocates a SECItem the caller must free * The caller can pass an optional arena to to indicate where to place * the resultant cipherText. */ static SECStatus -sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue, +sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue, SECItem **cipherText) { SFTKDBEncryptedDataInfo edi; @@ -187,40 +184,38 @@ sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue, SECStatus rv; PLArenaPool *localArena = NULL; - localArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (localArena == NULL) { - return SECFailure; + return SECFailure; } - algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg, - cipherValue->param); + algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg, + cipherValue->param); if (algid == NULL) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } rv = SECOID_CopyAlgorithmID(localArena, &edi.algorithm, algid); SECOID_DestroyAlgorithmID(algid, PR_TRUE); if (rv != SECSuccess) { - goto loser; + goto loser; } edi.encryptedData = cipherValue->value; - *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi, - sftkdb_EncryptedDataInfoTemplate); + *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi, + sftkdb_EncryptedDataInfoTemplate); if (*cipherText == NULL) { - rv = SECFailure; + rv = SECFailure; } loser: if (localArena) { - PORT_FreeArena(localArena,PR_FALSE); + PORT_FreeArena(localArena, PR_FALSE); } return rv; } - /* * Use our key to decode a cipherText block from the database. * @@ -228,7 +223,7 @@ loser: * with SECITEM_FreeItem by the caller. */ SECStatus -sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain) +sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain) { SECStatus rv; sftkCipherValue cipherValue; @@ -236,22 +231,22 @@ sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain) /* First get the cipher type */ rv = sftkdb_decodeCipherText(cipherText, &cipherValue); if (rv != SECSuccess) { - goto loser; + goto loser; } - *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value, - PR_FALSE, NULL); + *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value, + PR_FALSE, NULL); if (*plain == NULL) { - rv = SECFailure; - goto loser; - } + rv = SECFailure; + goto loser; + } loser: if (cipherValue.param) { - nsspkcs5_DestroyPBEParameter(cipherValue.param); + nsspkcs5_DestroyPBEParameter(cipherValue.param); } if (cipherValue.arena) { - PORT_FreeArena(cipherValue.arena,PR_FALSE); + PORT_FreeArena(cipherValue.arena, PR_FALSE); } return rv; } @@ -263,8 +258,8 @@ loser: * salt automatically. */ SECStatus -sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, - SECItem *plainText, SECItem **cipherText) +sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, + SECItem *plainText, SECItem **cipherText) { SECStatus rv; sftkCipherValue cipherValue; @@ -275,32 +270,33 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, cipherValue.alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC; cipherValue.salt.len = SHA1_LENGTH; cipherValue.salt.data = saltData; - RNG_GenerateGlobalRandomBytes(saltData,cipherValue.salt.len); + RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len); - param = nsspkcs5_NewParam(cipherValue.alg, &cipherValue.salt, 1); + param = nsspkcs5_NewParam(cipherValue.alg, HASH_AlgSHA1, &cipherValue.salt, + 1); if (param == NULL) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } cipher = nsspkcs5_CipherData(param, passKey, plainText, PR_TRUE, NULL); if (cipher == NULL) { - rv = SECFailure; - goto loser; - } + rv = SECFailure; + goto loser; + } cipherValue.value = *cipher; cipherValue.param = param; rv = sftkdb_encodeCipherText(arena, &cipherValue, cipherText); if (rv != SECSuccess) { - goto loser; + goto loser; } loser: if (cipher) { - SECITEM_FreeItem(cipher, PR_TRUE); + SECITEM_FreeItem(cipher, PR_TRUE); } if (param) { - nsspkcs5_DestroyPBEParameter(param); + nsspkcs5_DestroyPBEParameter(param); } return rv; } @@ -312,10 +308,10 @@ loser: * must preallocate the space in the secitem. */ static SECStatus -sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey, - NSSPKCS5PBEParameter *param, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem *signData) +sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey, + NSSPKCS5PBEParameter *param, + CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, + SECItem *plainText, SECItem *signData) { SECStatus rv = SECFailure; SECItem *key = NULL; @@ -326,23 +322,23 @@ sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey, hashType = HASH_FromHMACOid(param->encAlg); if (hashType == HASH_AlgNULL) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return SECFailure; + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; } hashObj = HASH_GetRawHashObject(hashType); if (hashObj == NULL) { - goto loser; + goto loser; } key = nsspkcs5_ComputeKeyAndIV(param, passKey, NULL, PR_FALSE); if (!key) { - goto loser; + goto loser; } hashCx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE); if (!hashCx) { - goto loser; + goto loser; } HMAC_Begin(hashCx); /* Tie this value to a particular object. This is most important for @@ -358,10 +354,10 @@ sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey, loser: if (hashCx) { - HMAC_Destroy(hashCx, PR_TRUE); + HMAC_Destroy(hashCx, PR_TRUE); } if (key) { - SECITEM_FreeItem(key,PR_TRUE); + SECITEM_FreeItem(key, PR_TRUE); } return rv; } @@ -372,40 +368,39 @@ loser: * plainText is the plainText of the attribute. */ SECStatus -sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem *signText) +sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID, + CK_ATTRIBUTE_TYPE attrType, + SECItem *plainText, SECItem *signText) { SECStatus rv; sftkCipherValue signValue; SECItem signature; unsigned char signData[HASH_LENGTH_MAX]; - /* First get the cipher type */ rv = sftkdb_decodeCipherText(signText, &signValue); if (rv != SECSuccess) { - goto loser; + goto loser; } signature.data = signData; signature.len = sizeof(signData); - rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param, - objectID, attrType, plainText, &signature); + rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param, + objectID, attrType, plainText, &signature); if (rv != SECSuccess) { - goto loser; + goto loser; } - if (SECITEM_CompareItem(&signValue.value,&signature) != 0) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - rv = SECFailure; + if (SECITEM_CompareItem(&signValue.value, &signature) != 0) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + rv = SECFailure; } loser: if (signValue.param) { - nsspkcs5_DestroyPBEParameter(signValue.param); + nsspkcs5_DestroyPBEParameter(signValue.param); } if (signValue.arena) { - PORT_FreeArena(signValue.arena,PR_FALSE); + PORT_FreeArena(signValue.arena, PR_FALSE); } return rv; } @@ -415,9 +410,9 @@ loser: * attribute. The signText is a PKCS 5 v2 pbe. */ SECStatus -sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem **signature) +sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, + CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, + SECItem *plainText, SECItem **signature) { SECStatus rv; sftkCipherValue signValue; @@ -446,13 +441,13 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, signValue.salt.data = saltData; signValue.value.data = signData; signValue.value.len = hmacLength; - RNG_GenerateGlobalRandomBytes(saltData,prfLength); + RNG_GenerateGlobalRandomBytes(saltData, prfLength); /* initialize our pkcs5 parameter */ - param = nsspkcs5_NewParam(signValue.alg, &signValue.salt, 1); + param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 1); if (param == NULL) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } param->keyID = pbeBitGenIntegrityKey; /* set the PKCS 5 v2 parameters, not extractable from the @@ -462,47 +457,46 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, param->keyLen = hmacLength; rv = SECOID_SetAlgorithmID(param->poolp, ¶m->prfAlg, prfAlg, NULL); if (rv != SECSuccess) { - goto loser; + goto loser; } - /* calculate the mac */ rv = sftkdb_pbehash(signValue.alg, passKey, param, objectID, attrType, - plainText, &signValue.value); + plainText, &signValue.value); if (rv != SECSuccess) { - goto loser; + goto loser; } signValue.param = param; /* write it out */ rv = sftkdb_encodeCipherText(arena, &signValue, signature); if (rv != SECSuccess) { - goto loser; + goto loser; } loser: if (param) { - nsspkcs5_DestroyPBEParameter(param); + nsspkcs5_DestroyPBEParameter(param); } return rv; } /* * safely swith the passed in key for the one caches in the keydb handle - * + * * A key attached to the handle tells us the the token is logged in. - * We can used the key attached to the handle in sftkdb_EncryptAttribute + * We can used the key attached to the handle in sftkdb_EncryptAttribute * and sftkdb_DecryptAttribute calls. - */ -static void + */ +static void sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey) { unsigned char *data; int len; if (keydb->passwordLock == NULL) { - PORT_Assert(keydb->type != SFTK_KEYDB_TYPE); - return; + PORT_Assert(keydb->type != SFTK_KEYDB_TYPE); + return; } /* an atomic pointer set would be nice */ @@ -533,10 +527,10 @@ PRBool sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb) { if (!sftkdb_InUpdateMerge(keydb)) { - return PR_FALSE; + return PR_FALSE; } if (keydb->updateDBIsInit && !keydb->updatePasswordKey) { - return PR_TRUE; + return PR_TRUE; } return PR_FALSE; } @@ -551,17 +545,17 @@ sftkdb_GetUpdatePasswordKey(SFTKDBHandle *handle) /* if we're a cert db, fetch it from our peer key db */ if (handle->type == SFTK_CERTDB_TYPE) { - handle = handle->peerDB; + handle = handle->peerDB; } /* don't have one */ if (!handle) { - return NULL; + return NULL; } PZ_Lock(handle->passwordLock); if (handle->updatePasswordKey) { - key = SECITEM_DupItem(handle->updatePasswordKey); + key = SECITEM_DupItem(handle->updatePasswordKey); } PZ_Unlock(handle->passwordLock); @@ -578,23 +572,23 @@ sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle) /* don't have one */ if (!handle) { - return; + return; } /* if we're a cert db, we don't have one */ if (handle->type == SFTK_CERTDB_TYPE) { - return; + return; } PZ_Lock(handle->passwordLock); if (handle->updatePasswordKey) { - key = handle->updatePasswordKey; - handle->updatePasswordKey = NULL; + key = handle->updatePasswordKey; + handle->updatePasswordKey = NULL; } PZ_Unlock(handle->passwordLock); if (key) { - SECITEM_ZfreeItem(key, PR_TRUE); + SECITEM_ZfreeItem(key, PR_TRUE); } return; @@ -602,24 +596,24 @@ sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle) /* * what password db we use depends heavily on the update state machine - * + * * 1) no update db, return the normal database. * 2) update db and no merge return the update db. - * 3) update db and in merge: - * return the update db if we need the update db's password, + * 3) update db and in merge: + * return the update db if we need the update db's password, * otherwise return our normal datbase. */ static SDB * sftk_getPWSDB(SFTKDBHandle *keydb) { if (!keydb->update) { - return keydb->db; + return keydb->db; } if (!sftkdb_InUpdateMerge(keydb)) { - return keydb->update; + return keydb->update; } if (sftkdb_NeedUpdateDBPassword(keydb)) { - return keydb->update; + return keydb->update; } return keydb->db; } @@ -629,7 +623,7 @@ sftk_getPWSDB(SFTKDBHandle *keydb) * This is will show up outside of PKCS #11 as CKF_USER_PIN_INIT * in the token flags. */ -SECStatus +SECStatus sftkdb_HasPasswordSet(SFTKDBHandle *keydb) { SECItem salt, value; @@ -639,12 +633,12 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb) SDB *db; if (keydb == NULL) { - return SECFailure; + return SECFailure; } db = sftk_getPWSDB(keydb); if (db == NULL) { - return SECFailure; + return SECFailure; } salt.data = saltData; @@ -654,13 +648,12 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb) crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); /* If no password is set, we can update right away */ - if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update - && crv != CKR_OK) { - /* update the peer certdb if it exists */ - if (keydb->peerDB) { - sftkdb_Update(keydb->peerDB, NULL); - } - sftkdb_Update(keydb, NULL); + if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update && crv != CKR_OK) { + /* update the peer certdb if it exists */ + if (keydb->peerDB) { + sftkdb_Update(keydb->peerDB, NULL); + } + sftkdb_Update(keydb, NULL); } return (crv == CKR_OK) ? SECSuccess : SECFailure; } @@ -671,7 +664,7 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb) /* * check if the supplied password is valid */ -SECStatus +SECStatus sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) { SECStatus rv; @@ -684,18 +677,19 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) CK_RV crv; if (keydb == NULL) { - return SECFailure; + return SECFailure; } db = sftk_getPWSDB(keydb); if (db == NULL) { - return SECFailure; + return SECFailure; } key.data = NULL; key.len = 0; - if (pw == NULL) pw=""; + if (pw == NULL) + pw = ""; /* get the entry from the database */ salt.data = saltData; @@ -704,148 +698,148 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) value.len = sizeof(valueData); crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); if (crv != CKR_OK) { - rv = SECFailure; - goto done; + rv = SECFailure; + goto done; } /* get our intermediate key based on the entry salt value */ rv = sftkdb_passwordToKey(keydb, &salt, pw, &key); if (rv != SECSuccess) { - goto done; + goto done; } /* decrypt the entry value */ rv = sftkdb_DecryptAttribute(&key, &value, &result); if (rv != SECSuccess) { - goto done; + goto done; } /* if it's what we expect, update our key in the database handle and * return Success */ if ((result->len == SFTK_PW_CHECK_LEN) && - PORT_Memcmp(result->data, SFTK_PW_CHECK_STRING, SFTK_PW_CHECK_LEN) == 0){ - /* - * We have a password, now lets handle any potential update cases.. - * - * First, the normal case: no update. In this case we only need the - * the password for our only DB, which we now have, we switch - * the keys and fall through. - * Second regular (non-merge) update: The target DB does not yet have - * a password initialized, we now have the password for the source DB, - * so we can switch the keys and simply update the target database. - * Merge update case: This one is trickier. - * 1) If we need the source DB password, then we just got it here. - * We need to save that password, - * then we need to check to see if we need or have the target - * database password. - * If we have it (it's the same as the source), or don't need - * it (it's not set or is ""), we can start the update now. - * If we don't have it, we need the application to get it from - * the user. Clear our sessions out to simulate a token - * removal. C_GetTokenInfo will change the token description - * and the token will still appear to be logged out. - * 2) If we already have the source DB password, this password is - * for the target database. We can now move forward with the - * update, as we now have both required passwords. - * - */ + PORT_Memcmp(result->data, SFTK_PW_CHECK_STRING, SFTK_PW_CHECK_LEN) == 0) { + /* + * We have a password, now lets handle any potential update cases.. + * + * First, the normal case: no update. In this case we only need the + * the password for our only DB, which we now have, we switch + * the keys and fall through. + * Second regular (non-merge) update: The target DB does not yet have + * a password initialized, we now have the password for the source DB, + * so we can switch the keys and simply update the target database. + * Merge update case: This one is trickier. + * 1) If we need the source DB password, then we just got it here. + * We need to save that password, + * then we need to check to see if we need or have the target + * database password. + * If we have it (it's the same as the source), or don't need + * it (it's not set or is ""), we can start the update now. + * If we don't have it, we need the application to get it from + * the user. Clear our sessions out to simulate a token + * removal. C_GetTokenInfo will change the token description + * and the token will still appear to be logged out. + * 2) If we already have the source DB password, this password is + * for the target database. We can now move forward with the + * update, as we now have both required passwords. + * + */ PZ_Lock(keydb->passwordLock); - if (sftkdb_NeedUpdateDBPassword(keydb)) { - /* Squirrel this special key away. - * This has the side effect of turning sftkdb_NeedLegacyPW off, - * as well as changing which database is returned from - * SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword() - * and sftkdb_HasPasswordSet()) */ - keydb->updatePasswordKey = SECITEM_DupItem(&key); - PZ_Unlock(keydb->passwordLock); - if (keydb->updatePasswordKey == NULL) { - /* PORT_Error set by SECITEM_DupItem */ - rv = SECFailure; - goto done; - } - - /* Simulate a token removal -- we need to do this any + if (sftkdb_NeedUpdateDBPassword(keydb)) { + /* Squirrel this special key away. + * This has the side effect of turning sftkdb_NeedLegacyPW off, + * as well as changing which database is returned from + * SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword() + * and sftkdb_HasPasswordSet()) */ + keydb->updatePasswordKey = SECITEM_DupItem(&key); + PZ_Unlock(keydb->passwordLock); + if (keydb->updatePasswordKey == NULL) { + /* PORT_Error set by SECITEM_DupItem */ + rv = SECFailure; + goto done; + } + + /* Simulate a token removal -- we need to do this any * any case at this point so the token name is correct. */ - *tokenRemoved = PR_TRUE; - - /* - * OK, we got the update DB password, see if we need a password - * for the target... - */ - if (sftkdb_HasPasswordSet(keydb) == SECSuccess) { - /* We have a password, do we know what the password is? - * check 1) for the password the user supplied for the - * update DB, - * and 2) for the null password. - * - * RECURSION NOTE: we are calling ourselves here. This means - * any updates, switchKeys, etc will have been completed - * if these functions return successfully, in those cases - * just exit returning Success. We don't recurse infinitely - * because we are making this call from a NeedUpdateDBPassword - * block and we've already set that update password at this - * point. */ - rv = sftkdb_CheckPassword(keydb, pw, tokenRemoved); - if (rv == SECSuccess) { - /* source and target databases have the same password, we - * are good to go */ - goto done; - } - sftkdb_CheckPassword(keydb, "", tokenRemoved); - - /* - * Important 'NULL' code here. At this point either we - * succeeded in logging in with "" or we didn't. + *tokenRemoved = PR_TRUE; + + /* + * OK, we got the update DB password, see if we need a password + * for the target... + */ + if (sftkdb_HasPasswordSet(keydb) == SECSuccess) { + /* We have a password, do we know what the password is? + * check 1) for the password the user supplied for the + * update DB, + * and 2) for the null password. + * + * RECURSION NOTE: we are calling ourselves here. This means + * any updates, switchKeys, etc will have been completed + * if these functions return successfully, in those cases + * just exit returning Success. We don't recurse infinitely + * because we are making this call from a NeedUpdateDBPassword + * block and we've already set that update password at this + * point. */ + rv = sftkdb_CheckPassword(keydb, pw, tokenRemoved); + if (rv == SECSuccess) { + /* source and target databases have the same password, we + * are good to go */ + goto done; + } + sftkdb_CheckPassword(keydb, "", tokenRemoved); + + /* + * Important 'NULL' code here. At this point either we + * succeeded in logging in with "" or we didn't. * * If we did succeed at login, our machine state will be set - * to logged in appropriately. The application will find that - * it's logged in as soon as it opens a new session. We have - * also completed the update. Life is good. - * - * If we did not succeed, well the user still successfully - * logged into the update database, since we faked the token - * removal it's just like the user logged into his smart card - * then removed it. the actual login work, so we report that - * success back to the user, but we won't actually be - * logged in. The application will find this out when it - * checks it's login state, thus triggering another password - * prompt so we can get the real target DB password. - * - * summary, we exit from here with SECSuccess no matter what. - */ - rv = SECSuccess; - goto done; - } else { - /* there is no password, just fall through to update. - * update will write the source DB's password record - * into the target DB just like it would in a non-merge - * update case. */ - } - } else { - PZ_Unlock(keydb->passwordLock); - } - /* load the keys, so the keydb can parse it's key set */ - sftkdb_switchKeys(keydb, &key); - - /* we need to update, do it now */ - if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) { - /* update the peer certdb if it exists */ - if (keydb->peerDB) { - sftkdb_Update(keydb->peerDB, &key); - } - sftkdb_Update(keydb, &key); - } + * to logged in appropriately. The application will find that + * it's logged in as soon as it opens a new session. We have + * also completed the update. Life is good. + * + * If we did not succeed, well the user still successfully + * logged into the update database, since we faked the token + * removal it's just like the user logged into his smart card + * then removed it. the actual login work, so we report that + * success back to the user, but we won't actually be + * logged in. The application will find this out when it + * checks it's login state, thus triggering another password + * prompt so we can get the real target DB password. + * + * summary, we exit from here with SECSuccess no matter what. + */ + rv = SECSuccess; + goto done; + } else { + /* there is no password, just fall through to update. + * update will write the source DB's password record + * into the target DB just like it would in a non-merge + * update case. */ + } + } else { + PZ_Unlock(keydb->passwordLock); + } + /* load the keys, so the keydb can parse it's key set */ + sftkdb_switchKeys(keydb, &key); + + /* we need to update, do it now */ + if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) { + /* update the peer certdb if it exists */ + if (keydb->peerDB) { + sftkdb_Update(keydb->peerDB, &key); + } + sftkdb_Update(keydb, &key); + } } else { rv = SECFailure; - /*PORT_SetError( bad password); */ + /*PORT_SetError( bad password); */ } done: if (key.data) { - PORT_ZFree(key.data,key.len); + PORT_ZFree(key.data, key.len); } if (result) { - SECITEM_FreeItem(result,PR_TRUE); + SECITEM_FreeItem(result, PR_TRUE); } return rv; } @@ -859,24 +853,23 @@ sftkdb_PWCached(SFTKDBHandle *keydb) return keydb->passwordKey.data ? SECSuccess : SECFailure; } - static CK_RV sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, - CK_OBJECT_HANDLE id, SECItem *newKey) + CK_OBJECT_HANDLE id, SECItem *newKey) { CK_ATTRIBUTE authAttrs[] = { - {CKA_MODULUS, NULL, 0}, - {CKA_PUBLIC_EXPONENT, NULL, 0}, - {CKA_CERT_SHA1_HASH, NULL, 0}, - {CKA_CERT_MD5_HASH, NULL, 0}, - {CKA_TRUST_SERVER_AUTH, NULL, 0}, - {CKA_TRUST_CLIENT_AUTH, NULL, 0}, - {CKA_TRUST_EMAIL_PROTECTION, NULL, 0}, - {CKA_TRUST_CODE_SIGNING, NULL, 0}, - {CKA_TRUST_STEP_UP_APPROVED, NULL, 0}, - {CKA_NSS_OVERRIDE_EXTENSIONS, NULL, 0}, + { CKA_MODULUS, NULL, 0 }, + { CKA_PUBLIC_EXPONENT, NULL, 0 }, + { CKA_CERT_SHA1_HASH, NULL, 0 }, + { CKA_CERT_MD5_HASH, NULL, 0 }, + { CKA_TRUST_SERVER_AUTH, NULL, 0 }, + { CKA_TRUST_CLIENT_AUTH, NULL, 0 }, + { CKA_TRUST_EMAIL_PROTECTION, NULL, 0 }, + { CKA_TRUST_CODE_SIGNING, NULL, 0 }, + { CKA_TRUST_STEP_UP_APPROVED, NULL, 0 }, + { CKA_NSS_OVERRIDE_EXTENSIONS, NULL, 0 }, }; - CK_ULONG authAttrCount = sizeof(authAttrs)/sizeof(CK_ATTRIBUTE); + CK_ULONG authAttrCount = sizeof(authAttrs) / sizeof(CK_ATTRIBUTE); unsigned int i, count; SFTKDBHandle *keyHandle = handle; SDB *keyTarget = NULL; @@ -884,39 +877,39 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, id &= SFTK_OBJ_ID_MASK; if (handle->type != SFTK_KEYDB_TYPE) { - keyHandle = handle->peerDB; + keyHandle = handle->peerDB; } if (keyHandle == NULL) { - return CKR_OK; + return CKR_OK; } /* old DB's don't have meta data, finished with MACs */ keyTarget = SFTK_GET_SDB(keyHandle); - if ((keyTarget->sdb_flags &SDB_HAS_META) == 0) { - return CKR_OK; + if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) { + return CKR_OK; } /* - * STEP 1: find the MACed attributes of this object + * STEP 1: find the MACed attributes of this object */ (void)sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount); count = 0; /* allocate space for the attributes */ - for (i=0; i < authAttrCount; i++) { - if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)){ - continue; - } - count++; - authAttrs[i].pValue = PORT_ArenaAlloc(arena,authAttrs[i].ulValueLen); - if (authAttrs[i].pValue == NULL) { - break; - } + for (i = 0; i < authAttrCount; i++) { + if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)) { + continue; + } + count++; + authAttrs[i].pValue = PORT_ArenaAlloc(arena, authAttrs[i].ulValueLen); + if (authAttrs[i].pValue == NULL) { + break; + } } /* if count was zero, none were found, finished with MACs */ if (count == 0) { - return CKR_OK; + return CKR_OK; } (void)sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount); @@ -924,48 +917,49 @@ sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, /* GetAttributeValue just verified the old macs, safe to write * them out then... */ - for (i=0; i < authAttrCount; i++) { - SECItem *signText; - SECItem plainText; - SECStatus rv; - - if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)){ - continue; - } - - plainText.data = authAttrs[i].pValue; - plainText.len = authAttrs[i].ulValueLen; - rv = sftkdb_SignAttribute(arena, newKey, id, - authAttrs[i].type, &plainText, &signText); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - rv = sftkdb_PutAttributeSignature(handle, keyTarget, id, - authAttrs[i].type, signText); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } + for (i = 0; i < authAttrCount; i++) { + SECItem *signText; + SECItem plainText; + SECStatus rv; + + if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)) { + continue; + } + + plainText.data = authAttrs[i].pValue; + plainText.len = authAttrs[i].ulValueLen; + rv = sftkdb_SignAttribute(arena, newKey, id, + authAttrs[i].type, &plainText, &signText); + if (rv != SECSuccess) { + return CKR_GENERAL_ERROR; + } + rv = sftkdb_PutAttributeSignature(handle, keyTarget, id, + authAttrs[i].type, signText); + if (rv != SECSuccess) { + return CKR_GENERAL_ERROR; + } } return CKR_OK; } - + static CK_RV sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, - CK_OBJECT_HANDLE id, SECItem *newKey) + CK_OBJECT_HANDLE id, SECItem *newKey) { CK_RV crv = CKR_OK; CK_RV crv2; CK_ATTRIBUTE *first, *last; CK_ATTRIBUTE privAttrs[] = { - {CKA_VALUE, NULL, 0}, - {CKA_PRIVATE_EXPONENT, NULL, 0}, - {CKA_PRIME_1, NULL, 0}, - {CKA_PRIME_2, NULL, 0}, - {CKA_EXPONENT_1, NULL, 0}, - {CKA_EXPONENT_2, NULL, 0}, - {CKA_COEFFICIENT, NULL, 0} }; - CK_ULONG privAttrCount = sizeof(privAttrs)/sizeof(CK_ATTRIBUTE); + { CKA_VALUE, NULL, 0 }, + { CKA_PRIVATE_EXPONENT, NULL, 0 }, + { CKA_PRIME_1, NULL, 0 }, + { CKA_PRIME_2, NULL, 0 }, + { CKA_EXPONENT_1, NULL, 0 }, + { CKA_EXPONENT_2, NULL, 0 }, + { CKA_COEFFICIENT, NULL, 0 } + }; + CK_ULONG privAttrCount = sizeof(privAttrs) / sizeof(CK_ATTRIBUTE); unsigned int i, count; /* @@ -980,74 +974,74 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, * find the valid block of attributes and fill allocate space for * their data */ first = last = NULL; - for (i=0; i < privAttrCount; i++) { - /* find the block of attributes that are appropriate for this - * objects. There should only be once contiguous block, if not + for (i = 0; i < privAttrCount; i++) { + /* find the block of attributes that are appropriate for this + * objects. There should only be once contiguous block, if not * there's an error. * * find the first and last good entry. */ - if ((privAttrs[i].ulValueLen == -1) || (privAttrs[i].ulValueLen == 0)){ - if (!first) continue; - if (!last) { - /* previous entry was last good entry */ - last= &privAttrs[i-1]; - } - continue; - } - if (!first) { - first = &privAttrs[i]; - } - if (last) { - /* OOPS, we've found another good entry beyond the end of the - * last good entry, we need to fail here. */ - crv = CKR_GENERAL_ERROR; - break; - } - privAttrs[i].pValue = PORT_ArenaAlloc(arena,privAttrs[i].ulValueLen); - if (privAttrs[i].pValue == NULL) { - crv = CKR_HOST_MEMORY; - break; - } + if ((privAttrs[i].ulValueLen == -1) || (privAttrs[i].ulValueLen == 0)) { + if (!first) + continue; + if (!last) { + /* previous entry was last good entry */ + last = &privAttrs[i - 1]; + } + continue; + } + if (!first) { + first = &privAttrs[i]; + } + if (last) { + /* OOPS, we've found another good entry beyond the end of the + * last good entry, we need to fail here. */ + crv = CKR_GENERAL_ERROR; + break; + } + privAttrs[i].pValue = PORT_ArenaAlloc(arena, privAttrs[i].ulValueLen); + if (privAttrs[i].pValue == NULL) { + crv = CKR_HOST_MEMORY; + break; + } } if (first == NULL) { - /* no valid entries found, return error based on crv2 */ - return crv2; + /* no valid entries found, return error based on crv2 */ + return crv2; } if (last == NULL) { - last = &privAttrs[privAttrCount-1]; + last = &privAttrs[privAttrCount - 1]; } if (crv != CKR_OK) { - return crv; + return crv; } /* read the attributes */ - count = (last-first)+1; + count = (last - first) + 1; crv = sftkdb_GetAttributeValue(keydb, id, first, count); if (crv != CKR_OK) { - return crv; + return crv; } /* * STEP 2: read the encrypt the attributes with the new key. */ - for (i=0; i < count; i++) { - SECItem plainText; - SECItem *result; - SECStatus rv; - - plainText.data = first[i].pValue; - plainText.len = first[i].ulValueLen; - rv = sftkdb_EncryptAttribute(arena, newKey, &plainText, &result); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - first[i].pValue = result->data; - first[i].ulValueLen = result->len; - /* clear our sensitive data out */ - PORT_Memset(plainText.data, 0, plainText.len); + for (i = 0; i < count; i++) { + SECItem plainText; + SECItem *result; + SECStatus rv; + + plainText.data = first[i].pValue; + plainText.len = first[i].ulValueLen; + rv = sftkdb_EncryptAttribute(arena, newKey, &plainText, &result); + if (rv != SECSuccess) { + return CKR_GENERAL_ERROR; + } + first[i].pValue = result->data; + first[i].ulValueLen = result->len; + /* clear our sensitive data out */ + PORT_Memset(plainText.data, 0, plainText.len); } - /* * STEP 3: write the newly encrypted attributes out directly */ @@ -1058,10 +1052,10 @@ sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, return crv; } - + static CK_RV -sftk_convertAttributes(SFTKDBHandle *handle, - CK_OBJECT_HANDLE id, SECItem *newKey) +sftk_convertAttributes(SFTKDBHandle *handle, + CK_OBJECT_HANDLE id, SECItem *newKey) { CK_RV crv = CKR_OK; PLArenaPool *arena = NULL; @@ -1069,7 +1063,7 @@ sftk_convertAttributes(SFTKDBHandle *handle, /* get a new arena to simplify cleanup */ arena = PORT_NewArena(1024); if (!arena) { - return CKR_HOST_MEMORY; + return CKR_HOST_MEMORY; } /* @@ -1077,14 +1071,14 @@ sftk_convertAttributes(SFTKDBHandle *handle, */ crv = sftk_updateMacs(arena, handle, id, newKey); if (crv != CKR_OK) { - goto loser; + goto loser; } if (handle->type == SFTK_KEYDB_TYPE) { - crv = sftk_updateEncrypted(arena, handle, id, newKey); - if (crv != CKR_OK) { - goto loser; - } + crv = sftk_updateEncrypted(arena, handle, id, newKey); + if (crv != CKR_OK) { + goto loser; + } } /* free up our mess */ @@ -1098,13 +1092,12 @@ loser: return crv; } - /* * must be called with the old key active. */ CK_RV -sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template, - CK_ULONG count, SECItem *newKey) +sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template, + CK_ULONG count, SECItem *newKey) { SDBFind *find = NULL; CK_ULONG idCount = SFTK_MAX_IDS; @@ -1115,26 +1108,26 @@ sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template, crv = sftkdb_FindObjectsInit(handle, template, count, &find); if (crv != CKR_OK) { - return crv; + return crv; } while ((crv == CKR_OK) && (idCount == SFTK_MAX_IDS)) { - crv = sftkdb_FindObjects(handle, find, ids, SFTK_MAX_IDS, &idCount); - for (i=0; (crv == CKR_OK) && (i < idCount); i++) { - crv = sftk_convertAttributes(handle, ids[i], newKey); - } + crv = sftkdb_FindObjects(handle, find, ids, SFTK_MAX_IDS, &idCount); + for (i = 0; (crv == CKR_OK) && (i < idCount); i++) { + crv = sftk_convertAttributes(handle, ids[i], newKey); + } } crv2 = sftkdb_FindObjectsFinal(handle, find); - if (crv == CKR_OK) crv = crv2; + if (crv == CKR_OK) + crv = crv2; return crv; } - /* * change the database password. */ SECStatus -sftkdb_ChangePassword(SFTKDBHandle *keydb, +sftkdb_ChangePassword(SFTKDBHandle *keydb, char *oldPin, char *newPin, PRBool *tokenRemoved) { SECStatus rv = SECSuccess; @@ -1149,12 +1142,12 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, SDB *db; if (keydb == NULL) { - return SECFailure; + return SECFailure; } db = SFTK_GET_SDB(keydb); if (db == NULL) { - return SECFailure; + return SECFailure; } newKey.data = NULL; @@ -1162,8 +1155,8 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, /* make sure we have a valid old pin */ crv = (*keydb->db->sdb_Begin)(keydb->db); if (crv != CKR_OK) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } salt.data = saltData; salt.len = sizeof(saltData); @@ -1171,68 +1164,66 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, value.len = sizeof(valueData); crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); if (crv == CKR_OK) { - rv = sftkdb_CheckPassword(keydb, oldPin, tokenRemoved); - if (rv == SECFailure) { - goto loser; - } + rv = sftkdb_CheckPassword(keydb, oldPin, tokenRemoved); + if (rv == SECFailure) { + goto loser; + } } else { - salt.len = SHA1_LENGTH; - RNG_GenerateGlobalRandomBytes(salt.data,salt.len); + salt.len = SHA1_LENGTH; + RNG_GenerateGlobalRandomBytes(salt.data, salt.len); } rv = sftkdb_passwordToKey(keydb, &salt, newPin, &newKey); if (rv != SECSuccess) { - goto loser; + goto loser; } - /* * convert encrypted entries here. */ crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey); if (crv != CKR_OK) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } /* fix up certdb macs */ certdb = keydb->peerDB; if (certdb) { - CK_ATTRIBUTE objectType = { CKA_CLASS, 0, sizeof(CK_OBJECT_CLASS) }; - CK_OBJECT_CLASS myClass = CKO_NETSCAPE_TRUST; - - objectType.pValue = &myClass; - crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - myClass = CKO_PUBLIC_KEY; - crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } + CK_ATTRIBUTE objectType = { CKA_CLASS, 0, sizeof(CK_OBJECT_CLASS) }; + CK_OBJECT_CLASS myClass = CKO_NETSCAPE_TRUST; + + objectType.pValue = &myClass; + crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); + if (crv != CKR_OK) { + rv = SECFailure; + goto loser; + } + myClass = CKO_PUBLIC_KEY; + crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); + if (crv != CKR_OK) { + rv = SECFailure; + goto loser; + } } - plainText.data = (unsigned char *)SFTK_PW_CHECK_STRING; plainText.len = SFTK_PW_CHECK_LEN; rv = sftkdb_EncryptAttribute(NULL, &newKey, &plainText, &result); if (rv != SECSuccess) { - goto loser; + goto loser; } value.data = result->data; value.len = result->len; crv = (*keydb->db->sdb_PutMetaData)(keydb->db, "password", &salt, &value); if (crv != CKR_OK) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } crv = (*keydb->db->sdb_Commit)(keydb->db); if (crv != CKR_OK) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } keydb->newKey = NULL; @@ -1241,15 +1232,15 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, loser: if (newKey.data) { - PORT_ZFree(newKey.data,newKey.len); + PORT_ZFree(newKey.data, newKey.len); } if (result) { - SECITEM_FreeItem(result, PR_TRUE); + SECITEM_FreeItem(result, PR_TRUE); } if (rv != SECSuccess) { (*keydb->db->sdb_Abort)(keydb->db); } - + return rv; } @@ -1264,9 +1255,7 @@ sftkdb_ClearPassword(SFTKDBHandle *keydb) oldKey.len = 0; sftkdb_switchKeys(keydb, &oldKey); if (oldKey.data) { - PORT_ZFree(oldKey.data, oldKey.len); + PORT_ZFree(oldKey.data, oldKey.len); } return SECSuccess; } - - |