andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: /* andre@0: * Internal data structures and functions used by pkcs11.c andre@0: */ andre@0: #ifndef _PKCS11I_H_ andre@0: #define _PKCS11I_H_ 1 andre@0: andre@0: #include "nssilock.h" andre@0: #include "seccomon.h" andre@0: #include "secoidt.h" andre@0: #include "lowkeyti.h" andre@0: #include "pkcs11t.h" andre@0: andre@0: #include "sftkdbt.h" andre@0: #include "chacha20poly1305.h" andre@0: #include "hasht.h" andre@0: andre@0: /* andre@0: * Configuration Defines andre@0: * andre@0: * The following defines affect the space verse speed trade offs of andre@0: * the PKCS #11 module. For the most part the current settings are optimized andre@0: * for web servers, where we want faster speed and lower lock contention at andre@0: * the expense of space. andre@0: */ andre@0: andre@0: /* andre@0: * The attribute allocation strategy is static allocation: andre@0: * Attributes are pre-allocated as part of the session object and used from andre@0: * the object array. andre@0: */ andre@0: #define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in andre@0: * the object (must me the absolute max) */ andre@0: #define ATTR_SPACE 50 /* Maximum size of attribute data before extra andre@0: * data needs to be allocated. This is set to andre@0: * enough space to hold an SSL MASTER secret */ andre@0: andre@0: #define NSC_STRICT PR_FALSE /* forces the code to do strict template andre@0: * matching when doing C_FindObject on token andre@0: * objects. This will slow down search in andre@0: * NSS. */ andre@0: /* default search block allocations and increments */ andre@0: #define NSC_CERT_BLOCK_SIZE 50 andre@0: #define NSC_SEARCH_BLOCK_SIZE 5 andre@0: #define NSC_SLOT_LIST_BLOCK_SIZE 10 andre@0: andre@0: #define NSC_FIPS_MODULE 1 andre@0: #define NSC_NON_FIPS_MODULE 0 andre@0: andre@0: /* these are data base storage hashes, not cryptographic hashes.. The define andre@0: * the effective size of the various object hash tables */ andre@0: /* clients care more about memory usage than lookup performance on andre@0: * cyrptographic objects. Clients also have less objects around to play with andre@0: * andre@0: * we eventually should make this configurable at runtime! Especially now that andre@0: * NSS is a shared library. andre@0: */ andre@0: #define SPACE_ATTRIBUTE_HASH_SIZE 32 andre@0: #define SPACE_SESSION_OBJECT_HASH_SIZE 32 andre@0: #define SPACE_SESSION_HASH_SIZE 32 andre@0: #define TIME_ATTRIBUTE_HASH_SIZE 32 andre@0: #define TIME_SESSION_OBJECT_HASH_SIZE 1024 andre@0: #define TIME_SESSION_HASH_SIZE 1024 andre@0: #define MAX_OBJECT_LIST_SIZE 800 andre@0: /* how many objects to keep on the free list andre@0: * before we start freeing them */ andre@0: #define MAX_KEY_LEN 256 /* maximum symmetric key length in bytes */ andre@0: andre@0: /* andre@0: * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number. andre@0: * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0. andre@0: * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0. andre@0: * andre@0: * HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS andre@0: * 1024 9 512 2 andre@0: * 1024 5 32 32 andre@0: * 1024 1 2 512 andre@0: * 1024 0 1 1024 andre@0: * 4096 11 2048 2 andre@0: * 4096 9 512 8 andre@0: * 4096 5 32 128 andre@0: * 4096 1 2 2048 andre@0: * 4096 0 1 4096 andre@0: */ andre@0: #define LOG2_BUCKETS_PER_SESSION_LOCK 1 andre@0: #define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK)) andre@0: /* NOSPREAD sessionID to hash table index macro has been slower. */ andre@0: andre@0: /* define typedefs, double as forward declarations as well */ andre@0: typedef struct SFTKAttributeStr SFTKAttribute; andre@0: typedef struct SFTKObjectListStr SFTKObjectList; andre@0: typedef struct SFTKObjectFreeListStr SFTKObjectFreeList; andre@0: typedef struct SFTKObjectListElementStr SFTKObjectListElement; andre@0: typedef struct SFTKObjectStr SFTKObject; andre@0: typedef struct SFTKSessionObjectStr SFTKSessionObject; andre@0: typedef struct SFTKTokenObjectStr SFTKTokenObject; andre@0: typedef struct SFTKSessionStr SFTKSession; andre@0: typedef struct SFTKSlotStr SFTKSlot; andre@0: typedef struct SFTKSessionContextStr SFTKSessionContext; andre@0: typedef struct SFTKSearchResultsStr SFTKSearchResults; andre@0: typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo; andre@0: typedef struct SFTKHashSignInfoStr SFTKHashSignInfo; andre@0: typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo; andre@0: typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo; andre@0: typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo; andre@0: typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info; andre@0: typedef struct SFTKItemTemplateStr SFTKItemTemplate; andre@0: andre@0: /* define function pointer typdefs for pointer tables */ andre@0: typedef void (*SFTKDestroy)(void *, PRBool); andre@0: typedef void (*SFTKBegin)(void *); andre@0: typedef SECStatus (*SFTKCipher)(void *,void *,unsigned int *,unsigned int, andre@0: void *, unsigned int); andre@0: typedef SECStatus (*SFTKVerify)(void *,void *,unsigned int,void *,unsigned int); andre@0: typedef void (*SFTKHash)(void *,void *,unsigned int); andre@0: typedef void (*SFTKEnd)(void *,void *,unsigned int *,unsigned int); andre@0: typedef void (*SFTKFree)(void *); andre@0: andre@0: /* Value to tell if an attribute is modifiable or not. andre@0: * NEVER: attribute is only set on creation. andre@0: * ONCOPY: attribute is set on creation and can only be changed on copy. andre@0: * SENSITIVE: attribute can only be changed to TRUE. andre@0: * ALWAYS: attribute can always be changed. andre@0: */ andre@0: typedef enum { andre@0: SFTK_NEVER = 0, andre@0: SFTK_ONCOPY = 1, andre@0: SFTK_SENSITIVE = 2, andre@0: SFTK_ALWAYS = 3 andre@0: } SFTKModifyType; andre@0: andre@0: /* andre@0: * Free Status Enum... tell us more information when we think we're andre@0: * deleting an object. andre@0: */ andre@0: typedef enum { andre@0: SFTK_DestroyFailure, andre@0: SFTK_Destroyed, andre@0: SFTK_Busy andre@0: } SFTKFreeStatus; andre@0: andre@0: /* andre@0: * attribute values of an object. andre@0: */ andre@0: struct SFTKAttributeStr { andre@0: SFTKAttribute *next; andre@0: SFTKAttribute *prev; andre@0: PRBool freeAttr; andre@0: PRBool freeData; andre@0: /*must be called handle to make sftkqueue_find work */ andre@0: CK_ATTRIBUTE_TYPE handle; andre@0: CK_ATTRIBUTE attrib; andre@0: unsigned char space[ATTR_SPACE]; andre@0: }; andre@0: andre@0: andre@0: /* andre@0: * doubly link list of objects andre@0: */ andre@0: struct SFTKObjectListStr { andre@0: SFTKObjectList *next; andre@0: SFTKObjectList *prev; andre@0: SFTKObject *parent; andre@0: }; andre@0: andre@0: struct SFTKObjectFreeListStr { andre@0: SFTKObject *head; andre@0: PZLock *lock; andre@0: int count; andre@0: }; andre@0: andre@0: /* andre@0: * PKCS 11 crypto object structure andre@0: */ andre@0: struct SFTKObjectStr { andre@0: SFTKObject *next; andre@0: SFTKObject *prev; andre@0: CK_OBJECT_CLASS objclass; andre@0: CK_OBJECT_HANDLE handle; andre@0: int refCount; andre@0: PZLock *refLock; andre@0: SFTKSlot *slot; andre@0: void *objectInfo; andre@0: SFTKFree infoFree; andre@0: }; andre@0: andre@0: struct SFTKTokenObjectStr { andre@0: SFTKObject obj; andre@0: SECItem dbKey; andre@0: }; andre@0: andre@0: struct SFTKSessionObjectStr { andre@0: SFTKObject obj; andre@0: SFTKObjectList sessionList; andre@0: PZLock *attributeLock; andre@0: SFTKSession *session; andre@0: PRBool wasDerived; andre@0: int nextAttr; andre@0: SFTKAttribute attrList[MAX_OBJS_ATTRS]; andre@0: PRBool optimizeSpace; andre@0: unsigned int hashSize; andre@0: SFTKAttribute *head[1]; andre@0: }; andre@0: andre@0: /* andre@0: * struct to deal with a temparary list of objects andre@0: */ andre@0: struct SFTKObjectListElementStr { andre@0: SFTKObjectListElement *next; andre@0: SFTKObject *object; andre@0: }; andre@0: andre@0: /* andre@0: * Area to hold Search results andre@0: */ andre@0: struct SFTKSearchResultsStr { andre@0: CK_OBJECT_HANDLE *handles; andre@0: int size; andre@0: int index; andre@0: int array_size; andre@0: }; andre@0: andre@0: andre@0: /* andre@0: * the universal crypto/hash/sign/verify context structure andre@0: */ andre@0: typedef enum { andre@0: SFTK_ENCRYPT, andre@0: SFTK_DECRYPT, andre@0: SFTK_HASH, andre@0: SFTK_SIGN, andre@0: SFTK_SIGN_RECOVER, andre@0: SFTK_VERIFY, andre@0: SFTK_VERIFY_RECOVER andre@0: } SFTKContextType; andre@0: andre@0: /** max block size of supported block ciphers */ andre@0: #define SFTK_MAX_BLOCK_SIZE 16 andre@0: /** currently SHA512 is the biggest hash length */ andre@0: #define SFTK_MAX_MAC_LENGTH 64 andre@0: #define SFTK_INVALID_MAC_SIZE 0xffffffff andre@0: andre@0: /** Particular ongoing operation in session (sign/verify/digest/encrypt/...) andre@0: * andre@0: * Understanding sign/verify context: andre@0: * multi=1 hashInfo=0 block (symmetric) cipher MACing andre@0: * multi=1 hashInfo=X PKC S/V with prior hashing andre@0: * multi=0 hashInfo=0 PKC S/V one shot (w/o hashing) andre@0: * multi=0 hashInfo=X *** shouldn't happen *** andre@0: */ andre@0: struct SFTKSessionContextStr { andre@0: SFTKContextType type; andre@0: PRBool multi; /* is multipart */ andre@0: PRBool rsa; /* is rsa */ andre@0: PRBool doPad; /* use PKCS padding for block ciphers */ andre@0: unsigned int blockSize; /* blocksize for padding */ andre@0: unsigned int padDataLength; /* length of the valid data in padbuf */ andre@0: /** latest incomplete block of data for block cipher */ andre@0: unsigned char padBuf[SFTK_MAX_BLOCK_SIZE]; andre@0: /** result of MAC'ing of latest full block of data with block cipher */ andre@0: unsigned char macBuf[SFTK_MAX_BLOCK_SIZE]; andre@0: CK_ULONG macSize; /* size of a general block cipher mac*/ andre@0: void *cipherInfo; andre@0: void *hashInfo; andre@0: unsigned int cipherInfoLen; andre@0: CK_MECHANISM_TYPE currentMech; andre@0: SFTKCipher update; andre@0: SFTKHash hashUpdate; andre@0: SFTKEnd end; andre@0: SFTKDestroy destroy; andre@0: SFTKDestroy hashdestroy; andre@0: SFTKVerify verify; andre@0: unsigned int maxLen; andre@0: SFTKObject *key; andre@0: }; andre@0: andre@0: /* andre@0: * Sessions (have objects) andre@0: */ andre@0: struct SFTKSessionStr { andre@0: SFTKSession *next; andre@0: SFTKSession *prev; andre@0: CK_SESSION_HANDLE handle; andre@0: int refCount; andre@0: PZLock *objectLock; andre@0: int objectIDCount; andre@0: CK_SESSION_INFO info; andre@0: CK_NOTIFY notify; andre@0: CK_VOID_PTR appData; andre@0: SFTKSlot *slot; andre@0: SFTKSearchResults *search; andre@0: SFTKSessionContext *enc_context; andre@0: SFTKSessionContext *hash_context; andre@0: SFTKSessionContext *sign_context; andre@0: SFTKObjectList *objects[1]; andre@0: }; andre@0: andre@0: /* andre@0: * slots (have sessions and objects) andre@0: * andre@0: * The array of sessionLock's protect the session hash table (head[]) andre@0: * as well as the reference count of session objects in that bucket andre@0: * (head[]->refCount), objectLock protects all elements of the slot's andre@0: * object hash tables (sessObjHashTable[] and tokObjHashTable), and andre@0: * sessionObjectHandleCount. andre@0: * slotLock protects the remaining protected elements: andre@0: * password, isLoggedIn, ssoLoggedIn, and sessionCount, andre@0: * and pwCheckLock serializes the key database password checks in andre@0: * NSC_SetPIN and NSC_Login. andre@0: * andre@0: * Each of the fields below has the following lifetime as commented andre@0: * next to the fields: andre@0: * invariant - This value is set when the slot is first created and andre@0: * never changed until it is destroyed. andre@0: * per load - This value is set when the slot is first created, or andre@0: * when the slot is used to open another directory. Between open and close andre@0: * this field does not change. andre@0: * variable - This value changes through the normal process of slot operation. andre@0: * - reset. The value of this variable is cleared during an open/close andre@0: * cycles. andre@0: * - preserved. The value of this variable is preserved over open/close andre@0: * cycles. andre@0: */ andre@0: struct SFTKSlotStr { andre@0: CK_SLOT_ID slotID; /* invariant */ andre@0: PZLock *slotLock; /* invariant */ andre@0: PZLock **sessionLock; /* invariant */ andre@0: unsigned int numSessionLocks; /* invariant */ andre@0: unsigned long sessionLockMask; /* invariant */ andre@0: PZLock *objectLock; /* invariant */ andre@0: PRLock *pwCheckLock; /* invariant */ andre@0: PRBool present; /* variable -set */ andre@0: PRBool hasTokens; /* per load */ andre@0: PRBool isLoggedIn; /* variable - reset */ andre@0: PRBool ssoLoggedIn; /* variable - reset */ andre@0: PRBool needLogin; /* per load */ andre@0: PRBool DB_loaded; /* per load */ andre@0: PRBool readOnly; /* per load */ andre@0: PRBool optimizeSpace; /* invariant */ andre@0: SFTKDBHandle *certDB; /* per load */ andre@0: SFTKDBHandle *keyDB; /* per load */ andre@0: int minimumPinLen; /* per load */ andre@0: PRInt32 sessionIDCount; /* atomically incremented */ andre@0: /* (preserved) */ andre@0: int sessionIDConflict; /* not protected by a lock */ andre@0: /* (preserved) */ andre@0: int sessionCount; /* variable - reset */ andre@0: PRInt32 rwSessionCount; /* set by atomic operations */ andre@0: /* (reset) */ andre@0: int sessionObjectHandleCount;/* variable - perserved */ andre@0: int index; /* invariant */ andre@0: PLHashTable *tokObjHashTable; /* invariant */ andre@0: SFTKObject **sessObjHashTable; /* variable - reset */ andre@0: unsigned int sessObjHashSize; /* invariant */ andre@0: SFTKSession **head; /* variable -reset */ andre@0: unsigned int sessHashSize; /* invariant */ andre@0: char tokDescription[33]; /* per load */ andre@0: char updateTokDescription[33]; /* per load */ andre@0: char slotDescription[65]; /* invariant */ andre@0: }; andre@0: andre@0: /* andre@0: * special joint operations Contexts andre@0: */ andre@0: struct SFTKHashVerifyInfoStr { andre@0: SECOidTag hashOid; andre@0: void *params; andre@0: NSSLOWKEYPublicKey *key; andre@0: }; andre@0: andre@0: struct SFTKHashSignInfoStr { andre@0: SECOidTag hashOid; andre@0: void *params; andre@0: NSSLOWKEYPrivateKey *key; andre@0: }; andre@0: andre@0: /** andre@0: * Contexts for RSA-OAEP andre@0: */ andre@0: struct SFTKOAEPEncryptInfoStr { andre@0: CK_RSA_PKCS_OAEP_PARAMS *params; andre@0: NSSLOWKEYPublicKey *key; andre@0: }; andre@0: andre@0: struct SFTKOAEPDecryptInfoStr { andre@0: CK_RSA_PKCS_OAEP_PARAMS *params; andre@0: NSSLOWKEYPrivateKey *key; andre@0: }; andre@0: andre@0: /* context for the Final SSLMAC message */ andre@0: struct SFTKSSLMACInfoStr { andre@0: void *hashContext; andre@0: SFTKBegin begin; andre@0: SFTKHash update; andre@0: SFTKEnd end; andre@0: CK_ULONG macSize; andre@0: int padSize; andre@0: unsigned char key[MAX_KEY_LEN]; andre@0: unsigned int keySize; andre@0: }; andre@0: andre@0: /* SFTKChaCha20Poly1305Info saves the key, tag length, nonce, and additional andre@0: * data for a ChaCha20+Poly1305 AEAD operation. */ andre@0: struct SFTKChaCha20Poly1305InfoStr { andre@0: ChaCha20Poly1305Context freeblCtx; andre@0: unsigned char nonce[8]; andre@0: unsigned char ad[16]; andre@0: unsigned char *adOverflow; andre@0: unsigned int adLen; andre@0: }; andre@0: andre@0: /* andre@0: * Template based on SECItems, suitable for passing as arrays andre@0: */ andre@0: struct SFTKItemTemplateStr { andre@0: CK_ATTRIBUTE_TYPE type; andre@0: SECItem *item; andre@0: }; andre@0: andre@0: /* macro for setting SFTKTemplates. */ andre@0: #define SFTK_SET_ITEM_TEMPLATE(templ, count, itemPtr, attr) \ andre@0: templ[count].type = attr; \ andre@0: templ[count].item = itemPtr andre@0: andre@0: #define SFTK_MAX_ITEM_TEMPLATE 10 andre@0: andre@0: /* andre@0: * session handle modifiers andre@0: */ andre@0: #define SFTK_SESSION_SLOT_MASK 0xff000000L andre@0: andre@0: /* andre@0: * object handle modifiers andre@0: */ andre@0: #define SFTK_TOKEN_MASK 0x80000000L andre@0: #define SFTK_TOKEN_MAGIC 0x80000000L andre@0: #define SFTK_TOKEN_TYPE_MASK 0x70000000L andre@0: /* keydb (high bit == 0) */ andre@0: #define SFTK_TOKEN_TYPE_PRIV 0x10000000L andre@0: #define SFTK_TOKEN_TYPE_PUB 0x20000000L andre@0: #define SFTK_TOKEN_TYPE_KEY 0x30000000L andre@0: /* certdb (high bit == 1) */ andre@0: #define SFTK_TOKEN_TYPE_TRUST 0x40000000L andre@0: #define SFTK_TOKEN_TYPE_CRL 0x50000000L andre@0: #define SFTK_TOKEN_TYPE_SMIME 0x60000000L andre@0: #define SFTK_TOKEN_TYPE_CERT 0x70000000L andre@0: andre@0: #define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC|SFTK_TOKEN_TYPE_CRL|1) andre@0: /* how big (in bytes) a password/pin we can deal with */ andre@0: #define SFTK_MAX_PIN 255 andre@0: /* minimum password/pin length (in Unicode characters) in FIPS mode */ andre@0: #define FIPS_MIN_PIN 7 andre@0: andre@0: /* slot ID's */ andre@0: #define NETSCAPE_SLOT_ID 1 andre@0: #define PRIVATE_KEY_SLOT_ID 2 andre@0: #define FIPS_SLOT_ID 3 andre@0: andre@0: /* slot helper macros */ andre@0: #define sftk_SlotFromSession(sp) ((sp)->slot) andre@0: #define sftk_isToken(id) (((id) & SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC) andre@0: andre@0: /* the session hash multiplier (see bug 201081) */ andre@0: #define SHMULTIPLIER 1791398085 andre@0: andre@0: /* queueing helper macros */ andre@0: #define sftk_hash(value,size) \ andre@0: ((PRUint32)((value) * SHMULTIPLIER) & (size-1)) andre@0: #define sftkqueue_add(element,id,head,hash_size) \ andre@0: { int tmp = sftk_hash(id,hash_size); \ andre@0: (element)->next = (head)[tmp]; \ andre@0: (element)->prev = NULL; \ andre@0: if ((head)[tmp]) (head)[tmp]->prev = (element); \ andre@0: (head)[tmp] = (element); } andre@0: #define sftkqueue_find(element,id,head,hash_size) \ andre@0: for( (element) = (head)[sftk_hash(id,hash_size)]; (element) != NULL; \ andre@0: (element) = (element)->next) { \ andre@0: if ((element)->handle == (id)) { break; } } andre@0: #define sftkqueue_is_queued(element,id,head,hash_size) \ andre@0: ( ((element)->next) || ((element)->prev) || \ andre@0: ((head)[sftk_hash(id,hash_size)] == (element)) ) andre@0: #define sftkqueue_delete(element,id,head,hash_size) \ andre@0: if ((element)->next) (element)->next->prev = (element)->prev; \ andre@0: if ((element)->prev) (element)->prev->next = (element)->next; \ andre@0: else (head)[sftk_hash(id,hash_size)] = ((element)->next); \ andre@0: (element)->next = NULL; \ andre@0: (element)->prev = NULL; \ andre@0: andre@0: #define sftkqueue_init_element(element) \ andre@0: (element)->prev = NULL; andre@0: andre@0: #define sftkqueue_add2(element, id, index, head) \ andre@0: { \ andre@0: (element)->next = (head)[index]; \ andre@0: if ((head)[index]) \ andre@0: (head)[index]->prev = (element); \ andre@0: (head)[index] = (element); \ andre@0: } andre@0: andre@0: #define sftkqueue_find2(element, id, index, head) \ andre@0: for ( (element) = (head)[index]; \ andre@0: (element) != NULL; \ andre@0: (element) = (element)->next) { \ andre@0: if ((element)->handle == (id)) { break; } \ andre@0: } andre@0: andre@0: #define sftkqueue_delete2(element, id, index, head) \ andre@0: if ((element)->next) (element)->next->prev = (element)->prev; \ andre@0: if ((element)->prev) (element)->prev->next = (element)->next; \ andre@0: else (head)[index] = ((element)->next); andre@0: andre@0: #define sftkqueue_clear_deleted_element(element) \ andre@0: (element)->next = NULL; \ andre@0: (element)->prev = NULL; \ andre@0: andre@0: andre@0: /* sessionID (handle) is used to determine session lock bucket */ andre@0: #ifdef NOSPREAD andre@0: /* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */ andre@0: #define SFTK_SESSION_LOCK(slot,handle) \ andre@0: ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) \ andre@0: & (slot)->sessionLockMask]) andre@0: #else andre@0: /* SPREAD: ID & (perbucket-1) */ andre@0: #define SFTK_SESSION_LOCK(slot,handle) \ andre@0: ((slot)->sessionLock[(handle) & (slot)->sessionLockMask]) andre@0: #endif andre@0: andre@0: /* expand an attribute & secitem structures out */ andre@0: #define sftk_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen andre@0: #define sftk_item_expand(ip) (ip)->data,(ip)->len andre@0: andre@0: typedef struct sftk_token_parametersStr { andre@0: CK_SLOT_ID slotID; andre@0: char *configdir; andre@0: char *certPrefix; andre@0: char *keyPrefix; andre@0: char *updatedir; andre@0: char *updCertPrefix; andre@0: char *updKeyPrefix; andre@0: char *updateID; andre@0: char *tokdes; andre@0: char *slotdes; andre@0: char *updtokdes; andre@0: int minPW; andre@0: PRBool readOnly; andre@0: PRBool noCertDB; andre@0: PRBool noKeyDB; andre@0: PRBool forceOpen; andre@0: PRBool pwRequired; andre@0: PRBool optimizeSpace; andre@0: } sftk_token_parameters; andre@0: andre@0: typedef struct sftk_parametersStr { andre@0: char *configdir; andre@0: char *updatedir; andre@0: char *updateID; andre@0: char *secmodName; andre@0: char *man; andre@0: char *libdes; andre@0: PRBool readOnly; andre@0: PRBool noModDB; andre@0: PRBool noCertDB; andre@0: PRBool forceOpen; andre@0: PRBool pwRequired; andre@0: PRBool optimizeSpace; andre@0: sftk_token_parameters *tokens; andre@0: int token_count; andre@0: } sftk_parameters; andre@0: andre@0: andre@0: /* path stuff (was machine dependent) used by dbinit.c and pk11db.c */ andre@0: #define CERT_DB_FMT "%scert%s.db" andre@0: #define KEY_DB_FMT "%skey%s.db" andre@0: andre@0: SEC_BEGIN_PROTOS andre@0: andre@0: /* shared functions between pkcs11.c and fipstokn.c */ andre@0: extern PRBool nsf_init; andre@0: extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS); andre@0: extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS); andre@0: extern PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV* crv); andre@0: extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent, andre@0: CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex); andre@0: andre@0: /* slot initialization, reinit, shutdown and destruction */ andre@0: extern CK_RV SFTK_SlotInit(char *configdir, char *updatedir, char *updateID, andre@0: sftk_token_parameters *params, int moduleIndex); andre@0: extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir, andre@0: char *updatedir, char *updateID, andre@0: sftk_token_parameters *params, int moduleIndex); andre@0: extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot); andre@0: extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot); andre@0: extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout); andre@0: andre@0: andre@0: /* internal utility functions used by pkcs11.c */ andre@0: extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object, andre@0: CK_ATTRIBUTE_TYPE type); andre@0: extern void sftk_FreeAttribute(SFTKAttribute *attribute); andre@0: extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type, andre@0: const void *valPtr, CK_ULONG length); andre@0: extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, andre@0: SFTKObject *object, CK_ATTRIBUTE_TYPE type); andre@0: extern CK_RV sftk_MultipleAttribute2SecItem(PLArenaPool *arena, andre@0: SFTKObject *object, SFTKItemTemplate *templ, int count); andre@0: extern unsigned int sftk_GetLengthInBits(unsigned char *buf, andre@0: unsigned int bufLen); andre@0: extern CK_RV sftk_ConstrainAttribute(SFTKObject *object, andre@0: CK_ATTRIBUTE_TYPE type, int minLength, int maxLength, int minMultiple); andre@0: extern PRBool sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type); andre@0: extern PRBool sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type); andre@0: extern void sftk_DeleteAttributeType(SFTKObject *object, andre@0: CK_ATTRIBUTE_TYPE type); andre@0: extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, andre@0: SFTKObject *object, CK_ATTRIBUTE_TYPE type); andre@0: extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item, andre@0: SFTKObject *object, andre@0: CK_ATTRIBUTE_TYPE type); andre@0: extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type, andre@0: CK_OBJECT_CLASS inClass); andre@0: extern PRBool sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass); andre@0: extern char *sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type); andre@0: extern void sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type); andre@0: extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, andre@0: CK_ULONG *longData); andre@0: extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, andre@0: const void *value, unsigned int len); andre@0: extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, andre@0: const void *value, unsigned int len); andre@0: extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth); andre@0: andre@0: extern SFTKObject *sftk_NewObject(SFTKSlot *slot); andre@0: extern CK_RV sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject); andre@0: extern SFTKFreeStatus sftk_FreeObject(SFTKObject *object); andre@0: extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object); andre@0: extern void sftk_ReferenceObject(SFTKObject *object); andre@0: extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, andre@0: SFTKSession *session); andre@0: extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object); andre@0: extern void sftk_AddObject(SFTKSession *session, SFTKObject *object); andre@0: /* clear out all the existing object ID to database key mappings. andre@0: * used to reinit a token */ andre@0: extern CK_RV SFTK_ClearTokenKeyHashTable(SFTKSlot *slot); andre@0: andre@0: extern CK_RV sftk_searchObjectList(SFTKSearchResults *search, andre@0: SFTKObject **head, unsigned int size, andre@0: PZLock *lock, CK_ATTRIBUTE_PTR inTemplate, andre@0: int count, PRBool isLoggedIn); andre@0: extern SFTKObjectListElement *sftk_FreeObjectListElement( andre@0: SFTKObjectListElement *objectList); andre@0: extern void sftk_FreeObjectList(SFTKObjectListElement *objectList); andre@0: extern void sftk_FreeSearch(SFTKSearchResults *search); andre@0: extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session); andre@0: andre@0: extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all); andre@0: extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle); andre@0: extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); andre@0: extern void sftk_FreeSession(SFTKSession *session); andre@0: extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, andre@0: CK_VOID_PTR pApplication, CK_FLAGS flags); andre@0: extern void sftk_update_state(SFTKSlot *slot,SFTKSession *session); andre@0: extern void sftk_update_all_states(SFTKSlot *slot); andre@0: extern void sftk_FreeContext(SFTKSessionContext *context); andre@0: extern void sftk_InitFreeLists(void); andre@0: extern void sftk_CleanupFreeLists(void); andre@0: andre@0: extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object, andre@0: CK_KEY_TYPE key_type, CK_RV *crvp); andre@0: extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object, andre@0: CK_KEY_TYPE key_type, CK_RV *crvp); andre@0: extern void sftk_FormatDESKey(unsigned char *key, int length); andre@0: extern PRBool sftk_CheckDESKey(unsigned char *key); andre@0: extern PRBool sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type); andre@0: andre@0: /* mechanism allows this operation */ andre@0: extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op); andre@0: andre@0: /* helper function which calls nsslowkey_FindKeyByPublicKey after safely andre@0: * acquiring a reference to the keydb from the slot */ andre@0: NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey); andre@0: andre@0: /* andre@0: * parameter parsing functions andre@0: */ andre@0: CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS); andre@0: void sftk_freeParams(sftk_parameters *params); andre@0: andre@0: andre@0: /* andre@0: * narrow objects andre@0: */ andre@0: SFTKSessionObject * sftk_narrowToSessionObject(SFTKObject *); andre@0: SFTKTokenObject * sftk_narrowToTokenObject(SFTKObject *); andre@0: andre@0: /* andre@0: * token object utilities andre@0: */ andre@0: void sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle); andre@0: PRBool sftk_poisonHandle(SFTKSlot *slot, SECItem *dbkey, andre@0: CK_OBJECT_HANDLE handle); andre@0: SFTKObject * sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, andre@0: CK_OBJECT_HANDLE handle); andre@0: SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so); andre@0: andre@0: andre@0: /* J-PAKE (jpakesftk.c) */ andre@0: extern andre@0: CK_RV jpake_Round1(HASH_HashType hashType, andre@0: CK_NSS_JPAKERound1Params * params, andre@0: SFTKObject * key); andre@0: extern andre@0: CK_RV jpake_Round2(HASH_HashType hashType, andre@0: CK_NSS_JPAKERound2Params * params, andre@0: SFTKObject * sourceKey, SFTKObject * key); andre@0: extern andre@0: CK_RV jpake_Final(HASH_HashType hashType, andre@0: const CK_NSS_JPAKEFinalParams * params, andre@0: SFTKObject * sourceKey, SFTKObject * key); andre@0: andre@0: /* Constant time MAC functions (hmacct.c) */ andre@0: andre@0: struct sftk_MACConstantTimeCtxStr { andre@0: const SECHashObject *hash; andre@0: unsigned char mac[64]; andre@0: unsigned char secret[64]; andre@0: unsigned int headerLength; andre@0: unsigned int secretLength; andre@0: unsigned int totalLength; andre@0: unsigned char header[75]; andre@0: }; andre@0: typedef struct sftk_MACConstantTimeCtxStr sftk_MACConstantTimeCtx; andre@0: sftk_MACConstantTimeCtx* sftk_HMACConstantTime_New( andre@0: CK_MECHANISM_PTR mech, SFTKObject *key); andre@0: sftk_MACConstantTimeCtx* sftk_SSLv3MACConstantTime_New( andre@0: CK_MECHANISM_PTR mech, SFTKObject *key); andre@0: void sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len); andre@0: void sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len); andre@0: void sftk_MACConstantTime_EndHash( andre@0: void *pctx, void *out, unsigned int *outLength, unsigned int maxLength); andre@0: void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool); andre@0: andre@0: /**************************************** andre@0: * implement TLS Pseudo Random Function (PRF) andre@0: */ andre@0: andre@0: extern CK_RV andre@0: sftk_TLSPRFInit(SFTKSessionContext *context, andre@0: SFTKObject * key, andre@0: CK_KEY_TYPE key_type, andre@0: HASH_HashType hash_alg); andre@0: andre@0: SEC_END_PROTOS andre@0: andre@0: #endif /* _PKCS11I_H_ */