diff options
author | relyea%netscape.com <devnull@localhost> | 2002-02-03 03:37:26 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2002-02-03 03:37:26 +0000 |
commit | 4cd8747f6ed708dc205b0fe3074339e102b09961 (patch) | |
tree | 4de239719ac9a3e5b3974eaab38c5e27001d04f4 | |
parent | 8fffebcd84eb23926d3c36984e0c656169fa71f7 (diff) | |
download | nss-hg-4cd8747f6ed708dc205b0fe3074339e102b09961.tar.gz |
Bug 117978: accessor functions to all JCE keystore API to be implemented.
-rw-r--r-- | security/nss/lib/cryptohi/keyhi.h | 17 | ||||
-rw-r--r-- | security/nss/lib/cryptohi/keythi.h | 9 | ||||
-rw-r--r-- | security/nss/lib/cryptohi/seckey.c | 93 | ||||
-rw-r--r-- | security/nss/lib/nss/nss.def | 14 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 133 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11func.h | 38 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11kea.c | 3 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11skey.c | 101 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11slot.c | 53 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/secmodi.h | 2 |
10 files changed, 438 insertions, 25 deletions
diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h index 051591580..844a44877 100644 --- a/security/nss/lib/cryptohi/keyhi.h +++ b/security/nss/lib/cryptohi/keyhi.h @@ -251,6 +251,23 @@ SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list, #define PRIVKEY_LIST_NEXT(n) ((SECKEYPrivateKeyListNode *)n->links.next) #define PRIVKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) +SECKEYPublicKeyList* +SECKEY_NewPublicKeyList(void); + +void +SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys); + +void +SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node); + +SECStatus +SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list, + SECKEYPublicKey *key); + +#define PUBKEY_LIST_HEAD(l) ((SECKEYPublicKeyListNode*)PR_LIST_HEAD(&l->list)) +#define PUBKEY_LIST_NEXT(n) ((SECKEYPublicKeyListNode *)n->links.next) +#define PUBKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) + SEC_END_PROTOS #endif /* _KEYHI_H_ */ diff --git a/security/nss/lib/cryptohi/keythi.h b/security/nss/lib/cryptohi/keythi.h index 9a7f9c9ea..7b864b868 100644 --- a/security/nss/lib/cryptohi/keythi.h +++ b/security/nss/lib/cryptohi/keythi.h @@ -210,5 +210,14 @@ typedef struct { PRArenaPool *arena; } SECKEYPrivateKeyList; +typedef struct { + PRCList links; + SECKEYPublicKey *key; +} SECKEYPublicKeyListNode; + +typedef struct { + PRCList list; + PRArenaPool *arena; +} SECKEYPublicKeyList; #endif /* _KEYTHI_H_ */ diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c index adaa398e6..271c9fb1f 100644 --- a/security/nss/lib/cryptohi/seckey.c +++ b/security/nss/lib/cryptohi/seckey.c @@ -209,7 +209,9 @@ SECKEY_DestroyPublicKey(SECKEYPublicKey *pubk) { if (pubk) { if (pubk->pkcs11Slot) { - PK11_DestroyObject(pubk->pkcs11Slot,pubk->pkcs11ID); + if (!PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { + PK11_DestroyObject(pubk->pkcs11Slot,pubk->pkcs11ID); + } PK11_FreeSlot(pubk->pkcs11Slot); } if (pubk->arena) { @@ -1072,8 +1074,14 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk) copyk->arena = arena; copyk->keyType = pubk->keyType; - copyk->pkcs11Slot = NULL; /* go get own reference */ - copyk->pkcs11ID = CK_INVALID_HANDLE; + if (pubk->pkcs11Slot && + PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { + copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); + copyk->pkcs11ID = pubk->pkcs11ID; + } else { + copyk->pkcs11Slot = NULL; /* go get own reference */ + copyk->pkcs11ID = CK_INVALID_HANDLE; + } switch (pubk->keyType) { case rsaKey: rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, @@ -1504,7 +1512,7 @@ SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge, CERTSignedData sd; SECItem sig; SECKEYPublicKey *pubKey = NULL; - int len; + unsigned int len; signedItem.data = NULL; @@ -1823,3 +1831,80 @@ SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list, loser: return(SECFailure); } + + +SECKEYPublicKeyList* +SECKEY_NewPublicKeyList(void) +{ + PRArenaPool *arena = NULL; + SECKEYPublicKeyList *ret = NULL; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if ( arena == NULL ) { + goto loser; + } + + ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena, + sizeof(SECKEYPublicKeyList)); + if ( ret == NULL ) { + goto loser; + } + + ret->arena = arena; + + PR_INIT_CLIST(&ret->list); + + return(ret); + +loser: + if ( arena != NULL ) { + PORT_FreeArena(arena, PR_FALSE); + } + + return(NULL); +} + +void +SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys) +{ + while( !PR_CLIST_IS_EMPTY(&keys->list) ) { + SECKEY_RemovePublicKeyListNode( + (SECKEYPublicKeyListNode*)(PR_LIST_HEAD(&keys->list)) ); + } + + PORT_FreeArena(keys->arena, PR_FALSE); + + return; +} + + +void +SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node) +{ + PR_ASSERT(node->key); + SECKEY_DestroyPublicKey(node->key); + node->key = NULL; + PR_REMOVE_LINK(&node->links); + return; + +} + +SECStatus +SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list, + SECKEYPublicKey *key) +{ + SECKEYPublicKeyListNode *node; + + node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena, + sizeof(SECKEYPublicKeyListNode)); + if ( node == NULL ) { + goto loser; + } + + PR_INSERT_BEFORE(&node->links, &list->list); + node->key = key; + return(SECSuccess); + +loser: + return(SECFailure); +} diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index c6ae99675..e29a8c827 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -630,7 +630,21 @@ NSS_Get_SEC_SignedCertificateTemplate; NSS_Get_SEC_UTF8StringTemplate; ;+# for JSS PK11_ImportDERPrivateKeyInfoAndReturnKey; +PK11_ImportPublicKey; PK11_ImportPrivateKeyInfoAndReturnKey; +PK11_ImportSymKeyWithFlags; +PK11_ListPublicKeysInSlot; +PK11_ListPrivKeysInSlot; +PK11_ListFixedKeysInSlot; +PK11_DeleteTokenPrivateKey; +PK11_DeleteTokenPublicKey; +PK11_DeleteTokenSymKey; +PK11_GetSymKeyNickname; +PK11_GetPublicKeyNickname; +PK11_GetPrivateKeyNickname; +PK11_SetSymKeyNickname; +PK11_SetPublicKeyNickname; +PK11_SetPrivateKeyNickname; SECKEY_DecodeDERSubjectPublicKeyInfo; ;+# for debugging nss_DumpCertificateCacheInfo; diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index d2f2c7591..5fe17e5b8 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -684,8 +684,9 @@ CERTCertificate * PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey) { PK11SlotInfo *slot = privKey->pkcs11Slot; + CK_OBJECT_HANDLE handle = privKey->pkcs11ID; CK_OBJECT_HANDLE certID = - PK11_MatchItem(slot,privKey->pkcs11ID,CKO_CERTIFICATE); + PK11_MatchItem(slot,handle,CKO_CERTIFICATE); SECStatus rv; CERTCertificate *cert; @@ -693,7 +694,7 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey) /* couldn't find it on the card, look in our data base */ SECItem derSubject; - rv = PK11_ReadAttribute(slot, privKey->pkcs11ID, CKA_SUBJECT, NULL, + rv = PK11_ReadAttribute(slot, handle, CKA_SUBJECT, NULL, &derSubject); if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_NO_CERTIFICATE); @@ -714,12 +715,12 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey) * this function also frees the privKey structure. */ SECStatus -PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey) +PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force) { CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey); /* found a cert matching the private key?. */ - if (cert != NULL) { + if (!force && cert != NULL) { /* yes, don't delete the key */ CERT_DestroyCertificate(cert); SECKEY_DestroyPrivateKey(privKey); @@ -731,6 +732,22 @@ PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey) return SECSuccess; } +/* + * destroy a private key if there are no matching certs. + * this function also frees the privKey structure. + */ +SECStatus +PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey) +{ + /* now, then it's safe for the key to go away */ + if (pubKey->pkcs11Slot == NULL) { + return SECFailure; + } + PK11_DestroyTokenObject(pubKey->pkcs11Slot,pubKey->pkcs11ID); + SECKEY_DestroyPublicKey(pubKey); + return SECSuccess; +} + /* * delete a cert and it's private key (if no other certs are pointing to the @@ -751,7 +768,7 @@ PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx) /* For 3.4, utilize the generic cert delete function */ SEC_DeletePermCertificate(cert); #endif - PK11_DeleteTokenPrivateKey(privKey); + PK11_DeleteTokenPrivateKey(privKey, PR_FALSE); } if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) { PK11_DestroyTokenObject(slot,pubKey); @@ -932,7 +949,6 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) return rv; } - /* Traverse slots callback */ typedef struct pk11TraverseSlotStr { SECStatus (*callback)(PK11SlotInfo *,CK_OBJECT_HANDLE, void *); @@ -1098,12 +1114,16 @@ PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot, pk11KeyCallback perKeyCB; pk11TraverseSlot perObjectCB; CK_OBJECT_CLASS privkClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE theTemplate[1]; - int templateSize = 1; + CK_BBOOL ckTrue = CK_TRUE; + CK_ATTRIBUTE theTemplate[2]; + int templateSize = 2; theTemplate[0].type = CKA_CLASS; theTemplate[0].pValue = &privkClass; theTemplate[0].ulValueLen = sizeof(privkClass); + theTemplate[1].type = CKA_TOKEN; + theTemplate[1].pValue = &ckTrue; + theTemplate[1].ulValueLen = sizeof(ckTrue); if(slot==NULL) { return SECSuccess; @@ -3487,8 +3507,14 @@ static SECStatus listCertsCallback(CERTCertificate* cert, void*arg) { CERTCertList *list = (CERTCertList*)arg; + char *nickname = NULL; + + if (cert->nickname) { + nickname = PORT_ArenaStrdup(list->arena,cert->nickname); + } - return CERT_AddCertToListTail(list, CERT_DupCertificate(cert)); + return CERT_AddCertToListTailWithData(list, + CERT_DupCertificate(cert),nickname); } CERTCertList * @@ -3515,7 +3541,6 @@ static SECStatus privateKeyListCallback(SECKEYPrivateKey *key, void *arg) { SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList*)arg; - return SECKEY_AddPrivateKeyToListTail(list, SECKEY_CopyPrivateKey(key)); } @@ -3539,6 +3564,94 @@ PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot) return keys; } +SECKEYPublicKeyList* +PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname) +{ + CK_ATTRIBUTE findTemp[4]; + CK_ATTRIBUTE *attrs; + CK_BBOOL ckTrue = CK_TRUE; + CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY; + int tsize = 0; + int objCount = 0; + CK_OBJECT_HANDLE *key_ids; + SECStatus status; + SECKEYPublicKeyList *keys; + int i,len; + + + attrs = findTemp; + PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; + if (nickname) { + len = PORT_Strlen(nickname)-1; + PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; + } + tsize = attrs - findTemp; + PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); + + key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); + if (key_ids == NULL) { + return NULL; + } + keys = SECKEY_NewPublicKeyList(); + if (keys == NULL) { + PORT_Free(key_ids); + } + + for (i=0; i < objCount ; i++) { + SECKEYPublicKey *pubKey = + PK11_ExtractPublicKey(slot,nullKey,key_ids[i]); + SECKEY_AddPublicKeyToListTail(keys, pubKey); + } + + PORT_Free(key_ids); + return keys; +} + +SECKEYPrivateKeyList* +PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) +{ + CK_ATTRIBUTE findTemp[4]; + CK_ATTRIBUTE *attrs; + CK_BBOOL ckTrue = CK_TRUE; + CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY; + int tsize = 0; + int objCount = 0; + CK_OBJECT_HANDLE *key_ids; + SECStatus status; + SECKEYPrivateKeyList *keys; + int i,len; + + + attrs = findTemp; + PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; + if (nickname) { + len = PORT_Strlen(nickname)-1; + PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; + } + tsize = attrs - findTemp; + PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); + + key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); + if (key_ids == NULL) { + return NULL; + } + keys = SECKEY_NewPrivateKeyList(); + if (keys == NULL) { + PORT_Free(key_ids); + } + + for (i=0; i < objCount ; i++) { + SECKEYPrivateKey *privKey = + PK11_MakePrivKey(slot,nullKey,PR_TRUE,key_ids[i],wincx); + SECKEY_AddPrivateKeyToListTail(keys, privKey); + } + + PORT_Free(key_ids); + return keys; +} + /* * return the certificate associated with a derCert */ diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h index c9093df83..e0b2cb886 100644 --- a/security/nss/lib/pk11wrap/pk11func.h +++ b/security/nss/lib/pk11wrap/pk11func.h @@ -231,7 +231,10 @@ PK11SymKey *PK11_CreateSymKey(PK11SlotInfo *slot, void PK11_FreeSymKey(PK11SymKey *key); PK11SymKey *PK11_ReferenceSymKey(PK11SymKey *symKey); PK11SymKey *PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,void *wincx); + PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx); +PK11SymKey *PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, + CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, + SECItem *key, CK_FLAGS flags, PRBool isPerm, void *wincx); PK11SymKey *PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin, CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx); @@ -243,6 +246,8 @@ CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey, PRBool isToken); PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, SECItem *param, int keySize,void *wincx); +PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, + void *wincx); /* Key Generation specialized for SDR (fixed DES3 key) */ PK11SymKey *PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx); @@ -272,11 +277,23 @@ PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID, void *wincx); -SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey); +SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey,PRBool force); +SECStatus PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey); +SECStatus PK11_DeleteTokenSymKey(PK11SymKey *symKey); SECStatus PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx); SECKEYPrivateKey * PK11_LoadPrivKey(PK11SlotInfo *slot, SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive); +SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, + CK_OBJECT_HANDLE id); +char * PK11_GetSymKeyNickname(PK11SymKey *symKey); +char * PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey); +char * PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey); +SECStatus PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname); +SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, + const char *nickname); +SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, + const char *nickname); /* size to hold key in bytes */ unsigned int PK11_GetKeyLength(PK11SymKey *key); @@ -353,6 +370,11 @@ SECItem * PK11_GetKeyIDFromPrivateKey(SECKEYPrivateKey *key, void *wincx); SECItem* PK11_DEREncodePublicKey(SECKEYPublicKey *pubk); PK11SymKey* PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech); +SECKEYPrivateKeyList* PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, + char *nickname, void *wincx); +SECKEYPublicKeyList* PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, + char *nickname); +/* depricated */ SECKEYPrivateKeyList* PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot); /********************************************************************** @@ -421,10 +443,8 @@ SECStatus PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, void *arg); SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot, SECStatus(* callback)(CERTCertificate*, void *), void *arg); -CERTCertList * -PK11_ListCerts(PK11CertListType type, void *pwarg); -CERTCertList * -PK11_ListCertsInSlot(PK11SlotInfo *slot); +CERTCertList * PK11_ListCerts(PK11CertListType type, void *pwarg); +CERTCertList * PK11_ListCertsInSlot(PK11SlotInfo *slot); SECStatus PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx); @@ -523,6 +543,12 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, PRBool SECMOD_HasRootCerts(void); +PRBool PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle); + +char * PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id) ; +SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, + const char *nickname) ; + SEC_END_PROTOS #endif diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c index b5b810d0b..d6046bd99 100644 --- a/security/nss/lib/pk11wrap/pk11kea.c +++ b/security/nss/lib/pk11wrap/pk11kea.c @@ -68,9 +68,6 @@ pk11_FindRSAPubKey(PK11SlotInfo *slot) return pk11_FindObjectByTemplate(slot,theTemplate,template_count); } -SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, - CK_OBJECT_HANDLE id); - PK11SymKey * pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index 1d5dc2c4e..96772f82e 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -471,13 +471,14 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, return symKey; } + /* * turn key bits into an appropriate key object */ PK11SymKey * PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, - CK_FLAGS flags, void *wincx) + CK_FLAGS flags, PRBool isPerm, void *wincx) { PK11SymKey * symKey; unsigned int templateCount = 0; @@ -489,6 +490,9 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; + if (isPerm) { + PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(keyType) ); attrs++; + } templateCount = attrs - keyTemplate; templateCount += pk11_FlagsToAttributes(flags, attrs, &cktrue); PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); @@ -496,6 +500,9 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, keyType = PK11_GetKeyType(type,key->len); symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, keyTemplate, templateCount, key, wincx); + if (isPerm) { + symKey->owner = PR_FALSE; + } return symKey; } @@ -655,6 +662,47 @@ PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID, PR_FALSE, wincx); } +PK11SymKey * +PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) +{ + CK_ATTRIBUTE findTemp[4]; + CK_ATTRIBUTE *attrs; + CK_BBOOL ckTrue = CK_TRUE; + CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; + int tsize = 0; + int objCount = 0; + CK_OBJECT_HANDLE *key_ids; + PK11SymKey *nextKey = NULL; + PK11SymKey *topKey = NULL; + int i,len; + + attrs = findTemp; + PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; + if (nickname) { + len = PORT_Strlen(nickname)-1; + PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; + } + tsize = attrs - findTemp; + PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); + + key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); + if (key_ids == NULL) { + return NULL; + } + + for (i=0; i < objCount ; i++) { + nextKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, + CKM_INVALID_MECHANISM, key_ids[i], PR_FALSE, wincx); + if (nextKey) { + nextKey->next = topKey; + topKey = nextKey; + } + } + PORT_Free(key_ids); + return topKey; +} + void * PK11_GetWindow(PK11SymKey *key) { @@ -681,6 +729,17 @@ PK11_ExtractKeyValue(PK11SymKey *symKey) &symKey->data); } +SECStatus +PK11_DeleteTokenSymKey(PK11SymKey *symKey) +{ + if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) { + return SECFailure; + } + PK11_DestroyTokenObject(symKey->slot,symKey->objectID); + symKey->objectID = CK_INVALID_HANDLE; + return SECSuccess; +} + SECItem * __PK11_GetKeyData(PK11SymKey *symKey) { @@ -3590,7 +3649,7 @@ PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength) PR_FALSE,PR_FALSE); PK11_ExitContextMonitor(cx); if (data) *len = length; - } else if (saveLength >= cx->savedLength) { + } else if ((unsigned) saveLength >= cx->savedLength) { data = (unsigned char*)cx->savedData; if (cx->savedData) { PORT_Memcpy(save,cx->savedData,cx->savedLength); @@ -4796,3 +4855,41 @@ PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech) return pk11_CopyToSlot(PK11_GetSlotFromKey(originalKey), mech, CKA_SIGN, originalKey); } + +char * +PK11_GetSymKeyNickname(PK11SymKey *symKey) +{ + return PK11_GetObjectNickname(symKey->slot,symKey->objectID); +} + +char * +PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey) +{ + return PK11_GetObjectNickname(privKey->pkcs11Slot,privKey->pkcs11ID); +} + +char * +PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey) +{ + return PK11_GetObjectNickname(pubKey->pkcs11Slot,pubKey->pkcs11ID); +} + +SECStatus +PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname) +{ + return PK11_SetObjectNickname(symKey->slot,symKey->objectID,nickname); +} + +SECStatus +PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname) +{ + return PK11_SetObjectNickname(privKey->pkcs11Slot, + privKey->pkcs11ID,nickname); +} + +SECStatus +PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname) +{ + return PK11_SetObjectNickname(pubKey->pkcs11Slot, + pubKey->pkcs11ID,nickname); +} diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index c76ba8bbe..82a48c68d 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -4369,3 +4369,56 @@ have_key_len: return CKR_OK; } + +PRBool +PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle) +{ + return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN); +} + +char * +PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id) +{ + char *nickname = NULL; + SECItem result; + SECStatus rv; + + rv = PK11_ReadAttribute(slot,id,CKA_LABEL,NULL,&result); + if (rv != SECSuccess) { + return NULL; + } + + nickname = PORT_ZAlloc(result.len); + if (nickname == NULL) { + PORT_Free(result.data); + return NULL; + } + PORT_Memcpy(nickname, result.data, result.len); + PORT_Free(result.data); + return nickname; +} + +SECStatus +PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, + const char *nickname) +{ + int len = PORT_Strlen(nickname)-1; + CK_ATTRIBUTE setTemplate; + CK_RV crv; + + if (len < 0) { + return SECFailure; + } + + PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *) nickname, len); + PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_SetAttributeValue(slot->session, id, + &setTemplate, 1); + PK11_ExitSlotMonitor(slot); + if (crv != CKR_OK) { + PK11_ExitSlotMonitor(slot); + PORT_SetError(PK11_MapError(crv)); + return SECFailure; + } + return SECSuccess; +} diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h index 087d072f2..685af1c2f 100644 --- a/security/nss/lib/pk11wrap/secmodi.h +++ b/security/nss/lib/pk11wrap/secmodi.h @@ -89,6 +89,8 @@ CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event, void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib); CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *inTemplate,int tsize); +CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot, + CK_ATTRIBUTE *inTemplate,int tsize, int *objCount); SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot, PK11DefaultArrayEntry *entry, PRBool add); |