Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: nss/lib/softoken/pkcs11u.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « nss/lib/softoken/pkcs11ni.h ('k') | nss/lib/softoken/sdb.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: nss/lib/softoken/pkcs11u.c
diff --git a/nss/lib/softoken/pkcs11u.c b/nss/lib/softoken/pkcs11u.c
deleted file mode 100644
index de5cbbc29b02c800c61dbf3ab9d9f99ffeec23e5..0000000000000000000000000000000000000000
--- a/nss/lib/softoken/pkcs11u.c
+++ /dev/null
@@ -1,1978 +0,0 @@
-/* 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/. */
-/*
- * Internal PKCS #11 functions. Should only be called by pkcs11.c
- */
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "lowkeyi.h"
-#include "secasn1.h"
-#include "blapi.h"
-#include "secerr.h"
-#include "prnetdb.h" /* for PR_ntohl */
-#include "sftkdb.h"
-#include "softoken.h"
-
-/*
- * ******************** Attribute Utilities *******************************
- */
-
-/*
- * create a new attribute with type, value, and length. Space is allocated
- * to hold value.
- */
-static SFTKAttribute *
-sftk_NewAttribute(SFTKObject *object,
- CK_ATTRIBUTE_TYPE type, const void *value, CK_ULONG len)
-{
- SFTKAttribute *attribute;
-
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
- int index;
-
- if (so == NULL) {
- /* allocate new attribute in a buffer */
- PORT_Assert(0);
- return NULL;
- }
- /*
- * We attempt to keep down contention on Malloc and Arena locks by
- * limiting the number of these calls on high traversed paths. This
- * is done for attributes by 'allocating' them from a pool already
- * allocated by the parent object.
- */
- PZ_Lock(so->attributeLock);
- index = so->nextAttr++;
- PZ_Unlock(so->attributeLock);
- PORT_Assert(index < MAX_OBJS_ATTRS);
- if (index >= MAX_OBJS_ATTRS) return NULL;
-
- attribute = &so->attrList[index];
- attribute->attrib.type = type;
- attribute->freeAttr = PR_FALSE;
- attribute->freeData = PR_FALSE;
- if (value) {
- if (len <= ATTR_SPACE) {
- attribute->attrib.pValue = attribute->space;
- } else {
- attribute->attrib.pValue = PORT_Alloc(len);
- attribute->freeData = PR_TRUE;
- }
- if (attribute->attrib.pValue == NULL) {
- return NULL;
- }
- PORT_Memcpy(attribute->attrib.pValue,value,len);
- attribute->attrib.ulValueLen = len;
- } else {
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- attribute->attrib.type = type;
- attribute->handle = type;
- attribute->next = attribute->prev = NULL;
- return attribute;
-}
-
-/*
- * Free up all the memory associated with an attribute. Reference count
- * must be zero to call this.
- */
-static void
-sftk_DestroyAttribute(SFTKAttribute *attribute)
-{
- if (attribute->freeData) {
- if (attribute->attrib.pValue) {
- /* clear out the data in the attribute value... it may have been
- * sensitive data */
- PORT_Memset(attribute->attrib.pValue, 0,
- attribute->attrib.ulValueLen);
- }
- PORT_Free(attribute->attrib.pValue);
- }
- PORT_Free(attribute);
-}
-
-/*
- * release a reference to an attribute structure
- */
-void
-sftk_FreeAttribute(SFTKAttribute *attribute)
-{
- if (attribute->freeAttr) {
- sftk_DestroyAttribute(attribute);
- return;
- }
-}
-
-static SFTKAttribute *
-sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *myattribute = NULL;
- SFTKDBHandle *dbHandle = NULL;
- CK_RV crv = CKR_HOST_MEMORY;
-
- myattribute = (SFTKAttribute*)PORT_Alloc(sizeof(SFTKAttribute));
- if (myattribute == NULL) {
- goto loser;
- }
-
- dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
-
- myattribute->handle = type;
- myattribute->attrib.type = type;
- myattribute->attrib.pValue = myattribute->space;
- myattribute->attrib.ulValueLen = ATTR_SPACE;
- myattribute->next = myattribute->prev = NULL;
- myattribute->freeAttr = PR_TRUE;
- myattribute->freeData = PR_FALSE;
-
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
-
- /* attribute is bigger than our attribute space buffer, malloc it */
- if (crv == CKR_BUFFER_TOO_SMALL) {
- myattribute->attrib.pValue = NULL;
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
- if (crv != CKR_OK) {
- goto loser;
- }
- myattribute->attrib.pValue = PORT_Alloc(myattribute->attrib.ulValueLen);
- if (myattribute->attrib.pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- myattribute->freeData = PR_TRUE;
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
- }
-loser:
- if (dbHandle) {
- sftk_freeDB(dbHandle);
- }
- if (crv != CKR_OK) {
- if (myattribute) {
- myattribute->attrib.ulValueLen = 0;
- sftk_FreeAttribute(myattribute);
- myattribute = NULL;
- }
- }
- return myattribute;
-}
-
-/*
- * look up and attribute structure from a type and Object structure.
- * The returned attribute is referenced and needs to be freed when
- * it is no longer needed.
- */
-SFTKAttribute *
-sftk_FindAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) {
- return sftk_FindTokenAttribute(sftk_narrowToTokenObject(object),type);
- }
-
- PZ_Lock(sessObject->attributeLock);
- sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize);
- PZ_Unlock(sessObject->attributeLock);
-
- return(attribute);
-}
-
-/*
- * Take a buffer and it's length and return it's true size in bits;
- */
-unsigned int
-sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
-{
- unsigned int size = bufLen * 8;
- unsigned int i;
-
- /* Get the real length in bytes */
- for (i=0; i < bufLen; i++) {
- unsigned char c = *buf++;
- if (c != 0) {
- unsigned char m;
- for (m=0x80; m > 0 ; m = m >> 1) {
- if ((c & m) != 0) {
- break;
- }
- size--;
- }
- break;
- }
- size-=8;
- }
- return size;
-}
-
-/*
- * Constrain a big num attribute. to size and padding
- * minLength means length of the object must be greater than equal to minLength
- * maxLength means length of the object must be less than equal to maxLength
- * minMultiple means that object length mod minMultiple must equal 0.
- * all input sizes are in bits.
- * if any constraint is '0' that constraint is not checked.
- */
-CK_RV
-sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- int minLength, int maxLength, int minMultiple)
-{
- SFTKAttribute *attribute;
- int size;
- unsigned char *ptr;
-
- attribute = sftk_FindAttribute(object, type);
- if (!attribute) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- ptr = (unsigned char *) attribute->attrib.pValue;
- if (ptr == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- size = sftk_GetLengthInBits(ptr, attribute->attrib.ulValueLen);
- sftk_FreeAttribute(attribute);
-
- if ((minLength != 0) && (size < minLength)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- if ((maxLength != 0) && (size > maxLength)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- if ((minMultiple != 0) && ((size % minMultiple) != 0)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- return CKR_OK;
-}
-
-PRBool
-sftk_hasAttributeToken(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
-{
- CK_ATTRIBUTE template;
- CK_RV crv;
- SFTKDBHandle *dbHandle;
-
- dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
- template.type = type;
- template.pValue = NULL;
- template.ulValueLen = 0;
-
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, &template, 1);
- sftk_freeDB(dbHandle);
-
- /* attribute is bigger than our attribute space buffer, malloc it */
- return (crv == CKR_OK) ? PR_TRUE : PR_FALSE;
-}
-
-/*
- * return true if object has attribute
- */
-PRBool
-sftk_hasAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) {
- return sftk_hasAttributeToken(sftk_narrowToTokenObject(object), type);
- }
-
- PZ_Lock(sessObject->attributeLock);
- sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize);
- PZ_Unlock(sessObject->attributeLock);
-
- return (PRBool)(attribute != NULL);
-}
-
-/*
- * add an attribute to an object
- */
-static void
-sftk_AddAttribute(SFTKObject *object,SFTKAttribute *attribute)
-{
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) return;
- PZ_Lock(sessObject->attributeLock);
- sftkqueue_add(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize);
- PZ_Unlock(sessObject->attributeLock);
-}
-
-/*
- * copy an unsigned attribute into a SECItem. Secitem is allocated in
- * the specified arena.
- */
-CK_RV
-sftk_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,SFTKObject *object,
- CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
-
- item->data = NULL;
-
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- (void)SECITEM_AllocItem(arena, item, attribute->attrib.ulValueLen);
- if (item->data == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(item->data, attribute->attrib.pValue, item->len);
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-/*
- * fetch multiple attributes into SECItems. Secitem data is allocated in
- * the specified arena.
- */
-CK_RV
-sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *object,
- SFTKItemTemplate *itemTemplate, int itemTemplateCount)
-{
-
- CK_RV crv = CKR_OK;
- CK_ATTRIBUTE templateSpace[SFTK_MAX_ITEM_TEMPLATE];
- CK_ATTRIBUTE *template;
- SFTKTokenObject *tokObject;
- SFTKDBHandle *dbHandle = NULL;
- int i;
-
- tokObject = sftk_narrowToTokenObject(object);
-
- /* session objects, just loop through the list */
- if (tokObject == NULL) {
- for (i=0; i < itemTemplateCount; i++) {
- crv = sftk_Attribute2SecItem(arena,itemTemplate[i].item, object,
- itemTemplate[i].type);
- if (crv != CKR_OK) {
- return crv;
- }
- }
- return CKR_OK;
- }
-
- /* don't do any work if none is required */
- if (itemTemplateCount == 0) {
- return CKR_OK;
- }
-
- /* don't allocate the template unless we need it */
- if (itemTemplateCount > SFTK_MAX_ITEM_TEMPLATE) {
- template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount);
- } else {
- template = templateSpace;
- }
-
- if (template == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
- if (dbHandle == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- /* set up the PKCS #11 template */
- for (i=0; i < itemTemplateCount; i++) {
- template[i].type = itemTemplate[i].type;
- template[i].pValue = NULL;
- template[i].ulValueLen = 0;
- }
-
- /* fetch the attribute lengths */
- crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
- template, itemTemplateCount);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* allocate space for the attributes */
- for (i=0; i < itemTemplateCount ; i++) {
- template[i].pValue = PORT_ArenaAlloc(arena, template[i].ulValueLen);
- if (template[i].pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- }
-
- /* fetch the attributes */
- crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
- template, itemTemplateCount);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* Fill in the items */
- for (i=0; i < itemTemplateCount; i++) {
- itemTemplate[i].item->data = template[i].pValue;
- itemTemplate[i].item->len = template[i].ulValueLen;
- }
-
-loser:
- if (template != templateSpace) {
- PORT_Free(template);
- }
- if (dbHandle) {
- sftk_freeDB(dbHandle);
- }
-
- return crv;
-}
-
-
-/*
- * delete an attribute from an object
- */
-static void
-sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
-{
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) {
- return ;
- }
- PZ_Lock(sessObject->attributeLock);
- if (sftkqueue_is_queued(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize)) {
- sftkqueue_delete(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize);
- }
- PZ_Unlock(sessObject->attributeLock);
-}
-
-/*
- * this is only valid for CK_BBOOL type attributes. Return the state
- * of that attribute.
- */
-PRBool
-sftk_isTrue(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- PRBool tok = PR_FALSE;
-
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) { return PR_FALSE; }
- tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
- sftk_FreeAttribute(attribute);
-
- return tok;
-}
-
-/*
- * force an attribute to null.
- * this is for sensitive keys which are stored in the database, we don't
- * want to keep this info around in memory in the clear.
- */
-void
-sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
-
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return;
-
- if (attribute->attrib.pValue != NULL) {
- PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
- if (attribute->freeData) {
- PORT_Free(attribute->attrib.pValue);
- }
- attribute->freeData = PR_FALSE;
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- sftk_FreeAttribute(attribute);
-}
-
-
-static CK_RV
-sftk_forceTokenAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
-{
- CK_ATTRIBUTE attribute;
- SFTKDBHandle *dbHandle = NULL;
- SFTKTokenObject *to = sftk_narrowToTokenObject(object);
- CK_RV crv;
-
- PORT_Assert(to);
- if (to == NULL) {
- return CKR_DEVICE_ERROR;
- }
-
- dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
-
- attribute.type = type;
- attribute.pValue = (void *)value;
- attribute.ulValueLen = len;
-
- crv = sftkdb_SetAttributeValue(dbHandle, object, &attribute, 1);
- sftk_freeDB(dbHandle);
- return crv;
-}
-
-/*
- * force an attribute to a specifc value.
- */
-CK_RV
-sftk_forceAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
-{
- SFTKAttribute *attribute;
- void *att_val = NULL;
- PRBool freeData = PR_FALSE;
-
- PORT_Assert(object);
- PORT_Assert(object->refCount);
- PORT_Assert(object->slot);
- if (!object ||
- !object->refCount ||
- !object->slot) {
- return CKR_DEVICE_ERROR;
- }
- if (sftk_isToken(object->handle)) {
- return sftk_forceTokenAttribute(object,type,value,len);
- }
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return sftk_AddAttributeType(object,type,value,len);
-
-
- if (value) {
- if (len <= ATTR_SPACE) {
- att_val = attribute->space;
- } else {
- att_val = PORT_Alloc(len);
- freeData = PR_TRUE;
- }
- if (att_val == NULL) {
- return CKR_HOST_MEMORY;
- }
- if (attribute->attrib.pValue == att_val) {
- PORT_Memset(attribute->attrib.pValue,0,
- attribute->attrib.ulValueLen);
- }
- PORT_Memcpy(att_val,value,len);
- }
- if (attribute->attrib.pValue != NULL) {
- if (attribute->attrib.pValue != att_val) {
- PORT_Memset(attribute->attrib.pValue,0,
- attribute->attrib.ulValueLen);
- }
- if (attribute->freeData) {
- PORT_Free(attribute->attrib.pValue);
- }
- attribute->freeData = PR_FALSE;
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- if (att_val) {
- attribute->attrib.pValue = att_val;
- attribute->attrib.ulValueLen = len;
- attribute->freeData = freeData;
- }
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-/*
- * return a null terminated string from attribute 'type'. This string
- * is allocated and needs to be freed with PORT_Free() When complete.
- */
-char *
-sftk_getString(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- char *label = NULL;
-
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return NULL;
-
- if (attribute->attrib.pValue != NULL) {
- label = (char *) PORT_Alloc(attribute->attrib.ulValueLen+1);
- if (label == NULL) {
- sftk_FreeAttribute(attribute);
- return NULL;
- }
-
- PORT_Memcpy(label,attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- label[attribute->attrib.ulValueLen] = 0;
- }
- sftk_FreeAttribute(attribute);
- return label;
-}
-
-/*
- * decode when a particular attribute may be modified
- * SFTK_NEVER: This attribute must be set at object creation time and
- * can never be modified.
- * SFTK_ONCOPY: This attribute may be modified only when you copy the
- * object.
- * SFTK_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
- * CK_FALSE to CK_TRUE.
- * SFTK_ALWAYS: This attribute can always be modified.
- * Some attributes vary their modification type based on the class of the
- * object.
- */
-SFTKModifyType
-sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
-{
- /* if we don't know about it, user user defined, always allow modify */
- SFTKModifyType mtype = SFTK_ALWAYS;
-
- switch(type) {
- /* NEVER */
- case CKA_CLASS:
- case CKA_CERTIFICATE_TYPE:
- case CKA_KEY_TYPE:
- case CKA_MODULUS:
- case CKA_MODULUS_BITS:
- case CKA_PUBLIC_EXPONENT:
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME:
- case CKA_SUBPRIME:
- case CKA_BASE:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- case CKA_VALUE_LEN:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- case CKA_NETSCAPE_DB:
- mtype = SFTK_NEVER;
- break;
-
- /* ONCOPY */
- case CKA_TOKEN:
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- mtype = SFTK_ONCOPY;
- break;
-
- /* SENSITIVE */
- case CKA_SENSITIVE:
- case CKA_EXTRACTABLE:
- mtype = SFTK_SENSITIVE;
- break;
-
- /* ALWAYS */
- case CKA_LABEL:
- case CKA_APPLICATION:
- case CKA_ID:
- case CKA_SERIAL_NUMBER:
- case CKA_START_DATE:
- case CKA_END_DATE:
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_VERIFY:
- case CKA_SIGN_RECOVER:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- case CKA_UNWRAP:
- mtype = SFTK_ALWAYS;
- break;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- mtype = (inClass == CKO_DATA) ? SFTK_ALWAYS : SFTK_NEVER;
- break;
-
- case CKA_SUBJECT:
- mtype = (inClass == CKO_CERTIFICATE) ? SFTK_NEVER : SFTK_ALWAYS;
- break;
- default:
- break;
- }
- return mtype;
-}
-
-/* decode if a particular attribute is sensitive (cannot be read
- * back to the user of if the object is set to SENSITIVE) */
-PRBool
-sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
-{
- switch(type) {
- /* ALWAYS */
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- return PR_TRUE;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- /* PRIVATE and SECRET KEYS have SENSITIVE values */
- return (PRBool)((inClass == CKO_PRIVATE_KEY) || (inClass == CKO_SECRET_KEY));
-
- default:
- break;
- }
- return PR_FALSE;
-}
-
-/*
- * copy an attribute into a SECItem. Secitem is allocated in the specified
- * arena.
- */
-CK_RV
-sftk_Attribute2SecItem(PLArenaPool *arena,SECItem *item,SFTKObject *object,
- CK_ATTRIBUTE_TYPE type)
-{
- int len;
- SFTKAttribute *attribute;
-
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- len = attribute->attrib.ulValueLen;
-
- if (arena) {
- item->data = (unsigned char *) PORT_ArenaAlloc(arena,len);
- } else {
- item->data = (unsigned char *) PORT_Alloc(len);
- }
- if (item->data == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
- }
- item->len = len;
- PORT_Memcpy(item->data,attribute->attrib.pValue, len);
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-CK_RV
-sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- CK_ULONG *longData)
-{
- SFTKAttribute *attribute;
-
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- *longData = *(CK_ULONG *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-void
-sftk_DeleteAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return ;
- sftk_DeleteAttribute(object,attribute);
- sftk_FreeAttribute(attribute);
-}
-
-CK_RV
-sftk_AddAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *valPtr, CK_ULONG length)
-{
- SFTKAttribute *attribute;
- attribute = sftk_NewAttribute(object,type,valPtr,length);
- if (attribute == NULL) { return CKR_HOST_MEMORY; }
- sftk_AddAttribute(object,attribute);
- return CKR_OK;
-}
-
-/*
- * ******************** Object Utilities *******************************
- */
-
-/* must be called holding sftk_tokenKeyLock(slot) */
-static SECItem *
-sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
-{
- return (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle);
-}
-
-/*
- * use the refLock. This operations should be very rare, so the added
- * contention on the ref lock should be lower than the overhead of adding
- * a new lock. We use separate functions for this just in case I'm wrong.
- */
-static void
-sftk_tokenKeyLock(SFTKSlot *slot) {
- SKIP_AFTER_FORK(PZ_Lock(slot->objectLock));
-}
-
-static void
-sftk_tokenKeyUnlock(SFTKSlot *slot) {
- SKIP_AFTER_FORK(PZ_Unlock(slot->objectLock));
-}
-
-static PRIntn
-sftk_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
-{
- SECItem *item = (SECItem *)entry->value;
-
- SECITEM_FreeItem(item, PR_TRUE);
- return HT_ENUMERATE_NEXT;
-}
-
-CK_RV
-SFTK_ClearTokenKeyHashTable(SFTKSlot *slot)
-{
- sftk_tokenKeyLock(slot);
- PORT_Assert(!slot->present);
- PL_HashTableEnumerateEntries(slot->tokObjHashTable, sftk_freeHashItem, NULL);
- sftk_tokenKeyUnlock(slot);
- return CKR_OK;
-}
-
-
-/* allocation hooks that allow us to recycle old object structures */
-static SFTKObjectFreeList sessionObjectList = { NULL, NULL, 0 };
-static SFTKObjectFreeList tokenObjectList = { NULL, NULL, 0 };
-
-SFTKObject *
-sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace,
- SFTKObjectFreeList *list, unsigned int hashSize, PRBool isSessionObject)
-{
- SFTKObject *object;
- int size = 0;
-
- if (!optimizeSpace) {
- PZ_Lock(list->lock);
- object = list->head;
- if (object) {
- list->head = object->next;
- list->count--;
- }
- PZ_Unlock(list->lock);
- if (object) {
- object->next = object->prev = NULL;
- *hasLocks = PR_TRUE;
- return object;
- }
- }
- size = isSessionObject ? sizeof(SFTKSessionObject)
- + hashSize *sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);
-
- object = (SFTKObject*)PORT_ZAlloc(size);
- if (isSessionObject && object) {
- ((SFTKSessionObject *)object)->hashSize = hashSize;
- }
- *hasLocks = PR_FALSE;
- return object;
-}
-
-static void
-sftk_PutObjectToList(SFTKObject *object, SFTKObjectFreeList *list,
- PRBool isSessionObject) {
-
- /* the code below is equivalent to :
- * optimizeSpace = isSessionObject ? object->optimizeSpace : PR_FALSE;
- * just faster.
- */
- PRBool optimizeSpace = isSessionObject &&
- ((SFTKSessionObject *)object)->optimizeSpace;
- if (object->refLock && !optimizeSpace
- && (list->count < MAX_OBJECT_LIST_SIZE)) {
- PZ_Lock(list->lock);
- object->next = list->head;
- list->head = object;
- list->count++;
- PZ_Unlock(list->lock);
- return;
- }
- if (isSessionObject) {
- SFTKSessionObject *so = (SFTKSessionObject *)object;
- PZ_DestroyLock(so->attributeLock);
- so->attributeLock = NULL;
- }
- if (object->refLock) {
- PZ_DestroyLock(object->refLock);
- object->refLock = NULL;
- }
- PORT_Free(object);
-}
-
-static SFTKObject *
-sftk_freeObjectData(SFTKObject *object) {
- SFTKObject *next = object->next;
-
- PORT_Free(object);
- return next;
-}
-
-static void
-sftk_InitFreeList(SFTKObjectFreeList *list)
-{
- list->lock = PZ_NewLock(nssILockObject);
-}
-
-void sftk_InitFreeLists(void)
-{
- sftk_InitFreeList(&sessionObjectList);
- sftk_InitFreeList(&tokenObjectList);
-}
-
-static void
-sftk_CleanupFreeList(SFTKObjectFreeList *list, PRBool isSessionList)
-{
- SFTKObject *object;
-
- if (!list->lock) {
- return;
- }
- SKIP_AFTER_FORK(PZ_Lock(list->lock));
- for (object= list->head; object != NULL;
- object = sftk_freeObjectData(object)) {
- PZ_DestroyLock(object->refLock);
- if (isSessionList) {
- PZ_DestroyLock(((SFTKSessionObject *)object)->attributeLock);
- }
- }
- list->count = 0;
- list->head = NULL;
- SKIP_AFTER_FORK(PZ_Unlock(list->lock));
- SKIP_AFTER_FORK(PZ_DestroyLock(list->lock));
- list->lock = NULL;
-}
-
-void
-sftk_CleanupFreeLists(void)
-{
- sftk_CleanupFreeList(&sessionObjectList, PR_TRUE);
- sftk_CleanupFreeList(&tokenObjectList, PR_FALSE);
-}
-
-
-/*
- * Create a new object
- */
-SFTKObject *
-sftk_NewObject(SFTKSlot *slot)
-{
- SFTKObject *object;
- SFTKSessionObject *sessObject;
- PRBool hasLocks = PR_FALSE;
- unsigned int i;
- unsigned int hashSize = 0;
-
- hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE :
- TIME_ATTRIBUTE_HASH_SIZE;
-
- object = sftk_GetObjectFromList(&hasLocks, slot->optimizeSpace,
- &sessionObjectList, hashSize, PR_TRUE);
- if (object == NULL) {
- return NULL;
- }
- sessObject = (SFTKSessionObject *)object;
- sessObject->nextAttr = 0;
-
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- sessObject->attrList[i].attrib.pValue = NULL;
- sessObject->attrList[i].freeData = PR_FALSE;
- }
- sessObject->optimizeSpace = slot->optimizeSpace;
-
- object->handle = 0;
- object->next = object->prev = NULL;
- object->slot = slot;
-
- object->refCount = 1;
- sessObject->sessionList.next = NULL;
- sessObject->sessionList.prev = NULL;
- sessObject->sessionList.parent = object;
- sessObject->session = NULL;
- sessObject->wasDerived = PR_FALSE;
- if (!hasLocks) object->refLock = PZ_NewLock(nssILockRefLock);
- if (object->refLock == NULL) {
- PORT_Free(object);
- return NULL;
- }
- if (!hasLocks) sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
- if (sessObject->attributeLock == NULL) {
- PZ_DestroyLock(object->refLock);
- PORT_Free(object);
- return NULL;
- }
- for (i=0; i < sessObject->hashSize; i++) {
- sessObject->head[i] = NULL;
- }
- object->objectInfo = NULL;
- object->infoFree = NULL;
- return object;
-}
-
-static CK_RV
-sftk_DestroySessionObjectData(SFTKSessionObject *so)
-{
- int i;
-
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- unsigned char *value = so->attrList[i].attrib.pValue;
- if (value) {
- PORT_Memset(value,0,so->attrList[i].attrib.ulValueLen);
- if (so->attrList[i].freeData) {
- PORT_Free(value);
- }
- so->attrList[i].attrib.pValue = NULL;
- so->attrList[i].freeData = PR_FALSE;
- }
- }
-/* PZ_DestroyLock(so->attributeLock);*/
- return CKR_OK;
-}
-
-/*
- * free all the data associated with an object. Object reference count must
- * be 'zero'.
- */
-static CK_RV
-sftk_DestroyObject(SFTKObject *object)
-{
- CK_RV crv = CKR_OK;
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
- SFTKTokenObject *to = sftk_narrowToTokenObject(object);
-
- PORT_Assert(object->refCount == 0);
-
- /* delete the database value */
- if (to) {
- if (to->dbKey.data) {
- PORT_Free(to->dbKey.data);
- to->dbKey.data = NULL;
- }
- }
- if (so) {
- sftk_DestroySessionObjectData(so);
- }
- if (object->objectInfo) {
- (*object->infoFree)(object->objectInfo);
- object->objectInfo = NULL;
- object->infoFree = NULL;
- }
- if (so) {
- sftk_PutObjectToList(object,&sessionObjectList,PR_TRUE);
- } else {
- sftk_PutObjectToList(object,&tokenObjectList,PR_FALSE);
- }
- return crv;
-}
-
-void
-sftk_ReferenceObject(SFTKObject *object)
-{
- PZ_Lock(object->refLock);
- object->refCount++;
- PZ_Unlock(object->refLock);
-}
-
-static SFTKObject *
-sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot)
-{
- SFTKObject *object;
- PRUint32 index = sftk_hash(handle, slot->sessObjHashSize);
-
- if (sftk_isToken(handle)) {
- return sftk_NewTokenObject(slot, NULL, handle);
- }
-
- PZ_Lock(slot->objectLock);
- sftkqueue_find2(object, handle, index, slot->sessObjHashTable);
- if (object) {
- sftk_ReferenceObject(object);
- }
- PZ_Unlock(slot->objectLock);
-
- return(object);
-}
-/*
- * look up and object structure from a handle. OBJECT_Handles only make
- * sense in terms of a given session. make a reference to that object
- * structure returned.
- */
-SFTKObject *
-sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session)
-{
- SFTKSlot *slot = sftk_SlotFromSession(session);
-
- return sftk_ObjectFromHandleOnSlot(handle,slot);
-}
-
-
-/*
- * release a reference to an object handle
- */
-SFTKFreeStatus
-sftk_FreeObject(SFTKObject *object)
-{
- PRBool destroy = PR_FALSE;
- CK_RV crv;
-
- PZ_Lock(object->refLock);
- if (object->refCount == 1) destroy = PR_TRUE;
- object->refCount--;
- PZ_Unlock(object->refLock);
-
- if (destroy) {
- crv = sftk_DestroyObject(object);
- if (crv != CKR_OK) {
- return SFTK_DestroyFailure;
- }
- return SFTK_Destroyed;
- }
- return SFTK_Busy;
-}
-
-/*
- * add an object to a slot and session queue. These two functions
- * adopt the object.
- */
-void
-sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object)
-{
- PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
- sftkqueue_init_element(object);
- PZ_Lock(slot->objectLock);
- sftkqueue_add2(object, object->handle, index, slot->sessObjHashTable);
- PZ_Unlock(slot->objectLock);
-}
-
-void
-sftk_AddObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
-
- if (so) {
- PZ_Lock(session->objectLock);
- sftkqueue_add(&so->sessionList,0,session->objects,0);
- so->session = session;
- PZ_Unlock(session->objectLock);
- }
- sftk_AddSlotObject(slot,object);
- sftk_ReferenceObject(object);
-}
-
-/*
- * delete an object from a slot and session queue
- */
-CK_RV
-sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
- CK_RV crv = CKR_OK;
- PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
-
- /* Handle Token case */
- if (so && so->session) {
- SFTKSession *session = so->session;
- PZ_Lock(session->objectLock);
- sftkqueue_delete(&so->sessionList,0,session->objects,0);
- PZ_Unlock(session->objectLock);
- PZ_Lock(slot->objectLock);
- sftkqueue_delete2(object, object->handle, index, slot->sessObjHashTable);
- PZ_Unlock(slot->objectLock);
- sftkqueue_clear_deleted_element(object);
- sftk_FreeObject(object); /* free the reference owned by the queue */
- } else {
- SFTKDBHandle *handle = sftk_getDBForTokenObject(slot, object->handle);
-#ifdef DEBUG
- SFTKTokenObject *to = sftk_narrowToTokenObject(object);
- PORT_Assert(to);
-#endif
- crv = sftkdb_DestroyObject(handle, object->handle);
- sftk_freeDB(handle);
- }
- return crv;
-}
-
-/*
- * Token objects don't explicitly store their attributes, so we need to know
- * what attributes make up a particular token object before we can copy it.
- * below are the tables by object type.
- */
-static const CK_ATTRIBUTE_TYPE commonAttrs[] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_MODIFIABLE
-};
-static const CK_ULONG commonAttrsCount =
- sizeof(commonAttrs)/sizeof(commonAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE commonKeyAttrs[] = {
- CKA_ID, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, CKA_LOCAL, CKA_KEY_TYPE
-};
-static const CK_ULONG commonKeyAttrsCount =
- sizeof(commonKeyAttrs)/sizeof(commonKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE secretKeyAttrs[] = {
- CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN,
- CKA_VERIFY, CKA_WRAP, CKA_UNWRAP, CKA_VALUE
-};
-static const CK_ULONG secretKeyAttrsCount =
- sizeof(secretKeyAttrs)/sizeof(secretKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE commonPubKeyAttrs[] = {
- CKA_ENCRYPT, CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_WRAP, CKA_SUBJECT
-};
-static const CK_ULONG commonPubKeyAttrsCount =
- sizeof(commonPubKeyAttrs)/sizeof(commonPubKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE rsaPubKeyAttrs[] = {
- CKA_MODULUS, CKA_PUBLIC_EXPONENT
-};
-static const CK_ULONG rsaPubKeyAttrsCount =
- sizeof(rsaPubKeyAttrs)/sizeof(rsaPubKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dsaPubKeyAttrs[] = {
- CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-static const CK_ULONG dsaPubKeyAttrsCount =
- sizeof(dsaPubKeyAttrs)/sizeof(dsaPubKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = {
- CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-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,
- CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB
-};
-static const CK_ULONG commonPrivKeyAttrsCount =
- sizeof(commonPrivKeyAttrs)/sizeof(commonPrivKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = {
- CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
- CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT
-};
-static const CK_ULONG rsaPrivKeyAttrsCount =
- sizeof(rsaPrivKeyAttrs)/sizeof(rsaPrivKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dsaPrivKeyAttrs[] = {
- CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-static const CK_ULONG dsaPrivKeyAttrsCount =
- sizeof(dsaPrivKeyAttrs)/sizeof(dsaPrivKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = {
- CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-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
-};
-static const CK_ULONG certAttrsCount =
- sizeof(certAttrs)/sizeof(certAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE trustAttrs[] = {
- CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_EMAIL_PROTECTION,
- CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED
-};
-static const CK_ULONG trustAttrsCount =
- sizeof(trustAttrs)/sizeof(trustAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE smimeAttrs[] = {
- CKA_SUBJECT, CKA_NETSCAPE_EMAIL, CKA_NETSCAPE_SMIME_TIMESTAMP, CKA_VALUE
-};
-static const CK_ULONG smimeAttrsCount =
- sizeof(smimeAttrs)/sizeof(smimeAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE crlAttrs[] = {
- CKA_SUBJECT, CKA_VALUE, CKA_NETSCAPE_URL, CKA_NETSCAPE_KRL
-};
-static const CK_ULONG crlAttrsCount =
- sizeof(crlAttrs)/sizeof(crlAttrs[0]);
-
-/* copy an object based on it's table */
-CK_RV
-stfk_CopyTokenAttributes(SFTKObject *destObject,SFTKTokenObject *src_to,
- const CK_ATTRIBUTE_TYPE *attrArray, CK_ULONG attrCount)
-{
- SFTKAttribute *attribute;
- SFTKAttribute *newAttribute;
- CK_RV crv = CKR_OK;
- unsigned int i;
-
- for (i=0; i < attrCount; i++) {
- if (!sftk_hasAttribute(destObject,attrArray[i])) {
- attribute =sftk_FindAttribute(&src_to->obj, attrArray[i]);
- if (!attribute) {
- continue; /* return CKR_ATTRIBUTE_VALUE_INVALID; */
- }
- /* we need to copy the attribute since each attribute
- * only has one set of link list pointers */
- newAttribute = sftk_NewAttribute( destObject,
- sftk_attr_expand(&attribute->attrib));
- sftk_FreeAttribute(attribute); /* free the old attribute */
- if (!newAttribute) {
- return CKR_HOST_MEMORY;
- }
- sftk_AddAttribute(destObject,newAttribute);
- }
- }
- return crv;
-}
-
-CK_RV
-stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to)
-{
- CK_RV crv;
- CK_KEY_TYPE key_type;
- SFTKAttribute *attribute;
-
- /* copy the common attributes for all keys first */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- /* copy the common attributes for all private keys next */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
- commonPrivKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
- PORT_Assert(attribute); /* if it wasn't here, ww should have failed
- * copying the common attributes */
- if (!attribute) {
- /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
- * the fact is, the only reason we couldn't get the attribute would
- * be a memory error or database error (an error in the 'device').
- * if we have a database error code, we could return it here */
- crv = CKR_DEVICE_ERROR;
- goto fail;
- }
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- /* finally copy the attributes for various private key types */
- switch (key_type) {
- case CKK_RSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPrivKeyAttrs,
- rsaPrivKeyAttrsCount);
- break;
- case CKK_DSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPrivKeyAttrs,
- dsaPrivKeyAttrsCount);
- break;
- case CKK_DH:
- 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. */
- }
-fail:
- return crv;
-}
-
-CK_RV
-stfk_CopyTokenPublicKey(SFTKObject *destObject,SFTKTokenObject *src_to)
-{
- CK_RV crv;
- CK_KEY_TYPE key_type;
- SFTKAttribute *attribute;
-
- /* copy the common attributes for all keys first */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
-
- /* copy the common attributes for all public keys next */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs,
- commonPubKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
- PORT_Assert(attribute); /* if it wasn't here, ww should have failed
- * copying the common attributes */
- if (!attribute) {
- /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
- * the fact is, the only reason we couldn't get the attribute would
- * be a memory error or database error (an error in the 'device').
- * if we have a database error code, we could return it here */
- crv = CKR_DEVICE_ERROR;
- goto fail;
- }
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- /* finally copy the attributes for various public key types */
- switch (key_type) {
- case CKK_RSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPubKeyAttrs,
- rsaPubKeyAttrsCount);
- break;
- case CKK_DSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPubKeyAttrs,
- dsaPubKeyAttrsCount);
- break;
- case CKK_DH:
- 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. */
- }
-fail:
- return crv;
-}
-CK_RV
-stfk_CopyTokenSecretKey(SFTKObject *destObject,SFTKTokenObject *src_to)
-{
- CK_RV crv;
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs,
- secretKeyAttrsCount);
-fail:
- return crv;
-}
-
-/*
- * Copy a token object. We need to explicitly copy the relevant
- * attributes since token objects don't store those attributes in
- * the token itself.
- */
-CK_RV
-sftk_CopyTokenObject(SFTKObject *destObject,SFTKObject *srcObject)
-{
- SFTKTokenObject *src_to = sftk_narrowToTokenObject(srcObject);
- CK_RV crv;
-
- PORT_Assert(src_to);
- if (src_to == NULL) {
- return CKR_DEVICE_ERROR; /* internal state inconsistant */
- }
-
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs,
- commonAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- switch (src_to->obj.objclass) {
- case CKO_CERTIFICATE:
- crv = stfk_CopyTokenAttributes(destObject, src_to, certAttrs,
- certAttrsCount);
- break;
- case CKO_NETSCAPE_TRUST:
- crv = stfk_CopyTokenAttributes(destObject, src_to, trustAttrs,
- trustAttrsCount);
- break;
- case CKO_NETSCAPE_SMIME:
- crv = stfk_CopyTokenAttributes(destObject, src_to, smimeAttrs,
- smimeAttrsCount);
- break;
- case CKO_NETSCAPE_CRL:
- crv = stfk_CopyTokenAttributes(destObject, src_to, crlAttrs,
- crlAttrsCount);
- break;
- case CKO_PRIVATE_KEY:
- crv = stfk_CopyTokenPrivateKey(destObject,src_to);
- break;
- case CKO_PUBLIC_KEY:
- crv = stfk_CopyTokenPublicKey(destObject,src_to);
- break;
- case CKO_SECRET_KEY:
- crv = stfk_CopyTokenSecretKey(destObject,src_to);
- break;
- default:
- crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
- * of token keys into our database. */
- }
-fail:
- return crv;
-}
-
-/*
- * copy the attributes from one object to another. Don't overwrite existing
- * attributes. NOTE: This is a pretty expensive operation since it
- * grabs the attribute locks for the src object for a *long* time.
- */
-CK_RV
-sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject)
-{
- SFTKAttribute *attribute;
- SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
- unsigned int i;
-
- if (src_so == NULL) {
- return sftk_CopyTokenObject(destObject,srcObject);
- }
-
- PZ_Lock(src_so->attributeLock);
- for(i=0; i < src_so->hashSize; i++) {
- attribute = src_so->head[i];
- do {
- if (attribute) {
- if (!sftk_hasAttribute(destObject,attribute->handle)) {
- /* we need to copy the attribute since each attribute
- * only has one set of link list pointers */
- SFTKAttribute *newAttribute = sftk_NewAttribute(
- destObject,sftk_attr_expand(&attribute->attrib));
- if (newAttribute == NULL) {
- PZ_Unlock(src_so->attributeLock);
- return CKR_HOST_MEMORY;
- }
- sftk_AddAttribute(destObject,newAttribute);
- }
- attribute=attribute->next;
- }
- } while (attribute != NULL);
- }
- PZ_Unlock(src_so->attributeLock);
-
- return CKR_OK;
-}
-
-/*
- * ******************** Search Utilities *******************************
- */
-
-/* add an object to a search list */
-CK_RV
-AddToList(SFTKObjectListElement **list,SFTKObject *object)
-{
- SFTKObjectListElement *newElem =
- (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement));
-
- if (newElem == NULL) return CKR_HOST_MEMORY;
-
- newElem->next = *list;
- newElem->object = object;
- sftk_ReferenceObject(object);
-
- *list = newElem;
- return CKR_OK;
-}
-
-
-/* return true if the object matches the template */
-PRBool
-sftk_objectMatch(SFTKObject *object,CK_ATTRIBUTE_PTR theTemplate,int count)
-{
- int i;
-
- for (i=0; i < count; i++) {
- SFTKAttribute *attribute = sftk_FindAttribute(object,theTemplate[i].type);
- if (attribute == NULL) {
- return PR_FALSE;
- }
- if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
- if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue,
- theTemplate[i].ulValueLen) == 0) {
- sftk_FreeAttribute(attribute);
- continue;
- }
- }
- sftk_FreeAttribute(attribute);
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/* search through all the objects in the queue and return the template matches
- * in the object list.
- */
-CK_RV
-sftk_searchObjectList(SFTKSearchResults *search,SFTKObject **head,
- unsigned int size, PZLock *lock, CK_ATTRIBUTE_PTR theTemplate,
- int count, PRBool isLoggedIn)
-{
- unsigned int i;
- SFTKObject *object;
- CK_RV crv = CKR_OK;
-
- for(i=0; i < size; i++) {
- /* We need to hold the lock to copy a consistant version of
- * the linked list. */
- PZ_Lock(lock);
- for (object = head[i]; object != NULL; object= object->next) {
- if (sftk_objectMatch(object,theTemplate,count)) {
- /* don't return objects that aren't yet visible */
- if ((!isLoggedIn) && sftk_isTrue(object,CKA_PRIVATE)) continue;
- sftk_addHandle(search,object->handle);
- }
- }
- PZ_Unlock(lock);
- }
- return crv;
-}
-
-/*
- * free a single list element. Return the Next object in the list.
- */
-SFTKObjectListElement *
-sftk_FreeObjectListElement(SFTKObjectListElement *objectList)
-{
- SFTKObjectListElement *ol = objectList->next;
-
- sftk_FreeObject(objectList->object);
- PORT_Free(objectList);
- return ol;
-}
-
-/* free an entire object list */
-void
-sftk_FreeObjectList(SFTKObjectListElement *objectList)
-{
- SFTKObjectListElement *ol;
-
- for (ol= objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {}
-}
-
-/*
- * free a search structure
- */
-void
-sftk_FreeSearch(SFTKSearchResults *search)
-{
- if (search->handles) {
- PORT_Free(search->handles);
- }
- PORT_Free(search);
-}
-
-/*
- * ******************** Session Utilities *******************************
- */
-
-/* update the sessions state based in it's flags and wether or not it's
- * logged in */
-void
-sftk_update_state(SFTKSlot *slot,SFTKSession *session)
-{
- if (slot->isLoggedIn) {
- if (slot->ssoLoggedIn) {
- session->info.state = CKS_RW_SO_FUNCTIONS;
- } else if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_USER_FUNCTIONS;
- } else {
- session->info.state = CKS_RO_USER_FUNCTIONS;
- }
- } else {
- if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_PUBLIC_SESSION;
- } else {
- session->info.state = CKS_RO_PUBLIC_SESSION;
- }
- }
-}
-
-/* update the state of all the sessions on a slot */
-void
-sftk_update_all_states(SFTKSlot *slot)
-{
- unsigned int i;
- SFTKSession *session;
-
- for (i=0; i < slot->sessHashSize; i++) {
- PZLock *lock = SFTK_SESSION_LOCK(slot,i);
- PZ_Lock(lock);
- for (session = slot->head[i]; session; session = session->next) {
- sftk_update_state(slot,session);
- }
- PZ_Unlock(lock);
- }
-}
-
-/*
- * context are cipher and digest contexts that are associated with a session
- */
-void
-sftk_FreeContext(SFTKSessionContext *context)
-{
- if (context->cipherInfo) {
- (*context->destroy)(context->cipherInfo,PR_TRUE);
- }
- if (context->hashInfo) {
- (*context->hashdestroy)(context->hashInfo,PR_TRUE);
- }
- if (context->key) {
- sftk_FreeObject(context->key);
- context->key = NULL;
- }
- PORT_Free(context);
-}
-
-/*
- * create a new nession. NOTE: The session handle is not set, and the
- * session is not added to the slot's session queue.
- */
-SFTKSession *
-sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
- CK_FLAGS flags)
-{
- SFTKSession *session;
- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
-
- if (slot == NULL) return NULL;
-
- session = (SFTKSession*)PORT_Alloc(sizeof(SFTKSession));
- if (session == NULL) return NULL;
-
- session->next = session->prev = NULL;
- session->refCount = 1;
- session->enc_context = NULL;
- session->hash_context = NULL;
- session->sign_context = NULL;
- session->search = NULL;
- session->objectIDCount = 1;
- session->objectLock = PZ_NewLock(nssILockObject);
- if (session->objectLock == NULL) {
- PORT_Free(session);
- return NULL;
- }
- session->objects[0] = NULL;
-
- session->slot = slot;
- session->notify = notify;
- session->appData = pApplication;
- session->info.flags = flags;
- session->info.slotID = slotID;
- session->info.ulDeviceError = 0;
- sftk_update_state(slot,session);
- return session;
-}
-
-
-/* free all the data associated with a session. */
-static void
-sftk_DestroySession(SFTKSession *session)
-{
- SFTKObjectList *op,*next;
- PORT_Assert(session->refCount == 0);
-
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (op = session->objects[0]; op != NULL; op = next) {
- next = op->next;
- /* paranoia */
- op->next = op->prev = NULL;
- sftk_DeleteObject(session,op->parent);
- }
- PZ_DestroyLock(session->objectLock);
- if (session->enc_context) {
- sftk_FreeContext(session->enc_context);
- }
- if (session->hash_context) {
- sftk_FreeContext(session->hash_context);
- }
- if (session->sign_context) {
- sftk_FreeContext(session->sign_context);
- }
- if (session->search) {
- sftk_FreeSearch(session->search);
- }
- PORT_Free(session);
-}
-
-
-/*
- * look up a session structure from a session handle
- * generate a reference to it.
- */
-SFTKSession *
-sftk_SessionFromHandle(CK_SESSION_HANDLE handle)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
- SFTKSession *session;
- PZLock *lock;
-
- if (!slot) return NULL;
- lock = SFTK_SESSION_LOCK(slot,handle);
-
- PZ_Lock(lock);
- sftkqueue_find(session,handle,slot->head,slot->sessHashSize);
- if (session) session->refCount++;
- PZ_Unlock(lock);
-
- return (session);
-}
-
-/*
- * release a reference to a session handle
- */
-void
-sftk_FreeSession(SFTKSession *session)
-{
- PRBool destroy = PR_FALSE;
- SFTKSlot *slot = sftk_SlotFromSession(session);
- PZLock *lock = SFTK_SESSION_LOCK(slot,session->handle);
-
- PZ_Lock(lock);
- if (session->refCount == 1) destroy = PR_TRUE;
- session->refCount--;
- PZ_Unlock(lock);
-
- if (destroy) sftk_DestroySession(session);
-}
-
-void
-sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle)
-{
- if (search->handles == NULL) {
- return;
- }
- if (search->size >= search->array_size) {
- search->array_size += NSC_SEARCH_BLOCK_SIZE;
- search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles,
- sizeof(CK_OBJECT_HANDLE)* search->array_size);
- if (search->handles == NULL) {
- return;
- }
- }
- search->handles[search->size] = handle;
- search->size++;
-}
-
-static CK_RV
-handleToClass(SFTKSlot *slot, CK_OBJECT_HANDLE handle,
- CK_OBJECT_CLASS *objClass)
-{
- SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, handle);
- CK_ATTRIBUTE objClassTemplate;
- CK_RV crv;
-
- *objClass = CKO_DATA;
- objClassTemplate.type = CKA_CLASS;
- objClassTemplate.pValue = objClass;
- objClassTemplate.ulValueLen = sizeof(*objClass);
- crv = sftkdb_GetAttributeValue(dbHandle, handle, &objClassTemplate, 1);
- sftk_freeDB(dbHandle);
- return crv;
-}
-
-SFTKObject *
-sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
-{
- SFTKObject *object = NULL;
- PRBool hasLocks = PR_FALSE;
- CK_RV crv;
-
- object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0,
- PR_FALSE);
- if (object == NULL) {
- return NULL;
- }
-
- object->handle = handle;
- /* every object must have a class, if we can't get it, the object
- * doesn't exist */
- crv = handleToClass(slot, handle, &object->objclass);
- if (crv != CKR_OK) {
- goto loser;
- }
- object->slot = slot;
- object->objectInfo = NULL;
- object->infoFree = NULL;
- if (!hasLocks) {
- object->refLock = PZ_NewLock(nssILockRefLock);
- }
- if (object->refLock == NULL) {
- goto loser;
- }
- object->refCount = 1;
-
- return object;
-loser:
- if (object) {
- (void) sftk_DestroyObject(object);
- }
- return NULL;
-
-}
-
-SFTKTokenObject *
-sftk_convertSessionToToken(SFTKObject *obj)
-{
- SECItem *key;
- SFTKSessionObject *so = (SFTKSessionObject *)obj;
- SFTKTokenObject *to = sftk_narrowToTokenObject(obj);
- SECStatus rv;
-
- sftk_DestroySessionObjectData(so);
- PZ_DestroyLock(so->attributeLock);
- if (to == NULL) {
- return NULL;
- }
- sftk_tokenKeyLock(so->obj.slot);
- key = sftk_lookupTokenKeyByHandle(so->obj.slot,so->obj.handle);
- if (key == NULL) {
- sftk_tokenKeyUnlock(so->obj.slot);
- return NULL;
- }
- rv = SECITEM_CopyItem(NULL,&to->dbKey,key);
- sftk_tokenKeyUnlock(so->obj.slot);
- if (rv == SECFailure) {
- return NULL;
- }
-
- return to;
-}
-
-SFTKSessionObject *
-sftk_narrowToSessionObject(SFTKObject *obj)
-{
- return !sftk_isToken(obj->handle) ? (SFTKSessionObject *)obj : NULL;
-}
-
-SFTKTokenObject *
-sftk_narrowToTokenObject(SFTKObject *obj)
-{
- return sftk_isToken(obj->handle) ? (SFTKTokenObject *)obj : NULL;
-}
-
« no previous file with comments | « nss/lib/softoken/pkcs11ni.h ('k') | nss/lib/softoken/sdb.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698