Land Stan changes to tip. Mostly header file / structure / API cleanup. Note

that these changes *do not* affect the current build, except for some minor edits.
This commit is contained in:
ian.mcgreer%sun.com 2002-04-04 20:00:28 +00:00
Родитель 10974122ac
Коммит 5dc26469cd
15 изменённых файлов: 4197 добавлений и 853 удалений

Просмотреть файл

@ -32,29 +32,21 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.17 $ $Date: 2002-03-15 19:51:27 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.18 $ $Date: 2002-04-04 20:00:21 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifdef NSS_3_4_CODE
#include "pkcs11.h"
#else
#ifndef NSSCKEPV_H
#include "nssckepv.h"
#endif /* NSSCKEPV_H */
#endif /* NSS_3_4_CODE */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
static const CK_BBOOL s_true = CK_TRUE;
NSS_IMPLEMENT_DATA const NSSItem
g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) };
@ -111,6 +103,7 @@ nssCKObject_GetAttributes
CK_RV ckrv;
PRStatus nssrv;
PRBool alloced = PR_FALSE;
void *epv = nssSlot_GetCryptokiEPV(slot);
hSession = session->handle;
if (arenaOpt) {
mark = nssArena_Mark(arenaOpt);
@ -124,8 +117,8 @@ nssCKObject_GetAttributes
*/
if (obj_template[0].ulValueLen == 0) {
/* Get the storage size needed for each attribute */
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
object, obj_template, count);
ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
object, obj_template, count);
if (ckrv != CKR_OK &&
ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
ckrv != CKR_ATTRIBUTE_SENSITIVE)
@ -154,8 +147,8 @@ nssCKObject_GetAttributes
alloced = PR_TRUE;
}
/* Obtain the actual attribute values. */
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
object, obj_template, count);
ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
object, obj_template, count);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK &&
ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
@ -238,11 +231,12 @@ nssCKObject_IsAttributeTrue
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE atemplate = { 0, NULL, 0 };
CK_RV ckrv;
void *epv = nssSlot_GetCryptokiEPV(slot);
attr = &atemplate;
NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool);
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_GetAttributeValue(session->handle, object,
&atemplate, 1);
ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object,
&atemplate, 1);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
*rvStatus = PR_FAILURE;
@ -263,9 +257,10 @@ nssCKObject_SetAttributes
)
{
CK_RV ckrv;
void *epv = nssSlot_GetCryptokiEPV(slot);
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_SetAttributeValue(session->handle, object,
obj_template, count);
ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object,
obj_template, count);
nssSession_ExitMonitor(session);
if (ckrv == CKR_OK) {
return PR_SUCCESS;
@ -290,3 +285,366 @@ nssCKObject_IsTokenObjectTemplate
return PR_FALSE;
}
#ifdef PURE_STAN_BUILD
static NSSCertificateType
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
CK_CERTIFICATE_TYPE ckCertType;
if (!attrib->pValue) {
/* default to PKIX */
return NSSCertificateType_PKIX;
}
ckCertType = *((CK_ULONG *)attrib->pValue);
switch (ckCertType) {
case CKC_X_509:
return NSSCertificateType_PKIX;
default:
break;
}
return NSSCertificateType_Unknown;
}
/* incoming pointers must be valid */
NSS_IMPLEMENT PRStatus
nssCryptokiCertificate_GetAttributes
(
nssCryptokiObject *certObject,
nssSession *sessionOpt,
NSSArena *arenaOpt,
NSSCertificateType *certTypeOpt,
NSSItem *idOpt,
NSSDER *encodingOpt,
NSSDER *issuerOpt,
NSSDER *serialOpt,
NSSDER *subjectOpt,
NSSASCII7 **emailOpt
)
{
PRStatus status;
PRUint32 i;
nssSession *session;
NSSSlot *slot;
CK_ULONG template_size;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE cert_template[7];
/* Set up a template of all options chosen by caller */
NSS_CK_TEMPLATE_START(cert_template, attr, template_size);
if (certTypeOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE);
}
if (idOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
}
if (encodingOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
}
if (issuerOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
}
if (serialOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
}
if (subjectOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
}
if (emailOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_EMAIL);
}
NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size);
if (template_size == 0) {
/* caller didn't want anything */
return PR_SUCCESS;
}
status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
certObject, CKO_CERTIFICATE,
cert_template, template_size);
if (status != PR_SUCCESS) {
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(certObject->token);
slot = nssToken_GetSlot(certObject->token);
status = nssCKObject_GetAttributes(certObject->handle,
cert_template, template_size,
arenaOpt, session, slot);
nssSlot_Destroy(slot);
if (status != PR_SUCCESS) {
return status;
}
}
i=0;
if (certTypeOpt) {
*certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++;
}
if (idOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++;
}
if (encodingOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++;
}
if (issuerOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++;
}
if (serialOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++;
}
if (subjectOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++;
}
if (emailOpt) {
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[i], *emailOpt); i++;
}
return PR_SUCCESS;
}
static NSSKeyPairType
nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
CK_KEY_TYPE ckKeyType;
PR_ASSERT(attrib->pValue);
ckKeyType = *((CK_ULONG *)attrib->pValue);
switch (ckKeyType) {
case CKK_RSA: return NSSKeyPairType_RSA;
case CKK_DSA: return NSSKeyPairType_DSA;
default: break;
}
return NSSKeyPairType_Unknown;
}
NSS_IMPLEMENT PRStatus
nssCryptokiPrivateKey_GetAttributes
(
nssCryptokiObject *keyObject,
nssSession *sessionOpt,
NSSArena *arenaOpt,
NSSKeyPairType *keyTypeOpt,
NSSItem *idOpt
)
{
PRStatus status;
PRUint32 i;
nssSession *session;
NSSSlot *slot;
CK_ULONG template_size;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE key_template[2];
/* Set up a template of all options chosen by caller */
NSS_CK_TEMPLATE_START(key_template, attr, template_size);
if (keyTypeOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
}
if (idOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
}
NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
if (template_size == 0) {
/* caller didn't want anything */
return PR_SUCCESS;
}
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(keyObject->token);
slot = nssToken_GetSlot(keyObject->token);
status = nssCKObject_GetAttributes(keyObject->handle,
key_template, template_size,
arenaOpt, session, slot);
nssSlot_Destroy(slot);
if (status != PR_SUCCESS) {
return status;
}
i=0;
if (keyTypeOpt) {
*keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
}
if (idOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
}
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
nssCryptokiPublicKey_GetAttributes
(
nssCryptokiObject *keyObject,
nssSession *sessionOpt,
NSSArena *arenaOpt,
NSSKeyPairType *keyTypeOpt,
NSSItem *idOpt
)
{
PRStatus status;
PRUint32 i;
nssSession *session;
NSSSlot *slot;
CK_ULONG template_size;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE key_template[2];
/* Set up a template of all options chosen by caller */
NSS_CK_TEMPLATE_START(key_template, attr, template_size);
if (keyTypeOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
}
if (idOpt) {
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
}
NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
if (template_size == 0) {
/* caller didn't want anything */
return PR_SUCCESS;
}
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(keyObject->token);
slot = nssToken_GetSlot(keyObject->token);
status = nssCKObject_GetAttributes(keyObject->handle,
key_template, template_size,
arenaOpt, session, slot);
nssSlot_Destroy(slot);
if (status != PR_SUCCESS) {
return status;
}
i=0;
if (keyTypeOpt) {
*keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
}
if (idOpt) {
NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
}
return PR_SUCCESS;
}
static nssTrustLevel
get_nss_trust
(
CK_TRUST ckt
)
{
nssTrustLevel t;
switch (ckt) {
case CKT_NETSCAPE_TRUST_UNKNOWN: t = nssTrustLevel_Unknown; break;
case CKT_NETSCAPE_UNTRUSTED: t = nssTrustLevel_NotTrusted; break;
case CKT_NETSCAPE_TRUSTED_DELEGATOR: t = nssTrustLevel_TrustedDelegator;
break;
case CKT_NETSCAPE_VALID_DELEGATOR: t = nssTrustLevel_ValidDelegator; break;
case CKT_NETSCAPE_TRUSTED: t = nssTrustLevel_Trusted; break;
case CKT_NETSCAPE_VALID: t = nssTrustLevel_Valid; break;
}
return t;
}
NSS_IMPLEMENT PRStatus
nssCryptokiTrust_GetAttributes
(
nssCryptokiObject *trustObject,
nssSession *sessionOpt,
nssTrustLevel *serverAuth,
nssTrustLevel *clientAuth,
nssTrustLevel *codeSigning,
nssTrustLevel *emailProtection
)
{
PRStatus status;
NSSSlot *slot;
nssSession *session;
CK_BBOOL isToken;
CK_TRUST saTrust, caTrust, epTrust, csTrust;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE trust_template[5];
CK_ULONG trust_size;
/* Use the trust object to find the trust settings */
NSS_CK_TEMPLATE_START(trust_template, attr, trust_size);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust);
NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
trustObject,
CKO_NETSCAPE_TRUST,
trust_template, trust_size);
if (status != PR_SUCCESS) {
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(trustObject->token);
slot = nssToken_GetSlot(trustObject->token);
status = nssCKObject_GetAttributes(trustObject->handle,
trust_template, trust_size,
NULL, session, slot);
nssSlot_Destroy(slot);
if (status != PR_SUCCESS) {
return status;
}
}
*serverAuth = get_nss_trust(saTrust);
*clientAuth = get_nss_trust(caTrust);
*emailProtection = get_nss_trust(epTrust);
*codeSigning = get_nss_trust(csTrust);
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
nssCryptokiCRL_GetAttributes
(
nssCryptokiObject *crlObject,
nssSession *sessionOpt,
NSSArena *arenaOpt,
NSSItem *crl,
NSSItem *krl,
NSSItem *url
)
{
PRStatus status;
NSSSlot *slot;
nssSession *session;
CK_BBOOL isToken;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE crl_template[5];
CK_ULONG crl_size;
NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken);
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_URL);
NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
crlObject,
CKO_NETSCAPE_CRL,
crl_template, crl_size);
if (status != PR_SUCCESS) {
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(crlObject->token);
slot = nssToken_GetSlot(crlObject->token);
status = nssCKObject_GetAttributes(crlObject->handle,
crl_template, crl_size,
arenaOpt, session, slot);
nssSlot_Destroy(slot);
if (status != PR_SUCCESS) {
return status;
}
}
NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[0], crl);
NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[1], krl);
NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[2], url);
return PR_SUCCESS;
}
#endif /* PURE_STAN_BUILD */

Просмотреть файл

@ -41,7 +41,7 @@
#define CKHELPER_H
#ifdef DEBUG
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.13 $ $Date: 2002-01-23 01:20:32 $ $Name: $";
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.14 $ $Date: 2002-04-04 20:00:21 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSCKT_H
@ -50,10 +50,6 @@ static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision:
PR_BEGIN_EXTERN_C
/* Shortcut to cryptoki API functions. */
#define CKAPI(x) \
((CK_FUNCTION_LIST_PTR)((x)->epv))
/* Some globals to keep from constantly redeclaring common cryptoki
* attribute types on the stack.
*/

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -35,28 +35,119 @@
#define DEVM_H
#ifdef DEBUG
static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.4 $ $Date: 2001-11-08 00:14:52 $ $Name: $";
static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.5 $ $Date: 2002-04-04 20:00:21 $ $Name: $";
#endif /* DEBUG */
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifndef DEVTM_H
#include "devtm.h"
#endif /* DEVTM_H */
PR_BEGIN_EXTERN_C
/* Shortcut to cryptoki API functions. */
#define CKAPI(epv) \
((CK_FUNCTION_LIST_PTR)(epv))
NSS_EXTERN void
nssDevice_AddRef
(
struct nssDeviceBaseStr *device
);
NSS_EXTERN PRBool
nssDevice_Destroy
(
struct nssDeviceBaseStr *device
);
NSS_EXTERN PRBool
nssModule_IsThreadSafe
(
NSSModule *module
);
NSS_EXTERN PRBool
nssModule_IsInternal
(
NSSModule *mod
);
NSS_EXTERN PRBool
nssModule_IsModuleDBOnly
(
NSSModule *mod
);
NSS_EXTERN void *
nssModule_GetCryptokiEPV
(
NSSModule *mod
);
NSS_EXTERN NSSSlot *
nssSlot_Create
(
CK_SLOT_ID slotId,
NSSModule *parent
);
NSS_EXTERN void *
nssSlot_GetCryptokiEPV
(
NSSSlot *slot
);
NSS_EXTERN NSSToken *
nssToken_Create
(
CK_SLOT_ID slotID,
NSSSlot *peer
);
NSS_EXTERN void *
nssToken_GetCryptokiEPV
(
NSSToken *token
);
NSS_EXTERN nssSession *
nssToken_GetDefaultSession
(
NSSToken *token
);
NSS_EXTERN PRBool
nssToken_IsLoginRequired
(
NSSToken *token
);
NSS_EXTERN nssCryptokiObject *
nssCryptokiObject_Create
(
NSSToken *t,
nssSession *session,
CK_OBJECT_HANDLE h
);
/* PKCS#11 stores strings in a fixed-length buffer padded with spaces. This
* function gets the length of the actual string.
*/
NSS_EXTERN PRUint32
nssPKCS11StringLength(
nssPKCS11String_Length
(
CK_CHAR *pkcs11str,
PRUint32 bufLen
);

Просмотреть файл

@ -32,30 +32,72 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devmod.c,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devmod.c,v $ $Revision: 1.3 $ $Date: 2002-04-04 20:00:21 $ $Name: $";
#endif /* DEBUG */
#include "nspr.h"
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
#ifndef NSSCKEPV_H
#include "nssckepv.h"
#endif /* NSSCKEPV_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
#ifdef PURE_STAN_CODE
extern void FC_GetFunctionList(void);
extern void NSC_GetFunctionList(void);
extern void NSC_ModuleDBFunc(void);
/* The list of boolean flags used to describe properties of a
* module.
*/
#define NSSMODULE_FLAGS_NOT_THREADSAFE 0x0001 /* isThreadSafe */
#define NSSMODULE_FLAGS_INTERNAL 0x0002 /* isInternal */
#define NSSMODULE_FLAGS_FIPS 0x0004 /* isFIPS */
#define NSSMODULE_FLAGS_MODULE_DB 0x0008 /* isModuleDB */
#define NSSMODULE_FLAGS_MODULE_DB_ONLY 0x0010 /* moduleDBOnly */
#define NSSMODULE_FLAGS_CRITICAL 0x0020 /* isCritical */
struct NSSModuleStr {
struct nssDeviceBaseStr base;
NSSUTF8 *libraryName;
PRLibrary *library;
char *libraryParams;
void *moduleDBFunc;
void *epv;
CK_INFO info;
NSSSlot **slots;
PRUint32 numSlots;
PRBool isLoaded;
struct {
PRInt32 trust;
PRInt32 cipher;
PRInt32 certStorage;
} order;
};
#define NSSMODULE_IS_THREADSAFE(module) \
(!(module->base.flags & NSSMODULE_FLAGS_NOT_THREADSAFE))
#define NSSMODULE_IS_INTERNAL(module) \
(module->base.flags & NSSMODULE_FLAGS_INTERNAL)
#define NSSMODULE_IS_FIPS(module) \
(module->base.flags & NSSMODULE_FLAGS_FIPS)
#define NSSMODULE_IS_MODULE_DB(module) \
(module->base.flags & NSSMODULE_FLAGS_MODULE_DB)
#define NSSMODULE_IS_MODULE_DB_ONLY(module) \
(module->base.flags & NSSMODULE_FLAGS_MODULE_DB_ONLY)
#define NSSMODULE_IS_CRITICAL(module) \
(module->base.flags & NSSMODULE_FLAGS_CRITICAL)
/* Threading callbacks for C_Initialize. Use NSPR threads. */
@ -92,6 +134,9 @@ nss_ck_UnlockMutex(CK_VOID_PTR mutex)
}
/* Default callback args to C_Initialize */
/* XXX not const because we are modifying the pReserved argument in order
* to use the libraryParams extension.
*/
static CK_C_INITIALIZE_ARGS
s_ck_initialize_args = {
nss_ck_CreateMutex, /* CreateMutex */
@ -103,6 +148,171 @@ s_ck_initialize_args = {
NULL /* pReserved */
};
/* load all slots in a module. */
static PRStatus
module_load_slots(NSSModule *mod)
{
CK_ULONG i, ulNumSlots;
CK_SLOT_ID *slotIDs;
nssArenaMark *mark = NULL;
NSSSlot **slots;
PRStatus nssrv;
CK_RV ckrv;
/* Get the number of slots */
ckrv = CKAPI(mod->epv)->C_GetSlotList(CK_FALSE, NULL, &ulNumSlots);
if (ckrv != CKR_OK) {
/* what is the error? */
return PR_FAILURE;
}
/* Alloc memory for the array of slot ID's */
slotIDs = nss_ZNEWARRAY(NULL, CK_SLOT_ID, ulNumSlots);
if (!slotIDs) {
goto loser;
}
/* Get the actual slot list */
ckrv = CKAPI(mod->epv)->C_GetSlotList(CK_FALSE, slotIDs, &ulNumSlots);
if (ckrv != CKR_OK) {
/* what is the error? */
goto loser;
}
/* Alloc memory for the array of slots, in the module's arena */
mark = nssArena_Mark(mod->base.arena); /* why mark? it'll be destroyed */
if (!mark) {
return PR_FAILURE;
}
slots = nss_ZNEWARRAY(mod->base.arena, NSSSlot *, ulNumSlots);
if (!slots) {
goto loser;
}
/* Initialize each slot */
for (i=0; i<ulNumSlots; i++) {
slots[i] = nssSlot_Create(slotIDs[i], mod);
}
nss_ZFreeIf(slotIDs);
nssrv = nssArena_Unmark(mod->base.arena, mark);
if (nssrv != PR_SUCCESS) {
goto loser;
}
mod->slots = slots;
mod->numSlots = ulNumSlots;
return PR_SUCCESS;
loser:
if (mark) {
nssArena_Release(mod->base.arena, mark);
}
nss_ZFreeIf(slotIDs);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
nssModule_Load
(
NSSModule *mod
)
{
PRLibrary *library = NULL;
CK_C_GetFunctionList epv;
CK_RV ckrv;
if (NSSMODULE_IS_INTERNAL(mod)) {
/* internal, statically get the C_GetFunctionList function */
if (NSSMODULE_IS_FIPS(mod)) {
epv = (CK_C_GetFunctionList) FC_GetFunctionList;
} else {
epv = (CK_C_GetFunctionList) NSC_GetFunctionList;
}
if (NSSMODULE_IS_MODULE_DB(mod)) {
mod->moduleDBFunc = (void *) NSC_ModuleDBFunc;
}
if (NSSMODULE_IS_MODULE_DB_ONLY(mod)) {
mod->isLoaded = PR_TRUE; /* XXX needed? */
return PR_SUCCESS;
}
} else {
/* Use NSPR to load the library */
library = PR_LoadLibrary(mod->libraryName);
if (!library) {
/* what's the error to set? */
return PR_FAILURE;
}
mod->library = library;
/* Skip if only getting the db loader function */
if (!NSSMODULE_IS_MODULE_DB_ONLY(mod)) {
/* Load the cryptoki entry point function */
epv = (CK_C_GetFunctionList)PR_FindSymbol(library,
"C_GetFunctionList");
}
/* Load the module database loader function */
if (NSSMODULE_IS_MODULE_DB(mod)) {
mod->moduleDBFunc = (void *)PR_FindSymbol(library,
"NSS_ReturnModuleSpecData");
}
}
if (epv == NULL) {
goto loser;
}
/* Load the cryptoki entry point vector (function list) */
ckrv = (*epv)((CK_FUNCTION_LIST_PTR *)&mod->epv);
if (ckrv != CKR_OK) {
goto loser;
}
/* Initialize the module */
if (mod->libraryParams) {
s_ck_initialize_args.LibraryParameters = (void *)mod->libraryParams;
} else {
s_ck_initialize_args.LibraryParameters = NULL;
}
ckrv = CKAPI(mod->epv)->C_Initialize(&s_ck_initialize_args);
if (ckrv != CKR_OK) {
/* Apparently the token is not thread safe. Retry without
* threading parameters.
*/
mod->base.flags |= NSSMODULE_FLAGS_NOT_THREADSAFE;
ckrv = CKAPI(mod->epv)->C_Initialize((CK_VOID_PTR)NULL);
if (ckrv != CKR_OK) {
goto loser;
}
}
/* TODO: check the version # using C_GetInfo */
ckrv = CKAPI(mod->epv)->C_GetInfo(&mod->info);
if (ckrv != CKR_OK) {
goto loser;
}
/* TODO: if the name is not set, get it from info.libraryDescription */
/* Now load the slots */
if (module_load_slots(mod) != PR_SUCCESS) {
goto loser;
}
/* Module has successfully loaded */
mod->isLoaded = PR_TRUE;
return PR_SUCCESS;
loser:
if (library) {
PR_UnloadLibrary(library);
}
/* clear all values set above, they are invalid now */
mod->library = NULL;
mod->epv = NULL;
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
nssModule_Unload
(
NSSModule *mod
)
{
PRStatus nssrv = PR_SUCCESS;
if (mod->library) {
(void)CKAPI(mod->epv)->C_Finalize(NULL);
nssrv = PR_UnloadLibrary(mod->library);
}
/* Free the slots, yes? */
mod->library = NULL;
mod->epv = NULL;
mod->isLoaded = PR_FALSE;
return nssrv;
}
/* Alloc memory for a module. Copy in the module name and library path
* if provided. XXX use the opaque arg also, right?
*/
@ -130,21 +340,25 @@ nssModule_Create
/* if the name is a duplicate, should that be tested here? or
* wait for Load?
*/
rvMod->name = nssUTF8_Duplicate(moduleOpt, arena);
if (!rvMod->name) {
rvMod->base.name = nssUTF8_Duplicate(moduleOpt, arena);
if (!rvMod->base.name) {
goto loser;
}
}
if (uriOpt) {
/* Load the module from a URI. */
/* XXX at this time - only file URI (even worse, no file:// for now) */
rvMod->libraryPath = nssUTF8_Duplicate(uriOpt, arena);
if (!rvMod->libraryPath) {
rvMod->libraryName = nssUTF8_Duplicate(uriOpt, arena);
if (!rvMod->libraryName) {
goto loser;
}
}
rvMod->arena = arena;
rvMod->refCount = 1;
rvMod->base.arena = arena;
rvMod->base.refCount = 1;
rvMod->base.lock = PZ_NewLock(nssNSSILockOther);
if (!rvMod->base.lock) {
goto loser;
}
/* everything else is 0/NULL at this point. */
return rvMod;
loser:
@ -152,80 +366,401 @@ loser:
return (NSSModule *)NULL;
}
/* load all slots in a module. */
NSS_EXTERN PRStatus
nssCryptokiArgs_ParseNextPair
(
NSSUTF8 *start,
NSSUTF8 **attrib,
NSSUTF8 **value,
NSSUTF8 **remainder,
NSSArena *arenaOpt
);
static PRStatus
module_load_slots(NSSModule *mod)
parse_slot_flags
(
NSSSlot *slot,
NSSUTF8 *slotFlags
)
{
PRStatus nssrv = PR_SUCCESS;
#if 0
PRBool done = PR_FALSE;
NSSUTF8 *mark, *last;
last = mark = slotFlags;
while (PR_TRUE) {
while (*mark && *mark != ',') ++mark;
if (!*mark) done = PR_TRUE;
*mark = '\0';
if (nssUTF8_Equal(last, "RANDOM", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_HAS_RANDOM;
} else if (nssUTF8_Equal(last, "RSA", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_RSA;
} else if (nssUTF8_Equal(last, "DSA", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_DSA;
} else if (nssUTF8_Equal(last, "DH", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_DH;
} else if (nssUTF8_Equal(last, "RC2", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_RC2;
} else if (nssUTF8_Equal(last, "RC4", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_RC4;
} else if (nssUTF8_Equal(last, "RC5", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_RC5;
} else if (nssUTF8_Equal(last, "DES", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_DES;
} else if (nssUTF8_Equal(last, "AES", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_AES;
} else if (nssUTF8_Equal(last, "SHA1", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_SHA1;
} else if (nssUTF8_Equal(last, "MD2", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_MD2;
} else if (nssUTF8_Equal(last, "MD5", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_MD5;
} else if (nssUTF8_Equal(last, "SSL", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_SSL;
} else if (nssUTF8_Equal(last, "TLS", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_TLS;
} else if (nssUTF8_Equal(last, "PublicCerts", &nssrv)) {
slot->base.flags |= NSSSLOT_FLAGS_FRIENDLY;
} else {
return PR_FAILURE;
}
if (done) break;
last = ++mark;
}
#endif
return nssrv;
}
static PRStatus
parse_slot_parameters
(
NSSSlot *slot,
NSSUTF8 *slotParams,
NSSArena *tmparena
)
{
PRStatus nssrv = PR_SUCCESS;
NSSUTF8 *current, *remainder;
NSSUTF8 *attrib, *value;
current = slotParams;
while (nssrv == PR_SUCCESS) {
nssrv = nssCryptokiArgs_ParseNextPair(current,
&attrib, &value,
&remainder, tmparena);
if (nssrv != PR_SUCCESS) break;
if (value) {
if (nssUTF8_Equal(attrib, "slotFlags", &nssrv)) {
nssrv = parse_slot_flags(slot, value);
} else if (nssUTF8_Equal(attrib, "askpw", &nssrv)) {
} else if (nssUTF8_Equal(attrib, "timeout", &nssrv)) {
}
}
if (*remainder == '\0') break;
current = remainder;
}
return nssrv;
}
/* softoken seems to use "0x0000001", but no standard yet... perhaps this
* should store the number as an ID, in case the input isn't 1,2,3,...?
*/
static PRIntn
get_slot_number(NSSUTF8* snString)
{
/* XXX super big hack */
return atoi(&snString[strlen(snString)-1]);
}
static PRStatus
parse_module_slot_parameters
(
NSSModule *mod,
NSSUTF8 *slotParams
)
{
PRStatus nssrv = PR_SUCCESS;
NSSUTF8 *current, *remainder;
NSSUTF8 *attrib, *value;
NSSArena *tmparena;
PRIntn slotNum;
tmparena = nssArena_Create();
if (!tmparena) {
return PR_FAILURE;
}
current = slotParams;
while (nssrv == PR_SUCCESS) {
nssrv = nssCryptokiArgs_ParseNextPair(current,
&attrib, &value,
&remainder, tmparena);
if (nssrv != PR_SUCCESS) break;
if (value) {
slotNum = get_slot_number(attrib);
if (slotNum < 0 || slotNum > mod->numSlots) {
return PR_FAILURE;
}
nssrv = parse_slot_parameters(mod->slots[slotNum],
value, tmparena);
if (nssrv != PR_SUCCESS) break;
}
if (*remainder == '\0') break;
current = remainder;
}
return nssrv;
}
static PRStatus
parse_nss_flags
(
NSSModule *mod,
NSSUTF8 *nssFlags
)
{
PRStatus nssrv = PR_SUCCESS;
PRBool done = PR_FALSE;
NSSUTF8 *mark, *last;
last = mark = nssFlags;
while (PR_TRUE) {
while (*mark && *mark != ',') ++mark;
if (!*mark) done = PR_TRUE;
*mark = '\0';
if (nssUTF8_Equal(last, "internal", &nssrv)) {
mod->base.flags |= NSSMODULE_FLAGS_INTERNAL;
} else if (nssUTF8_Equal(last, "moduleDB", &nssrv)) {
mod->base.flags |= NSSMODULE_FLAGS_MODULE_DB;
} else if (nssUTF8_Equal(last, "moduleDBOnly", &nssrv)) {
mod->base.flags |= NSSMODULE_FLAGS_MODULE_DB_ONLY;
} else if (nssUTF8_Equal(last, "critical", &nssrv)) {
mod->base.flags |= NSSMODULE_FLAGS_CRITICAL;
} else {
return PR_FAILURE;
}
if (done) break;
last = ++mark;
}
return nssrv;
}
static PRStatus
parse_nss_parameters
(
NSSModule *mod,
NSSUTF8 *nssParams,
NSSArena *tmparena,
NSSUTF8 **slotParams
)
{
PRStatus nssrv = PR_SUCCESS;
NSSUTF8 *current, *remainder;
NSSUTF8 *attrib, *value;
current = nssParams;
while (nssrv == PR_SUCCESS) {
nssrv = nssCryptokiArgs_ParseNextPair(current,
&attrib, &value,
&remainder, tmparena);
if (nssrv != PR_SUCCESS) break;
if (value) {
if (nssUTF8_Equal(attrib, "flags", &nssrv) ||
nssUTF8_Equal(attrib, "Flags", &nssrv)) {
nssrv = parse_nss_flags(mod, value);
} else if (nssUTF8_Equal(attrib, "trustOrder", &nssrv)) {
mod->order.trust = atoi(value);
} else if (nssUTF8_Equal(attrib, "cipherOrder", &nssrv)) {
mod->order.cipher = atoi(value);
} else if (nssUTF8_Equal(attrib, "ciphers", &nssrv)) {
} else if (nssUTF8_Equal(attrib, "slotParams", &nssrv)) {
/* slotParams doesn't get an arena, it is handled separately */
*slotParams = nssUTF8_Duplicate(value, NULL);
}
}
if (*remainder == '\0') break;
current = remainder;
}
return nssrv;
}
static PRStatus
parse_module_parameters
(
NSSModule *mod,
NSSUTF8 *moduleParams,
NSSUTF8 **slotParams
)
{
PRStatus nssrv = PR_SUCCESS;
NSSUTF8 *current, *remainder;
NSSUTF8 *attrib, *value;
NSSArena *arena = mod->base.arena;
NSSArena *tmparena;
current = moduleParams;
tmparena = nssArena_Create();
if (!tmparena) {
return PR_FAILURE;
}
while (nssrv == PR_SUCCESS) {
nssrv = nssCryptokiArgs_ParseNextPair(current,
&attrib, &value,
&remainder, tmparena);
if (nssrv != PR_SUCCESS) break;
if (value) {
if (nssUTF8_Equal(attrib, "name", &nssrv)) {
mod->base.name = nssUTF8_Duplicate(value, arena);
} else if (nssUTF8_Equal(attrib, "library", &nssrv)) {
mod->libraryName = nssUTF8_Duplicate(value, arena);
} else if (nssUTF8_Equal(attrib, "parameters", &nssrv)) {
mod->libraryParams = nssUTF8_Duplicate(value, arena);
} else if (nssUTF8_Equal(attrib, "NSS", &nssrv)) {
parse_nss_parameters(mod, value, tmparena, slotParams);
}
}
if (*remainder == '\0') break;
current = remainder;
}
nssArena_Destroy(tmparena);
return nssrv;
}
static NSSUTF8 **
get_module_specs
(
NSSModule *mod
)
{
SECMODModuleDBFunc func = (SECMODModuleDBFunc)mod->moduleDBFunc;
if (func) {
return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
mod->libraryParams,
NULL);
}
return NULL;
}
/* XXX continue working on */
NSS_IMPLEMENT NSSModule *
nssModule_CreateFromSpec
(
NSSUTF8 *moduleSpec,
NSSModule *parent,
PRBool loadSubModules
)
{
CK_ULONG i, ulNumSlots;
CK_SLOT_ID *slotIDs;
nssArenaMark *mark = NULL;
NSSSlot **slots;
PRStatus nssrv;
CK_RV ckrv;
/* Get the number of slots */
ckrv = CKAPI(mod)->C_GetSlotList(CK_FALSE, NULL, &ulNumSlots);
if (ckrv != CKR_OK) {
/* what is the error? */
return PR_FAILURE;
NSSModule *thisModule;
NSSArena *arena;
NSSUTF8 *slotParams = NULL;
arena = nssArena_Create();
if (!arena) {
return NULL;
}
/* Alloc memory for the array of slot ID's */
slotIDs = nss_ZNEWARRAY(NULL, CK_SLOT_ID, ulNumSlots);
if (!slotIDs) {
thisModule = nss_ZNEW(arena, NSSModule);
if (!thisModule) {
goto loser;
}
/* Get the actual slot list */
ckrv = CKAPI(mod)->C_GetSlotList(CK_FALSE, slotIDs, &ulNumSlots);
if (ckrv != CKR_OK) {
/* what is the error? */
thisModule->base.lock = PZ_NewLock(nssILockOther);
if (!thisModule->base.lock) {
goto loser;
}
/* Alloc memory for the array of slots, in the module's arena */
mark = nssArena_Mark(mod->arena);
if (!mark) {
return PR_FAILURE;
}
slots = nss_ZNEWARRAY(mod->arena, NSSSlot *, ulNumSlots);
if (!slots) {
PR_AtomicIncrement(&thisModule->base.refCount);
thisModule->base.arena = arena;
thisModule->base.lock = PZ_NewLock(nssNSSILockOther);
if (!thisModule->base.lock) {
goto loser;
}
/* Initialize each slot */
for (i=0; i<ulNumSlots; i++) {
slots[i] = nssSlot_Create(mod->arena, slotIDs[i], mod);
}
nss_ZFreeIf(slotIDs);
nssrv = nssArena_Unmark(mod->arena, mark);
nssrv = parse_module_parameters(thisModule, moduleSpec, &slotParams);
if (nssrv != PR_SUCCESS) {
goto loser;
}
mod->slots = slots;
mod->numSlots = ulNumSlots;
return PR_SUCCESS;
loser:
if (mark) {
nssArena_Release(mod->arena, mark);
nssrv = nssModule_Load(thisModule);
if (nssrv != PR_SUCCESS) {
goto loser;
}
nss_ZFreeIf(slotIDs);
return PR_FAILURE;
if (slotParams) {
nssrv = parse_module_slot_parameters(thisModule, slotParams);
nss_ZFreeIf(slotParams);
if (nssrv != PR_SUCCESS) {
goto loser;
}
}
if (loadSubModules && NSSMODULE_IS_MODULE_DB(thisModule)) {
NSSUTF8 **moduleSpecs;
NSSUTF8 **index;
/* get the array of sub modules one level below this module */
moduleSpecs = get_module_specs(thisModule);
/* iterate over the array */
for (index = moduleSpecs; index && *index; index++) {
NSSModule *child;
/* load the child recursively */
child = nssModule_CreateFromSpec(*index, thisModule, PR_TRUE);
if (!child) {
/* when children fail, does the parent? */
nssrv = PR_FAILURE;
break;
}
if (NSSMODULE_IS_CRITICAL(child) && !child->isLoaded) {
nssrv = PR_FAILURE;
nssModule_Destroy(child);
break;
}
nssModule_Destroy(child);
/*nss_ZFreeIf(*index);*/
}
/*nss_ZFreeIf(moduleSpecs);*/
}
/* The global list inherits the reference */
nssrv = nssGlobalModuleList_Add(thisModule);
if (nssrv != PR_SUCCESS) {
goto loser;
}
return thisModule;
loser:
if (thisModule->base.lock) {
PZ_DestroyLock(thisModule->base.lock);
}
nssArena_Destroy(arena);
return (NSSModule *)NULL;
}
/* This is going to take much more thought. The module has a list of slots,
* each of which points to a token. Presumably, all are ref counted. Some
* kind of consistency check is needed here, or perhaps at a higher level.
*/
NSS_IMPLEMENT PRStatus
nssModule_Destroy
(
NSSModule *mod
)
{
PRUint32 i;
if (--mod->refCount == 0) {
/* Ignore any failure here. */
for (i=0; i<mod->numSlots; i++) {
nssSlot_Destroy(mod->slots[i]);
PRUint32 i, numSlots;
PR_AtomicDecrement(&mod->base.refCount);
if (mod->base.refCount == 0) {
if (mod->numSlots == 0) {
(void)nssModule_Unload(mod);
return nssArena_Destroy(mod->base.arena);
} else {
numSlots = mod->numSlots;
for (i=0; i<numSlots; i++) {
nssSlot_Destroy(mod->slots[i]);
}
}
}
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
nssModule_DestroyFromSlot
(
NSSModule *mod,
NSSSlot *slot
)
{
PRUint32 i, numSlots = 0;
PR_ASSERT(mod->base.refCount == 0);
for (i=0; i<mod->numSlots; i++) {
if (mod->slots[i] == slot) {
mod->slots[i] = NULL;
} else if (mod->slots[i]) {
numSlots++;
}
}
if (numSlots == 0) {
(void)nssModule_Unload(mod);
return NSSArena_Destroy(mod->arena);
return nssArena_Destroy(mod->base.arena);
}
return PR_SUCCESS;
}
@ -236,85 +771,70 @@ nssModule_AddRef
NSSModule *mod
)
{
++mod->refCount;
PR_AtomicIncrement(&mod->base.refCount);
return mod;
}
NSS_IMPLEMENT PRStatus
nssModule_Load
NSS_IMPLEMENT NSSUTF8 *
nssModule_GetName
(
NSSModule *mod
)
{
PRLibrary *library = NULL;
CK_C_GetFunctionList ep;
CK_RV ckrv;
/* Use NSPR to load the library */
library = PR_LoadLibrary((char *)mod->libraryPath);
if (!library) {
/* what's the error to set? */
return PR_FAILURE;
}
mod->library = library;
/* TODO: semantics here in SECMOD_LoadModule about module db */
/* Load the cryptoki entry point function */
ep = (CK_C_GetFunctionList)PR_FindSymbol(library, "C_GetFunctionList");
if (ep == NULL) {
goto loser;
}
/* Load the cryptoki entry point vector (function list) */
ckrv = (*ep)((CK_FUNCTION_LIST_PTR *)&mod->epv);
if (ckrv != CKR_OK) {
goto loser;
}
/* Initialize the module */
/* XXX This is where some additional parameters may need to come in,
* SECMOD_LoadModule has LibraryParameters
*/
ckrv = CKAPI(mod)->C_Initialize(&s_ck_initialize_args);
if (ckrv != CKR_OK) {
/* Apparently the token is not thread safe. Retry without
* threading parameters.
*/
mod->flags |= NSSMODULE_FLAGS_NOT_THREADSAFE;
ckrv = CKAPI(mod)->C_Initialize((CK_VOID_PTR)NULL);
if (ckrv != CKR_OK) {
goto loser;
}
}
/* TODO: check the version # using C_GetInfo */
/* TODO: if the name is not set, get it from info.libraryDescription */
/* Now load the slots */
if (module_load_slots(mod) != PR_SUCCESS) {
goto loser;
}
/* Module has successfully loaded */
return PR_SUCCESS;
loser:
if (library) {
PR_UnloadLibrary(library);
}
/* clear all values set above, they are invalid now */
mod->library = NULL;
mod->epv = NULL;
return PR_FAILURE;
return mod->base.name;
}
NSS_IMPLEMENT PRStatus
nssModule_Unload
NSS_IMPLEMENT PRBool
nssModule_IsThreadSafe
(
NSSModule *module
)
{
return NSSMODULE_IS_THREADSAFE(module);
}
NSS_IMPLEMENT PRBool
nssModule_IsInternal
(
NSSModule *mod
)
{
PRStatus nssrv = PR_SUCCESS;
if (mod->library) {
(void)CKAPI(mod)->C_Finalize(NULL);
nssrv = PR_UnloadLibrary(mod->library);
return NSSMODULE_IS_INTERNAL(mod);
}
NSS_IMPLEMENT PRBool
nssModule_IsModuleDBOnly
(
NSSModule *mod
)
{
return NSSMODULE_IS_MODULE_DB_ONLY(mod);
}
NSS_IMPLEMENT void *
nssModule_GetCryptokiEPV
(
NSSModule *mod
)
{
return mod->epv;
}
NSS_IMPLEMENT NSSSlot **
nssModule_GetSlots
(
NSSModule *mod
)
{
PRUint32 i;
NSSSlot **rvSlots;
rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, mod->numSlots + 1);
if (rvSlots) {
for (i=0; i<mod->numSlots; i++) {
rvSlots[i] = nssSlot_AddRef(mod->slots[i]);
}
}
/* Free the slots, yes? */
mod->library = NULL;
mod->epv = NULL;
return nssrv;
return rvSlots;
}
NSS_IMPLEMENT NSSSlot *
@ -326,9 +846,13 @@ nssModule_FindSlotByName
{
PRUint32 i;
PRStatus nssrv;
NSSSlot *slot;
NSSUTF8 *name;
for (i=0; i<mod->numSlots; i++) {
if (nssUTF8_Equal(mod->slots[i]->name, slotName, &nssrv)) {
return nssSlot_AddRef(mod->slots[i]);
slot = mod->slots[i];
name = nssSlot_GetName(slot);
if (nssUTF8_Equal(name, slotName, &nssrv)) {
return nssSlot_AddRef(slot);
}
if (nssrv != PR_SUCCESS) {
break;
@ -337,7 +861,7 @@ nssModule_FindSlotByName
return (NSSSlot *)NULL;
}
NSS_EXTERN NSSToken *
NSS_IMPLEMENT NSSToken *
nssModule_FindTokenByName
(
NSSModule *mod,
@ -347,50 +871,30 @@ nssModule_FindTokenByName
PRUint32 i;
PRStatus nssrv;
NSSToken *tok;
NSSUTF8 *name;
for (i=0; i<mod->numSlots; i++) {
tok = mod->slots[i]->token;
if (nssUTF8_Equal(tok->name, tokenName, &nssrv)) {
return nssToken_AddRef(tok);
}
if (nssrv != PR_SUCCESS) {
break;
tok = nssSlot_GetToken(mod->slots[i]);
if (tok) {
name = nssToken_GetName(tok);
if (nssUTF8_Equal(name, tokenName, &nssrv)) {
return tok;
}
if (nssrv != PR_SUCCESS) {
break;
}
}
}
return (NSSToken *)NULL;
}
NSS_IMPLEMENT PRStatus *
nssModule_TraverseCertificates
NSS_IMPLEMENT PRInt32
nssModule_GetCertOrder
(
NSSModule *mod,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
NSSModule *module
)
{
return NULL;
return 1; /* XXX */
}
#ifdef DEBUG
void
nssModule_Debug(NSSModule *m)
{
PRUint32 i;
printf("\n");
printf("Module Name: %s\n", m->name);
printf("Module Path: %s\n", m->libraryPath);
printf("Number of Slots in Module: %d\n\n", m->numSlots);
for (i=0; i<m->numSlots; i++) {
printf("\tSlot #%d\n", i);
if (m->slots[i]->name) {
printf("\tSlot Name: %s\n", m->slots[i]->name);
} else {
printf("\tSlot Name: <NULL>\n");
}
if (m->slots[i]->token) {
printf("\tToken Name: %s\n", m->slots[i]->token->name);
} else {
printf("\tToken: <NULL>\n");
}
}
}
#endif
#endif /* PURE_STAN_BUILD */

Просмотреть файл

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.22 $ $Date: 2002-04-03 19:22:11 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.23 $ $Date: 2002-04-04 20:00:22 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
@ -84,6 +84,7 @@ nssToken_DeleteStoredObject
PRStatus nssrv;
PRBool createdSession = PR_FALSE;
NSSToken *token = instance->token;
void *epv = token->epv;
nssSession *session = NULL;
if (nssCKObject_IsAttributeTrue(instance->handle, CKA_TOKEN,
token->defaultSession,
@ -99,7 +100,7 @@ nssToken_DeleteStoredObject
return PR_FAILURE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(token)->C_DestroyObject(session->handle, instance->handle);
ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle);
nssSession_ExitMonitor(session);
if (createdSession) {
nssSession_Destroy(session);
@ -121,6 +122,7 @@ import_object
{
nssSession *session = NULL;
PRBool createdSession = PR_FALSE;
void *epv = tok->epv;
CK_OBJECT_HANDLE object;
CK_RV ckrv;
if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
@ -143,7 +145,7 @@ import_object
return CK_INVALID_HANDLE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
ckrv = CKAPI(epv)->C_CreateObject(session->handle,
objectTemplate, otsize,
&object);
nssSession_ExitMonitor(session);
@ -169,21 +171,22 @@ find_object_by_template
CK_OBJECT_HANDLE rvObject = CK_INVALID_HANDLE;
CK_ULONG count = 0;
CK_RV ckrv;
void *epv = tok->epv;
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
hSession = session->handle;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
ckrv = CKAPI(epv)->C_FindObjectsInit(hSession, cktemplate, ctsize);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_HANDLE;
}
ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
ckrv = CKAPI(epv)->C_FindObjects(hSession, &rvObject, 1, &count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_HANDLE;
}
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
ckrv = CKAPI(epv)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
return CK_INVALID_HANDLE;
@ -215,18 +218,19 @@ traverse_objects_by_template
nssSession *session;
nssList *objectList = NULL;
int objectStackSize = OBJECT_STACK_SIZE;
void *epv = tok->epv;
slot = tok->slot;
objectStack = startOS;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
hSession = session->handle;
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_FindObjectsInit(hSession, obj_template, otsize);
ckrv = CKAPI(epv)->C_FindObjectsInit(hSession, obj_template, otsize);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
goto loser;
}
while (PR_TRUE) {
ckrv = CKAPI(slot)->C_FindObjects(hSession, objectStack,
ckrv = CKAPI(epv)->C_FindObjects(hSession, objectStack,
objectStackSize, &count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
@ -250,7 +254,7 @@ traverse_objects_by_template
break;
}
}
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
ckrv = CKAPI(epv)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
goto loser;
@ -1100,3 +1104,31 @@ loser:
return (NSSTrust *)NULL;
}
NSS_IMPLEMENT PRBool
nssToken_HasCrls
(
NSSToken *tok
)
{
return !tok->hasNoCrls;
}
NSS_IMPLEMENT PRStatus
nssToken_SetHasCrls
(
NSSToken *tok
)
{
tok->hasNoCrls = PR_FALSE;
return PR_SUCCESS;
}
NSS_IMPLEMENT PRBool
nssToken_IsPresent
(
NSSToken *token
)
{
return nssSlot_IsTokenPresent(token->slot);
}

Просмотреть файл

@ -32,37 +32,65 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devslot.c,v $ $Revision: 1.2 $ $Date: 2001-12-07 01:35:53 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devslot.c,v $ $Revision: 1.3 $ $Date: 2002-04-04 20:00:22 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifndef NSSCKEPV_H
#include "nssckepv.h"
#endif /* NSSCKEPV_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
#ifdef NSS_3_4_CODE
#include "pkcs11.h"
#else
#ifndef NSSCKEPV_H
#include "nssckepv.h"
#endif /* NSSCKEPV_H */
#endif /* NSS_3_4_CODE */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
/* measured in seconds */
#define NSSSLOT_TOKEN_DELAY_TIME 10
/* this should track global and per-transaction login information */
#ifdef PURE_STAN_CODE
typedef enum {
nssSlotAskPasswordTimes_FirstTime = 0,
nssSlotAskPasswordTimes_EveryTime = 1,
nssSlotAskPasswordTimes_Timeout = 2
}
nssSlotAskPasswordTimes;
struct nssSlotAuthInfoStr
{
PRTime lastLogin;
nssSlotAskPasswordTimes askTimes;
PRIntervalTime askPasswordTimeout;
};
struct NSSSlotStr
{
struct nssDeviceBaseStr base;
NSSModule *module; /* Parent */
NSSToken *token; /* Peer */
CK_SLOT_ID slotID;
CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
struct nssSlotAuthInfoStr authInfo;
PRIntervalTime lastTokenPing;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
#endif
};
#endif /* PURE_STAN_CODE */
#define NSSSLOT_IS_FRIENDLY(slot) \
(slot->base.flags & NSSSLOT_FLAGS_FRIENDLY)
/* measured as interval */
static PRIntervalTime s_token_delay_time = 0;
/* The flags needed to open a read-only session. */
static const CK_FLAGS s_ck_readonly_flags = CKF_SERIAL_SESSION;
#ifdef PURE_STAN
/* In pk11slot.c, this was a no-op. So it is here also. */
static CK_RV PR_CALLBACK
nss_ck_slot_notify
@ -74,56 +102,41 @@ nss_ck_slot_notify
{
return CKR_OK;
}
#endif
/* maybe this should really inherit completely from the module... I dunno,
* any uses of slots where independence is needed?
*/
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT NSSSlot *
nssSlot_Create
(
NSSArena *arenaOpt,
CK_SLOT_ID slotID,
NSSModule *parent
)
{
NSSArena *arena = NULL;
nssArenaMark *mark = NULL;
NSSSlot *rvSlot;
NSSToken *token = NULL;
NSSUTF8 *slotName = NULL;
PRUint32 length;
PRBool newArena;
PRStatus nssrv;
CK_SLOT_INFO slotInfo;
CK_RV ckrv;
if (arenaOpt) {
arena = arenaOpt;
mark = nssArena_Mark(arena);
if (!mark) {
return (NSSSlot *)NULL;
}
newArena = PR_FALSE;
} else {
arena = NSSArena_Create();
if(!arena) {
return (NSSSlot *)NULL;
}
newArena = PR_TRUE;
void *epv;
arena = NSSArena_Create();
if(!arena) {
return (NSSSlot *)NULL;
}
rvSlot = nss_ZNEW(arena, NSSSlot);
if (!rvSlot) {
goto loser;
}
/* Get slot information */
ckrv = CKAPI(parent)->C_GetSlotInfo(slotID, &slotInfo);
epv = nssModule_GetCryptokiEPV(parent);
ckrv = CKAPI(epv)->C_GetSlotInfo(slotID, &slotInfo);
if (ckrv != CKR_OK) {
/* set an error here, eh? */
goto loser;
}
/* Grab the slot description from the PKCS#11 fixed-length buffer */
length = nssPKCS11StringLength(slotInfo.slotDescription,
sizeof(slotInfo.slotDescription));
length = nssPKCS11String_Length(slotInfo.slotDescription,
sizeof(slotInfo.slotDescription));
if (length > 0) {
slotName = nssUTF8_Create(arena, nssStringType_UTF8String,
(void *)slotInfo.slotDescription, length);
@ -131,45 +144,31 @@ nssSlot_Create
goto loser;
}
}
if (!arenaOpt) {
/* Avoid confusion now - only set the slot's arena to a non-NULL value
* if a new arena is created. Otherwise, depend on the caller (having
* passed arenaOpt) to free the arena.
*/
rvSlot->arena = arena;
rvSlot->base.arena = arena;
rvSlot->base.refCount = 1;
rvSlot->base.name = slotName;
rvSlot->base.lock = PZ_NewLock(nssNSSILockOther); /* XXX */
if (!rvSlot->base.lock) {
goto loser;
}
rvSlot->refCount = 1;
rvSlot->epv = parent->epv;
rvSlot->module = parent;
rvSlot->name = slotName;
rvSlot->module = parent; /* refs go from module to slots */
rvSlot->slotID = slotID;
rvSlot->ckFlags = slotInfo.flags;
/* Initialize the token if present. */
if (slotInfo.flags & CKF_TOKEN_PRESENT) {
token = nssToken_Create(arena, slotID, rvSlot);
token = nssToken_Create(slotID, rvSlot);
if (!token) {
goto loser;
}
}
rvSlot->token = token;
if (mark) {
nssrv = nssArena_Unmark(arena, mark);
if (nssrv != PR_SUCCESS) {
goto loser;
}
}
return rvSlot;
loser:
if (newArena) {
nssArena_Destroy(arena);
} else {
if (mark) {
nssArena_Release(arena, mark);
}
}
nssArena_Destroy(arena);
/* everything was created in the arena, nothing to see here, move along */
return (NSSSlot *)NULL;
}
#endif /* PURE_STAN_BUILD */
NSS_IMPLEMENT PRStatus
nssSlot_Destroy
@ -177,46 +176,304 @@ nssSlot_Destroy
NSSSlot *slot
)
{
if (--slot->refCount == 0) {
#ifndef NSS_3_4_CODE
/* Not going to do this in 3.4, maybe never */
#ifdef PURE_STAN_BUILD
PR_AtomicDecrement(&slot->base.refCount);
if (slot->base.refCount == 0) {
nssToken_Destroy(slot->token);
#endif
if (slot->arena) {
return NSSArena_Destroy(slot->arena);
} else {
nss_ZFreeIf(slot);
}
nssModule_DestroyFromSlot(slot->module, slot);
return nssArena_Destroy(slot->base.arena);
}
#endif
return PR_SUCCESS;
}
NSS_IMPLEMENT void
NSSSlot_Destroy
(
NSSSlot *slot
)
{
(void)nssSlot_Destroy(slot);
}
NSS_IMPLEMENT NSSSlot *
nssSlot_AddRef
(
NSSSlot *slot
)
{
++slot->refCount;
PR_AtomicIncrement(&slot->base.refCount);
return slot;
}
NSS_IMPLEMENT NSSUTF8 *
nssSlot_GetName
(
NSSSlot *slot,
NSSArena *arenaOpt
NSSSlot *slot
)
{
if (slot->name) {
return nssUTF8_Duplicate(slot->name, arenaOpt);
return slot->base.name;
}
NSS_IMPLEMENT NSSUTF8 *
nssSlot_GetTokenName
(
NSSSlot *slot
)
{
return nssToken_GetName(slot->token);
}
static PRBool
within_token_delay_period(NSSSlot *slot)
{
PRIntervalTime time, lastTime;
/* Set the delay time for checking the token presence */
if (s_token_delay_time == 0) {
s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME);
}
return (NSSUTF8 *)NULL;
time = PR_IntervalNow();
lastTime = slot->lastTokenPing;
if ((time > lastTime) && ((time - lastTime) < s_token_delay_time)) {
return PR_TRUE;
}
slot->lastTokenPing = time;
return PR_FALSE;
}
NSS_IMPLEMENT PRBool
nssSlot_IsTokenPresent
(
NSSSlot *slot
)
{
CK_RV ckrv;
PRStatus nssrv;
/* XXX */
nssSession *session;
CK_SLOT_INFO slotInfo;
void *epv;
/* permanent slots are always present */
if (nssSlot_IsPermanent(slot)) {
return PR_TRUE;
}
/* avoid repeated calls to check token status within set interval */
if (within_token_delay_period(slot)) {
return (PRBool)((slot->ckFlags & CKF_TOKEN_PRESENT) != 0);
}
/* First obtain the slot info */
#ifdef PURE_STAN_BUILD
epv = nssModule_GetCryptokiEPV(slot->module);
#else
epv = slot->epv;
#endif
if (!epv) {
return PR_FALSE;
}
ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo);
if (ckrv != CKR_OK) {
slot->token->base.name[0] = 0; /* XXX */
return PR_FALSE;
}
slot->ckFlags = slotInfo.flags;
/* check for the presence of the token */
if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
if (!slot->token) {
/* token was ne'er present */
return PR_FALSE;
}
session = nssToken_GetDefaultSession(slot->token);
nssSession_EnterMonitor(session);
/* token is not present */
if (session->handle != CK_INVALID_SESSION) {
/* session is valid, close and invalidate it */
CKAPI(epv)->C_CloseSession(session->handle);
session->handle = CK_INVALID_SESSION;
}
nssSession_ExitMonitor(session);
slot->token->base.name[0] = 0; /* XXX */
return PR_FALSE;
#ifdef PURE_STAN_CODE
} else if (!slot->token) {
/* token was not present at boot time, is now */
slot->token = nssToken_Create(slot->slotID, slot);
return (slot->token != NULL);
#endif
}
/* token is present, use the session info to determine if the card
* has been removed and reinserted.
*/
session = nssToken_GetDefaultSession(slot->token);
nssSession_EnterMonitor(session);
if (session->handle != CK_INVALID_SESSION) {
CK_SESSION_INFO sessionInfo;
ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo);
if (ckrv != CKR_OK) {
/* session is screwy, close and invalidate it */
CKAPI(epv)->C_CloseSession(session->handle);
session->handle = CK_INVALID_SESSION;
}
}
nssSession_ExitMonitor(session);
/* token not removed, finished */
if (session->handle != CK_INVALID_SESSION) {
return PR_TRUE;
} else {
/* token has been removed, need to refresh with new session */
nssrv = nssSlot_Refresh(slot);
if (nssrv != PR_SUCCESS) {
slot->token->base.name[0] = 0; /* XXX */
return PR_FALSE;
}
return PR_TRUE;
}
}
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT NSSModule *
nssSlot_GetModule
(
NSSSlot *slot
)
{
return nssModule_AddRef(slot->module);
}
#endif /* PURE_STAN_BUILD */
NSS_IMPLEMENT void *
nssSlot_GetCryptokiEPV
(
NSSSlot *slot
)
{
#ifdef PURE_STAN_BUILD
return nssModule_GetCryptokiEPV(slot->module);
#else
return slot->epv;
#endif
}
NSS_IMPLEMENT NSSToken *
nssSlot_GetToken
(
NSSSlot *slot
)
{
if (nssSlot_IsTokenPresent(slot)) {
return nssToken_AddRef(slot->token);
}
return (NSSToken *)NULL;
}
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRBool
nssSlot_IsPermanent
(
NSSSlot *slot
)
{
return (!(slot->ckFlags & CKF_REMOVABLE_DEVICE));
}
NSS_IMPLEMENT PRBool
nssSlot_IsFriendly
(
NSSSlot *slot
)
{
return PR_TRUE /* XXX NSSSLOT_IS_FRIENDLY(slot)*/;
}
NSS_IMPLEMENT PRBool
nssSlot_IsHardware
(
NSSSlot *slot
)
{
return (slot->ckFlags & CKF_HW_SLOT);
}
NSS_IMPLEMENT PRStatus
nssSlot_Refresh
(
NSSSlot *slot
)
{
/* XXX */
#if 0
nssToken_Destroy(slot->token);
if (slotInfo.flags & CKF_TOKEN_PRESENT) {
slot->token = nssToken_Create(NULL, slotID, slot);
}
#endif
return PR_SUCCESS;
}
static PRBool
slot_needs_login
(
NSSSlot *slot,
nssSession *session
)
{
PRBool needsLogin, logout;
struct nssSlotAuthInfoStr *authInfo = &slot->authInfo;
void *epv = nssModule_GetCryptokiEPV(slot->module);
if (!nssToken_IsLoginRequired(slot->token)) {
return PR_FALSE;
}
if (authInfo->askTimes == nssSlotAskPasswordTimes_EveryTime) {
logout = PR_TRUE;
} else if (authInfo->askTimes == nssSlotAskPasswordTimes_Timeout) {
PRIntervalTime currentTime = PR_IntervalNow();
if (authInfo->lastLogin - currentTime < authInfo->askPasswordTimeout) {
logout = PR_FALSE;
} else {
logout = PR_TRUE;
}
} else { /* nssSlotAskPasswordTimes_FirstTime */
logout = PR_FALSE;
}
if (logout) {
/* The login has expired, timeout */
nssSession_EnterMonitor(session);
CKAPI(epv)->C_Logout(session->handle);
nssSession_ExitMonitor(session);
needsLogin = PR_TRUE;
} else {
CK_RV ckrv;
CK_SESSION_INFO sessionInfo;
nssSession_EnterMonitor(session);
ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
/* XXX error -- invalidate session */
return PR_FALSE;
}
switch (sessionInfo.state) {
case CKS_RW_PUBLIC_SESSION:
case CKS_RO_PUBLIC_SESSION:
default:
needsLogin = PR_TRUE;
break;
case CKS_RW_USER_FUNCTIONS:
case CKS_RW_SO_FUNCTIONS:
case CKS_RO_USER_FUNCTIONS:
needsLogin = PR_FALSE;
break;
}
}
return needsLogin;
}
static PRStatus
nssslot_login(NSSSlot *slot, nssSession *session,
CK_USER_TYPE userType, NSSCallback *pwcb)
slot_login
(
NSSSlot *slot,
nssSession *session,
CK_USER_TYPE userType,
NSSCallback *pwcb
)
{
PRStatus nssrv;
PRUint32 attempts;
@ -224,15 +481,19 @@ nssslot_login(NSSSlot *slot, nssSession *session,
NSSUTF8 *password = NULL;
CK_ULONG pwLen;
CK_RV ckrv;
void *epv;
if (!pwcb->getPW) {
/* set error INVALID_ARG */
return PR_FAILURE;
}
epv = nssModule_GetCryptokiEPV(slot->module);
keepTrying = PR_TRUE;
nssrv = PR_FAILURE;
attempts = 0;
while (keepTrying) {
nssrv = pwcb->getPW(slot->name, &attempts, pwcb->arg, &password);
/* use the token name, since it is present */
NSSUTF8 *tokenName = nssToken_GetName(slot->token);
nssrv = pwcb->getPW(tokenName, attempts, pwcb->arg, &password);
if (nssrv != PR_SUCCESS) {
nss_SetError(NSS_ERROR_USER_CANCELED);
break;
@ -242,8 +503,8 @@ nssslot_login(NSSSlot *slot, nssSession *session,
break;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_Login(session->handle, userType,
(CK_CHAR_PTR)password, pwLen);
ckrv = CKAPI(epv)->C_Login(session->handle, userType,
(CK_CHAR_PTR)password, pwLen);
nssSession_ExitMonitor(session);
switch (ckrv) {
case CKR_OK:
@ -265,129 +526,130 @@ nssslot_login(NSSSlot *slot, nssSession *session,
password = NULL;
++attempts;
}
nss_ZFreeIf(password);
return nssrv;
}
static PRStatus
nssslot_init_password(NSSSlot *slot, nssSession *rwSession, NSSCallback *pwcb)
init_slot_password
(
NSSSlot *slot,
nssSession *rwSession,
NSSUTF8 *password
)
{
NSSUTF8 *userPW = NULL;
NSSUTF8 *ssoPW = NULL;
PRStatus nssrv;
PRStatus status;
NSSUTF8 *ssoPW = "";
CK_ULONG userPWLen, ssoPWLen;
CK_RV ckrv;
if (!pwcb->getInitPW) {
/* set error INVALID_ARG */
return PR_FAILURE;
}
void *epv = nssModule_GetCryptokiEPV(slot->module);
/* Get the SO and user passwords */
nssrv = pwcb->getInitPW(slot->name, pwcb->arg, &ssoPW, &userPW);
if (nssrv != PR_SUCCESS) goto loser;
userPWLen = (CK_ULONG)nssUTF8_Length(userPW, &nssrv);
if (nssrv != PR_SUCCESS) goto loser;
ssoPWLen = (CK_ULONG)nssUTF8_Length(ssoPW, &nssrv);
if (nssrv != PR_SUCCESS) goto loser;
userPWLen = (CK_ULONG)nssUTF8_Length(password, &status);
if (status != PR_SUCCESS) {
goto loser;
}
ssoPWLen = (CK_ULONG)nssUTF8_Length(ssoPW, &status);
if (status != PR_SUCCESS) {
goto loser;
}
/* First log in as SO */
ckrv = CKAPI(slot)->C_Login(rwSession->handle, CKU_SO,
(CK_CHAR_PTR)ssoPW, ssoPWLen);
ckrv = CKAPI(epv)->C_Login(rwSession->handle, CKU_SO,
(CK_CHAR_PTR)ssoPW, ssoPWLen);
if (ckrv != CKR_OK) {
/* set error ...SO_LOGIN_FAILED */
goto loser;
}
/* Now change the user PIN */
ckrv = CKAPI(slot)->C_InitPIN(rwSession->handle,
(CK_CHAR_PTR)userPW, userPWLen);
ckrv = CKAPI(epv)->C_InitPIN(rwSession->handle,
(CK_CHAR_PTR)password, userPWLen);
if (ckrv != CKR_OK) {
/* set error */
goto loser;
}
nss_ZFreeIf(ssoPW);
nss_ZFreeIf(userPW);
return PR_SUCCESS;
loser:
nss_ZFreeIf(ssoPW);
nss_ZFreeIf(userPW);
return PR_FAILURE;
}
static PRStatus
nssslot_change_password(NSSSlot *slot, nssSession *rwSession, NSSCallback *pwcb)
change_slot_password
(
NSSSlot *slot,
nssSession *rwSession,
NSSUTF8 *oldPassword,
NSSUTF8 *newPassword
)
{
NSSUTF8 *userPW = NULL;
NSSUTF8 *newPW = NULL;
PRUint32 attempts;
PRStatus nssrv;
PRBool keepTrying = PR_TRUE;
PRStatus status;
CK_ULONG userPWLen, newPWLen;
CK_RV ckrv;
if (!pwcb->getNewPW) {
/* set error INVALID_ARG */
return PR_FAILURE;
void *epv = nssModule_GetCryptokiEPV(slot->module);
userPWLen = (CK_ULONG)nssUTF8_Length(oldPassword, &status);
if (status != PR_SUCCESS) {
return status;
}
attempts = 0;
while (keepTrying) {
nssrv = pwcb->getNewPW(slot->name, &attempts, pwcb->arg,
&userPW, &newPW);
if (nssrv != PR_SUCCESS) {
nss_SetError(NSS_ERROR_USER_CANCELED);
break;
}
userPWLen = (CK_ULONG)nssUTF8_Length(userPW, &nssrv);
if (nssrv != PR_SUCCESS) return nssrv;
newPWLen = (CK_ULONG)nssUTF8_Length(newPW, &nssrv);
if (nssrv != PR_SUCCESS) return nssrv;
nssSession_EnterMonitor(rwSession);
ckrv = CKAPI(slot)->C_SetPIN(rwSession->handle,
(CK_CHAR_PTR)userPW, userPWLen,
(CK_CHAR_PTR)newPW, newPWLen);
nssSession_ExitMonitor(rwSession);
switch (ckrv) {
case CKR_OK:
slot->authInfo.lastLogin = PR_Now();
nssrv = PR_SUCCESS;
keepTrying = PR_FALSE;
break;
case CKR_PIN_INCORRECT:
nss_SetError(NSS_ERROR_INVALID_PASSWORD);
keepTrying = PR_TRUE; /* received bad pw, keep going */
break;
default:
nssrv = PR_FAILURE;
keepTrying = PR_FALSE;
break;
}
nss_ZFreeIf(userPW);
nss_ZFreeIf(newPW);
userPW = NULL;
newPW = NULL;
++attempts;
newPWLen = (CK_ULONG)nssUTF8_Length(newPassword, &status);
if (status != PR_SUCCESS) {
return status;
}
nss_ZFreeIf(userPW);
nss_ZFreeIf(newPW);
return nssrv;
nssSession_EnterMonitor(rwSession);
ckrv = CKAPI(epv)->C_SetPIN(rwSession->handle,
(CK_CHAR_PTR)oldPassword, userPWLen,
(CK_CHAR_PTR)newPassword, newPWLen);
nssSession_ExitMonitor(rwSession);
switch (ckrv) {
case CKR_OK:
slot->authInfo.lastLogin = PR_Now();
status = PR_SUCCESS;
break;
case CKR_PIN_INCORRECT:
nss_SetError(NSS_ERROR_INVALID_PASSWORD);
status = PR_FAILURE;
break;
default:
status = PR_FAILURE;
break;
}
return status;
}
NSS_IMPLEMENT PRStatus
nssSlot_Login
(
NSSSlot *slot,
PRBool asSO,
NSSCallback *pwcb
)
{
PRBool needsLogin, needsInit;
CK_USER_TYPE userType;
userType = (asSO) ? CKU_SO : CKU_USER;
needsInit = PR_FALSE; /* XXX */
needsLogin = PR_TRUE; /* XXX */
if (needsInit) {
return nssSlot_SetPassword(slot, pwcb);
} else if (needsLogin) {
return nssslot_login(slot, slot->token->defaultSession,
userType, pwcb);
PRStatus status;
CK_USER_TYPE userType = CKU_USER;
NSSToken *token = nssSlot_GetToken(slot);
nssSession *session;
if (!token) {
return PR_FAILURE;
}
return PR_SUCCESS; /* login not required */
if (!nssToken_IsLoginRequired(token)) {
nssToken_Destroy(token);
return PR_SUCCESS;
}
session = nssToken_GetDefaultSession(slot->token);
if (nssToken_NeedsPINInitialization(token)) {
NSSUTF8 *password = NULL;
if (!pwcb->getInitPW) {
nssToken_Destroy(token);
return PR_FAILURE; /* don't know how to get initial password */
}
status = (*pwcb->getInitPW)(slot->base.name, pwcb->arg, &password);
if (status == PR_SUCCESS) {
session = nssSlot_CreateSession(slot, NULL, PR_TRUE);
status = init_slot_password(slot, session, password);
nssSession_Destroy(session);
}
} else if (slot_needs_login(slot, session)) {
status = slot_login(slot, session, userType, pwcb);
} else {
status = PR_SUCCESS;
}
nssToken_Destroy(token);
return status;
}
NSS_IMPLEMENT PRStatus
@ -397,12 +659,15 @@ nssSlot_Logout
nssSession *sessionOpt
)
{
nssSession *session;
PRStatus nssrv = PR_SUCCESS;
nssSession *session;
CK_RV ckrv;
session = (sessionOpt) ? sessionOpt : slot->token->defaultSession;
void *epv = nssModule_GetCryptokiEPV(slot->module);
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(slot->token);
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_Logout(session->handle);
ckrv = CKAPI(epv)->C_Logout(session->handle);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
/* translate the error */
@ -411,6 +676,16 @@ nssSlot_Logout
return nssrv;
}
NSS_IMPLEMENT PRBool
nssSlot_IsLoggedIn
(
NSSSlot *slot
)
{
nssSession *session = nssToken_GetDefaultSession(slot->token);
return !slot_needs_login(slot, session);
}
NSS_IMPLEMENT void
nssSlot_SetPasswordDefaults
(
@ -421,28 +696,36 @@ nssSlot_SetPasswordDefaults
slot->authInfo.askPasswordTimeout = askPasswordTimeout;
}
NSS_IMPLEMENT PRStatus
nssSlot_SetPassword
(
NSSSlot *slot,
NSSCallback *pwcb
NSSUTF8 *oldPasswordOpt,
NSSUTF8 *newPassword
)
{
PRStatus nssrv;
PRStatus status;
nssSession *rwSession;
PRBool needsInit;
needsInit = PR_FALSE; /* XXX */
NSSToken *token = nssSlot_GetToken(slot);
if (!token) {
return PR_FAILURE;
}
rwSession = nssSlot_CreateSession(slot, NULL, PR_TRUE);
if (needsInit) {
nssrv = nssslot_init_password(slot, rwSession, pwcb);
if (nssToken_NeedsPINInitialization(token)) {
status = init_slot_password(slot, rwSession, newPassword);
} else if (oldPasswordOpt) {
status = change_slot_password(slot, rwSession,
oldPasswordOpt, newPassword);
} else {
nssrv = nssslot_change_password(slot, rwSession, pwcb);
/* old password must be given in order to change */
status = PR_FAILURE;
}
nssSession_Destroy(rwSession);
return nssrv;
nssToken_Destroy(token);
return status;
}
#ifdef PURE_STAN
NSS_IMPLEMENT nssSession *
nssSlot_CreateSession
(
@ -453,18 +736,15 @@ nssSlot_CreateSession
{
CK_RV ckrv;
CK_FLAGS ckflags;
CK_SESSION_HANDLE session;
CK_SESSION_HANDLE handle;
void *epv = nssModule_GetCryptokiEPV(slot->module);
nssSession *rvSession;
ckflags = s_ck_readonly_flags;
if (readWrite) {
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);
ckrv = CKAPI(epv)->C_OpenSession(slot->slotID, ckflags,
slot, nss_ck_slot_notify, &handle);
if (ckrv != CKR_OK) {
/* set an error here, eh? */
return (nssSession *)NULL;
@ -473,7 +753,7 @@ nssSlot_CreateSession
if (!rvSession) {
return (nssSession *)NULL;
}
if (slot->module->flags & NSSMODULE_FLAGS_NOT_THREADSAFE) {
if (!nssModule_IsThreadSafe(slot->module)) {
/* If the parent module is not threadsafe, create lock to manage
* session within threads.
*/
@ -487,7 +767,7 @@ nssSlot_CreateSession
return (nssSession *)NULL;
}
}
rvSession->handle = session;
rvSession->handle = handle;
rvSession->slot = slot;
rvSession->isRW = readWrite;
return rvSession;
@ -501,7 +781,8 @@ nssSession_Destroy
{
CK_RV ckrv = CKR_OK;
if (s) {
ckrv = CKAPI(s->slot)->C_CloseSession(s->handle);
void *epv = s->slot->epv;
ckrv = CKAPI(epv)->C_CloseSession(s->handle);
if (s->lock) {
PZ_DestroyLock(s->lock);
}
@ -509,7 +790,7 @@ nssSession_Destroy
}
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}
#endif
#endif /* PURE_STAN_BUILD */
NSS_IMPLEMENT PRStatus
nssSession_EnterMonitor

Просмотреть файл

@ -35,7 +35,7 @@
#define DEVT_H
#ifdef DEBUG
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.13 $ $Date: 2002-03-07 23:21:33 $ $Name: $";
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.14 $ $Date: 2002-04-04 20:00:22 $ $Name: $";
#endif /* DEBUG */
/*
@ -72,60 +72,21 @@ PR_BEGIN_EXTERN_C
typedef struct nssSessionStr nssSession;
/* The list of boolean flags used to describe properties of a
* module.
*/
#define NSSMODULE_FLAGS_NOT_THREADSAFE 0x0001 /* isThreadSafe */
struct NSSModuleStr {
NSSArena *arena;
PRInt32 refCount;
NSSUTF8 *name;
NSSUTF8 *libraryPath;
PRLibrary *library;
void *epv;
NSSSlot **slots;
PRUint32 numSlots;
PRUint32 flags;
};
/* The list of boolean flags used to describe properties of a
* slot.
*/
#define NSSSLOT_FLAGS_LOGIN_REQUIRED 0x0001 /* needLogin */
/*#define NSSSLOT_FLAGS_READONLY 0x0002*/ /* readOnly */
/* this should track global and per-transaction login information */
struct nssSlotAuthInfoStr
/* XXX until NSSTokenStr is moved */
struct nssDeviceBaseStr
{
PRTime lastLogin;
PRInt32 askPasswordTimeout;
};
struct NSSSlotStr
{
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 nssSlotAuthInfoStr authInfo;
NSSTrustDomain *trustDomain;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
#endif
NSSArena *arena;
PZLock *lock;
PRInt32 refCount;
NSSUTF8 *name;
PRUint32 flags;
};
/* XXX until devobject.c goes away */
struct NSSTokenStr
{
NSSArena *arena;
PRInt32 refCount;
struct nssDeviceBaseStr base;
NSSSlot *slot; /* Parent (or peer, if you will) */
NSSUTF8 *name;
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
PRUint32 flags;
void *epv;
@ -141,12 +102,41 @@ struct NSSTokenStr
#endif
};
typedef enum {
nssSlotAskPasswordTimes_FirstTime = 0,
nssSlotAskPasswordTimes_EveryTime = 1,
nssSlotAskPasswordTimes_Timeout = 2
}
nssSlotAskPasswordTimes;
struct nssSlotAuthInfoStr
{
PRTime lastLogin;
nssSlotAskPasswordTimes askTimes;
PRIntervalTime askPasswordTimeout;
};
struct NSSSlotStr
{
struct nssDeviceBaseStr base;
NSSModule *module; /* Parent */
NSSToken *token; /* Peer */
CK_SLOT_ID slotID;
CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
struct nssSlotAuthInfoStr authInfo;
PRIntervalTime lastTokenPing;
#ifdef NSS_3_4_CODE
void *epv;
PK11SlotInfo *pk11slot;
#endif
};
struct nssSessionStr
{
PZLock *lock;
CK_SESSION_HANDLE handle;
NSSSlot *slot;
PRBool isRW;
PZLock *lock;
CK_SESSION_HANDLE handle;
NSSSlot *slot;
PRBool isRW;
};
typedef enum {
@ -154,17 +144,14 @@ typedef enum {
NSSCertificateType_PKIX = 1
} NSSCertificateType;
#ifdef nodef
typedef enum {
nssTrustLevel_Unknown = 0,
nssTrustLevel_NotTrusted = 1,
nssTrustLevel_Trusted = 2,
nssTrustLevel_TrustedDelegator = 3,
nssTrustLevel_Valid = 4
nssTrustLevel_Valid = 4,
nssTrustLevel_ValidDelegator = 5
} nssTrustLevel;
#else
typedef CK_ULONG nssTrustLevel; /* for now */
#endif
typedef struct nssCryptokiInstanceStr nssCryptokiInstance;
@ -176,6 +163,8 @@ struct nssCryptokiInstanceStr
NSSUTF8 *label;
};
typedef struct nssCryptokiInstanceStr nssCryptokiObject;
typedef struct nssTokenCertSearchStr nssTokenCertSearch;
typedef enum {
@ -195,6 +184,9 @@ struct nssTokenCertSearchStr
*/
};
struct nssSlotListStr;
typedef struct nssSlotListStr nssSlotList;
struct NSSAlgorithmAndParametersStr
{
CK_MECHANISM mechanism;

Просмотреть файл

@ -0,0 +1,60 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef DEVTM_H
#define DEVTM_H
#ifdef DEBUG
static const char DEVTM_CVS_ID[] = "@(#) $RCSfile: devtm.h,v $ $Revision: 1.1 $ $Date: 2002-04-04 20:00:22 $ $Name: $";
#endif /* DEBUG */
/*
* devtm.h
*
* This file contains module-private definitions for the low-level
* cryptoki devices.
*/
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
PR_BEGIN_EXTERN_C
#define MAX_LOCAL_CACHE_OBJECTS 10
typedef struct nssTokenObjectCacheStr nssTokenObjectCache;
PR_END_EXTERN_C
#endif /* DEVTM_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -32,21 +32,544 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.1 $ $Date: 2001-11-08 00:14:53 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.2 $ $Date: 2002-04-04 20:00:23 $ $Name: $";
#endif /* DEBUG */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT nssCryptokiObject *
nssCryptokiObject_Create
(
NSSToken *t,
nssSession *session,
CK_OBJECT_HANDLE h
)
{
PRStatus status;
NSSSlot *slot;
nssCryptokiObject *object;
CK_BBOOL *isTokenObject;
CK_ATTRIBUTE cert_template[] = {
{ CKA_TOKEN, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
slot = nssToken_GetSlot(t);
status = nssCKObject_GetAttributes(h, cert_template, 2,
NULL, session, slot);
nssSlot_Destroy(slot);
if (status != PR_SUCCESS) {
/* a failure here indicates a device error */
return (nssCryptokiObject *)NULL;
}
object = nss_ZNEW(NULL, nssCryptokiObject);
if (!object) {
return (nssCryptokiObject *)NULL;
}
object->handle = h;
object->token = nssToken_AddRef(t);
isTokenObject = (CK_BBOOL *)cert_template[0].pValue;
object->isTokenObject = *isTokenObject;
nss_ZFreeIf(isTokenObject);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label);
return object;
}
NSS_IMPLEMENT void
nssCryptokiObject_Destroy
(
nssCryptokiObject *object
)
{
if (object) {
nssToken_Destroy(object->token);
nss_ZFreeIf(object->label);
nss_ZFreeIf(object);
}
}
NSS_IMPLEMENT nssCryptokiObject *
nssCryptokiObject_Clone
(
nssCryptokiObject *object
)
{
nssCryptokiObject *rvObject;
rvObject = nss_ZNEW(NULL, nssCryptokiObject);
if (rvObject) {
rvObject->handle = object->handle;
rvObject->token = nssToken_AddRef(object->token);
rvObject->isTokenObject = object->isTokenObject;
if (object->label) {
rvObject->label = nssUTF8_Duplicate(object->label, NULL);
}
}
return rvObject;
}
NSS_EXTERN PRBool
nssCryptokiObject_Equal
(
nssCryptokiObject *o1,
nssCryptokiObject *o2
)
{
return (o1->token == o2->token && o1->handle == o2->handle);
}
NSS_IMPLEMENT PRUint32
nssPKCS11StringLength(CK_CHAR *pkcs11Str, PRUint32 bufLen)
nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen)
{
PRInt32 i;
for (i = bufLen - 1; i>=0; ) {
if (pkcs11Str[i] != ' ') break;
if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0') break;
--i;
}
return (PRUint32)(i + 1);
}
/*
* Slot arrays
*/
NSS_IMPLEMENT NSSSlot **
nssSlotArray_Clone
(
NSSSlot **slots
)
{
NSSSlot **rvSlots = NULL;
NSSSlot **sp = slots;
PRUint32 count = 0;
while (sp && *sp) count++;
if (count > 0) {
rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
if (rvSlots) {
sp = slots;
count = 0;
for (sp = slots; *sp; sp++) {
rvSlots[count++] = nssSlot_AddRef(*sp);
}
}
}
return rvSlots;
}
NSS_IMPLEMENT void
nssModuleArray_Destroy
(
NSSModule **modules
)
{
if (modules) {
NSSModule **mp;
for (mp = modules; *mp; mp++) {
nssModule_Destroy(*mp);
}
nss_ZFreeIf(modules);
}
}
NSS_IMPLEMENT void
nssSlotArray_Destroy
(
NSSSlot **slots
)
{
if (slots) {
NSSSlot **slotp;
for (slotp = slots; *slotp; slotp++) {
nssSlot_Destroy(*slotp);
}
nss_ZFreeIf(slots);
}
}
NSS_IMPLEMENT void
NSSSlotArray_Destroy
(
NSSSlot **slots
)
{
nssSlotArray_Destroy(slots);
}
NSS_IMPLEMENT void
nssTokenArray_Destroy
(
NSSToken **tokens
)
{
if (tokens) {
NSSToken **tokenp;
for (tokenp = tokens; *tokenp; tokenp++) {
nssToken_Destroy(*tokenp);
}
nss_ZFreeIf(tokens);
}
}
NSS_IMPLEMENT void
NSSTokenArray_Destroy
(
NSSToken **tokens
)
{
return nssTokenArray_Destroy(tokens);
}
NSS_IMPLEMENT void
nssCryptokiObjectArray_Destroy
(
nssCryptokiObject **objects
)
{
if (objects) {
nssCryptokiObject **op;
for (op = objects; *op; op++) {
nssCryptokiObject_Destroy(*op);
}
nss_ZFreeIf(objects);
}
}
/*
* Slot lists
*/
struct nssSlotListNodeStr
{
PRCList link;
NSSSlot *slot;
PRUint32 order;
};
/* XXX separate slots with non-present tokens? */
struct nssSlotListStr
{
NSSArena *arena;
PRBool i_allocated_arena;
PZLock *lock;
PRCList head;
PRUint32 count;
};
NSS_IMPLEMENT nssSlotList *
nssSlotList_Create
(
NSSArena *arenaOpt
)
{
nssSlotList *rvList;
NSSArena *arena;
nssArenaMark *mark;
if (arenaOpt) {
arena = arenaOpt;
mark = nssArena_Mark(arena);
if (!mark) {
return (nssSlotList *)NULL;
}
} else {
arena = nssArena_Create();
if (!arena) {
return (nssSlotList *)NULL;
}
}
rvList = nss_ZNEW(arena, nssSlotList);
if (!rvList) {
goto loser;
}
rvList->lock = PZ_NewLock(nssILockOther); /* XXX */
if (!rvList->lock) {
goto loser;
}
PR_INIT_CLIST(&rvList->head);
rvList->arena = arena;
rvList->i_allocated_arena = (arenaOpt == NULL);
nssArena_Unmark(arena, mark);
return rvList;
loser:
if (arenaOpt) {
nssArena_Release(arena, mark);
} else {
nssArena_Destroy(arena);
}
return (nssSlotList *)NULL;
}
NSS_IMPLEMENT void
nssSlotList_Destroy
(
nssSlotList *slotList
)
{
PRCList *link;
struct nssSlotListNodeStr *node;
if (slotList) {
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
node = (struct nssSlotListNodeStr *)link;
nssSlot_Destroy(node->slot);
link = PR_NEXT_LINK(link);
}
if (slotList->i_allocated_arena) {
nssArena_Destroy(slotList->arena);
}
}
}
/* XXX should do allocs outside of lock */
NSS_IMPLEMENT PRStatus
nssSlotList_Add
(
nssSlotList *slotList,
NSSSlot *slot,
PRUint32 order
)
{
PRCList *link;
struct nssSlotListNodeStr *node;
PZ_Lock(slotList->lock);
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
node = (struct nssSlotListNodeStr *)link;
if (order < node->order) {
break;
}
link = PR_NEXT_LINK(link);
}
node = nss_ZNEW(slotList->arena, struct nssSlotListNodeStr);
if (!node) {
return PR_FAILURE;
}
PR_INIT_CLIST(&node->link);
node->slot = nssSlot_AddRef(slot);
node->order = order;
PR_INSERT_AFTER(&node->link, link);
slotList->count++;
PZ_Unlock(slotList->lock);
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
nssSlotList_AddModuleSlots
(
nssSlotList *slotList,
NSSModule *module,
PRUint32 order
)
{
nssArenaMark *mark = NULL;
NSSSlot **sp, **slots = NULL;
PRCList *link;
struct nssSlotListNodeStr *node;
PZ_Lock(slotList->lock);
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
node = (struct nssSlotListNodeStr *)link;
if (order < node->order) {
break;
}
link = PR_NEXT_LINK(link);
}
slots = nssModule_GetSlots(module);
if (!slots) {
PZ_Unlock(slotList->lock);
return PR_SUCCESS;
}
mark = nssArena_Mark(slotList->arena);
if (!mark) {
goto loser;
}
for (sp = slots; *sp; sp++) {
node = nss_ZNEW(slotList->arena, struct nssSlotListNodeStr);
if (!node) {
goto loser;
}
PR_INIT_CLIST(&node->link);
node->slot = *sp; /* have ref from nssModule_GetSlots */
node->order = order;
PR_INSERT_AFTER(&node->link, link);
slotList->count++;
}
PZ_Unlock(slotList->lock);
nssArena_Unmark(slotList->arena, mark);
return PR_SUCCESS;
loser:
PZ_Unlock(slotList->lock);
if (mark) {
nssArena_Release(slotList->arena, mark);
}
if (slots) {
nssSlotArray_Destroy(slots);
}
return PR_FAILURE;
}
NSS_IMPLEMENT NSSSlot **
nssSlotList_GetSlots
(
nssSlotList *slotList
)
{
PRUint32 i;
PRCList *link;
struct nssSlotListNodeStr *node;
NSSSlot **rvSlots = NULL;
PZ_Lock(slotList->lock);
rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, slotList->count + 1);
if (!rvSlots) {
PZ_Unlock(slotList->lock);
return (NSSSlot **)NULL;
}
i = 0;
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
node = (struct nssSlotListNodeStr *)link;
rvSlots[i] = nssSlot_AddRef(node->slot);
link = PR_NEXT_LINK(link);
i++;
}
PZ_Unlock(slotList->lock);
return rvSlots;
}
#if 0
NSS_IMPLEMENT NSSSlot *
nssSlotList_GetBestSlotForAlgorithmAndParameters
(
nssSlotList *slotList,
NSSAlgorithmAndParameters *ap
)
{
PRCList *link;
struct nssSlotListNodeStr *node;
NSSSlot *rvSlot = NULL;
PZ_Lock(slotList->lock);
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
node = (struct nssSlotListNodeStr *)link;
if (nssSlot_DoesAlgorithmAndParameters(ap)) {
rvSlot = nssSlot_AddRef(node->slot); /* XXX check isPresent? */
}
link = PR_NEXT_LINK(link);
}
PZ_Unlock(slotList->lock);
return rvSlot;
}
#endif
NSS_IMPLEMENT NSSSlot *
nssSlotList_GetBestSlot
(
nssSlotList *slotList
)
{
PRCList *link;
struct nssSlotListNodeStr *node;
NSSSlot *rvSlot = NULL;
PZ_Lock(slotList->lock);
if (PR_CLIST_IS_EMPTY(&slotList->head)) {
PZ_Unlock(slotList->lock);
return (NSSSlot *)NULL;
}
link = PR_NEXT_LINK(&slotList->head);
node = (struct nssSlotListNodeStr *)link;
rvSlot = nssSlot_AddRef(node->slot); /* XXX check isPresent? */
PZ_Unlock(slotList->lock);
return rvSlot;
}
NSS_IMPLEMENT NSSSlot *
nssSlotList_FindSlotByName
(
nssSlotList *slotList,
NSSUTF8 *slotName
)
{
PRCList *link;
struct nssSlotListNodeStr *node;
NSSSlot *rvSlot = NULL;
PZ_Lock(slotList->lock);
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
NSSUTF8 *sName;
node = (struct nssSlotListNodeStr *)link;
sName = nssSlot_GetName(node->slot);
if (nssUTF8_Equal(sName, slotName, NULL)) {
rvSlot = nssSlot_AddRef(node->slot);
break;
}
link = PR_NEXT_LINK(link);
}
PZ_Unlock(slotList->lock);
return rvSlot;
}
NSS_IMPLEMENT NSSToken *
nssSlotList_FindTokenByName
(
nssSlotList *slotList,
NSSUTF8 *tokenName
)
{
PRCList *link;
struct nssSlotListNodeStr *node;
NSSToken *rvToken = NULL;
PZ_Lock(slotList->lock);
link = PR_NEXT_LINK(&slotList->head);
while (link != &slotList->head) {
NSSUTF8 *tName;
node = (struct nssSlotListNodeStr *)link;
tName = nssSlot_GetTokenName(node->slot);
if (nssUTF8_Equal(tName, tokenName, NULL)) {
rvToken = nssSlot_GetToken(node->slot);
break;
}
link = PR_NEXT_LINK(link);
}
PZ_Unlock(slotList->lock);
return rvToken;
}
#endif /* PURE_STAN_BUILD */
/* XXX of course this doesn't belong here */
NSS_IMPLEMENT NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateSHA1Digest
(
NSSArena *arenaOpt
)
{
NSSAlgorithmAndParameters *rvAP = NULL;
rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
if (rvAP) {
rvAP->mechanism.mechanism = CKM_SHA_1;
rvAP->mechanism.pParameter = NULL;
rvAP->mechanism.ulParameterLen = 0;
}
return rvAP;
}
NSS_IMPLEMENT NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateMD5Digest
(
NSSArena *arenaOpt
)
{
NSSAlgorithmAndParameters *rvAP = NULL;
rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
if (rvAP) {
rvAP->mechanism.mechanism = CKM_MD5;
rvAP->mechanism.pParameter = NULL;
rvAP->mechanism.ulParameterLen = 0;
}
return rvAP;
}

Просмотреть файл

@ -30,7 +30,7 @@
# may use your version of this file under either the MPL or the
# GPL.
#
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.5 $ $Date: 2002-03-14 04:12:15 $ $Name: $"
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.6 $ $Date: 2002-04-04 20:00:23 $ $Name: $"
CORE_DEPTH = ../../..
@ -39,6 +39,7 @@ PRIVATE_EXPORTS = \
devt.h \
dev.h \
nssdevt.h \
nssdev.h \
$(NULL)
EXPORTS = \

Просмотреть файл

@ -0,0 +1,72 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef NSSDEV_H
#define NSSDEV_H
#ifdef DEBUG
static const char NSSDEV_CVS_ID[] = "@(#) $RCSfile: nssdev.h,v $ $Revision: 1.1 $ $Date: 2002-04-04 20:00:23 $ $Name: $";
#endif /* DEBUG */
/*
* nssdev.h
*
* High-level methods for interaction with cryptoki devices
*/
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
PR_BEGIN_EXTERN_C
/* NSSAlgorithmAndParameters
*
* NSSAlgorithmAndParameters_CreateSHA1Digest
* NSSAlgorithmAndParameters_CreateMD5Digest
*/
NSS_EXTERN NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateSHA1Digest
(
NSSArena *arenaOpt
);
NSS_EXTERN NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateMD5Digest
(
NSSArena *arenaOpt
);
PR_END_EXTERN_C
#endif /* DEV_H */

Просмотреть файл

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.9 $ $Date: 2002-03-14 04:12:20 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.10 $ $Date: 2002-04-04 20:00:26 $ $Name: $";
#endif /* DEBUG */
#ifndef NSS_3_4_CODE
@ -121,13 +121,12 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
if (!rvSlot) {
return NULL;
}
rvSlot->refCount = 1;
rvSlot->base.refCount = 1;
rvSlot->pk11slot = nss3slot;
rvSlot->epv = nss3slot->functionList;
rvSlot->slotID = nss3slot->slotID;
rvSlot->trustDomain = td;
/* Grab the slot name from the PKCS#11 fixed-length buffer */
rvSlot->name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
return rvSlot;
}
@ -139,7 +138,7 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
if (!rvToken) {
return NULL;
}
rvToken->refCount = 1;
rvToken->base.refCount = 1;
rvToken->pk11slot = nss3slot;
rvToken->epv = nss3slot->functionList;
rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
@ -148,11 +147,11 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
nss3slot->defRWSession);
rvToken->trustDomain = td;
/* Grab the token name from the PKCS#11 fixed-length buffer */
rvToken->name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
rvToken->slot->token = rvToken;
rvToken->defaultSession->slot = rvToken->slot;
rvToken->arena = td->arena;
rvToken->base.arena = td->arena;
return rvToken;
}
@ -162,7 +161,7 @@ nssToken_UpdateName(NSSToken *token)
if (!token) {
return;
}
token->name = nssUTF8_Duplicate(token->pk11slot->token_name,token->arena);
token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
}
NSS_IMPLEMENT PRBool
@ -183,7 +182,7 @@ nssToken_Refresh(NSSToken *token)
return PR_SUCCESS;
}
nss3slot = token->pk11slot;
token->defaultSession = nssSession_ImportNSS3Session(token->slot->arena,
token->defaultSession = nssSession_ImportNSS3Session(token->slot->base.arena,
nss3slot->session,
nss3slot->sessionLock,
nss3slot->defRWSession);

Просмотреть файл

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.46 $ $Date: 2002-04-03 19:22:14 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.47 $ $Date: 2002-04-04 20:00:28 $ $Name: $";
#endif /* DEBUG */
/*
@ -254,7 +254,7 @@ nssToken_LoadCerts(NSSToken *token)
search.cached = NULL;
search.searchType = nssTokenSearchType_TokenOnly;
if (!token->certList) {
token->certList = nssList_Create(token->arena, PR_FALSE);
token->certList = nssList_Create(token->base.arena, PR_FALSE);
if (!token->certList) {
return PR_FAILURE;
}