pkcs11u.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,271 行 · 第 1/3 页
C
1,271 行
* decode when a particular attribute may be modified * PK11_NEVER: This attribute must be set at object creation time and * can never be modified. * PK11_ONCOPY: This attribute may be modified only when you copy the * object. * PK11_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from * CK_FALSE to CK_TRUE. * PK11_ALWAYS: This attribute can always be modified. * Some attributes vary their modification type based on the class of the * object. */PK11ModifyTypepk11_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass){ /* if we don't know about it, user user defined, always allow modify */ PK11ModifyType mtype = PK11_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 = PK11_NEVER; break; /* ONCOPY */ case CKA_TOKEN: case CKA_PRIVATE: case CKA_MODIFIABLE: mtype = PK11_ONCOPY; break; /* SENSITIVE */ case CKA_SENSITIVE: case CKA_EXTRACTABLE: mtype = PK11_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 = PK11_ALWAYS; break; /* DEPENDS ON CLASS */ case CKA_VALUE: mtype = (inClass == CKO_DATA) ? PK11_ALWAYS : PK11_NEVER; break; case CKA_SUBJECT: mtype = (inClass == CKO_CERTIFICATE) ? PK11_NEVER : PK11_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) */PRBoolpk11_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_RVpk11_Attribute2SecItem(PLArenaPool *arena,SECItem *item,PK11Object *object, CK_ATTRIBUTE_TYPE type){ int len; PK11Attribute *attribute; attribute = pk11_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) { pk11_FreeAttribute(attribute); return CKR_HOST_MEMORY; } item->len = len; PORT_Memcpy(item->data,attribute->attrib.pValue, len); pk11_FreeAttribute(attribute); return CKR_OK;}voidpk11_DeleteAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type){ PK11Attribute *attribute; attribute = pk11_FindAttribute(object, type); if (attribute == NULL) return ; pk11_DeleteAttribute(object,attribute); pk11_FreeAttribute(attribute);}CK_RVpk11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr, CK_ULONG length){ PK11Attribute *attribute; attribute = pk11_NewAttribute(object,type,valPtr,length); if (attribute == NULL) { return CKR_HOST_MEMORY; } pk11_AddAttribute(object,attribute); return CKR_OK;}/* * ******************** Object Utilities ******************************* *//* allocation hooks that allow us to recycle old object structures */#ifdef MAX_OBJECT_LIST_SIZEstatic PK11Object * objectFreeList = NULL;static PRLock *objectLock = NULL;static int object_count = 0;#endifPK11Object *pk11_GetObjectFromList(PRBool *hasLocks) { PK11Object *object;#if MAX_OBJECT_LIST_SIZE if (objectLock == NULL) { objectLock = PR_NewLock(); } PK11_USE_THREADS(PR_Lock(objectLock)); object = objectFreeList; if (object) { objectFreeList = object->next; object_count--; } PK11_USE_THREADS(PR_Unlock(objectLock)); if (object) { object->next = object->prev = NULL; *hasLocks = PR_TRUE; return object; }#endif object = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object)); *hasLocks = PR_FALSE; return object;}static voidpk11_PutObjectToList(PK11Object *object) {#ifdef MAX_OBJECT_LIST_SIZE if (object_count < MAX_OBJECT_LIST_SIZE) { PK11_USE_THREADS(PR_Lock(objectLock)); object->next = objectFreeList; objectFreeList = object; object_count++; PK11_USE_THREADS(PR_Unlock(objectLock)); return; }#endif PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);) PK11_USE_THREADS(PR_DestroyLock(object->refLock);) object->attributeLock = object->refLock = NULL; PORT_Free(object);}/* * Create a new object */PK11Object *pk11_NewObject(PK11Slot *slot){ PK11Object *object; PLArenaPool *arena; PRBool hasLocks = PR_FALSE; int i;#ifdef NO_ARENA object = pk11_GetObjectFromList(&hasLocks); if (object == NULL) { return NULL; } object->nextAttr = 0;#else arena = PORT_NewArena(2048); if (arena == NULL) return NULL; object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11Object)); if (object == NULL) { PORT_FreeArena(arena,PR_FALSE); return NULL; } object->arena = arena; for (i=0; i < MAX_OBJS_ATTRS; i++) { object->attrList[i].attrib.pValue = NULL; }#endif object->handle = 0; object->next = object->prev = NULL; object->sessionList.next = NULL; object->sessionList.prev = NULL; object->sessionList.parent = object; object->inDB = PR_FALSE; object->label = NULL; object->refCount = 1; object->session = NULL; object->slot = slot; object->objclass = 0xffff; object->wasDerived = PR_FALSE;#ifdef PKCS11_USE_THREADS if (!hasLocks) object->refLock = PR_NewLock(); if (object->refLock == NULL) {#ifdef NO_ARENA PORT_Free(object);#else PORT_FreeArena(arena,PR_FALSE);#endif return NULL; } if (!hasLocks) object->attributeLock = PR_NewLock(); if (object->attributeLock == NULL) { PK11_USE_THREADS(PR_DestroyLock(object->refLock);)#ifdef NO_ARENA PORT_Free(object);#else PORT_FreeArena(arena,PR_FALSE);#endif return NULL; }#else object->attributeLock = NULL; object->refLock = NULL;#endif for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) { object->head[i] = NULL; } object->objectInfo = NULL; object->infoFree = NULL; return object;}/* * free all the data associated with an object. Object reference count must * be 'zero'. */static CK_RVpk11_DestroyObject(PK11Object *object){#if defined(REF_COUNT_ATTRIBUTE) || defined(NO_ARENA) int i;#endif SECItem pubKey; CK_RV crv = CKR_OK; SECStatus rv; PLArenaPool *arena = NULL; PORT_Assert(object->refCount == 0); /* delete the database value */ if (object->inDB) { if (pk11_isToken(object->handle)) { /* remove the objects from the real data base */ switch (object->handle & PK11_TOKEN_TYPE_MASK) { case PK11_TOKEN_TYPE_PRIV: /* KEYID is the public KEY for DSA and DH, and the MODULUS for * RSA */ crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB); if (crv != CKR_OK) break; rv = SECKEY_DeleteKey(SECKEY_GetDefaultKeyDB(), &pubKey); if (rv != SECSuccess) crv= CKR_DEVICE_ERROR; break; case PK11_TOKEN_TYPE_CERT: rv = SEC_DeletePermCertificate((CERTCertificate *)object->objectInfo); if (rv != SECSuccess) crv = CKR_DEVICE_ERROR; break; } } } if (object->label) PORT_Free(object->label); object->inDB = PR_FALSE; object->label = NULL;#ifdef NO_ARENA for (i=0; i < MAX_OBJS_ATTRS; i++) { unsigned char *value = object->attrList[i].attrib.pValue; if (value) { PORT_Memset(value,0,object->attrList[i].attrib.ulValueLen); if (value != object->attrList[i].space) { PORT_Free(value); } object->attrList[i].attrib.pValue = NULL; } }#endif#ifdef REF_COUNT_ATTRIBUTE /* clean out the attributes */ /* since no one is referencing us, it's safe to walk the chain * without a lock */ for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) { PK11Attribute *ap,*next; for (ap = object->head[i]; ap != NULL; ap = next) { next = ap->next; /* paranoia */ ap->next = ap->prev = NULL; pk11_FreeAttribute(ap); } object->head[i] = NULL; }#endif if (object->objectInfo) { (*object->infoFree)(object->objectInfo); }#ifdef NO_ARENA pk11_PutObjectToList(object);#else PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);) PK11_USE_THREADS(PR_DestroyLock(object->refLock);) arena = object->arena; PORT_FreeArena(arena,PR_FALSE);#endif return crv;}voidpk11_ReferenceObject(PK11Object *object){ PK11_USE_THREADS(PR_Lock(object->refLock);) object->refCount++; PK11_USE_THREADS(PR_Unlock(object->refLock);)}static PK11Object *pk11_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, PK11Slot *slot){ PK11Object **head; PRLock *lock; PK11Object *object; head = slot->tokObjects; lock = slot->objectLock; PK11_USE_THREADS(PR_Lock(lock);) pk11queue_find(object,handle,head,TOKEN_OBJECT_HASH_SIZE); if (object) { pk11_ReferenceObject(object); } PK11_USE_THREADS(PR_Unlock(lock);) 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. */PK11Object *pk11_ObjectFromHandle(CK_OBJECT_HANDLE handle, PK11Session *session){ PK11Slot *slot = pk11_SlotFromSession(session); return pk11_ObjectFromHandleOnSlot(handle,slot);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?