Update NSS to 3.48 while keeping vc2013 hackfix and no-sslkeylogfile intact.

This commit is contained in:
Roy Tam 2020-01-03 13:36:26 +08:00
commit 171849c8e5
351 changed files with 115185 additions and 57946 deletions

View file

@ -134,6 +134,7 @@ get_attr_type_str(CK_ATTRIBUTE_TYPE atype, char *str, int len)
CASE(CKA_RESET_ON_INIT);
CASE(CKA_HAS_RESET);
CASE(CKA_VENDOR_DEFINED);
CASE(CKA_PROFILE_ID);
CASE(CKA_NSS_URL);
CASE(CKA_NSS_EMAIL);
CASE(CKA_NSS_SMIME_INFO);
@ -189,6 +190,7 @@ get_obj_class(CK_OBJECT_CLASS objClass, char *str, int len)
CASE(CKO_SECRET_KEY);
CASE(CKO_HW_FEATURE);
CASE(CKO_DOMAIN_PARAMETERS);
CASE(CKO_PROFILE);
CASE(CKO_NSS_CRL);
CASE(CKO_NSS_SMIME);
CASE(CKO_NSS_TRUST);
@ -202,6 +204,27 @@ get_obj_class(CK_OBJECT_CLASS objClass, char *str, int len)
PR_snprintf(str, len, "0x%p", objClass);
}
static void
get_profile_val(CK_PROFILE_ID profile, char *str, int len)
{
const char *a = NULL;
switch (profile) {
CASE(CKP_INVALID_ID);
CASE(CKP_BASELINE_PROVIDER);
CASE(CKP_EXTENDED_PROVIDER);
CASE(CKP_AUTHENTICATION_TOKEN);
CASE(CKP_PUBLIC_CERTIFICATES_TOKEN);
default:
break;
}
if (a)
PR_snprintf(str, len, "%s", a);
else
PR_snprintf(str, len, "0x%p", profile);
}
static void
get_trust_val(CK_TRUST trust, char *str, int len)
{
@ -376,6 +399,8 @@ print_mechanism(CK_MECHANISM_PTR m)
CASE(CKM_AES_KEY_GEN);
CASE(CKM_AES_MAC);
CASE(CKM_AES_MAC_GENERAL);
CASE(CKM_AES_CMAC);
CASE(CKM_AES_CMAC_GENERAL);
CASE(CKM_CAMELLIA_CBC);
CASE(CKM_CAMELLIA_CBC_ENCRYPT_DATA);
CASE(CKM_CAMELLIA_CBC_PAD);
@ -686,6 +711,14 @@ print_attr_value(CK_ATTRIBUTE_PTR attr)
atype, valstr, attr->ulValueLen));
break;
}
case CKA_PROFILE_ID:
if (attr->ulValueLen > 0 && attr->pValue) {
CK_PROFILE_ID profile = *((CK_PROFILE_ID *)attr->pValue);
get_profile_val(profile, valstr, sizeof valstr);
PR_LOG(modlog, 4, (fmt_s_s_d,
atype, valstr, attr->ulValueLen));
break;
}
case CKA_ISSUER:
case CKA_SUBJECT:
if (attr->ulValueLen > 0 && attr->pValue) {

View file

@ -245,7 +245,7 @@ pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
/* Get the cryptoki object from the handle */
token = PK11Slot_GetNSSToken(slot);
if (token->defaultSession) {
if (token && token->defaultSession) {
co = nssCryptokiObject_Create(token, token->defaultSession, certID);
} else {
PORT_SetError(SEC_ERROR_NO_TOKEN);
@ -307,9 +307,15 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
CERTCertificate *cert = NULL;
CERTCertTrust *trust;
if (slot == NULL || certID == CK_INVALID_HANDLE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
cert = pk11_fastCert(slot, certID, privateLabel, &nickname);
if (cert == NULL)
if (cert == NULL) {
goto loser;
}
if (nickname) {
if (cert->nickname != NULL) {
@ -406,6 +412,93 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
return (cert);
}
CK_OBJECT_HANDLE *
PK11_FindCertHandlesForKeyHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle,
int *certHandleCountOut)
{
if (!slot || !certHandleCountOut || keyHandle == CK_INVALID_HANDLE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
PORTCheapArenaPool arena;
PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
CK_ATTRIBUTE idTemplate[] = {
{ CKA_ID, NULL, 0 },
};
const int idAttrCount = sizeof(idTemplate) / sizeof(idTemplate[0]);
CK_RV crv = PK11_GetAttributes(&arena.arena, slot, keyHandle, idTemplate, idAttrCount);
if (crv != CKR_OK) {
PORT_DestroyCheapArena(&arena);
PORT_SetError(PK11_MapError(crv));
return NULL;
}
if ((idTemplate[0].ulValueLen == 0) || (idTemplate[0].ulValueLen == -1)) {
PORT_DestroyCheapArena(&arena);
PORT_SetError(SEC_ERROR_BAD_KEY);
return NULL;
}
CK_OBJECT_CLASS searchClass = CKO_CERTIFICATE;
CK_ATTRIBUTE searchTemplate[] = {
idTemplate[0],
{ CKA_CLASS, &searchClass, sizeof(searchClass) }
};
const int searchAttrCount = sizeof(searchTemplate) / sizeof(searchTemplate[0]);
CK_OBJECT_HANDLE *ids = pk11_FindObjectsByTemplate(slot, searchTemplate, searchAttrCount, certHandleCountOut);
PORT_DestroyCheapArena(&arena);
return ids;
}
CERTCertList *
PK11_GetCertsMatchingPrivateKey(SECKEYPrivateKey *privKey)
{
if (!privKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
CERTCertList *certs = CERT_NewCertList();
if (!certs) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return NULL;
}
PK11SlotInfo *slot = privKey->pkcs11Slot;
CK_OBJECT_HANDLE handle = privKey->pkcs11ID;
CK_OBJECT_HANDLE certID = PK11_MatchItem(slot, handle, CKO_CERTIFICATE);
/* If we can't get a matching certID, there are no matching certificates,
* which is not an error. */
if (certID == CK_INVALID_HANDLE) {
return certs;
}
int certHandleCount = 0;
CK_OBJECT_HANDLE *certHandles = PK11_FindCertHandlesForKeyHandle(slot, handle, &certHandleCount);
if (!certHandles) {
/* If certHandleCount is 0, there are no matching certificates, which is
* not an error. */
if (certHandleCount == 0) {
return certs;
}
CERT_DestroyCertList(certs);
return NULL;
}
int i;
for (i = 0; i < certHandleCount; i++) {
CERTCertificate *cert = PK11_MakeCertFromHandle(slot, certHandles[i], NULL);
/* If PK11_MakeCertFromHandle fails for one handle, optimistically
assume other handles may succeed (i.e. this is best-effort). */
if (!cert) {
continue;
}
if (CERT_AddCertToListTail(certs, cert) != SECSuccess) {
CERT_DestroyCertificate(cert);
}
}
PORT_Free(certHandles);
return certs;
}
/*
* delete a cert and it's private key (if no other certs are pointing to the
* private key.

View file

@ -1008,12 +1008,12 @@ PK11_DigestFinal(PK11Context *context, unsigned char *data,
}
PK11_ExitContextMonitor(context);
*outLen = (unsigned int)len;
context->init = PR_FALSE; /* allow Begin to start up again */
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
*outLen = (unsigned int)len;
return SECSuccess;
}

View file

@ -488,12 +488,10 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
goto fail;
#ifdef DEBUG_MODULE
if (PR_TRUE) {
modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
mod->functionList = (void *)nss_InsertDeviceLog(
(CK_FUNCTION_LIST_PTR)mod->functionList);
}
modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
mod->functionList = (void *)nss_InsertDeviceLog(
(CK_FUNCTION_LIST_PTR)mod->functionList);
}
#endif

View file

@ -236,6 +236,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
case CKM_AES_GCM:
case CKM_AES_MAC:
case CKM_AES_MAC_GENERAL:
case CKM_AES_CMAC:
case CKM_AES_CMAC_GENERAL:
case CKM_AES_CBC_PAD:
case CKM_AES_KEY_GEN:
case CKM_NETSCAPE_AES_KEY_WRAP:
@ -453,6 +455,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_AES_GCM:
case CKM_AES_MAC:
case CKM_AES_MAC_GENERAL:
case CKM_AES_CMAC:
case CKM_AES_CMAC_GENERAL:
case CKM_AES_CBC_PAD:
case CKM_AES_KEY_GEN:
return CKM_AES_KEY_GEN;

View file

@ -4,6 +4,8 @@
/*
* This file manages object type indepentent functions.
*/
#include <limits.h>
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
@ -933,11 +935,11 @@ PK11_Decrypt(PK11SymKey *symKey,
if (haslock)
PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner);
*outLen = len;
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
*outLen = len;
return SECSuccess;
}
@ -979,11 +981,11 @@ PK11_Encrypt(PK11SymKey *symKey,
if (haslock)
PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner);
*outLen = len;
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
*outLen = len;
return SECSuccess;
}
@ -1665,10 +1667,10 @@ pk11_CreateGenericObjectHelper(PK11SlotInfo *slot,
/* This is the classic interface. Applications would call this function to
* create new object that would not be destroyed later. This lead to resource
* leaks (and thus memory leaks in the PKCS #11 module). To solve this we have
* a new interface that automatically marks objects created on the fly to be
* destroyed later.
* a new interface that automatically marks objects created on the fly to be
* destroyed later.
* The old interface is preserved because applications like Mozilla purposefully
* leak the reference to be found later with PK11_FindGenericObjects. New
* leak the reference to be found later with PK11_FindGenericObjects. New
* applications should use the new interface PK11_CreateManagedGenericObject */
PK11GenericObject *
PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
@ -1678,8 +1680,8 @@ PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
PR_FALSE);
}
/* Use this interface. It will automatically destroy any temporary objects
* (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still
/* Use this interface. It will automatically destroy any temporary objects
* (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still
* need to be destroyed by hand with PK11_DestroyTokenObject.
*/
PK11GenericObject *
@ -1828,15 +1830,24 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
{
CK_OBJECT_HANDLE *objID = NULL;
CK_ULONG returned_count = 0;
PRBool owner = PR_TRUE;
CK_SESSION_HANDLE session;
PRBool haslock = PR_FALSE;
CK_RV crv = CKR_SESSION_HANDLE_INVALID;
PK11_EnterSlotMonitor(slot);
if (slot->session != CK_INVALID_SESSION) {
crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
session = pk11_GetNewSession(slot, &owner);
haslock = (!owner || !(slot->isThreadSafe));
if (haslock) {
PK11_EnterSlotMonitor(slot);
}
if (session != CK_INVALID_SESSION) {
crv = PK11_GETTAB(slot)->C_FindObjectsInit(session,
findTemplate, templCount);
}
if (crv != CKR_OK) {
PK11_ExitSlotMonitor(slot);
if (haslock)
PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner);
PORT_SetError(PK11_MapError(crv));
*object_count = -1;
return NULL;
@ -1861,7 +1872,7 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
PORT_Free(oldObjID);
break;
}
crv = PK11_GETTAB(slot)->C_FindObjects(slot->session,
crv = PK11_GETTAB(slot)->C_FindObjects(session,
&objID[*object_count], PK11_SEARCH_CHUNKSIZE, &returned_count);
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
@ -1872,8 +1883,11 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
*object_count += returned_count;
} while (returned_count == PK11_SEARCH_CHUNKSIZE);
PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session);
PK11_ExitSlotMonitor(slot);
PK11_GETTAB(slot)->C_FindObjectsFinal(session);
if (haslock) {
PK11_ExitSlotMonitor(slot);
}
pk11_CloseSession(slot, session, owner);
if (objID && (*object_count == 0)) {
PORT_Free(objID);
@ -1883,6 +1897,96 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
*object_count = -1;
return objID;
}
SECStatus
PK11_FindRawCertsWithSubject(PK11SlotInfo *slot, SECItem *derSubject,
CERTCertificateList **results)
{
if (!slot || !derSubject || !results) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
*results = NULL;
// derSubject->data may be null. If so, derSubject->len must be 0.
if (!derSubject->data && derSubject->len != 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
CK_ATTRIBUTE subjectTemplate[] = {
{ CKA_CERTIFICATE_TYPE, &ckc_x_509, sizeof(ckc_x_509) },
{ CKA_CLASS, &cko_certificate, sizeof(cko_certificate) },
{ CKA_SUBJECT, derSubject->data, derSubject->len },
};
int templateCount = sizeof(subjectTemplate) / sizeof(subjectTemplate[0]);
int handleCount = 0;
CK_OBJECT_HANDLE *handles =
pk11_FindObjectsByTemplate(slot, subjectTemplate, templateCount,
&handleCount);
if (!handles) {
// pk11_FindObjectsByTemplate indicates there was an error by setting
// handleCount to -1 (and it has set an error with PORT_SetError).
if (handleCount == -1) {
return SECFailure;
}
return SECSuccess;
}
PORT_Assert(handleCount > 0);
if (handleCount <= 0) {
PORT_Free(handles);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
if (handleCount > INT_MAX / sizeof(SECItem)) {
PORT_Free(handles);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
PORT_Free(handles);
return SECFailure;
}
CERTCertificateList *rawCertificates =
PORT_ArenaNew(arena, CERTCertificateList);
if (!rawCertificates) {
PORT_Free(handles);
PORT_FreeArena(arena, PR_FALSE);
return SECFailure;
}
rawCertificates->arena = arena;
rawCertificates->certs = PORT_ArenaNewArray(arena, SECItem, handleCount);
if (!rawCertificates->certs) {
PORT_Free(handles);
PORT_FreeArena(arena, PR_FALSE);
return SECFailure;
}
rawCertificates->len = handleCount;
int handleIndex;
for (handleIndex = 0; handleIndex < handleCount; handleIndex++) {
SECStatus rv =
PK11_ReadAttribute(slot, handles[handleIndex], CKA_VALUE, arena,
&rawCertificates->certs[handleIndex]);
if (rv != SECSuccess) {
PORT_Free(handles);
PORT_FreeArena(arena, PR_FALSE);
return SECFailure;
}
if (!rawCertificates->certs[handleIndex].data) {
PORT_Free(handles);
PORT_FreeArena(arena, PR_FALSE);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
}
PORT_Free(handles);
*results = rawCertificates;
return SECSuccess;
}
/*
* given a PKCS #11 object, match it's peer based on the KeyID. searchID
* is typically a privateKey or a certificate while the peer is the opposite

View file

@ -654,17 +654,17 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
pbeAlgorithm = SEC_OID_PKCS5_PBKDF2;
/*
* 'algorithm' is the overall algorithm oid tag used to wrap the
* entire algoithm ID block. For PKCS5v1 and PKCS12, this
* entire algorithm ID block. For PKCS5v1 and PKCS12, this
* algorithm OID has encoded in it both the PBE KDF function
* and the encryption algorithm. For PKCS 5v2, PBE KDF and
* encryption/macing oids are encoded as parameters in
* the algorithm ID block.
*
* Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11
* mechanism, where as in PKCS 5v2, this alogithm tag does not map
* mechanism, where as in PKCS 5v2, this algorithm tag does not map
* directly to a PKCS #11 mechanim, instead the 2 oids in the
* algorithm ID block map the the actual PKCS #11 mechanism.
* gorithm is). We use choose this algorithm oid based on the
* algorithm is). We use choose this algorithm oid based on the
* cipherAlgorithm to determine what this should be (MAC1 or PBES2).
*/
if (algorithm == SEC_OID_PKCS5_PBKDF2) {

View file

@ -499,6 +499,10 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue : &ckfalse,
sizeof(CK_BBOOL));
attrs++;
if (nickname) {
PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
attrs++;
}
ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue);
if (ck_id == NULL) {
goto loser;

View file

@ -275,12 +275,9 @@ PK11SymKey *PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot,
PK11SymKey *PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent,
PK11Origin origin, CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID,
PRBool owner, void *wincx);
/* PK11_GetWrapKey and PK11_SetWrapKey are not thread safe. */
PK11SymKey *PK11_GetWrapKey(PK11SlotInfo *slot, int wrap,
CK_MECHANISM_TYPE type, int series, void *wincx);
/*
* This function is not thread-safe. It can only be called when only
* one thread has a reference to wrapKey.
*/
void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey);
CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey);
/*
@ -875,6 +872,25 @@ SECStatus PK11_WriteRawAttribute(PK11ObjectType type, void *object,
PK11SlotList *
PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg);
/*
* Finds all certificates on the given slot with the given subject distinguished
* name and returns them as DER bytes. If no such certificates can be found,
* returns SECSuccess and sets *results to NULL. If a failure is encountered
* while fetching any of the matching certificates, SECFailure is returned and
* *results will be NULL.
*/
SECStatus
PK11_FindRawCertsWithSubject(PK11SlotInfo *slot, SECItem *derSubject,
CERTCertificateList **results);
/*
* Finds and returns all certificates with a public key that matches the given
* private key. May return an empty list if no certificates match. Returns NULL
* if a failure is encountered.
*/
CERTCertList *
PK11_GetCertsMatchingPrivateKey(SECKEYPrivateKey *privKey);
/**********************************************************************
* New functions which are already deprecated....
**********************************************************************/

View file

@ -357,7 +357,9 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
}
/*
* turn key handle into an appropriate key object
* Restore a symmetric wrapping key that was saved using PK11_SetWrapKey.
*
* This function is provided for ABI compatibility; see PK11_SetWrapKey below.
*/
PK11SymKey *
PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
@ -365,33 +367,51 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
{
PK11SymKey *symKey = NULL;
if (slot->series != series)
PK11_EnterSlotMonitor(slot);
if (slot->series != series ||
slot->refKeys[wrap] == CK_INVALID_HANDLE) {
PK11_ExitSlotMonitor(slot);
return NULL;
if (slot->refKeys[wrap] == CK_INVALID_HANDLE)
return NULL;
if (type == CKM_INVALID_MECHANISM)
}
if (type == CKM_INVALID_MECHANISM) {
type = slot->wrapMechanism;
}
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
PK11_ExitSlotMonitor(slot);
return symKey;
}
/*
* This function is not thread-safe because it sets wrapKey->sessionOwner
* without using a lock or atomic routine. It can only be called when
* only one thread has a reference to wrapKey.
* This function sets an attribute on the current slot with a wrapping key. The
* data saved is ephemeral; it needs to be run every time the program is
* invoked.
*
* Since NSS 3.45, this function is marginally more thread safe. It uses the
* slot lock (if present) and fails silently if a value is already set. Use
* PK11_GetWrapKey() after calling this function to get the current wrapping key
* in case there was an update on another thread.
*
* Either way, using this function is inadvisable. It's provided for ABI
* compatibility only.
*/
void
PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey)
{
/* save the handle and mechanism for the wrapping key */
/* mark the key and session as not owned by us to they don't get freed
* when the key goes way... that lets us reuse the key later */
slot->refKeys[wrap] = wrapKey->objectID;
wrapKey->owner = PR_FALSE;
wrapKey->sessionOwner = PR_FALSE;
slot->wrapMechanism = wrapKey->type;
PK11_EnterSlotMonitor(slot);
if (wrap < PR_ARRAY_SIZE(slot->refKeys) &&
slot->refKeys[wrap] == CK_INVALID_HANDLE) {
/* save the handle and mechanism for the wrapping key */
/* mark the key and session as not owned by us so they don't get freed
* when the key goes way... that lets us reuse the key later */
slot->refKeys[wrap] = wrapKey->objectID;
wrapKey->owner = PR_FALSE;
wrapKey->sessionOwner = PR_FALSE;
slot->wrapMechanism = wrapKey->type;
}
PK11_ExitSlotMonitor(slot);
}
/*
@ -610,7 +630,7 @@ PK11_GetWindow(PK11SymKey *key)
}
/*
* extract a symetric key value. NOTE: if the key is sensitive, we will
* extract a symmetric key value. NOTE: if the key is sensitive, we will
* not be able to do this operation. This function is used to move
* keys from one token to another */
SECStatus
@ -618,6 +638,11 @@ PK11_ExtractKeyValue(PK11SymKey *symKey)
{
SECStatus rv;
if (symKey == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (symKey->data.data != NULL) {
if (symKey->size == 0) {
symKey->size = symKey->data.len;

View file

@ -419,6 +419,8 @@ PK11_NewSlotInfo(SECMODModule *mod)
slot->hasRootCerts = PR_FALSE;
slot->hasRootTrust = PR_FALSE;
slot->nssToken = NULL;
slot->profileList = NULL;
slot->profileCount = 0;
return slot;
}
@ -446,6 +448,9 @@ PK11_DestroySlot(PK11SlotInfo *slot)
if (slot->mechanismList) {
PORT_Free(slot->mechanismList);
}
if (slot->profileList) {
PORT_Free(slot->profileList);
}
if (slot->isThreadSafe && slot->sessionLock) {
PZ_DestroyLock(slot->sessionLock);
}
@ -1170,6 +1175,76 @@ PK11_ReadMechanismList(PK11SlotInfo *slot)
return SECSuccess;
}
static SECStatus
pk11_ReadProfileList(PK11SlotInfo *slot)
{
CK_ATTRIBUTE findTemp[2];
CK_ATTRIBUTE *attrs;
CK_BBOOL cktrue = CK_TRUE;
CK_OBJECT_CLASS oclass = CKO_PROFILE;
int tsize;
int objCount;
CK_OBJECT_HANDLE *handles = NULL;
int i;
attrs = findTemp;
PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue));
attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &oclass, sizeof(oclass));
attrs++;
tsize = attrs - findTemp;
PORT_Assert(tsize <= sizeof(findTemp) / sizeof(CK_ATTRIBUTE));
if (slot->profileList) {
PORT_Free(slot->profileList);
slot->profileList = NULL;
}
slot->profileCount = 0;
objCount = 0;
handles = pk11_FindObjectsByTemplate(slot, findTemp, tsize, &objCount);
if (handles == NULL) {
if (objCount < 0) {
return SECFailure; /* error code is set */
}
PORT_Assert(objCount == 0);
return SECSuccess;
}
slot->profileList = (CK_PROFILE_ID *)
PORT_Alloc(objCount * sizeof(CK_PROFILE_ID));
if (slot->profileList == NULL) {
PORT_Free(handles);
return SECFailure; /* error code is set */
}
for (i = 0; i < objCount; i++) {
CK_ULONG value;
value = PK11_ReadULongAttribute(slot, handles[i], CKA_PROFILE_ID);
if (value == CK_UNAVAILABLE_INFORMATION) {
continue;
}
slot->profileList[slot->profileCount++] = value;
}
PORT_Free(handles);
return SECSuccess;
}
static PRBool
pk11_HasProfile(PK11SlotInfo *slot, CK_PROFILE_ID id)
{
int i;
for (i = 0; i < slot->profileCount; i++) {
if (slot->profileList[i] == id) {
return PR_TRUE;
}
}
return PR_FALSE;
}
/*
* initialize a new token
* unlike initialize slot, this can be called multiple times in the lifetime
@ -1291,6 +1366,11 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
if (status != PR_SUCCESS)
return SECFailure;
rv = pk11_ReadProfileList(slot);
if (rv != SECSuccess) {
return SECFailure;
}
if (!(slot->isInternal) && (slot->hasRandom)) {
/* if this slot has a random number generater, use it to add entropy
* to the internal slot. */
@ -1439,6 +1519,11 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
slot->slotID = slotID;
slot->isThreadSafe = mod->isThreadSafe;
slot->hasRSAInfo = PR_FALSE;
slot->module = mod; /* NOTE: we don't make a reference here because
* modules have references to their slots. This
* works because modules keep implicit references
* from their slots, and won't unload and disappear
* until all their slots have been freed */
if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID, &slotInfo) != CKR_OK) {
slot->disabled = PR_TRUE;
@ -1448,11 +1533,6 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
/* test to make sure claimed mechanism work */
slot->needTest = mod->internal ? PR_FALSE : PR_TRUE;
slot->module = mod; /* NOTE: we don't make a reference here because
* modules have references to their slots. This
* works because modules keep implicit references
* from their slots, and won't unload and disappear
* until all their slots have been freed */
(void)PK11_MakeString(NULL, slot->slot_name,
(char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription));
slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT);
@ -1695,6 +1775,7 @@ PK11_IsFriendly(PK11SlotInfo *slot)
{
/* internal slot always has public readable certs */
return (PRBool)(slot->isInternal ||
pk11_HasProfile(slot, CKP_PUBLIC_CERTIFICATES_TOKEN) ||
((slot->defaultFlags & SECMOD_FRIENDLY_FLAG) ==
SECMOD_FRIENDLY_FLAG));
}
@ -2096,10 +2177,6 @@ PK11_GetAllTokens(CK_MECHANISM_TYPE type, PRBool needRW, PRBool loadCerts,
SECMODModuleList *modules;
SECMODListLock *moduleLock;
int i;
#if defined(XP_WIN32)
int j = 0;
PRInt32 waste[16];
#endif
moduleLock = SECMOD_GetDefaultModuleListLock();
if (!moduleLock) {
@ -2124,18 +2201,6 @@ PK11_GetAllTokens(CK_MECHANISM_TYPE type, PRBool needRW, PRBool loadCerts,
modules = SECMOD_GetDefaultModuleList();
for (mlp = modules; mlp != NULL; mlp = mlp->next) {
#if defined(XP_WIN32)
/* This is works around some horrible cache/page thrashing problems
** on Win32. Without this, this loop can take up to 6 seconds at
** 100% CPU on a Pentium-Pro 200. The thing this changes is to
** increase the size of the stack frame and modify it.
** Moving the loop code itself seems to have no effect.
** Dunno why this combination makes a difference, but it does.
*/
waste[j & 0xf] = j++;
#endif
for (i = 0; i < mlp->module->slotCount; i++) {
PK11SlotInfo *slot = mlp->module->slots[i];

View file

@ -111,6 +111,8 @@ struct PK11SlotInfoStr {
CK_TOKEN_INFO tokenInfo;
/* fast mechanism lookup */
char mechanismBits[256];
CK_PROFILE_ID *profileList;
int profileCount;
};
/* Symetric Key structure. Reference Counted */