зеркало из https://github.com/mozilla/pjs.git
cleanup; add nssSession type to allow multiple sessions accessing the token API
This commit is contained in:
Родитель
75f90bba49
Коммит
4ddecbc706
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:07 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.2 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef PKIT_H
|
||||
|
@ -55,20 +55,25 @@ static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.1 $ $Da
|
|||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_BBOOL
|
||||
g_ck_true = CK_TRUE;
|
||||
static const CK_BBOOL s_true = CK_TRUE;
|
||||
NSS_IMPLEMENT_DATA const NSSItem
|
||||
g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) };
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_BBOOL
|
||||
g_ck_false = CK_FALSE;
|
||||
static const CK_BBOOL s_false = CK_FALSE;
|
||||
NSS_IMPLEMENT_DATA const NSSItem
|
||||
g_ck_false = { (CK_VOID_PTR)&s_false, sizeof(s_false) };
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_OBJECT_CLASS
|
||||
g_ck_obj_class_cert = CKO_CERTIFICATE;
|
||||
static const CK_OBJECT_CLASS s_class_cert = CKO_CERTIFICATE;
|
||||
NSS_IMPLEMENT_DATA const NSSItem
|
||||
g_ck_class_cert = { (CK_VOID_PTR)&s_class_cert, sizeof(s_class_cert) };
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_OBJECT_CLASS
|
||||
g_ck_obj_class_pubkey = CKO_PUBLIC_KEY;
|
||||
static const CK_OBJECT_CLASS s_class_pubkey = CKO_PUBLIC_KEY;
|
||||
NSS_IMPLEMENT_DATA const NSSItem
|
||||
g_ck_class_pubkey = { (CK_VOID_PTR)&s_class_pubkey, sizeof(s_class_pubkey) };
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_OBJECT_CLASS
|
||||
g_ck_obj_class_privkey = CKO_PRIVATE_KEY;
|
||||
static const CK_OBJECT_CLASS s_class_privkey = CKO_PRIVATE_KEY;
|
||||
NSS_IMPLEMENT_DATA const NSSItem
|
||||
g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey) };
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSCKObject_GetAttributes
|
||||
|
@ -77,16 +82,16 @@ NSSCKObject_GetAttributes
|
|||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG count,
|
||||
NSSArena *arenaOpt,
|
||||
nssSession *session,
|
||||
NSSSlot *slot
|
||||
)
|
||||
{
|
||||
nssArenaMark *mark;
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_SESSION_HANDLE hSession;
|
||||
CK_ULONG i;
|
||||
CK_RV ckrv;
|
||||
PRStatus nssrv;
|
||||
/* use the default session */
|
||||
session = slot->token->session.handle;
|
||||
hSession = session->handle;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
if (arenaOpt) {
|
||||
mark = nssArenaMark(arenaOpt);
|
||||
|
@ -96,7 +101,7 @@ NSSCKObject_GetAttributes
|
|||
}
|
||||
#endif
|
||||
/* Get the storage size needed for each attribute */
|
||||
ckrv = CKAPI(slot)->C_GetAttributeValue(session,
|
||||
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
|
||||
object, obj_template, count);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here */
|
||||
|
@ -111,7 +116,7 @@ NSSCKObject_GetAttributes
|
|||
}
|
||||
}
|
||||
/* Obtain the actual attribute values. */
|
||||
ckrv = CKAPI(slot)->C_GetAttributeValue(session,
|
||||
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
|
||||
object, obj_template, count);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here */
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define CKHELPER_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:08 $ $Name: $";
|
||||
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.2 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
|
@ -59,120 +59,21 @@ PR_BEGIN_EXTERN_C
|
|||
*/
|
||||
|
||||
/* Boolean values */
|
||||
NSS_EXTERN_DATA const CK_BBOOL g_ck_true;
|
||||
NSS_EXTERN_DATA const CK_BBOOL g_ck_false;
|
||||
NSS_EXTERN_DATA const NSSItem g_ck_true;
|
||||
NSS_EXTERN_DATA const NSSItem g_ck_false;
|
||||
|
||||
/* Object classes */
|
||||
NSS_EXTERN_DATA const CK_OBJECT_CLASS g_ck_obj_class_cert;
|
||||
NSS_EXTERN_DATA const CK_OBJECT_CLASS g_ck_obj_class_pubkey;
|
||||
NSS_EXTERN_DATA const CK_OBJECT_CLASS g_ck_obj_class_privkey;
|
||||
|
||||
/*
|
||||
* Helpers for building templates.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NSS_SET_CK_ATTRIB_GLOBAL(cktmpl, i, ckattr, global_value)
|
||||
*
|
||||
* used to set one of the global attributes defined above.
|
||||
*/
|
||||
#define NSS_SET_CK_ATTRIB_GLOBAL(cktmpl, i, ckattr, global_value) \
|
||||
(cktmpl)[i].type = ckattr; \
|
||||
(cktmpl)[i].pValue = (CK_VOID_PTR)&(global_value); \
|
||||
(cktmpl)[i].ulValueLen = (CK_ULONG)sizeof(global_value);
|
||||
|
||||
/*
|
||||
* NSS_SET_CK_ATTRIB_TRUE(cktmpl, i, ckattr)
|
||||
*
|
||||
* Set an attribute to CK_TRUE in a template
|
||||
*/
|
||||
#define NSS_SET_CK_ATTRIB_TRUE(cktmpl, i, ckattr) \
|
||||
NSS_SET_CK_ATTRIB_GLOBAL(cktmpl, i, ckattr, g_ck_true)
|
||||
|
||||
/*
|
||||
* NSS_SET_CK_ATTRIB_FALSE(cktmpl, i, ckattr)
|
||||
*
|
||||
* Set an attribute to CK_FALSE in a template
|
||||
*/
|
||||
#define NSS_SET_CK_ATTRIB_FALSE(cktmpl, i, ckattr) \
|
||||
NSS_SET_CK_ATTRIB_GLOBAL(cktmpl, i, ckattr, g_ck_false)
|
||||
|
||||
/*
|
||||
* NSS_SET_CK_ATTRIB_ITEM(cktmpl, i, ckattr, item)
|
||||
*
|
||||
* Set an attribute in a template to use data from an item
|
||||
*/
|
||||
#define NSS_SET_CK_ATTRIB_ITEM(cktmpl, i, ckattr, item) \
|
||||
(cktmpl)[i].type = ckattr; \
|
||||
(cktmpl)[i].pValue = (CK_VOID_PTR)(item)->data; \
|
||||
(cktmpl)[i].ulValueLen = (CK_ULONG)(item)->len;
|
||||
|
||||
/* Create Templates */
|
||||
|
||||
/* Certificate template
|
||||
*
|
||||
* NSS_CK_CERTIFICATE_CREATE4(cktmpl, subject, id, der)
|
||||
*
|
||||
* CKA_CLASS = CKO_CERTIFICATE
|
||||
* CKA_SUBJECT = subject->data
|
||||
* CKA_ID = id->data
|
||||
* CKA_VALUE = der->data
|
||||
*/
|
||||
|
||||
#define NSS_CK_CERTIFICATE_CREATE4(cktmpl, subject, id, der) \
|
||||
NSS_SET_CK_ATTRIB_GLOBAL(cktmpl, 0, CKA_CLASS, g_ck_obj_class_cert) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 1, CKA_SUBJECT, subject) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 2, CKA_ID, id) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 3, CKA_VALUE, der)
|
||||
|
||||
/* Search Templates */
|
||||
|
||||
/* NSS_CK_CERTIFICATE_SEARCH(cktmpl)
|
||||
*
|
||||
* Set up a search template for any cert object
|
||||
*/
|
||||
#define NSS_CK_CERTIFICATE_SEARCH(cktmpl) \
|
||||
NSS_SET_CK_ATTRIB_GLOBAL(cktmpl, 0, CKA_CLASS, g_ck_obj_class_cert)
|
||||
|
||||
/* NSS_CK_CERTIFICATE_SEARCH_LABEL2(cktmpl, label)
|
||||
*
|
||||
* Set up a search template for a cert using label->data
|
||||
*/
|
||||
#define NSS_CK_CERTIFICATE_SEARCH_LABEL2(cktmpl, label) \
|
||||
NSS_CK_CERTIFICATE_SEARCH(cktmpl) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 1, CKA_LABEL, label)
|
||||
|
||||
/* NSS_CK_CERTIFICATE_SEARCH_SUBJECT2(cktmpl, subject)
|
||||
*
|
||||
* Set up a search template for a cert using subject->data
|
||||
*/
|
||||
#define NSS_CK_CERTIFICATE_SEARCH_SUBJECT2(cktmpl, subject) \
|
||||
NSS_CK_CERTIFICATE_SEARCH(cktmpl) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 1, CKA_SUBJECT, subject)
|
||||
|
||||
/* NSS_CK_CERTIFICATE_SEARCH_ID2(cktmpl, id)
|
||||
*
|
||||
* Set up a search template for a cert using id->data
|
||||
*/
|
||||
#define NSS_CK_CERTIFICATE_SEARCH_ID2(cktmpl, id) \
|
||||
NSS_CK_CERTIFICATE_SEARCH(cktmpl) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 1, CKA_ID, id)
|
||||
|
||||
/* NSS_CK_CERTIFICATE_SEARCH_DER2(cktmpl, der)
|
||||
*
|
||||
* Set up a search template for a cert using der->data
|
||||
*/
|
||||
#define NSS_CK_CERTIFICATE_SEARCH_DER2(cktmpl, der) \
|
||||
NSS_CK_CERTIFICATE_SEARCH(cktmpl) \
|
||||
NSS_SET_CK_ATTRIB_ITEM(cktmpl, 1, CKA_VALUE, der)
|
||||
NSS_EXTERN_DATA const NSSItem g_ck_class_cert;
|
||||
NSS_EXTERN_DATA const NSSItem g_ck_class_pubkey;
|
||||
NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
|
||||
|
||||
/* NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item)
|
||||
*
|
||||
* Convert a CK_ATTRIBUTE to an NSSItem.
|
||||
*/
|
||||
#define NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item) \
|
||||
(item)->data = (void *)(attrib)->pValue; \
|
||||
(item)->size = (PRUint32)(attrib)->ulValueLen; \
|
||||
#define NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item) \
|
||||
(item)->data = (void *)(attrib)->pValue; \
|
||||
(item)->size = (PRUint32)(attrib)->ulValueLen; \
|
||||
|
||||
/* Get an array of attributes from an object. */
|
||||
NSS_EXTERN PRStatus
|
||||
|
@ -182,6 +83,7 @@ NSSCKObject_GetAttributes
|
|||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG count,
|
||||
NSSArena *arenaOpt,
|
||||
nssSession *session,
|
||||
NSSSlot *slot
|
||||
);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define DEV_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:08 $ $Name: $";
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.2 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEVT_H
|
||||
|
@ -60,6 +60,11 @@ static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.1 $ $Dat
|
|||
* |-----------|---> NSSSlot <--> NSSToken
|
||||
*/
|
||||
|
||||
/* XXX These should probably all be "nss" not "NSS". Though the types are
|
||||
* exposed, the API's should not be (with the exception of functions
|
||||
* put in a friend header.
|
||||
*/
|
||||
|
||||
#ifndef DEVT_H
|
||||
#include "devt.h"
|
||||
#endif /* DEVT_H */
|
||||
|
@ -162,6 +167,14 @@ NSSSlot_Logout
|
|||
* NSSSlot_ChangePassword
|
||||
*/
|
||||
|
||||
NSS_EXTERN nssSession *
|
||||
NSSSlot_CreateSession
|
||||
(
|
||||
NSSSlot *slot,
|
||||
NSSArena *arenaOpt,
|
||||
PRBool readOnly /* so far, this is the only flag used */
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSToken *
|
||||
NSSToken_Create
|
||||
(
|
||||
|
@ -184,41 +197,47 @@ NSS_EXTERN NSSCertificate *
|
|||
NSSToken_ImportCertificate
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPublicKey *
|
||||
NSSToken_ImportPublicKey
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPrivateKey *
|
||||
NSSToken_ImportPrivateKey
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSymmetricKey *
|
||||
NSSToken_ImportSymmetricKey
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPublicKey *
|
||||
NSSToken_GenerateKeyPair
|
||||
(
|
||||
NSSToken *tok
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt
|
||||
/* algorithm and parameters */
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSymmetricKey *
|
||||
NSSToken_GenerateSymmetricKey
|
||||
(
|
||||
NSSToken *tok
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt
|
||||
/* algorithm and parameters */
|
||||
);
|
||||
|
||||
|
@ -227,18 +246,49 @@ NSS_EXTERN PRStatus
|
|||
NSSToken_DeleteStoredObject
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_OBJECT_HANDLE object
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSCertificate **
|
||||
NSSToken_FindCertificatesByTemplate
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
);
|
||||
|
||||
/* again, a questionable function. maybe some tokens allow this? */
|
||||
NSS_EXTERN PRStatus *
|
||||
NSSToken_TraverseCertificates
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssSession_Destroy
|
||||
(
|
||||
nssSession *s
|
||||
);
|
||||
|
||||
/* would like to inline */
|
||||
NSS_EXTERN PRStatus
|
||||
nssSession_EnterMonitor
|
||||
(
|
||||
nssSession *s
|
||||
);
|
||||
|
||||
/* would like to inline */
|
||||
NSS_EXTERN PRStatus
|
||||
nssSession_ExitMonitor
|
||||
(
|
||||
nssSession *s
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
void NSSModule_Debug(NSSModule *m);
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define DEVT_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:09 $ $Name: $";
|
||||
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.2 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -64,6 +64,8 @@ typedef struct NSSSlotStr NSSSlot;
|
|||
|
||||
typedef struct NSSTokenStr NSSToken;
|
||||
|
||||
typedef struct nssSessionStr nssSession;
|
||||
|
||||
/* The list of boolean flags used to describe properties of a
|
||||
* module.
|
||||
*/
|
||||
|
@ -89,34 +91,34 @@ struct NSSModuleStr {
|
|||
|
||||
struct NSSSlotStr
|
||||
{
|
||||
NSSArena *arena;
|
||||
PRInt32 refCount;
|
||||
NSSModule *module; /* Parent */
|
||||
NSSToken *token; /* Child (or peer, if you will) */
|
||||
NSSUTF8 *name;
|
||||
void *epv;
|
||||
CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
|
||||
PRUint32 flags;
|
||||
NSSArena *arena;
|
||||
PRInt32 refCount;
|
||||
NSSModule *module; /* Parent */
|
||||
NSSToken *token; /* Child (or peer, if you will) */
|
||||
NSSUTF8 *name;
|
||||
CK_SLOT_ID slotID;
|
||||
void *epv;
|
||||
CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
|
||||
PRUint32 flags;
|
||||
};
|
||||
|
||||
struct NSSTokenStr
|
||||
{
|
||||
NSSArena *arena;
|
||||
PRInt32 refCount;
|
||||
NSSSlot *slot; /* Parent (or peer, if you will) */
|
||||
NSSUTF8 *name;
|
||||
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
|
||||
PRUint32 flags;
|
||||
struct {
|
||||
/* according to PK11SlotInfoStr, a default session for "quick-and-dirty"
|
||||
* functions
|
||||
*/
|
||||
CK_SESSION_HANDLE handle;
|
||||
PZLock *lock;
|
||||
} session;
|
||||
NSSArena *arena;
|
||||
PRInt32 refCount;
|
||||
NSSSlot *slot; /* Parent (or peer, if you will) */
|
||||
NSSUTF8 *name;
|
||||
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
|
||||
PRUint32 flags;
|
||||
nssSession *defaultSession;
|
||||
};
|
||||
|
||||
struct NSSTokenStr;
|
||||
struct nssSessionStr
|
||||
{
|
||||
PZLock *lock;
|
||||
CK_SESSION_HANDLE handle;
|
||||
NSSSlot *slot;
|
||||
};
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: module.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: module.c,v $ $Revision: 1.2 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
|
@ -318,7 +318,8 @@ NSSModule_TraverseCertificates
|
|||
PRUint32 i;
|
||||
for (i=0; i<mod->numSlots; i++) {
|
||||
/* might as well skip straight to token, right? or is this slot? */
|
||||
NSSToken_TraverseCertificates(mod->slots[i]->token, callback, arg);
|
||||
NSSToken_TraverseCertificates(mod->slots[i]->token,
|
||||
NULL, callback, arg);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.2 $ $Date: 2001-09-13 22:14:22 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.3 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
|
@ -55,6 +55,21 @@ static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.2 $ $Date:
|
|||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
/* The flags needed to open a read-only session. */
|
||||
static const CK_FLAGS s_ck_readonly_flags = CKF_SERIAL_SESSION;
|
||||
|
||||
/* In pk11slot.c, this was a no-op. So it is here also. */
|
||||
static CK_RV PR_CALLBACK
|
||||
nss_ck_slot_notify
|
||||
(
|
||||
CK_SESSION_HANDLE session,
|
||||
CK_NOTIFICATION event,
|
||||
CK_VOID_PTR pData
|
||||
)
|
||||
{
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/* maybe this should really inherit completely from the module... I dunno,
|
||||
* any uses of slots where independence is needed?
|
||||
*/
|
||||
|
@ -123,6 +138,7 @@ NSSSlot_Create
|
|||
rvSlot->epv = parent->epv;
|
||||
rvSlot->module = parent;
|
||||
rvSlot->name = slotName;
|
||||
rvSlot->slotID = slotID;
|
||||
rvSlot->ckFlags = slotInfo.flags;
|
||||
/* Initialize the token if present. */
|
||||
if (slotInfo.flags & CKF_TOKEN_PRESENT) {
|
||||
|
@ -166,3 +182,85 @@ NSSSlot_Destroy
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT nssSession *
|
||||
NSSSlot_CreateSession
|
||||
(
|
||||
NSSSlot *slot,
|
||||
NSSArena *arenaOpt,
|
||||
PRBool readOnly /* so far, this is the only flag used */
|
||||
)
|
||||
{
|
||||
CK_RV ckrv;
|
||||
CK_FLAGS ckflags;
|
||||
CK_SESSION_HANDLE session;
|
||||
nssSession *rvSession;
|
||||
ckflags = s_ck_readonly_flags;
|
||||
if (!readOnly) {
|
||||
ckflags |= CKF_RW_SESSION;
|
||||
}
|
||||
/* does the opening and closing of sessions need to be done in a
|
||||
* threadsafe manner? should there be a "meta-lock" controlling
|
||||
* calls like this?
|
||||
*/
|
||||
ckrv = CKAPI(slot)->C_OpenSession(slot->slotID, ckflags,
|
||||
slot, nss_ck_slot_notify, &session);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here, eh? */
|
||||
return (nssSession *)NULL;
|
||||
}
|
||||
rvSession = nss_ZNEW(arenaOpt, nssSession);
|
||||
if (!rvSession) {
|
||||
return (nssSession *)NULL;
|
||||
}
|
||||
if (slot->module->flags & NSSMODULE_FLAGS_NOT_THREADSAFE) {
|
||||
/* If the parent module is not threadsafe, create lock to manage
|
||||
* session within threads.
|
||||
*/
|
||||
rvSession->lock = PZ_NewLock(nssILockOther);
|
||||
if (!rvSession->lock) {
|
||||
/* need to translate NSPR error? */
|
||||
if (arenaOpt) {
|
||||
} else {
|
||||
nss_ZFreeIf(rvSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
rvSession->handle = session;
|
||||
rvSession->slot = slot;
|
||||
return rvSession;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssSession_Destroy
|
||||
(
|
||||
nssSession *s
|
||||
)
|
||||
{
|
||||
if (s) {
|
||||
if (s->lock) {
|
||||
PZ_DestroyLock(s->lock);
|
||||
}
|
||||
nss_ZFreeIf(s);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssSession_EnterMonitor
|
||||
(
|
||||
nssSession *s
|
||||
)
|
||||
{
|
||||
if (s->lock) PZ_Lock(s->lock);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssSession_ExitMonitor
|
||||
(
|
||||
nssSession *s
|
||||
)
|
||||
{
|
||||
return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.2 $ $Date: 2001-09-18 20:54:28 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
|
@ -59,30 +59,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.1 $ $Date:
|
|||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
/* If the token cannot manage threads, we have to. The following detect
|
||||
* a non-threadsafe token and lock/unlock its session handle.
|
||||
*/
|
||||
#define NSSTOKEN_ENTER_MONITOR(token) \
|
||||
if ((token)->session.lock) PZ_Lock((token)->session.lock)
|
||||
|
||||
#define NSSTOKEN_EXIT_MONITOR(token) \
|
||||
if ((token)->session.lock) PZ_Unlock((token)->session.lock)
|
||||
|
||||
/* The flags needed to open a read-only session. */
|
||||
static const CK_FLAGS s_ck_readonly_flags = CKF_SERIAL_SESSION;
|
||||
|
||||
/* In pk11slot.c, this was a no-op. So it is here also. */
|
||||
CK_RV PR_CALLBACK
|
||||
nss_ck_slot_notify
|
||||
(
|
||||
CK_SESSION_HANDLE session,
|
||||
CK_NOTIFICATION event,
|
||||
CK_VOID_PTR pData
|
||||
)
|
||||
{
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/* maybe this should really inherit completely from the module... I dunno,
|
||||
* any uses of slots where independence is needed?
|
||||
*/
|
||||
|
@ -97,12 +73,12 @@ NSSToken_Create
|
|||
NSSArena *arena;
|
||||
nssArenaMark *mark;
|
||||
NSSToken *rvToken;
|
||||
nssSession *session;
|
||||
NSSUTF8 *tokenName = NULL;
|
||||
PRUint32 length;
|
||||
PRBool newArena;
|
||||
PRStatus nssrv;
|
||||
CK_TOKEN_INFO tokenInfo;
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_RV ckrv;
|
||||
if (arenaOpt) {
|
||||
arena = arenaOpt;
|
||||
|
@ -124,16 +100,8 @@ NSSToken_Create
|
|||
if (!rvToken) {
|
||||
goto loser;
|
||||
}
|
||||
if (parent->module->flags & NSSMODULE_FLAGS_NOT_THREADSAFE) {
|
||||
/* If the parent module is not threadsafe, create lock to manage
|
||||
* session within threads.
|
||||
*/
|
||||
rvToken->session.lock = PZ_NewLock(nssILockOther);
|
||||
}
|
||||
/* Get token information */
|
||||
NSSTOKEN_ENTER_MONITOR(rvToken);
|
||||
ckrv = CKAPI(parent)->C_GetTokenInfo(slotID, &tokenInfo);
|
||||
NSSTOKEN_EXIT_MONITOR(rvToken);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here, eh? */
|
||||
goto loser;
|
||||
|
@ -147,13 +115,9 @@ NSSToken_Create
|
|||
goto loser;
|
||||
}
|
||||
}
|
||||
/* Open a session handle for the token. */
|
||||
NSSTOKEN_ENTER_MONITOR(rvToken);
|
||||
ckrv = CKAPI(parent)->C_OpenSession(slotID, s_ck_readonly_flags,
|
||||
parent, nss_ck_slot_notify, &session);
|
||||
NSSTOKEN_EXIT_MONITOR(rvToken);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here, eh? */
|
||||
/* Open a default session handle for the token. */
|
||||
session = NSSSlot_CreateSession(parent, arena, PR_TRUE);
|
||||
if (session == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
/* TODO: seed the RNG here */
|
||||
|
@ -167,7 +131,7 @@ NSSToken_Create
|
|||
rvToken->slot = parent;
|
||||
rvToken->name = tokenName;
|
||||
rvToken->ckFlags = tokenInfo.flags;
|
||||
rvToken->session.handle = session;
|
||||
rvToken->defaultSession = session;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
nssrv = nssArena_Unmark(arena, mark);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
|
@ -176,6 +140,9 @@ NSSToken_Create
|
|||
#endif
|
||||
return rvToken;
|
||||
loser:
|
||||
if (session) {
|
||||
nssSession_Destroy(session);
|
||||
}
|
||||
if (newArena) {
|
||||
nssArena_Destroy(arena);
|
||||
} else {
|
||||
|
@ -185,9 +152,6 @@ loser:
|
|||
}
|
||||
#endif
|
||||
}
|
||||
if (rvToken && rvToken->session.lock) {
|
||||
PZ_DestroyLock(rvToken->session.lock);
|
||||
}
|
||||
return (NSSToken *)NULL;
|
||||
}
|
||||
|
||||
|
@ -198,63 +162,164 @@ NSSToken_Destroy
|
|||
)
|
||||
{
|
||||
if (--tok->refCount == 0) {
|
||||
if (tok->defaultSession) {
|
||||
nssSession_Destroy(tok->defaultSession);
|
||||
}
|
||||
return NSSArena_Destroy(tok->arena);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus *
|
||||
NSSToken_TraverseCertificates
|
||||
/* This is only used by the Traverse function. If we ditch traversal,
|
||||
* ditch this.
|
||||
*/
|
||||
struct certCallbackStr {
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
/* also symmKeyCallbackStr, pubKeyCallbackStr, etc. */
|
||||
|
||||
/*
|
||||
* This callback examines each matching certificate by passing it to
|
||||
* a higher-level callback function.
|
||||
*/
|
||||
static PRStatus
|
||||
examine_cert_callback(NSSToken *t, nssSession *session,
|
||||
CK_OBJECT_HANDLE h, void *arg)
|
||||
{
|
||||
PRStatus cbrv;
|
||||
NSSCertificate *cert;
|
||||
struct certCallbackStr *ccb = (struct certCallbackStr *)arg;
|
||||
/* maybe it should be NSSToken_CreateCertificate(token, handle); */
|
||||
cert = NSSCertificate_CreateFromHandle(h, session, t->slot);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
cbrv = (*ccb->callback)(cert, ccb->arg);
|
||||
if (cbrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
collect_certs_callback(NSSToken *t, nssSession *session,
|
||||
CK_OBJECT_HANDLE h, void *arg)
|
||||
{
|
||||
NSSCertificate *cert;
|
||||
void *certList; /* nssList soon */
|
||||
certList = (void *)arg;
|
||||
cert = NSSCertificate_CreateFromHandle(h, session, t->slot);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
/* XXX add cert to list */
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
static PRStatus *
|
||||
nsstoken_TraverseObjects
|
||||
(
|
||||
NSSToken *tok,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
nssSession *session,
|
||||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG otsize,
|
||||
PRStatus (*callback)(NSSToken *t, nssSession *session,
|
||||
CK_OBJECT_HANDLE h, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
NSSSlot *slot;
|
||||
NSSCertificate *cert;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_ATTRIBUTE cert_template[1];
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_ULONG count;
|
||||
CK_RV ckrv;
|
||||
PRStatus cbrv;
|
||||
CK_RV ckrv;
|
||||
CK_ULONG count;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_SESSION_HANDLE hSession;
|
||||
slot = tok->slot;
|
||||
session = tok->session.handle;
|
||||
NSS_CK_CERTIFICATE_SEARCH(cert_template);
|
||||
NSSTOKEN_ENTER_MONITOR(tok);
|
||||
ckrv = CKAPI(slot)->C_FindObjectsInit(session, cert_template, 1);
|
||||
hSession = session->handle;
|
||||
ckrv = CKAPI(slot)->C_FindObjectsInit(hSession, obj_template, otsize);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
while (PR_TRUE) {
|
||||
ckrv = CKAPI(slot)->C_FindObjects(session, &object, 1, &count);
|
||||
/* this could be sped up by getting 5-10 at a time? */
|
||||
ckrv = CKAPI(slot)->C_FindObjects(hSession, &object, 1, &count);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
if (count == 0) {
|
||||
break;
|
||||
}
|
||||
/* it would be better if the next two were done outside of the
|
||||
* monitor. but we don't want this function anyway, right?
|
||||
*/
|
||||
cert = NSSCertificate_CreateFromHandle(object, slot);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
cbrv = (*callback)(cert, arg);
|
||||
cbrv = (*callback)(tok, session, object, arg);
|
||||
if (cbrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
ckrv = CKAPI(slot)->C_FindObjectsFinal(session);
|
||||
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
NSSTOKEN_EXIT_MONITOR(tok);
|
||||
return NULL; /* for now... */
|
||||
loser:
|
||||
NSSTOKEN_EXIT_MONITOR(tok);
|
||||
return NULL; /* for now... */
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus *
|
||||
NSSToken_TraverseCertificates
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
PRStatus *rvstack;
|
||||
nssSession *session;
|
||||
struct certCallbackStr ccb;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, g_ck_class_cert.data, g_ck_class_cert.size }
|
||||
};
|
||||
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
ccb.callback = callback;
|
||||
ccb.arg = arg;
|
||||
nssSession_EnterMonitor(session);
|
||||
rvstack = nsstoken_TraverseObjects(tok, session, cert_template, ctsize,
|
||||
examine_cert_callback, (void *)&ccb);
|
||||
nssSession_ExitMonitor(session);
|
||||
return rvstack;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
NSSToken_FindCertificatesByTemplate
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
)
|
||||
{
|
||||
PRStatus *rvstack;
|
||||
nssSession *session;
|
||||
void *certList; /* nssList soon */
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
nssSession_EnterMonitor(session);
|
||||
rvstack = nsstoken_TraverseObjects(tok, session, cktemplate, ctsize,
|
||||
collect_certs_callback,
|
||||
(void *)certList);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (rvstack) {
|
||||
/* examine the errors */
|
||||
goto loser;
|
||||
}
|
||||
/* XXX get an array from the list, return it */
|
||||
return (NSSCertificate **)NULL;
|
||||
loser:
|
||||
/* clean out the list */
|
||||
return (NSSCertificate **)NULL;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче