зеркало из https://github.com/mozilla/pjs.git
initial checkin of the cryptoki device library code for stan. The current
amount of implemented code does little more than basic initialization of a module and loading of a module's slots and tokens.
This commit is contained in:
Родитель
06c75393c7
Коммит
e79146d929
|
@ -0,0 +1,38 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:07 $ $Name: $"
|
||||
|
||||
include manifest.mn
|
||||
include config.mk
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:07 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef PKIT_H
|
||||
#include "pkit.h"
|
||||
#endif /* PKIT_H */
|
||||
|
||||
#ifndef DEVT_H
|
||||
#include "devt.h"
|
||||
#endif /* DEVT_H */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
#include "nssckepv.h"
|
||||
#endif /* NSSCKEPV_H */
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_BBOOL
|
||||
g_ck_true = CK_TRUE;
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_BBOOL
|
||||
g_ck_false = CK_FALSE;
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_OBJECT_CLASS
|
||||
g_ck_obj_class_cert = CKO_CERTIFICATE;
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_OBJECT_CLASS
|
||||
g_ck_obj_class_pubkey = CKO_PUBLIC_KEY;
|
||||
|
||||
NSS_IMPLEMENT_DATA const CK_OBJECT_CLASS
|
||||
g_ck_obj_class_privkey = CKO_PRIVATE_KEY;
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSCKObject_GetAttributes
|
||||
(
|
||||
CK_OBJECT_HANDLE object,
|
||||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG count,
|
||||
NSSArena *arenaOpt,
|
||||
NSSSlot *slot
|
||||
)
|
||||
{
|
||||
nssArenaMark *mark;
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_ULONG i;
|
||||
CK_RV ckrv;
|
||||
PRStatus nssrv;
|
||||
/* use the default session */
|
||||
session = slot->token->session.handle;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
if (arenaOpt) {
|
||||
mark = nssArenaMark(arenaOpt);
|
||||
if (!mark) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Get the storage size needed for each attribute */
|
||||
ckrv = CKAPI(slot)->C_GetAttributeValue(session,
|
||||
object, obj_template, count);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here */
|
||||
goto loser;
|
||||
}
|
||||
/* Allocate memory for each attribute. */
|
||||
for (i=0; i<count; i++) {
|
||||
obj_template[i].pValue = nss_ZAlloc(arenaOpt,
|
||||
obj_template[i].ulValueLen);
|
||||
if (!obj_template[i].pValue) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
/* Obtain the actual attribute values. */
|
||||
ckrv = CKAPI(slot)->C_GetAttributeValue(session,
|
||||
object, obj_template, count);
|
||||
if (ckrv != CKR_OK) {
|
||||
/* set an error here */
|
||||
goto loser;
|
||||
}
|
||||
#ifdef arena_mark_bug_fixed
|
||||
if (arenaOpt) {
|
||||
nssrv = nssArena_Unmark(arenaOpt, mark);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
if (arenaOpt) {
|
||||
/* release all arena memory allocated before the failure. */
|
||||
#ifdef arena_mark_bug_fixed
|
||||
(void)nssArena_Release(arenaOpt, mark);
|
||||
#endif
|
||||
} else {
|
||||
CK_ULONG j;
|
||||
/* free each heap object that was allocated before the failure. */
|
||||
for (j=0; j<i; j++) {
|
||||
nss_ZFreeIf(obj_template[j].pValue);
|
||||
}
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ckhelper.h
|
||||
*
|
||||
* This file contains some helper utilities for interaction with cryptoki.
|
||||
*/
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#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: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* Boolean values */
|
||||
NSS_EXTERN_DATA const CK_BBOOL g_ck_true;
|
||||
NSS_EXTERN_DATA const CK_BBOOL 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_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; \
|
||||
|
||||
/* Get an array of attributes from an object. */
|
||||
NSS_EXTERN PRStatus
|
||||
NSSCKObject_GetAttributes
|
||||
(
|
||||
CK_OBJECT_HANDLE object,
|
||||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG count,
|
||||
NSSArena *arenaOpt,
|
||||
NSSSlot *slot
|
||||
);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* CKHELPER_H */
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
CONFIG_CVS_ID = "@(#) $RCSfile: config.mk,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:08 $ $Name: $"
|
||||
|
||||
ifdef BUILD_IDG
|
||||
DEFINES += -DNSSDEBUG
|
||||
endif
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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 DEV_H
|
||||
#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: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEVT_H
|
||||
#include "devt.h"
|
||||
#endif /* DEVT_H */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
#ifndef NSSPKIT_H
|
||||
#include "nsspkit.h"
|
||||
#endif /* NSSPKIT_H */
|
||||
|
||||
/*
|
||||
* nssdev.h
|
||||
*
|
||||
* This file prototypes the methods of the low-level cryptoki devices.
|
||||
*
|
||||
* |-----------|---> NSSSlot <--> NSSToken
|
||||
* | NSSModule |---> NSSSlot <--> NSSToken
|
||||
* |-----------|---> NSSSlot <--> NSSToken
|
||||
*/
|
||||
|
||||
#ifndef DEVT_H
|
||||
#include "devt.h"
|
||||
#endif /* DEVT_H */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
NSS_EXTERN NSSModule *
|
||||
NSSModule_Create
|
||||
(
|
||||
NSSUTF8 *moduleOpt,
|
||||
NSSUTF8 *uriOpt,
|
||||
NSSUTF8 *opaqueOpt, /* XXX is this where the mech flags go??? */
|
||||
void *reserved
|
||||
/* XXX more? */
|
||||
);
|
||||
|
||||
/* This is to use the new loading mechanism. */
|
||||
NSS_EXTERN NSSModule *
|
||||
NSSModule_CreateFromSpec
|
||||
(
|
||||
NSSUTF8 *moduleSpec
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSModule_Destroy
|
||||
(
|
||||
NSSModule *mod
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSModule_Load
|
||||
(
|
||||
NSSModule *mod
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSModule_Unload
|
||||
(
|
||||
NSSModule *mod
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSModule_LogoutAllSlots
|
||||
(
|
||||
NSSModule *mod
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSlot **
|
||||
NSSModule_GetSlots
|
||||
(
|
||||
NSSModule *mod
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSlot *
|
||||
NSSModule_FindSlotByName
|
||||
(
|
||||
NSSModule *mod,
|
||||
NSSUTF8 *slotName
|
||||
);
|
||||
|
||||
/* This descends from NSSTrustDomain_TraverseCertificates, a questionable
|
||||
* function. Do we want NSS to have access to this at the module level?
|
||||
*/
|
||||
NSS_EXTERN PRStatus *
|
||||
NSSModule_TraverseCertificates
|
||||
(
|
||||
NSSModule *mod,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSlot *
|
||||
NSSSlot_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_SLOT_ID slotId,
|
||||
NSSModule *parent
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSSlot_Destroy
|
||||
(
|
||||
NSSSlot *slot
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSSlot_Login
|
||||
(
|
||||
NSSSlot *slot
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSSlot_Logout
|
||||
(
|
||||
NSSSlot *slot
|
||||
);
|
||||
|
||||
/*
|
||||
* NSSSlot_IsLoggedIn
|
||||
* NSSSlot_ChangePassword
|
||||
*/
|
||||
|
||||
NSS_EXTERN NSSToken *
|
||||
NSSToken_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_SLOT_ID slotID,
|
||||
NSSSlot *parent
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSToken_Destroy
|
||||
(
|
||||
NSSToken *tok
|
||||
);
|
||||
|
||||
/* Given a raw attribute template, import an object
|
||||
* (certificate, public key, private key, symmetric key)
|
||||
* Return the object as an NSS type.
|
||||
*/
|
||||
NSS_EXTERN NSSCertificate *
|
||||
NSSToken_ImportCertificate
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPublicKey *
|
||||
NSSToken_ImportPublicKey
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPrivateKey *
|
||||
NSSToken_ImportPrivateKey
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSymmetricKey *
|
||||
NSSToken_ImportSymmetricKey
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_ATTRIBUTE *cktemplate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPublicKey *
|
||||
NSSToken_GenerateKeyPair
|
||||
(
|
||||
NSSToken *tok
|
||||
/* algorithm and parameters */
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSSymmetricKey *
|
||||
NSSToken_GenerateSymmetricKey
|
||||
(
|
||||
NSSToken *tok
|
||||
/* algorithm and parameters */
|
||||
);
|
||||
|
||||
/* Permanently remove an object from the token. */
|
||||
NSS_EXTERN PRStatus
|
||||
NSSToken_DeleteStoredObject
|
||||
(
|
||||
NSSToken *tok,
|
||||
CK_OBJECT_HANDLE object
|
||||
);
|
||||
|
||||
/* again, a questionable function. maybe some tokens allow this? */
|
||||
NSS_EXTERN PRStatus *
|
||||
NSSToken_TraverseCertificates
|
||||
(
|
||||
NSSToken *tok,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
void NSSModule_Debug(NSSModule *m);
|
||||
#endif
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* DEV_H */
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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 DEVM_H
|
||||
#define DEVM_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:09 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
#endif /* DEVM_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/* 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(
|
||||
CK_CHAR *pkcs11str,
|
||||
PRUint32 bufLen
|
||||
);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* DEV_H */
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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 DEVT_H
|
||||
#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: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* nssdevt.h
|
||||
*
|
||||
* This file contains definitions for the low-level cryptoki devices.
|
||||
*/
|
||||
|
||||
#ifndef NSSBASET_H
|
||||
#include "nssbaset.h"
|
||||
#endif /* NSSBASET_H */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* NSSModule and NSSSlot -- placeholders for the PKCS#11 types
|
||||
*/
|
||||
|
||||
typedef struct NSSModuleStr NSSModule;
|
||||
|
||||
typedef struct NSSSlotStr NSSSlot;
|
||||
|
||||
typedef struct NSSTokenStr NSSToken;
|
||||
|
||||
/* 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 */
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct NSSTokenStr;
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* DEVT_H */
|
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $"
|
||||
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
PRIVATE_EXPORTS = \
|
||||
ckhelper.h \
|
||||
devt.h \
|
||||
dev.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
MODULE = security
|
||||
|
||||
CSRCS = \
|
||||
module.c \
|
||||
slot.c \
|
||||
token.c \
|
||||
util.c \
|
||||
ckhelper.c \
|
||||
$(NULL)
|
||||
|
||||
REQUIRES = security nspr
|
||||
|
||||
LIBRARY_NAME = nssdev
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: module.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#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 CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
/* Threading callbacks for C_Initialize. Use NSPR threads. */
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
nss_ck_CreateMutex(CK_VOID_PTR_PTR pMutex)
|
||||
{
|
||||
CK_VOID_PTR mutex = (CK_VOID_PTR)PZ_NewLock(nssILockOther);
|
||||
if (mutex != NULL) {
|
||||
*pMutex = (CK_VOID_PTR)mutex;
|
||||
return CKR_OK;
|
||||
}
|
||||
return CKR_HOST_MEMORY;
|
||||
}
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
nss_ck_DestroyMutex(CK_VOID_PTR mutex)
|
||||
{
|
||||
PZ_DestroyLock((PZLock *)mutex);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
nss_ck_LockMutex(CK_VOID_PTR mutex)
|
||||
{
|
||||
PZ_Lock((PZLock *)mutex);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
CK_RV PR_CALLBACK
|
||||
nss_ck_UnlockMutex(CK_VOID_PTR mutex)
|
||||
{
|
||||
return (PZ_Unlock((PZLock *)mutex) == PR_SUCCESS) ?
|
||||
CKR_OK : CKR_MUTEX_NOT_LOCKED;
|
||||
}
|
||||
|
||||
/* Default callback args to C_Initialize */
|
||||
static CK_C_INITIALIZE_ARGS
|
||||
s_ck_initialize_args = {
|
||||
nss_ck_CreateMutex, /* CreateMutex */
|
||||
nss_ck_DestroyMutex, /* DestroyMutex */
|
||||
nss_ck_LockMutex, /* LockMutex */
|
||||
nss_ck_UnlockMutex, /* UnlockMutex */
|
||||
CKF_LIBRARY_CANT_CREATE_OS_THREADS |
|
||||
CKF_OS_LOCKING_OK, /* flags */
|
||||
NULL /* pReserved */
|
||||
};
|
||||
|
||||
/* Alloc memory for a module. Copy in the module name and library path
|
||||
* if provided. XXX use the opaque arg also, right?
|
||||
*/
|
||||
NSS_IMPLEMENT NSSModule *
|
||||
NSSModule_Create
|
||||
(
|
||||
NSSUTF8 *moduleOpt,
|
||||
NSSUTF8 *uriOpt,
|
||||
NSSUTF8 *opaqueOpt,
|
||||
void *reserved
|
||||
)
|
||||
{
|
||||
NSSArena *arena;
|
||||
NSSModule *rvMod;
|
||||
arena = NSSArena_Create();
|
||||
if(!arena) {
|
||||
return (NSSModule *)NULL;
|
||||
}
|
||||
rvMod = nss_ZNEW(arena, NSSModule);
|
||||
if (!rvMod) {
|
||||
goto loser;
|
||||
}
|
||||
if (moduleOpt) {
|
||||
/* XXX making the gross assumption this is just the module name */
|
||||
/* if the name is a duplicate, should that be tested here? or
|
||||
* wait for Load?
|
||||
*/
|
||||
rvMod->name = nssUTF8_Duplicate(moduleOpt, arena);
|
||||
if (!rvMod->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) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
rvMod->arena = arena;
|
||||
rvMod->refCount = 1;
|
||||
/* everything else is 0/NULL at this point. */
|
||||
return rvMod;
|
||||
loser:
|
||||
nssArena_Destroy(arena);
|
||||
return (NSSModule *)NULL;
|
||||
}
|
||||
|
||||
/* 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)->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)->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 */
|
||||
#ifdef arena_mark_bug_fixed
|
||||
mark = nssArena_Mark(mod->arena);
|
||||
if (!mark) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
slots = nss_ZNEWARRAY(mod->arena, NSSSlot *, ulNumSlots);
|
||||
if (!slots) {
|
||||
goto loser;
|
||||
}
|
||||
/* Initialize each slot */
|
||||
for (i=0; i<ulNumSlots; i++) {
|
||||
slots[i] = NSSSlot_Create(mod->arena, slotIDs[i], mod);
|
||||
}
|
||||
nss_ZFreeIf(slotIDs);
|
||||
#ifdef arena_mark_bug_fixed
|
||||
nssrv = nssArena_Unmark(mod->arena, mark);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
mod->slots = slots;
|
||||
mod->numSlots = ulNumSlots;
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
#ifdef arena_mark_bug_fixed
|
||||
if (mark) {
|
||||
nssArena_Release(mod->arena, mark);
|
||||
}
|
||||
#endif
|
||||
nss_ZFreeIf(slotIDs);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
/* 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
|
||||
)
|
||||
{
|
||||
if (--mod->refCount == 0) {
|
||||
/* Ignore any failure here. */
|
||||
(void)NSSModule_Unload(mod);
|
||||
return NSSArena_Destroy(mod->arena);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSModule_Load
|
||||
(
|
||||
NSSModule *mod
|
||||
)
|
||||
{
|
||||
PRLibrary *library = NULL;
|
||||
CK_C_GetFunctionList ep;
|
||||
CK_RV ckrv;
|
||||
/* Use NSPR to load the library */
|
||||
library = PR_LoadLibrary(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;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSModule_Unload
|
||||
(
|
||||
NSSModule *mod
|
||||
)
|
||||
{
|
||||
PRStatus nssrv = PR_SUCCESS;
|
||||
if (mod->library) {
|
||||
(void)CKAPI(mod)->C_Finalize(NULL);
|
||||
nssrv = PR_UnloadLibrary(mod->library);
|
||||
}
|
||||
/* Free the slots, yes? */
|
||||
mod->library = NULL;
|
||||
mod->epv = NULL;
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus *
|
||||
NSSModule_TraverseCertificates
|
||||
(
|
||||
NSSModule *mod,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#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
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#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 CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
/* maybe this should really inherit completely from the module... I dunno,
|
||||
* any uses of slots where independence is needed?
|
||||
*/
|
||||
NSS_IMPLEMENT NSSSlot *
|
||||
NSSSlot_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_SLOT_ID slotID,
|
||||
NSSModule *parent
|
||||
)
|
||||
{
|
||||
NSSArena *arena;
|
||||
nssArenaMark *mark;
|
||||
NSSSlot *rvSlot;
|
||||
NSSToken *token;
|
||||
NSSUTF8 *slotName = NULL;
|
||||
PRUint32 length;
|
||||
PRBool newArena;
|
||||
PRStatus nssrv;
|
||||
CK_SLOT_INFO slotInfo;
|
||||
CK_RV ckrv;
|
||||
if (arenaOpt) {
|
||||
arena = arenaOpt;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
mark = nssArena_Mark(arena);
|
||||
if (!mark) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
newArena = PR_FALSE;
|
||||
} else {
|
||||
arena = NSSArena_Create();
|
||||
if(!arena) {
|
||||
return (NSSSlot *)NULL;
|
||||
}
|
||||
newArena = PR_TRUE;
|
||||
}
|
||||
rvSlot = nss_ZNEW(arena, NSSSlot);
|
||||
if (!rvSlot) {
|
||||
goto loser;
|
||||
}
|
||||
/* Get slot information */
|
||||
ckrv = CKAPI(parent)->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));
|
||||
if (length > 0) {
|
||||
slotName = nssUTF8_Create(arena, nssStringType_UTF8String,
|
||||
(void *)slotInfo.slotDescription, length);
|
||||
if (!slotName) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
/* Initialize the token if present. */
|
||||
if (slotInfo.flags & CKF_TOKEN_PRESENT) {
|
||||
token = NSSToken_Create(arena, slotID, rvSlot);
|
||||
}
|
||||
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->refCount = 1;
|
||||
rvSlot->epv = parent->epv;
|
||||
rvSlot->module = parent;
|
||||
rvSlot->name = slotName;
|
||||
rvSlot->ckFlags = slotInfo.flags;
|
||||
/* Get the token for the slot */
|
||||
token = NSSToken_Create(arenaOpt, slotID, rvSlot);
|
||||
if (!token) {
|
||||
goto loser;
|
||||
}
|
||||
rvSlot->token = token;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
nssrv = nssArena_Unmark(arena, mark);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
return rvSlot;
|
||||
loser:
|
||||
if (newArena) {
|
||||
nssArena_Destroy(arena);
|
||||
} else {
|
||||
#ifdef arena_mark_bug_fixed
|
||||
if (mark) {
|
||||
nssArena_Release(arena, mark);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* everything was created in the arena, nothing to see here, move along */
|
||||
return (NSSSlot *)NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSSlot_Destroy
|
||||
(
|
||||
NSSSlot *slot
|
||||
)
|
||||
{
|
||||
if (--slot->refCount == 0) {
|
||||
/*NSSToken_Destroy(slot->token);*/
|
||||
return NSSArena_Destroy(slot->arena);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#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 PKI_H
|
||||
#include "pki.h"
|
||||
#endif /* PKI_H */
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#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?
|
||||
*/
|
||||
NSS_IMPLEMENT NSSToken *
|
||||
NSSToken_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_SLOT_ID slotID,
|
||||
NSSSlot *parent
|
||||
)
|
||||
{
|
||||
NSSArena *arena;
|
||||
nssArenaMark *mark;
|
||||
NSSToken *rvToken;
|
||||
NSSUTF8 *tokenName = NULL;
|
||||
PRUint32 length;
|
||||
PRBool newArena;
|
||||
PRStatus nssrv;
|
||||
CK_TOKEN_INFO tokenInfo;
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_RV ckrv;
|
||||
if (arenaOpt) {
|
||||
arena = arenaOpt;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
mark = nssArena_Mark(arena);
|
||||
if (!mark) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
newArena = PR_FALSE;
|
||||
} else {
|
||||
arena = NSSArena_Create();
|
||||
if(!arena) {
|
||||
return (NSSToken *)NULL;
|
||||
}
|
||||
newArena = PR_TRUE;
|
||||
}
|
||||
rvToken = nss_ZNEW(arena, NSSToken);
|
||||
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;
|
||||
}
|
||||
/* Grab the slot description from the PKCS#11 fixed-length buffer */
|
||||
length = nssPKCS11StringLength(tokenInfo.label, sizeof(tokenInfo.label));
|
||||
if (length > 0) {
|
||||
tokenName = nssUTF8_Create(arena, nssStringType_UTF8String,
|
||||
(void *)tokenInfo.label, length);
|
||||
if (!tokenName) {
|
||||
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? */
|
||||
goto loser;
|
||||
}
|
||||
/* TODO: seed the RNG here */
|
||||
if (!arenaOpt) {
|
||||
/* Avoid confusion now - only set the token'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.
|
||||
*/
|
||||
rvToken->arena = arena;
|
||||
}
|
||||
rvToken->slot = parent;
|
||||
rvToken->name = tokenName;
|
||||
rvToken->ckFlags = tokenInfo.flags;
|
||||
rvToken->session.handle = session;
|
||||
#ifdef arena_mark_bug_fixed
|
||||
nssrv = nssArena_Unmark(arena, mark);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
return rvToken;
|
||||
loser:
|
||||
if (newArena) {
|
||||
nssArena_Destroy(arena);
|
||||
} else {
|
||||
#ifdef arena_mark_bug_fixed
|
||||
if (mark) {
|
||||
nssArena_Release(arena, mark);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (rvToken && rvToken->session.lock) {
|
||||
PZ_DestroyLock(rvToken->session.lock);
|
||||
}
|
||||
return (NSSToken *)NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSToken_Destroy
|
||||
(
|
||||
NSSToken *tok
|
||||
)
|
||||
{
|
||||
if (--tok->refCount == 0) {
|
||||
return NSSArena_Destroy(tok->arena);
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus *
|
||||
NSSToken_TraverseCertificates
|
||||
(
|
||||
NSSToken *tok,
|
||||
PRStatus (*callback)(NSSCertificate *c, 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;
|
||||
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);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
while (PR_TRUE) {
|
||||
ckrv = CKAPI(slot)->C_FindObjects(session, &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);
|
||||
if (cbrv != PR_SUCCESS) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
ckrv = CKAPI(slot)->C_FindObjectsFinal(session);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
NSSTOKEN_EXIT_MONITOR(tok);
|
||||
return NULL; /* for now... */
|
||||
loser:
|
||||
NSSTOKEN_EXIT_MONITOR(tok);
|
||||
return NULL; /* for now... */
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: util.c,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
#endif /* DEVM_H */
|
||||
|
||||
NSS_IMPLEMENT PRUint32
|
||||
nssPKCS11StringLength(CK_CHAR *pkcs11Str, PRUint32 bufLen)
|
||||
{
|
||||
PRInt32 i;
|
||||
for (i = bufLen - 1; i>=0; ) {
|
||||
if (pkcs11Str[i] != ' ') break;
|
||||
--i;
|
||||
}
|
||||
return (PRUint32)(i + 1);
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче