land changes for handling temporary and cached certs in 3.4

* separate trust object from cert object
* move handling of cryptoki objects into libdev
* implement digest in libdev (for trust object indexing)
* fixes in cache implementation; connect cache to 3.4 certs
* implement CERT_NewTempCertificate via crypto context
This commit is contained in:
ian.mcgreer%sun.com 2001-11-28 16:23:51 +00:00
Родитель 88ef1ac939
Коммит c3cb1b39dc
24 изменённых файлов: 2691 добавлений и 1779 удалений

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

@ -35,7 +35,7 @@
#define BASE_H
#ifdef DEBUG
static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.9 $ $Date: 2001-10-15 17:13:31 $ $Name: $";
static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.10 $ $Date: 2001-11-28 16:23:34 $ $Name: $";
#endif /* DEBUG */
/*
@ -562,6 +562,12 @@ nssItem_Create
const void *data
);
NSS_EXTERN void
nssItem_Destroy
(
NSSItem *item
);
NSS_EXTERN NSSItem *
nssItem_Duplicate
(
@ -831,8 +837,8 @@ nssList_Destroy
nssList *list
);
NSS_EXTERN PRStatus
nssList_DestroyElements
NSS_EXTERN void
nssList_Clear
(
nssList *list,
nssListElementDestructorFunc destructor
@ -1004,6 +1010,16 @@ nssListIterator_Finish
*
*/
NSS_EXTERN nssHash *
nssHash_Create
(
NSSArena *arenaOpt,
PRUint32 numBuckets,
PLHashFunction keyHash,
PLHashComparator keyCompare,
PLHashComparator valueCompare
);
NSS_EXTERN nssHash *
nssHash_CreatePointer
(

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.3 $ $Date: 2001-10-08 19:26:02 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.4 $ $Date: 2001-11-28 16:23:34 $ $Name: $";
#endif /* DEBUG */
/*
@ -112,7 +112,7 @@ nss_compare_items(const void *v1, const void *v2)
* nssHash_create
*
*/
static nssHash *
NSS_IMPLEMENT nssHash *
nssHash_Create
(
NSSArena *arenaOpt,

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: item.c,v $ $Revision: 1.1 $ $Date: 2000-03-31 19:50:14 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: item.c,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:35 $ $Name: $";
#endif /* DEBUG */
/*
@ -116,6 +116,19 @@ nssItem_Create
return (NSSItem *)NULL;
}
NSS_IMPLEMENT void
nssItem_Destroy
(
NSSItem *item
)
{
nss_ClearErrorStack();
nss_ZFreeIf(item->data);
nss_ZFreeIf(item);
}
/*
* nssItem_Duplicate
*

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: list.c,v $ $Revision: 1.7 $ $Date: 2001-11-16 19:36:43 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: list.c,v $ $Revision: 1.8 $ $Date: 2001-11-28 16:23:35 $ $Name: $";
#endif /* DEBUG */
/*
@ -138,8 +138,17 @@ nssList_Create
NSS_IMPLEMENT PRStatus
nssList_Destroy(nssList *list)
{
if (list->lock) PZ_DestroyLock(list->lock);
NSSArena_Destroy(list->arena);
PZLock *lock = list->lock;
if (list->arena) {
NSSArena_Destroy(list->arena);
list = NULL;
} else {
nssList_Clear(list, NULL);
}
if (lock) {
PZ_DestroyLock(lock);
}
nss_ZFreeIf(list);
return PR_SUCCESS;
}
@ -162,22 +171,23 @@ nssList_GetCompareFunction(nssList *list)
return list->compareFunc;
}
NSS_IMPLEMENT PRStatus
nssList_DestroyElements(nssList *list, nssListElementDestructorFunc destructor)
NSS_IMPLEMENT void
nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
{
PRCList *link;
nssListElement *node;
nssListElement *node, *tmp;
NSSLIST_LOCK_IF(list);
node = list->head;
while (node && list->count > 0) {
(*destructor)(node->data);
if (destructor) (*destructor)(node->data);
link = &node->link;
node = (nssListElement *)PR_NEXT_LINK(link);
tmp = (nssListElement *)PR_NEXT_LINK(link);
PR_REMOVE_LINK(link);
nss_ZFreeIf(node);
node = tmp;
--list->count;
}
NSSLIST_UNLOCK_IF(list);
return nssList_Destroy(list);
}
static PRStatus
@ -271,7 +281,7 @@ nssList_Get(nssList *list, void *data)
NSSLIST_LOCK_IF(list);
node = nsslist_get_matching_element(list, data);
NSSLIST_UNLOCK_IF(list);
return node->data;
return (node) ? node->data : NULL;
}
NSS_IMPLEMENT PRUint32
@ -286,14 +296,14 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
nssListIterator *iter;
void *el;
PRUint32 i = 0;
PR_ASSERT(maxElements > 0);
iter = nssList_CreateIterator(list);
for (el = nssListIterator_Start(iter); el != NULL;
el = nssListIterator_Next(iter))
{
rvArray[i++] = el;
if (maxElements > 0 && i == maxElements) break;
if (i == maxElements) break;
}
rvArray[i] = NULL;
nssListIterator_Finish(iter);
nssListIterator_Destroy(iter);
return PR_SUCCESS;

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

@ -116,8 +116,7 @@ CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
/* XXX store it on a writeable token */
goto done;
} else {
NSSCertificate *c = STAN_GetNSSCertificate(cert);
ret = STAN_ChangeCertTrust(c, trust);
ret = STAN_ChangeCertTrust(cert, trust);
rv = (ret == PR_SUCCESS) ? SECSuccess : SECFailure;
}
done:
@ -141,7 +140,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
}
if (c->nickname && strcmp(nickname, c->nickname) != 0) {
nss_ZFreeIf(c->nickname);
c->nickname = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->arena);
c->nickname = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena);
PORT_Free(cert->nickname);
cert->nickname = PORT_Strdup(nickname);
}
@ -168,6 +167,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
char *nickname, PRBool isperm, PRBool copyDER)
{
NSSCertificate *c;
NSSCryptoContext *context;
nssDecodedCert *dc;
NSSArena *arena;
CERTCertificate *cc;
@ -175,13 +175,19 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
if (!arena) {
return NULL;
}
c = NSSCertificate_Create(arena);
c = nss_ZNEW(arena, NSSCertificate);
if (!c) {
goto loser;
}
NSSITEM_FROM_SECITEM(&c->encoding, derCert);
c->object.arena = arena;
c->object.refCount = 1;
c->object.instanceList = nssList_Create(arena, PR_TRUE);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
/* Forces a decoding of the cert in order to obtain the parts used
* below
*/
cc = STAN_GetCERTCertificate(c);
c->arena = arena;
nssItem_Create(arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
nssItem_Create(arena,
@ -200,12 +206,13 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
(NSSUTF8 *)cc->emailAddr,
PORT_Strlen(cc->emailAddr));
}
c->trustDomain = handle;
cc->dbhandle = handle;
nssTrustDomain_AddCertsToCache(handle, &c, 1);
cc->istemp = 1;
cc->isperm = 0;
context = STAN_GetDefaultCryptoContext();
NSSCryptoContext_ImportCertificate(context, c);
/* This is a hack to work around the fact that an instance of the cert
* doesn't really exist until the import
*/
cc->nssCertificate = NULL;
cc = STAN_GetCERTCertificate(c);
return cc;
loser:
nssArena_Destroy(arena);
@ -363,10 +370,13 @@ CERT_DestroyCertificate(CERTCertificate *cert)
CERT_UnlockCertRefCount(cert);
if ( ( refCount == 0 ) && !cert->keepSession ) {
PRArenaPool *arena = cert->arena;
if ( cert->istemp ) {
/* uncache the cert ? */
}
/* delete the NSSCertificate */
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
NSSCertificate *tmp = STAN_GetNSSCertificate(cert);
if (tmp) {
nssTrustDomain_RemoveCertFromCache(td, tmp);
NSSCertificate_Destroy(tmp);
}
/* zero cert before freeing. Any stale references to this cert
* after this point will probably cause an exception. */
PORT_Memset(cert, 0, sizeof *cert);

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

@ -417,9 +417,13 @@ loser:
nss_ZFreeIf(nssTime);
if (status == PR_SUCCESS) {
/* if it's a root, the chain will only have one cert */
NSSCertificate *issuer = chain[1] ? chain[1] : chain[0];
CERTCertificate *rvc = STAN_GetCERTCertificate(issuer);
return rvc;
if (!chain[1]) {
/* need to dupe since caller expects new cert */
return CERT_DupCertificate(cert);
} else {
/* this is the only instance */
return STAN_GetCERTCertificate(chain[1]);
}
}
return NULL;
#endif

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

@ -32,13 +32,9 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.10 $ $Date: 2001-11-07 16:15:28 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.11 $ $Date: 2001-11-28 16:23:38 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */

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

@ -35,7 +35,7 @@
#define DEV_H
#ifdef DEBUG
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.13 $ $Date: 2001-11-09 00:36:10 $ $Name: $";
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.14 $ $Date: 2001-11-28 16:23:38 $ $Name: $";
#endif /* DEBUG */
#ifndef DEVT_H
@ -64,10 +64,6 @@ static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.13 $ $Da
* |-----------|---> NSSSlot <--> NSSToken
*/
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
PR_BEGIN_EXTERN_C
NSS_EXTERN NSSModule *
@ -248,16 +244,24 @@ nssToken_GetName
NSSToken *tok
);
/* Given a raw attribute template, import an object
* (certificate, public key, private key, symmetric key)
*/
NSS_EXTERN CK_OBJECT_HANDLE
nssToken_ImportObject
NSS_EXTERN PRStatus
nssToken_ImportCertificate
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR objectTemplate,
CK_ULONG otsize
NSSCertificate *cert,
NSSTrustDomain *td,
NSSCryptoContext *cc
);
NSS_EXTERN PRStatus
nssToken_ImportTrust
(
NSSToken *tok,
nssSession *sessionOpt,
NSSTrust *trust,
NSSTrustDomain *trustDomain,
NSSCryptoContext *cryptoContext
);
NSS_EXTERN NSSPublicKey *
@ -280,30 +284,15 @@ nssToken_GenerateSymmetricKey
NSS_EXTERN PRStatus
nssToken_DeleteStoredObject
(
NSSToken *tok,
nssSession *sessionOpt,
CK_OBJECT_HANDLE object
nssCryptokiInstance *instance
);
NSS_EXTERN CK_OBJECT_HANDLE
nssToken_FindObjectByTemplate
NSS_EXTERN NSSTrust *
nssToken_FindTrustForCert
(
NSSToken *tok,
NSSToken *token,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
);
NSS_EXTERN PRStatus
nssToken_TraverseCertificatesByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
nssList *cachedList,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
NSSCertificate *c
);
NSS_EXTERN PRStatus
@ -311,8 +300,95 @@ nssToken_TraverseCertificates
(
NSSToken *tok,
nssSession *sessionOpt,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
nssTokenCertSearch *search
);
NSS_EXTERN PRStatus
nssToken_TraverseCertificatesBySubject
(
NSSToken *token,
nssSession *sessionOpt,
NSSDER *subject,
nssTokenCertSearch *search
);
NSS_EXTERN PRStatus
nssToken_TraverseCertificatesByNickname
(
NSSToken *token,
nssSession *sessionOpt,
NSSUTF8 *name,
nssTokenCertSearch *search
);
NSS_EXTERN PRStatus
nssToken_TraverseCertificatesByEmail
(
NSSToken *token,
nssSession *sessionOpt,
NSSASCII7 *email,
nssTokenCertSearch *search
);
NSS_EXTERN NSSCertificate *
nssToken_FindCertificateByIssuerAndSerialNumber
(
NSSToken *token,
nssSession *sessionOpt,
NSSDER *issuer,
NSSDER *serial
);
NSS_EXTERN NSSCertificate *
nssToken_FindCertificateByEncodedCertificate
(
NSSToken *token,
nssSession *sessionOpt,
NSSBER *encodedCertificate
);
NSS_EXTERN NSSTrust *
nssToken_FindTrustForCert
(
NSSToken *token,
nssSession *session,
NSSCertificate *c
);
NSS_EXTERN NSSItem *
nssToken_Digest
(
NSSToken *tok,
nssSession *sessionOpt,
NSSAlgorithmAndParameters *ap,
NSSItem *data,
NSSItem *rvOpt,
NSSArena *arenaOpt
);
NSS_EXTERN PRStatus
nssToken_BeginDigest
(
NSSToken *tok,
nssSession *sessionOpt,
NSSAlgorithmAndParameters *ap
);
NSS_EXTERN PRStatus
nssToken_ContinueDigest
(
NSSToken *tok,
nssSession *sessionOpt,
NSSItem *item
);
NSS_EXTERN NSSItem *
nssToken_FinishDigest
(
NSSToken *tok,
nssSession *sessionOpt,
NSSItem *rvOpt,
NSSArena *arenaOpt
);
NSS_EXTERN PRStatus
@ -342,9 +418,17 @@ nssSession_IsReadWrite
nssSession *s
);
#ifdef DEBUG
void nssModule_Debug(NSSModule *m);
#endif
NSS_EXTERN NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateSHA1Digest
(
NSSArena *arenaOpt
);
NSS_EXTERN NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateMD5Digest
(
NSSArena *arenaOpt
);
PR_END_EXTERN_C

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devmod.c,v $ $Revision: 1.1 $ $Date: 2001-11-08 00:14:52 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devmod.c,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
#endif /* DEBUG */
#include "nspr.h"
@ -367,12 +367,6 @@ nssModule_TraverseCertificates
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,
NULL, callback, arg);
}
return NULL;
}

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

@ -0,0 +1,950 @@
/*
* 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: devobject.c,v $ $Revision: 1.1 $ $Date: 2001-11-28 16:23:39 $ $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 */
/* XXX */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifdef NSS_3_4_CODE
#include "pkim.h" /* for cert decoding */
#endif
/* The number of object handles to grab during each call to C_FindObjects */
#define OBJECT_STACK_SIZE 16
NSS_IMPLEMENT PRStatus
nssToken_DeleteStoredObject
(
nssCryptokiInstance *instance
)
{
CK_RV ckrv;
PRStatus nssrv;
PRBool createdSession;
NSSToken *token = instance->token;
nssSession *session = NULL;
if (nssCKObject_IsAttributeTrue(instance->handle, CKA_TOKEN,
token->defaultSession,
token->slot, &nssrv)) {
if (nssSession_IsReadWrite(token->defaultSession)) {
session = token->defaultSession;
} else {
session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
createdSession = PR_TRUE;
}
}
if (session == NULL) {
return PR_FAILURE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(token)->C_DestroyObject(session->handle, instance->handle);
nssSession_ExitMonitor(session);
if (createdSession) {
nssSession_Destroy(session);
}
if (ckrv != CKR_OK) {
return PR_FAILURE;
}
return PR_SUCCESS;
}
static CK_OBJECT_HANDLE
import_object
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR objectTemplate,
CK_ULONG otsize
)
{
nssSession *session = NULL;
PRBool createdSession = PR_FALSE;
CK_OBJECT_HANDLE object;
CK_RV ckrv;
if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
if (sessionOpt) {
if (!nssSession_IsReadWrite(sessionOpt)) {
return CK_INVALID_HANDLE;
} else {
session = sessionOpt;
}
} else if (nssSession_IsReadWrite(tok->defaultSession)) {
session = tok->defaultSession;
} else {
session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
createdSession = PR_TRUE;
}
} else {
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
}
if (session == NULL) {
return CK_INVALID_HANDLE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
objectTemplate, otsize,
&object);
nssSession_ExitMonitor(session);
if (createdSession) {
nssSession_Destroy(session);
}
if (ckrv != CKR_OK) {
return CK_INVALID_HANDLE;
}
return object;
}
static CK_OBJECT_HANDLE
find_object_by_template
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
CK_SESSION_HANDLE hSession;
CK_OBJECT_HANDLE rvObject;
CK_ULONG count;
CK_RV ckrv;
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
hSession = session->handle;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->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);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_HANDLE;
}
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
return CK_INVALID_HANDLE;
}
return rvObject;
}
static PRStatus
traverse_objects_by_template
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR obj_template,
CK_ULONG otsize,
PRStatus (*callback)(NSSToken *t, nssSession *session,
CK_OBJECT_HANDLE h, void *arg),
void *arg
)
{
NSSSlot *slot;
PRStatus cbrv;
PRUint32 i;
CK_RV ckrv;
CK_ULONG count;
CK_OBJECT_HANDLE *objectStack;
CK_OBJECT_HANDLE startOS[OBJECT_STACK_SIZE];
CK_SESSION_HANDLE hSession;
NSSArena *objectArena = NULL;
nssSession *session;
nssList *objectList = NULL;
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);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
goto loser;
}
while (PR_TRUE) {
ckrv = CKAPI(slot)->C_FindObjects(hSession, objectStack,
OBJECT_STACK_SIZE, &count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
goto loser;
}
if (count == OBJECT_STACK_SIZE) {
if (!objectList) {
objectArena = NSSArena_Create();
objectList = nssList_Create(objectArena, PR_FALSE);
}
objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
OBJECT_STACK_SIZE);
nssList_Add(objectList, objectStack);
} else {
break;
}
}
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
goto loser;
}
if (objectList) {
nssListIterator *objects;
objects = nssList_CreateIterator(objectList);
for (objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Start(objects);
objectStack != NULL;
objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Next(objects)) {
for (i=0; i<count; i++) {
cbrv = (*callback)(tok, session, objectStack[i], arg);
}
}
nssListIterator_Finish(objects);
count = OBJECT_STACK_SIZE;
}
for (i=0; i<count; i++) {
cbrv = (*callback)(tok, session, startOS[i], arg);
}
if (objectArena)
NSSArena_Destroy(objectArena);
return PR_SUCCESS;
loser:
if (objectArena)
NSSArena_Destroy(objectArena);
return PR_FAILURE;
}
static PRStatus
add_object_instance
(
nssPKIObject *object,
NSSToken *t,
CK_OBJECT_HANDLE h,
NSSTrustDomain *td,
NSSCryptoContext *cc
)
{
nssPKIObjectInstance *oi;
oi = nss_ZNEW(object->arena, nssPKIObjectInstance);
if (!oi) {
return PR_FAILURE;
}
oi->cryptoki.handle = h;
oi->cryptoki.token = t;
oi->trustDomain = td;
oi->cryptoContext = cc;
nssList_Add(object->instanceList, oi);
return PR_SUCCESS;
}
#if 0
#ifdef NSS_3_4_CODE
static void make_nss3_nickname(NSSCertificate *c)
{
/* In NSS 3.4, the semantic is that nickname = token name + label */
PRStatus utf8rv;
NSSUTF8 *tokenName;
NSSUTF8 *label;
char *fullname;
PRUint32 len, tlen;
tokenName = nssToken_GetName(c->token);
label = c->nickname ? c->nickname : c->email;
if (!label) return;
tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */
tlen += 1; /* : */
len = nssUTF8_Length(label, &utf8rv); /* label */
len += 1; /* \0 */
len += tlen;
fullname = nss_ZAlloc(c->arena, len);
utf8rv = nssUTF8_CopyIntoFixedBuffer(tokenName, fullname, tlen, ':');
utf8rv = nssUTF8_CopyIntoFixedBuffer(label, fullname + tlen,
len - tlen, '\0');
nss_ZFreeIf(c->nickname);
c->nickname = nssUTF8_Create(c->arena,
nssStringType_UTF8String,
fullname, len);
}
#endif
#endif
static NSSCertificateType
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
CK_CERTIFICATE_TYPE ckCertType;
ckCertType = *((CK_ULONG *)attrib->pValue);
switch (ckCertType) {
case CKC_X_509:
return NSSCertificateType_PKIX;
break;
default:
return NSSCertificateType_Unknown;
}
}
/* Create a certificate from an object handle. */
static NSSCertificate *
get_token_cert
(
NSSToken *token,
nssSession *sessionOpt,
CK_OBJECT_HANDLE handle
)
{
NSSCertificate *rvCert;
nssPKIObject *object;
NSSArena *arena;
nssSession *session;
PRStatus nssrv;
CK_ULONG template_size;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
{ CKA_ID, NULL, 0 },
{ CKA_VALUE, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 },
{ CKA_LABEL, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 },
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
};
template_size = sizeof(cert_template) / sizeof(cert_template[0]);
session = (sessionOpt) ? sessionOpt : token->defaultSession;
arena = nssArena_Create();
if (!arena) {
return NULL;
}
rvCert = nss_ZNEW(arena, NSSCertificate);
if (!rvCert) {
goto loser;
}
object = &rvCert->object;
object->arena = arena;
object->refCount = 1;
object->instanceList = nssList_Create(arena, PR_TRUE);
if (!object->instanceList) {
goto loser;
}
object->instances = nssList_CreateIterator(object->instanceList);
if (!object->instances) {
goto loser;
}
nssrv = nssCKObject_GetAttributes(handle,
cert_template, template_size,
arena, session, token->slot);
if (nssrv) {
goto loser;
}
rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->id);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[3], &rvCert->issuer);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->serial);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[5], rvCert->nickname);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->subject);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email);
#ifdef NSS_3_4_CODE
/* nss 3.4 database doesn't associate email address with cert */
if (!rvCert->email) {
nssDecodedCert *dc;
NSSASCII7 *email;
dc = nssCertificate_GetDecoding(rvCert);
email = dc->getEmailAddress(dc);
if (email) rvCert->email = nssUTF8_Duplicate(email, arena);
}
/*make_nss3_nickname(rvCert);*/
#endif
return rvCert;
loser:
nssArena_Destroy(arena);
return (NSSCertificate *)NULL;
}
NSS_IMPLEMENT PRStatus
nssToken_ImportCertificate
(
NSSToken *tok,
nssSession *sessionOpt,
NSSCertificate *cert,
NSSTrustDomain *td,
NSSCryptoContext *cc
)
{
CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
CK_OBJECT_HANDLE handle;
CK_ATTRIBUTE cert_tmpl[] = {
{ CKA_TOKEN, NULL, 0 },
{ CKA_CLASS, NULL, 0 },
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
{ CKA_ID, NULL, 0 },
{ CKA_LABEL, NULL, 0 },
{ CKA_VALUE, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
CK_ULONG ctsize = sizeof(cert_tmpl)/sizeof(cert_tmpl[0]);
if (td) {
/* trust domain == token object */
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 0, &g_ck_true);
} else {
/* crypto context == session object */
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 0, &g_ck_false);
}
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 1, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_VAR( cert_tmpl, 2, cert_type);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 3, &cert->id);
NSS_CK_SET_ATTRIBUTE_UTF8(cert_tmpl, 4, cert->nickname);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 5, &cert->encoding);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 6, &cert->issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 7, &cert->subject);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 8, &cert->serial);
/* Import the certificate onto the token */
handle = import_object(tok, sessionOpt, cert_tmpl, ctsize);
if (handle == CK_INVALID_HANDLE) {
return PR_FAILURE;
}
return add_object_instance(&cert->object, tok, handle, td, cc);
}
struct cert_search_index_str
{
NSSDER issuer;
NSSDER serial;
};
static PRBool
compare_cert_by_issuer_sn(void *a, void *b)
{
NSSCertificate *c = (NSSCertificate *)a;
struct cert_search_index_str *csi = (struct cert_search_index_str *)b;
return (nssItem_Equal(&c->issuer, &csi->issuer, NULL) &&
nssItem_Equal(&c->serial, &csi->serial, NULL));
}
static PRStatus
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
{
PRStatus nssrv;
PRBool found;
nssTokenCertSearch *search = (nssTokenCertSearch *)arg;
NSSCertificate *cert = NULL;
struct cert_search_index_str csi;
nssListIterator *instances;
nssPKIObjectInstance *oi;
CK_ATTRIBUTE issuersn_tmpl[] = {
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
CK_ULONG ist_size = sizeof(issuersn_tmpl) / sizeof(issuersn_tmpl[0]);
if (search->cached) {
nssrv = nssCKObject_GetAttributes(h, issuersn_tmpl, ist_size,
NULL, session, t->slot);
NSS_CK_ATTRIBUTE_TO_ITEM(&issuersn_tmpl[0], &csi.issuer);
NSS_CK_ATTRIBUTE_TO_ITEM(&issuersn_tmpl[1], &csi.serial);
cert = (NSSCertificate *)nssList_Get(search->cached, &csi);
nss_ZFreeIf(csi.issuer.data);
nss_ZFreeIf(csi.serial.data);
}
found = PR_FALSE;
if (cert) {
instances = cert->object.instances;
for (oi = (nssPKIObjectInstance *)nssListIterator_Start(instances);
oi != (nssPKIObjectInstance *)NULL;
oi = (nssPKIObjectInstance *)nssListIterator_Next(instances))
{
if (oi->cryptoki.handle == h && oi->cryptoki.token == t) {
found = PR_TRUE;
break;
}
}
nssListIterator_Finish(instances);
} else {
cert = get_token_cert(t, session, h);
if (!cert) return PR_FAILURE;
}
if (!found) {
nssrv = add_object_instance(&cert->object, t, h,
search->trustDomain,
search->cryptoContext);
if (nssrv != PR_SUCCESS) {
return nssrv;
}
}
return (*search->callback)(cert, search->cbarg);
}
/* traverse all certificates - this should only happen if the token
* has been marked as "traversable"
*/
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificates
(
NSSToken *token,
nssSession *sessionOpt,
nssTokenCertSearch *search
)
{
PRStatus nssrv;
/* this is really traversal - the template is all certs */
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 }
};
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
nssrv = traverse_objects_by_template(token, sessionOpt,
cert_template, ctsize,
retrieve_cert, search);
return nssrv;
}
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificatesBySubject
(
NSSToken *token,
nssSession *sessionOpt,
NSSDER *subject,
nssTokenCertSearch *search
)
{
PRStatus nssrv;
CK_ATTRIBUTE subj_tmpl[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
CK_ULONG stsize = (CK_ULONG)(sizeof(subj_tmpl) / sizeof(subj_tmpl[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(subj_tmpl, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(subj_tmpl, 1, subject);
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
/* now traverse the token certs matching this template */
nssrv = traverse_objects_by_template(token, sessionOpt,
subj_tmpl, stsize,
retrieve_cert, search);
return nssrv;
}
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificatesByNickname
(
NSSToken *token,
nssSession *sessionOpt,
NSSUTF8 *name,
nssTokenCertSearch *search
)
{
PRStatus nssrv;
CK_ATTRIBUTE nick_tmpl[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
CK_ULONG ntsize = sizeof(nick_tmpl) / sizeof(nick_tmpl[0]);
/* set up the search template */
NSS_CK_SET_ATTRIBUTE_ITEM(nick_tmpl, 0, &g_ck_class_cert);
nick_tmpl[1].pValue = (CK_VOID_PTR)name;
nick_tmpl[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
/* now traverse the token certs matching this template */
nssrv = traverse_objects_by_template(token, sessionOpt,
nick_tmpl, ntsize,
retrieve_cert, search);
if (nssrv != PR_SUCCESS) {
return nssrv;
}
#if 0
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
* im - this is not needed by the current softoken. However, I'm
* leaving it in until I have surveyed more tokens to see if it needed.
*/
nick_tmpl[1].ulValueLen++;
nssrv = traverse_objects_by_template(token, sessionOpt,
nick_tmpl, ntsize,
retrieve_cert, search);
#endif
return nssrv;
}
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificatesByEmail
(
NSSToken *token,
nssSession *sessionOpt,
NSSASCII7 *email,
nssTokenCertSearch *search
)
{
PRStatus nssrv;
CK_ATTRIBUTE email_tmpl[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
};
CK_ULONG etsize = sizeof(email_tmpl) / sizeof(email_tmpl[0]);
/* set up the search template */
NSS_CK_SET_ATTRIBUTE_ITEM(email_tmpl, 0, &g_ck_class_cert);
email_tmpl[1].pValue = (CK_VOID_PTR)email;
email_tmpl[1].ulValueLen = (CK_ULONG)nssUTF8_Length(email, &nssrv);
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
/* now traverse the token certs matching this template */
nssrv = traverse_objects_by_template(token, sessionOpt,
email_tmpl, etsize,
retrieve_cert, search);
if (nssrv != PR_SUCCESS) {
return nssrv;
}
#if 0
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
email_tmpl[1].ulValueLen++;
nssrv = traverse_objects_by_template(token, sessionOpt,
email_tmpl, etsize,
retrieve_cert, search);
#endif
return nssrv;
}
/* XXX these next two need to create instances as needed */
NSS_IMPLEMENT NSSCertificate *
nssToken_FindCertificateByIssuerAndSerialNumber
(
NSSToken *token,
nssSession *sessionOpt,
NSSDER *issuer,
NSSDER *serial
)
{
NSSCertificate *rvCert = NULL;
nssSession *session;
PRBool tokenObject;
PRStatus nssrv;
CK_ULONG ctsize;
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
/* Set the unique id */
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, serial);
/* get the object handle */
object = find_object_by_template(token, sessionOpt, cert_template, ctsize);
if (object == CK_INVALID_HANDLE) {
return NULL;
}
session = (sessionOpt) ? sessionOpt : token->defaultSession;
rvCert = get_token_cert(token, sessionOpt, object);
if (rvCert) {
NSSTrustDomain *td;
NSSCryptoContext *cc;
tokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN,
session, token->slot,
&nssrv);
if (tokenObject) {
td = token->trustDomain;
cc = NULL;
} else {
td = NULL;
cc = NULL; /* XXX how to recover the crypto context from
* the token?
*/
}
add_object_instance(&rvCert->object, token, object, td, cc);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
nssToken_FindCertificateByEncodedCertificate
(
NSSToken *token,
nssSession *sessionOpt,
NSSBER *encodedCertificate
)
{
NSSCertificate *rvCert = NULL;
nssSession *session;
PRBool tokenObject;
PRStatus nssrv;
CK_ULONG ctsize;
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_VALUE, NULL, 0 }
};
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, encodedCertificate);
/* get the object handle */
object = find_object_by_template(token, sessionOpt, cert_template, ctsize);
if (object == CK_INVALID_HANDLE) {
return NULL;
}
session = (sessionOpt) ? sessionOpt : token->defaultSession;
rvCert = get_token_cert(token, sessionOpt, object);
if (rvCert) {
NSSTrustDomain *td;
NSSCryptoContext *cc;
tokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN,
session, token->slot,
&nssrv);
if (tokenObject) {
td = token->trustDomain;
cc = NULL;
} else {
td = NULL;
cc = NULL; /* XXX how to recover the crypto context from
* the token?
*/
}
add_object_instance(&rvCert->object, token, object, td, cc);
}
return rvCert;
}
static void
sha1_hash(NSSToken *token, NSSItem *input, NSSItem *output)
{
NSSAlgorithmAndParameters *ap;
ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
(void)nssToken_Digest(token, NULL, ap, input, output, NULL);
nss_ZFreeIf(ap);
}
static void
md5_hash(NSSToken *token, NSSItem *input, NSSItem *output)
{
NSSAlgorithmAndParameters *ap;
ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
(void)nssToken_Digest(token, NULL, ap, input, output, NULL);
nss_ZFreeIf(ap);
}
NSS_IMPLEMENT PRStatus
nssToken_ImportTrust
(
NSSToken *tok,
nssSession *sessionOpt,
NSSTrust *trust,
NSSTrustDomain *trustDomain,
NSSCryptoContext *cryptoContext
)
{
PRStatus nssrv;
CK_OBJECT_HANDLE handle;
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_ATTRIBUTE trust_tmpl[] = {
{ CKA_TOKEN, NULL, 0 },
{ CKA_CLASS, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 },
{ CKA_CERT_SHA1_HASH, NULL, 0 },
{ CKA_CERT_MD5_HASH, NULL, 0 },
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
};
CK_ULONG tsize = sizeof(trust_tmpl) / sizeof(trust_tmpl[0]);
PRUint8 sha1[20]; /* this is cheating... */
PRUint8 md5[16];
NSSItem sha1_result, md5_result;
NSSCertificate *c = trust->certificate;
sha1_result.data = sha1; sha1_result.size = sizeof sha1;
md5_result.data = md5; md5_result.size = sizeof md5;
sha1_hash(tok, &c->encoding, &sha1_result);
md5_hash(tok, &c->encoding, &md5_result);
if (trustDomain) {
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 0, &g_ck_true);
} else {
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 0, &g_ck_false);
}
NSS_CK_SET_ATTRIBUTE_VAR( trust_tmpl, 1, tobjc);
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 2, &c->issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 3, &c->serial);
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 4, &sha1_result);
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 5, &md5_result);
/* now set the trust values */
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 6, trust->serverAuth);
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 7, trust->clientAuth);
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 8, trust->emailProtection);
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 9, trust->codeSigning);
/* import the trust object onto the token */
handle = import_object(tok, NULL, trust_tmpl, tsize);
if (handle != CK_INVALID_HANDLE) {
nssrv = add_object_instance(&trust->object, tok, handle,
trustDomain, cryptoContext);
} else {
nssrv = PR_FAILURE;
}
return nssrv;
}
static CK_OBJECT_HANDLE
get_cert_trust_handle
(
NSSToken *token,
nssSession *session,
NSSCertificate *c
)
{
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_ATTRIBUTE tobj_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_CERT_SHA1_HASH, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
CK_ULONG tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
PRUint8 sha1[20]; /* this is cheating... */
NSSItem sha1_result;
sha1_result.data = sha1; sha1_result.size = sizeof sha1;
sha1_hash(token, &c->encoding, &sha1_result);
NSS_CK_SET_ATTRIBUTE_VAR( tobj_template, 0, tobjc);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 1, &sha1_result);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial);
#ifdef NSS_3_4_CODE
if (PK11_HasRootCerts(token->pk11slot)) {
tobj_size -= 2;
}
/*
* we need to arrange for the built-in token to lose the bottom 2
* attributes so that old built-in tokens will continue to work.
*/
#endif
return find_object_by_template(token, session,
tobj_template, tobj_size);
}
NSS_IMPLEMENT NSSTrust *
nssToken_FindTrustForCert
(
NSSToken *token,
nssSession *sessionOpt,
NSSCertificate *c
)
{
PRStatus nssrv;
NSSTrust *rvTrust;
nssSession *session;
NSSArena *arena;
nssPKIObject *object;
CK_TRUST saTrust, caTrust, epTrust, csTrust;
CK_OBJECT_HANDLE tobjID;
CK_ATTRIBUTE trust_template[] = {
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
};
CK_ULONG trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
session = (sessionOpt) ? sessionOpt : token->defaultSession;
tobjID = get_cert_trust_handle(token, session, c);
if (tobjID == CK_INVALID_HANDLE) {
return NULL;
}
/* Then use the trust object to find the trust settings */
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, saTrust);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, caTrust);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, epTrust);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, csTrust);
nssrv = nssCKObject_GetAttributes(tobjID,
trust_template, trust_size,
NULL, session, token->slot);
if (nssrv != PR_SUCCESS) {
return NULL;
}
arena = nssArena_Create();
if (!arena) {
return NULL;
}
rvTrust = nss_ZNEW(arena, NSSTrust);
if (!rvTrust) {
nssArena_Destroy(arena);
return NULL;
}
object = &rvTrust->object;
object->arena = arena;
object->refCount = 1;
object->instanceList = nssList_Create(arena, PR_TRUE);
if (!object->instanceList) {
nssArena_Destroy(arena);
return NULL;
}
object->instances = nssList_CreateIterator(object->instanceList);
if (!object->instances) {
nssArena_Destroy(arena);
return NULL;
}
/* need to figure out trust domain and/or crypto context */
nssrv = add_object_instance(object, token, tobjID,
token->trustDomain, NULL);
if (nssrv != PR_SUCCESS) {
nssArena_Destroy(arena);
return NULL;
}
rvTrust->serverAuth = saTrust;
rvTrust->clientAuth = caTrust;
rvTrust->emailProtection = epTrust;
rvTrust->codeSigning = csTrust;
return rvTrust;
}

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

@ -35,7 +35,7 @@
#define DEVT_H
#ifdef DEBUG
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.6 $ $Date: 2001-11-08 00:14:53 $ $Name: $";
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
#endif /* DEBUG */
/*
@ -60,12 +60,18 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.6 $ $D
#include "nssckt.h"
#endif /* NSSCKT_H */
#ifndef BASET_H
#include "baset.h"
#endif /* BASET_H */
#ifdef NSS_3_4_CODE
#include "secmodt.h"
#endif /* NSS_3_4_CODE */
PR_BEGIN_EXTERN_C
typedef struct nssSessionStr nssSession;
/* The list of boolean flags used to describe properties of a
* module.
*/
@ -138,6 +144,47 @@ struct nssSessionStr
PRBool isRW;
};
typedef enum {
NSSCertificateType_Unknown = 0,
NSSCertificateType_PKIX = 1
} NSSCertificateType;
#ifdef nodef
typedef enum {
nssTrustLevel_Unknown = 0,
nssTrustLevel_NotTrusted = 1,
nssTrustLevel_Trusted = 2,
nssTrustLevel_TrustedDelegator = 3,
nssTrustLevel_Valid = 4
} nssTrustLevel;
#else
typedef CK_ULONG nssTrustLevel; /* for now */
#endif
typedef struct nssCryptokiInstanceStr nssCryptokiInstance;
struct nssCryptokiInstanceStr
{
CK_OBJECT_HANDLE handle;
NSSToken *token;
};
typedef struct nssTokenCertSearchStr nssTokenCertSearch;
struct nssTokenCertSearchStr
{
PRStatus (* callback)(NSSCertificate *c, void *arg);
void *cbarg;
nssList *cached;
NSSTrustDomain *trustDomain;
NSSCryptoContext *cryptoContext;
};
struct NSSAlgorithmAndParametersStr
{
CK_MECHANISM mechanism;
};
PR_END_EXTERN_C
#endif /* DEVT_H */

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.2 $ $Date: 2001-11-09 00:36:12 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.3 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
@ -43,23 +43,10 @@ static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.2 $ $Da
#include "devm.h"
#endif /* DEVM_H */
/* for the cache... */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifndef NSSCKEPV_H
#include "nssckepv.h"
#endif /* NSSCKEPV_H */
#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
@ -207,330 +194,191 @@ nssToken_GetName
return tok->name;
}
NSS_IMPLEMENT PRStatus
nssToken_DeleteStoredObject
NSS_IMPLEMENT NSSItem *
nssToken_Digest
(
NSSToken *tok,
nssSession *sessionOpt,
CK_OBJECT_HANDLE object
NSSAlgorithmAndParameters *ap,
NSSItem *data,
NSSItem *rvOpt,
NSSArena *arenaOpt
)
{
nssSession *session = NULL;
CK_RV ckrv;
PRStatus nssrv;
PRBool createdSession;
if (nssCKObject_IsAttributeTrue(object, CKA_TOKEN, tok->defaultSession,
tok->slot, &nssrv)) {
if (sessionOpt) {
if (!nssSession_IsReadWrite(sessionOpt)) {
return PR_FAILURE;;
} else {
session = sessionOpt;
}
} else if (nssSession_IsReadWrite(tok->defaultSession)) {
session = tok->defaultSession;
} else {
session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
createdSession = PR_TRUE;
}
}
if (session == NULL) {
return PR_FAILURE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok->slot)->C_DestroyObject(session->handle, object);
nssSession_ExitMonitor(session);
if (createdSession) {
nssSession_Destroy(session);
}
if (ckrv != CKR_OK) {
return PR_FAILURE;
}
return PR_SUCCESS;
}
NSS_IMPLEMENT CK_OBJECT_HANDLE
nssToken_ImportObject
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR objectTemplate,
CK_ULONG otsize
)
{
nssSession *session = NULL;
PRBool createdSession = PR_FALSE;
CK_OBJECT_HANDLE object;
CK_RV ckrv;
if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
if (sessionOpt) {
if (!nssSession_IsReadWrite(sessionOpt)) {
return CK_INVALID_HANDLE;
} else {
session = sessionOpt;
}
} else if (nssSession_IsReadWrite(tok->defaultSession)) {
session = tok->defaultSession;
} else {
session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
createdSession = PR_TRUE;
}
}
if (session == NULL) {
return PR_FAILURE;
}
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
objectTemplate, otsize,
&object);
nssSession_ExitMonitor(session);
if (createdSession) {
nssSession_Destroy(session);
}
if (ckrv != CKR_OK) {
return CK_INVALID_HANDLE;
}
return object;
}
NSS_IMPLEMENT CK_OBJECT_HANDLE
nssToken_FindObjectByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
CK_SESSION_HANDLE hSession;
CK_OBJECT_HANDLE rvObject;
CK_ULONG count;
CK_RV ckrv;
CK_ULONG digestLen;
CK_BYTE_PTR digest;
NSSItem *rvItem = NULL;
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
hSession = session->handle;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_HANDLE;
return NULL;
}
ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
#if 0
/* XXX the standard says this should work, but it doesn't */
ckrv = CKAPI(tok)->C_Digest(session->handle, NULL, 0, NULL, &digestLen);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_HANDLE;
return NULL;
}
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
return CK_INVALID_HANDLE;
}
return rvObject;
}
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
struct collect_arg_str
{
NSSArena *arena;
nssList *list;
PRUint32 maximum;
};
static PRStatus
collect_certs_callback(NSSToken *t, nssSession *session,
CK_OBJECT_HANDLE h, void *arg)
{
NSSCertificate *cert;
struct collect_arg_str *ca = (struct collect_arg_str *)arg;
cert = nssCertificate_CreateFromHandle(ca->arena, h, session, t->slot);
if (!cert) {
goto loser;
}
/* addref */
nssList_Add(ca->list, (void *)cert);
if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) {
/* signal the end of collection) */
nss_SetError(NSS_ERROR_MAXIMUM_FOUND);
return PR_FAILURE;
}
return PR_SUCCESS;
loser:
return PR_FAILURE;
}
struct cert_callback_str {
nssListIterator *cachedCerts;
PRStatus (*callback)(NSSCertificate *c, void *arg);
void *arg;
};
static PRStatus
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
{
NSSCertificate *cert = NULL;
NSSCertificate *c;
struct cert_callback_str *ccb = (struct cert_callback_str *)arg;
if (ccb->cachedCerts) {
for (c = (NSSCertificate *)nssListIterator_Start(ccb->cachedCerts);
c != (NSSCertificate *)NULL;
c = (NSSCertificate *)nssListIterator_Next(ccb->cachedCerts))
{
if (c->handle == h && c->token == t) {
/* this is enough, right? */
cert = c;
break;
}
}
nssListIterator_Finish(ccb->cachedCerts);
}
if (!cert) {
/* Could not find cert, so create it */
cert = nssCertificate_CreateFromHandle(NULL, h, session, t->slot);
if (!cert) {
goto loser;
}
}
/* Got the cert, feed it to the callback */
return (*ccb->callback)(cert, ccb->arg);
loser:
return PR_FAILURE;
}
#define OBJECT_STACK_SIZE 16
static PRStatus
nsstoken_TraverseObjects
(
NSSToken *tok,
nssSession *session,
CK_ATTRIBUTE_PTR obj_template,
CK_ULONG otsize,
PRStatus (*callback)(NSSToken *t, nssSession *session,
CK_OBJECT_HANDLE h, void *arg),
void *arg
)
{
NSSSlot *slot;
PRStatus cbrv;
PRUint32 i;
CK_RV ckrv;
CK_ULONG count;
CK_OBJECT_HANDLE *objectStack;
CK_OBJECT_HANDLE startOS[OBJECT_STACK_SIZE];
CK_SESSION_HANDLE hSession;
NSSArena *objectArena = NULL;
nssList *objectList = NULL;
slot = tok->slot;
hSession = session->handle;
objectStack = startOS;
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->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,
OBJECT_STACK_SIZE, &count);
if (ckrv != CKR_OK) {
#endif
digestLen = 0; /* XXX for now */
digest = NULL;
if (rvOpt) {
if (rvOpt->size > 0 && rvOpt->size < digestLen) {
nssSession_ExitMonitor(session);
goto loser;
/* the error should be bad args */
return NULL;
}
if (count == OBJECT_STACK_SIZE) {
if (!objectList) {
objectArena = NSSArena_Create();
objectList = nssList_Create(objectArena, PR_FALSE);
}
objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
OBJECT_STACK_SIZE);
nssList_Add(objectList, objectStack);
} else {
break;
if (rvOpt->data) {
digest = rvOpt->data;
}
digestLen = rvOpt->size;
}
if (!digest) {
digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
if (!digest) {
nssSession_ExitMonitor(session);
return NULL;
}
}
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
ckrv = CKAPI(tok)->C_Digest(session->handle,
(CK_BYTE_PTR)data->data,
(CK_ULONG)data->size,
(CK_BYTE_PTR)digest,
&digestLen);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
goto loser;
nss_ZFreeIf(digest);
return NULL;
}
if (objectList) {
nssListIterator *objects;
objects = nssList_CreateIterator(objectList);
for (objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Start(objects);
objectStack != NULL;
objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Next(objects)) {
for (i=0; i<count; i++) {
cbrv = (*callback)(tok, session, objectStack[i], arg);
}
}
nssListIterator_Finish(objects);
count = OBJECT_STACK_SIZE;
if (!rvOpt) {
rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
}
for (i=0; i<count; i++) {
cbrv = (*callback)(tok, session, startOS[i], arg);
}
if (objectArena)
NSSArena_Destroy(objectArena);
return PR_SUCCESS;
loser:
if (objectArena)
NSSArena_Destroy(objectArena);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificates
(
NSSToken *tok,
nssSession *sessionOpt,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
)
{
PRStatus nssrv;
/* this is really traversal - the template is all certs */
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 }
};
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
nssrv = nssToken_TraverseCertificatesByTemplate(tok, sessionOpt, NULL,
cert_template, ctsize,
callback, arg);
return nssrv;
return rvItem;
}
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificatesByTemplate
nssToken_BeginDigest
(
NSSToken *tok,
nssSession *sessionOpt,
nssList *cachedList,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
NSSAlgorithmAndParameters *ap
)
{
PRStatus rv;
CK_RV ckrv;
nssSession *session;
struct cert_callback_str ccb;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
/* this isn't really traversal, it's find by template ... */
if (cachedList) {
ccb.cachedCerts = nssList_CreateIterator(cachedList);
} else {
ccb.cachedCerts = NULL;
}
ccb.callback = callback;
ccb.arg = arg;
rv = nsstoken_TraverseObjects(tok, session,
cktemplate, ctsize,
retrieve_cert, (void *)&ccb);
return rv;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
nssSession_ExitMonitor(session);
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
nssToken_ContinueDigest
(
NSSToken *tok,
nssSession *sessionOpt,
NSSItem *item
)
{
CK_RV ckrv;
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->C_DigestUpdate(session->handle,
(CK_BYTE_PTR)item->data,
(CK_ULONG)item->size);
nssSession_ExitMonitor(session);
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}
NSS_IMPLEMENT NSSItem *
nssToken_FinishDigest
(
NSSToken *tok,
nssSession *sessionOpt,
NSSItem *rvOpt,
NSSArena *arenaOpt
)
{
CK_RV ckrv;
CK_ULONG digestLen;
CK_BYTE_PTR digest;
NSSItem *rvItem = NULL;
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->C_DigestFinal(session->handle, NULL, &digestLen);
if (ckrv != CKR_OK || digestLen == 0) {
nssSession_ExitMonitor(session);
return NULL;
}
digest = NULL;
if (rvOpt) {
if (rvOpt->size > 0 && rvOpt->size < digestLen) {
nssSession_ExitMonitor(session);
/* the error should be bad args */
return NULL;
}
if (rvOpt->data) {
digest = rvOpt->data;
}
digestLen = rvOpt->size;
}
if (!digest) {
digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
if (!digest) {
nssSession_ExitMonitor(session);
return NULL;
}
}
ckrv = CKAPI(tok)->C_DigestFinal(session->handle, digest, &digestLen);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
nss_ZFreeIf(digest);
return NULL;
}
if (!rvOpt) {
rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
}
return rvItem;
}
/* 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.3 $ $Date: 2001-11-08 00:14:53 $ $Name: $"
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.4 $ $Date: 2001-11-28 16:23:39 $ $Name: $"
CORE_DEPTH = ../../..
@ -48,9 +48,10 @@ MODULE = security
CSRCS = \
devmod.c \
devslot.c \
devtoken.c \
devutil.c \
devslot.c \
devobject.c \
devtoken.c \
devutil.c \
ckhelper.c \
$(NULL)

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

@ -35,7 +35,7 @@
#define NSSDEVT_H
#ifdef DEBUG
static const char NSSDEVT_CVS_ID[] = "@(#) $RCSfile: nssdevt.h,v $ $Revision: 1.2 $ $Date: 2001-11-08 00:14:54 $ $Name: $";
static const char NSSDEVT_CVS_ID[] = "@(#) $RCSfile: nssdevt.h,v $ $Revision: 1.3 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
#endif /* DEBUG */
/*
@ -64,8 +64,6 @@ typedef struct NSSSlotStr NSSSlot;
typedef struct NSSTokenStr NSSToken;
typedef struct nssSessionStr nssSession;
PR_END_EXTERN_C
#endif /* NSSDEVT_H */

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

@ -58,8 +58,9 @@
#include "pki3hack.h"
#include "dev3hack.h"
/*#include "dev.h" */
#include "dev.h"
#include "nsspki.h"
#include "pkim.h"
#include "pkitm.h"
#define PK11_SEARCH_CHUNKSIZE 10
@ -1135,6 +1136,23 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
return objID;
}
static PRStatus
get_newest_cert(NSSCertificate *c, void *arg)
{
nssDecodedCert *dc, *founddc;
NSSCertificate **cfound = (NSSCertificate **)arg;
if (!*cfound) {
*cfound = c;
return PR_SUCCESS;
}
dc = nssCertificate_GetDecoding(c);
founddc = nssCertificate_GetDecoding(*cfound);
if (!founddc->isNewerThan(founddc, dc)) {
*cfound = c;
}
return PR_SUCCESS;
}
CERTCertificate *
PK11_FindCertFromNickname(char *nickname, void *wincx) {
@ -1167,19 +1185,34 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
/* find token by name */
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
if (token) {
nssTokenCertSearch search;
nssList *certList;
certList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname,
certList);
/* set the search criteria */
search.callback = get_newest_cert;
search.cbarg = (void *)&cert;
search.cached = certList;
search.trustDomain = defaultTD;
search.cryptoContext = NULL;
/* find best cert on token */
cert = nssTrustDomain_FindBestCertificateByNicknameForToken(
defaultTD,
token,
(NSSUTF8 *)nickname,
NULL,
&usage,
NULL);
nssToken_TraverseCertificatesByNickname(token, NULL,
(NSSUTF8 *)nickname,
&search);
nssList_Destroy(certList);
if (!cert) {
/* don't have a "for token" here yet... */
cert = NSSTrustDomain_FindCertificateByEmail(defaultTD,
(NSSASCII7 *)nickname,
NULL, &usage, NULL);
certList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(
defaultTD,
nickname,
certList);
search.cached = certList;
nssToken_TraverseCertificatesByNickname(token, NULL,
(NSSASCII7 *)nickname,
&search);
nssList_Destroy(certList);
}
}
} else {
@ -1206,6 +1239,15 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
#endif
}
static PRStatus
collect_certs(NSSCertificate *c, void *arg)
{
nssList *list = (nssList *)arg;
/* Add the cert to the return list */
nssList_AddUnique(list, (void *)c);
return PR_SUCCESS;
}
CERTCertList *
PK11_FindCertsFromNickname(char *nickname, void *wincx) {
#ifdef NSS_CLASSIC
@ -1233,11 +1275,13 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
PORT_Free(certID);
return certList;
#else
PRStatus nssrv;
char *delimit = NULL;
char *tokenName;
CERTCertList *certList = CERT_NewCertList();
int i;
CERTCertList *certList = NULL;
NSSCertificate **foundCerts;
NSSCertificate **pCerts;
NSSCertificate *c;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
NSSToken *token;
@ -1247,14 +1291,25 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
/* find token by name */
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
if (token) {
/* find best cert on token */
foundCerts = nssTrustDomain_FindCertificatesByNicknameForToken(
defaultTD,
token,
(NSSUTF8 *)nickname,
NULL,
0,
NULL);
nssTokenCertSearch search;
PRUint32 count;
nssList *nameList;
nameList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname,
nameList);
/* set the search criteria */
search.callback = collect_certs;
search.cbarg = nameList;
search.cached = nameList;
search.trustDomain = defaultTD;
search.cryptoContext = NULL;
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
nickname, &search);
count = nssList_Count(nameList);
foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
nssList_GetArray(nameList, (void **)foundCerts, count);
nssList_Destroy(nameList);
}
*delimit = ':';
} else {
@ -1265,17 +1320,17 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
0,
NULL);
}
pCerts = foundCerts;
while (pCerts != NULL) {
NSSCertificate *c = *pCerts;
CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
pCerts++;
if (foundCerts) {
certList = CERT_NewCertList();
for (i=0, c = *foundCerts; c; c = foundCerts[++i]) {
CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
}
if (CERT_LIST_HEAD(certList) == NULL) {
CERT_DestroyCertList(certList);
certList = NULL;
}
nss_ZFreeIf(foundCerts);
}
if (CERT_LIST_HEAD(certList) == NULL) {
CERT_DestroyCertList(certList);
certList = NULL;
}
nss_ZFreeIf(foundCerts);
return certList;
#endif
}
@ -1482,10 +1537,22 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
PORT_SetError( PK11_MapError(crv) );
}
if (!cert->nickname && nickname) {
cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
}
cert->pkcs11ID = certID;
cert->dbhandle = STAN_GetDefaultTrustDomain();
if (cert->slot == NULL) {
cert->slot = PK11_ReferenceSlot(slot);
if (cert->nssCertificate) {
cert->nssCertificate->token = slot->nssToken;
nssPKIObjectInstance *instance;
NSSCertificate *c = cert->nssCertificate;
instance = nss_ZNEW(c->object.arena, nssPKIObjectInstance);
instance->cryptoki.token = slot->nssToken;
instance->cryptoki.handle = cert->pkcs11ID;
instance->trustDomain = cert->dbhandle;
nssList_Add(c->object.instanceList, instance);
} else {
cert->nssCertificate = STAN_GetNSSCertificate(cert);
}
@ -2262,31 +2329,29 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg);
#else
/* Alas, stan isn't really made for this... perhaps collect all matching
* subject certs on the token and then pass the certs to the callback?
*/
struct nss3_cert_cbstr pk11cb;
PRStatus nssrv;
NSSToken *tok;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 },
};
CK_ATTRIBUTE *attr = theTemplate;
CK_ULONG templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
NSSToken *token;
NSSDER subject;
NSSTrustDomain *td;
nssList *subjectList;
nssTokenCertSearch search;
pk11cb.callback = callback;
pk11cb.arg = arg;
tok = PK11Slot_GetNSSToken(slot);
if (tok) {
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, NULL,
theTemplate, templateSize,
convert_cert, &pk11cb);
} else {
return SECFailure;
}
td = STAN_GetDefaultTrustDomain();
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
subjectList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, subjectList);
/* set the search criteria */
search.callback = convert_cert;
search.cbarg = &pk11cb;
search.cached = subjectList;
search.trustDomain = td;
search.cryptoContext = NULL;
token = PK11Slot_GetNSSToken(slot);
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
&subject, &search);
nssList_Destroy(subjectList);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
}
@ -2328,31 +2393,37 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg);
#else
/* Alas, stan isn't really made for this... perhaps collect all matching
* subject certs on the token and then pass the certs to the callback?
*/
struct nss3_cert_cbstr pk11cb;
PRStatus nssrv;
NSSToken *tok;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 },
};
CK_ATTRIBUTE *attr = theTemplate;
CK_ULONG templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_LABEL,nickname->data,nickname->len);
NSSToken *token;
NSSTrustDomain *td;
NSSUTF8 *nick;
PRBool created = PR_FALSE;
nssTokenCertSearch search;
nssList *nameList;
pk11cb.callback = callback;
pk11cb.arg = arg;
tok = PK11Slot_GetNSSToken(slot);
if (tok) {
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, NULL,
theTemplate, templateSize,
convert_cert, &pk11cb);
if (nickname->data[nickname->len-1] != '\0') {
nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
nickname->data, nickname->len-1);
created = PR_TRUE;
} else {
return SECFailure;
nick = (NSSUTF8 *)nickname->data;
}
td = STAN_GetDefaultTrustDomain();
nameList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
/* set the search criteria */
search.callback = convert_cert;
search.cbarg = &pk11cb;
search.cached = nameList;
search.trustDomain = td;
search.cryptoContext = NULL;
token = PK11Slot_GetNSSToken(slot);
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
nick, &search);
nssList_Destroy(nameList);
if (created) nss_ZFreeIf(nick);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
}
@ -2387,17 +2458,29 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
callarg.templateCount = templateSize;
return PK11_TraverseSlot(slot, &callarg);
#else
PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
struct nss3_cert_cbstr pk11cb;
NSSToken *tok;
nssList *certList = nssList_Create(NULL, PR_FALSE);
nssTokenCertSearch search;
pk11cb.callback = callback;
pk11cb.arg = arg;
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
/* set the search criteria */
search.callback = convert_cert;
search.cbarg = &pk11cb;
search.cached = certList;
search.trustDomain = td;
search.cryptoContext = NULL;
tok = PK11Slot_GetNSSToken(slot);
if (tok) {
return (SECStatus)nssToken_TraverseCertificates(tok, NULL,
convert_cert, &pk11cb);
nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
} else {
return SECFailure;
nssrv = PR_FAILURE;
}
nssList_Destroy(certList);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
}
@ -2441,12 +2524,11 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
CERTCertificate *rvCert = NULL;
NSSCertificate *c;
NSSDER derCert;
derCert.data = (void *)cert->derCert.data;
derCert.size = (PRUint32)cert->derCert.len;
NSSToken *tok;
tok = PK11Slot_GetNSSToken(slot);
NSSITEM_FROM_SECITEM(&derCert, &cert->derCert);
/* XXX login to slots */
c = NSSTrustDomain_FindCertificateByEncodedCertificate(
STAN_GetDefaultTrustDomain(),
&derCert);
c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert);
if (c) {
rvCert = STAN_GetCERTCertificate(c);
}
@ -2803,7 +2885,11 @@ isOnList(CERTCertList *certList,CERTCertificate *cert)
return PR_FALSE;
}
static SECStatus
#ifdef NSS_CLASSIC
pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
#else
pk11ListCertCallback(CERTCertificate *cert, void *arg)
#endif
{
struct listCertsStr *listCertP = (struct listCertsStr *)arg;
CERTCertificate *newCert = NULL;
@ -2821,11 +2907,15 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
if (!isUnique && cert->nickname) {
nickname = PORT_ArenaStrdup(listCertP->certList->arena,cert->nickname);
}
#ifdef NSS_CLASSIC
if (derCert == NULL) {
newCert=CERT_DupCertificate(cert);
} else {
newCert=CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),&cert->derCert);
}
#else
newCert=CERT_DupCertificate(cert);
#endif
if (newCert == NULL) return SECSuccess;
@ -2870,13 +2960,6 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
return SECSuccess;
}
static SECStatus
pk11ListCertCallbackStub(CERTCertificate *cert, void *arg)
{
return pk11ListCertCallback(cert, NULL, arg);
}
CERTCertList *
PK11_ListCerts(PK11CertListType type, void *pwarg)
@ -2904,8 +2987,7 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
certList = CERT_NewCertList();
listCerts.type = type;
listCerts.certList = certList;
/* XXX need to fix, this callback is of a different form */
pk11cb.callback = pk11ListCertCallbackStub;
pk11cb.callback = pk11ListCertCallback;
pk11cb.arg = &listCerts;
NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
return certList;

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $ $Date: 2001-11-20 18:28:46 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.17 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
@ -51,17 +51,9 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $
#include "dev.h"
#endif /* DEV_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifndef CKT_H
#ifdef NSS_3_4_CODE
#include "pki3hack.h"
#define NSSCKT_H
#endif
#include "ckt.h"
#endif /* CKT_H */
#ifndef BASE_H
#include "base.h"
@ -69,37 +61,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $
extern const NSSError NSS_ERROR_NOT_FOUND;
/* Hm, sadly, I'm using PK11_HashBuf... Need to get crypto context going to
* get rid of that
*/
#ifndef NSS_3_4_CODE
#define NSS_3_4_CODE
#endif /* NSS_3_4_CODE */
#include "pk11func.h"
#include "hasht.h"
/* I assume the following accessors into cert fields will be needed.
* We need to be able to return basic cert info, however, these are
* really PKCS#11 fields, so maybe not these in particular (mcgreer)
*/
NSS_IMPLEMENT NSSUTF8 *
NSSCertificate_GetLabel
(
NSSCertificate *c
)
{
return c->nickname;
}
NSS_IMPLEMENT NSSItem *
NSSCertificate_GetID
(
NSSCertificate *c
)
{
return &c->id;
}
NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef
(
@ -107,350 +68,29 @@ nssCertificate_AddRef
)
{
#ifdef NSS_3_4_CODE
/*
CERTCertificate *cc = STAN_GetCERTCertificate(c);
CERT_DupCertificate(cc);
*/
#else
c->refCount++;
#endif
return c;
}
/* NSS needs access to this function, but does anyone else? */
/* XXX for the 3.4 hack anyway, yes */
NSS_IMPLEMENT NSSCertificate *
NSSCertificate_Create
(
NSSArena *arenaOpt
)
{
NSSArena *arena;
NSSCertificate *rvCert;
arena = (arenaOpt) ? arenaOpt : nssArena_Create();
if (!arena) {
goto loser;
}
arena = NSSArena_Create();
if(!arena) {
return (NSSCertificate *)NULL;
}
rvCert = nss_ZNEW(arena, NSSCertificate);
if (!rvCert) {
goto loser;
}
rvCert->refCount = 1;
if (!arenaOpt) {
rvCert->arena = arena;
}
rvCert->handle = CK_INVALID_HANDLE;
return rvCert;
loser:
if (!arenaOpt && arena) {
nssArena_Destroy(arena);
}
return (NSSCertificate *)NULL;
}
static NSSCertificateType
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
CK_CERTIFICATE_TYPE ckCertType;
ckCertType = *((CK_ULONG *)attrib->pValue);
switch (ckCertType) {
case CKC_X_509:
return NSSCertificateType_PKIX;
break;
default:
return NSSCertificateType_Unknown;
}
}
static CK_OBJECT_HANDLE
get_cert_trust_handle
(
NSSCertificate *c,
nssSession *session
)
{
CK_ULONG tobj_size;
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_ATTRIBUTE tobj_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_CERT_SHA1_HASH, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
unsigned char sha1_hash[SHA1_LENGTH];
tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 0, tobjc);
/* First, use the SHA-1 hash of the cert to locate the trust object */
/* XXX get rid of this PK11_ call! */
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, c->encoding.data, c->encoding.size);
tobj_template[1].pValue = (CK_VOID_PTR)sha1_hash;
tobj_template[1].ulValueLen = (CK_ULONG)SHA1_LENGTH;
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial);
#ifdef NSS_3_4_CODE
if (PK11_HasRootCerts(c->token->pk11slot)) {
tobj_size -= 2;
}
#endif
/*
* we need to arrange for the built-in token to loose the bottom 2
* attributes so that old built-in tokens will continue to work.
*/
return nssToken_FindObjectByTemplate(c->token, session,
tobj_template, tobj_size);
}
static PRStatus
nssCertificate_GetCertTrust
(
NSSCertificate *c,
nssSession *session
)
{
PRStatus nssrv;
CK_TRUST saTrust, caTrust, epTrust, csTrust;
CK_OBJECT_HANDLE tobjID;
CK_ULONG trust_size;
CK_ATTRIBUTE trust_template[] = {
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
};
trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
tobjID = get_cert_trust_handle(c, session);
if (tobjID == CK_INVALID_HANDLE) {
return PR_FAILURE;
}
/* Then use the trust object to find the trust settings */
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, saTrust);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, caTrust);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, epTrust);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, csTrust);
nssrv = nssCKObject_GetAttributes(tobjID,
trust_template, trust_size,
NULL, session, c->slot);
c->trust.serverAuth = saTrust;
c->trust.clientAuth = caTrust;
c->trust.emailProtection = epTrust;
c->trust.codeSigning = csTrust;
return PR_SUCCESS;
}
#ifdef NSS_3_4_CODE
static void make_nss3_nickname(NSSCertificate *c)
{
/* In NSS 3.4, the semantic is that nickname = token name + label */
PRStatus utf8rv;
NSSUTF8 *tokenName;
NSSUTF8 *label;
char *fullname;
PRUint32 len, tlen;
tokenName = nssToken_GetName(c->token);
label = c->nickname ? c->nickname : c->email;
if (!label) return;
tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */
tlen += 1; /* : */
len = nssUTF8_Length(label, &utf8rv); /* label */
len += 1; /* \0 */
len += tlen;
fullname = nss_ZAlloc(c->arena, len);
utf8rv = nssUTF8_CopyIntoFixedBuffer(tokenName, fullname, tlen, ':');
utf8rv = nssUTF8_CopyIntoFixedBuffer(label, fullname + tlen,
len - tlen, '\0');
nss_ZFreeIf(c->nickname);
c->nickname = nssUTF8_Create(c->arena,
nssStringType_UTF8String,
fullname, len);
}
#endif
/* Create a certificate from an object handle. */
NSS_IMPLEMENT NSSCertificate *
nssCertificate_CreateFromHandle
(
NSSArena *arenaOpt,
CK_OBJECT_HANDLE object,
nssSession *session,
NSSSlot *slot
)
{
NSSCertificate *rvCert;
PRStatus nssrv;
CK_ULONG template_size;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
{ CKA_ID, NULL, 0 },
{ CKA_VALUE, NULL, 0 },
{ CKA_LABEL, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 },
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
};
template_size = sizeof(cert_template) / sizeof(cert_template[0]);
rvCert = NSSCertificate_Create(arenaOpt);
if (!rvCert) {
return (NSSCertificate *)NULL;
}
rvCert->handle = object;
/* clean this up */
rvCert->slot = slot;
rvCert->token = slot->token;
rvCert->trustDomain = slot->token->trustDomain;
nssrv = nssCKObject_GetAttributes(object, cert_template, template_size,
rvCert->arena, session, slot);
if (nssrv) {
/* okay, but if failed because one of the attributes could not be
* found, do it gracefully (i.e., catch the error).
*/
goto loser;
}
rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->id);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[3], rvCert->nickname);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->issuer);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->serial);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email);
nssCertificate_GetCertTrust(rvCert, session);
#ifdef NSS_3_4_CODE
/* nss 3.4 database doesn't associate email address with cert */
if (!rvCert->email) {
nssDecodedCert *dc;
NSSASCII7 *email;
dc = nssCertificate_GetDecoding(rvCert);
email = dc->getEmailAddress(dc);
if (email) rvCert->email = nssUTF8_Duplicate(email, rvCert->arena);
}
make_nss3_nickname(rvCert);
#endif
return rvCert;
loser:
NSSCertificate_Destroy(rvCert);
return (NSSCertificate *)NULL;
}
static CK_OBJECT_HANDLE
create_cert_trust_object
(
NSSCertificate *c,
NSSTrust *trust
)
{
CK_ULONG tobj_size;
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_ATTRIBUTE tobj_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_TOKEN, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 },
{ CKA_CERT_SHA1_HASH, NULL, 0 },
{ CKA_CERT_MD5_HASH, NULL, 0 },
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
};
unsigned char sha1_hash[SHA1_LENGTH];
unsigned char md5_hash[MD5_LENGTH];
tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
NSS_CK_SET_ATTRIBUTE_VAR( tobj_template, 0, tobjc);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 1, &g_ck_true);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial);
/* First, use the SHA-1 hash of the cert to locate the trust object */
/* XXX get rid of this PK11_ call! */
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, c->encoding.data, c->encoding.size);
tobj_template[4].pValue = (CK_VOID_PTR)sha1_hash;
tobj_template[4].ulValueLen = (CK_ULONG)SHA1_LENGTH;
PK11_HashBuf(SEC_OID_MD5, md5_hash, c->encoding.data, c->encoding.size);
tobj_template[5].pValue = (CK_VOID_PTR)md5_hash;
tobj_template[5].ulValueLen = (CK_ULONG)MD5_LENGTH;
/* now set the trust values */
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 6, trust->serverAuth);
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 7, trust->clientAuth);
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 8, trust->emailProtection);
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 9, trust->codeSigning);
return nssToken_ImportObject(c->token, NULL, tobj_template, tobj_size);
}
NSS_IMPLEMENT PRStatus
nssCertificate_SetCertTrust
(
NSSCertificate *c,
NSSTrust *trust
)
{
PRStatus nssrv;
nssSession *session;
PRBool createdSession;
CK_OBJECT_HANDLE tobjID;
CK_ULONG trust_size;
CK_ATTRIBUTE trust_template[] = {
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
};
trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
if (!c->token) {
/* must live on a token already */
return PR_FAILURE;
}
session = c->token->defaultSession;
tobjID = get_cert_trust_handle(c, session);
if (tobjID == CK_INVALID_HANDLE) {
/* trust object doesn't exist yet, create one */
tobjID = create_cert_trust_object(c, trust);
if (tobjID == CK_INVALID_HANDLE) {
return PR_FAILURE;
}
c->trust.serverAuth = trust->serverAuth;
c->trust.clientAuth = trust->clientAuth;
c->trust.emailProtection = trust->emailProtection;
c->trust.codeSigning = trust->codeSigning;
return PR_SUCCESS;
}
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, trust->serverAuth);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, trust->clientAuth);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, trust->emailProtection);
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, trust->codeSigning);
/* changing cert trust requires rw session XXX session objects */
createdSession = PR_FALSE;
if (!nssSession_IsReadWrite(session)) {
createdSession = PR_TRUE;
session = nssSlot_CreateSession(c->slot, NULL, PR_TRUE);
}
nssrv = nssCKObject_SetAttributes(tobjID,
trust_template, trust_size,
session, c->slot);
if (createdSession) {
nssSession_Destroy(session);
}
if (nssrv == PR_FAILURE) {
return nssrv;
}
c->trust.serverAuth = trust->serverAuth;
c->trust.clientAuth = trust->clientAuth;
c->trust.emailProtection = trust->emailProtection;
c->trust.codeSigning = trust->codeSigning;
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
NSSCertificate_Destroy
(
NSSCertificate *c
)
{
#ifdef NSS_3_4_CODE
return NSSArena_Destroy(c->object.arena);
#else
if (--c->refCount == 0) {
return NSSArena_Destroy(c->arena);
}
#endif
return PR_SUCCESS;
}
@ -461,13 +101,24 @@ NSSCertificate_DeleteStoredObject
NSSCallback *uhh
)
{
/* delete it from storage, but leave it in memory */
/* according to PKCS#11 2.11 section 13.2, the token must know how
* to handle deletion when there are multiple threads attempting to use
* the same object.
/* this needs more thought on what will happen when there are multiple
* instances
*/
/* XXX use callback to log in if neccessary */
return nssToken_DeleteStoredObject(c->token, NULL, c->handle);
PRStatus nssrv = PR_SUCCESS;
nssPKIObjectInstance *instance;
nssListIterator *instances = c->object.instances;
for (instance = (nssPKIObjectInstance *)nssListIterator_Start(instances);
instance != (nssPKIObjectInstance *)NULL;
instance = (nssPKIObjectInstance *)nssListIterator_Next(instances))
{
nssrv = nssToken_DeleteStoredObject(&instance->cryptoki);
if (nssrv != PR_SUCCESS) {
break;
}
}
nssListIterator_Finish(instances);
return nssrv;
}
NSS_IMPLEMENT PRStatus
@ -538,10 +189,6 @@ nssCertificate_GetDecoding
if (!c->decoding) {
c->decoding = nssDecodedCert_Create(NULL, &c->encoding, c->type);
}
#ifdef NSS_3_4_CODE
/* cause the trust bits to get updated in the encoded cert */
(void) STAN_GetCERTCertificate(c);
#endif
return c->decoding;
}
@ -550,8 +197,10 @@ find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
{
NSSCertificate *rvCert = NULL;
NSSCertificate **subjectCerts;
NSSTrustDomain *td;
td = NSSCertificate_GetTrustDomain(c);
/* Find all certs with this cert's issuer as the subject */
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(c->trustDomain,
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td,
&c->issuer,
NULL,
0,
@ -599,7 +248,17 @@ NSSCertificate_BuildChain
nssList *chain;
NSSItem *issuerID;
NSSCertificate **rvChain;
NSSTrustDomain *td;
nssDecodedCert *dc;
td = NSSCertificate_GetTrustDomain(c);
#ifdef NSS_3_4_CODE
/* This goes down as a 3.4 hack. This function will need to be able to
* search both crypto contexts and trust domains for the chain.
*/
if (!td) {
td = STAN_GetDefaultTrustDomain();
}
#endif
chain = nssList_Create(NULL, PR_FALSE);
nssList_Add(chain, c);
if (statusOpt) *statusOpt = PR_SUCCESS;
@ -620,7 +279,7 @@ NSSCertificate_BuildChain
PRBool tmpca = usage->nss3lookingForCA;
usage->nss3lookingForCA = PR_TRUE;
#endif
c = NSSTrustDomain_FindBestCertificateBySubject(c->trustDomain,
c = NSSTrustDomain_FindBestCertificateBySubject(td,
&c->issuer,
timeOpt,
usage,
@ -641,8 +300,8 @@ finish:
if (rvOpt) {
rvChain = rvOpt;
} else {
rvChain = nss_ZNEWARRAY(arenaOpt,
NSSCertificate *, nssList_Count(chain) + 1);
rvLimit = nssList_Count(chain);
rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1);
}
nssList_GetArray(chain, (void **)rvChain, rvLimit);
nssList_Destroy(chain);
@ -656,12 +315,15 @@ NSSCertificate_GetTrustDomain
NSSCertificate *c
)
{
#if 0
if (c->trustDomain) {
return nssTrustDomain_AddRef(c->trustDomain);
PRStatus nssrv = PR_SUCCESS;
nssPKIObjectInstance *instance;
nssList *instances = c->object.instanceList;
nssrv = nssList_GetArray(instances, (void **)&instance, 1);
if (nssrv == PR_SUCCESS) {
return instance->trustDomain;
} else {
return (NSSTrustDomain *)NULL;
}
#endif
return (NSSTrustDomain *)NULL;
}
NSS_IMPLEMENT NSSToken *
@ -671,9 +333,6 @@ NSSCertificate_GetToken
PRStatus *statusOpt
)
{
if (c->token) {
return nssToken_AddRef(c->token);
}
return (NSSToken *)NULL;
}
@ -684,11 +343,6 @@ NSSCertificate_GetSlot
PRStatus *statusOpt
)
{
#if 0
if (c->token) {
return nssToken_GetSlot(c->token);
}
#endif
return (NSSSlot *)NULL;
}
@ -699,11 +353,6 @@ NSSCertificate_GetModule
PRStatus *statusOpt
)
{
#if 0
if (c->token) {
return nssToken_GetModule(c->token);
}
#endif
return (NSSModule *)NULL;
}
@ -799,15 +448,14 @@ NSSCertificate_GetPublicKey
NSSCertificate *c
)
{
#if 0
CK_ATTRIBUTE pubktemplate[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_ID, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
#if 0
PRStatus nssrv;
CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
#endif
NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
if (c->id.size > 0) {
/* CKA_ID */
@ -824,7 +472,6 @@ NSSCertificate_GetPublicKey
return (NSSPublicKey *)NULL;
}
/* Try the cert's token first */
#if 0
if (c->token) {
nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
}

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

@ -32,13 +32,26 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.4 $ $Date: 2001-10-11 18:41:50 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.5 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifdef NSS_3_4_CODE
#include "pk11func.h"
#include "dev3hack.h"
#endif
extern const NSSError NSS_ERROR_NOT_FOUND;
NSS_IMPLEMENT PRStatus
@ -91,8 +104,28 @@ NSSCryptoContext_ImportCertificate
NSSCertificate *c
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
NSSToken *token;
nssSession *session = NULL;
#ifdef NSS_3_4_CODE
/* XXX hack alert - what this needs to do is find the preferred
* token for cert storage
*/
if (PR_TRUE) {
PK11SlotInfo *slot = PK11_GetInternalSlot();
token = PK11Slot_GetNSSToken(slot);
}
#endif
/*
* question - are there multiple available tokens for the crypto context?
* in that case, it needs to store a session for each one
*/
#ifdef nodef
session = get_token_session(cc, tok);
if (!session) {
return PR_FAILURE;
}
#endif
return nssToken_ImportCertificate(token, session, c, NULL, cc);
}
NSS_IMPLEMENT NSSCertificate *
@ -428,10 +461,10 @@ struct token_session_str {
nssSession *session;
};
#ifdef nodef
static nssSession *
get_token_session(NSSCryptoContext *cc, NSSToken *tok)
{
#if 0
struct token_session_str *ts;
for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
ts != (struct token_session_str *)NULL;
@ -450,8 +483,8 @@ get_token_session(NSSCryptoContext *cc, NSSToken *tok)
nssList_AddElement(cc->sessionList, (void *)ts);
}
return ts->session;
#endif
}
#endif
NSS_IMPLEMENT NSSItem *
NSSCryptoContext_Decrypt
@ -516,6 +549,7 @@ NSSCryptoContext_Decrypt
}
return rvData;
#endif
return NULL;
}
NSS_IMPLEMENT PRStatus
@ -864,8 +898,8 @@ NSSCryptoContext_Digest
NSSArena *arenaOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
return nssToken_Digest(cc->token, cc->session, apOpt,
data, rvOpt, arenaOpt);
}
NSS_IMPLEMENT PRStatus
@ -876,8 +910,7 @@ NSSCryptoContext_BeginDigest
NSSCallback *uhhOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
return nssToken_BeginDigest(cc->token, cc->session, apOpt);
}
NSS_IMPLEMENT PRStatus
@ -888,8 +921,12 @@ NSSCryptoContext_ContinueDigest
NSSItem *item
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
/*
NSSAlgorithmAndParameters *ap;
ap = (apOpt) ? apOpt : cc->ap;
*/
/* why apOpt? can't change it at this point... */
return nssToken_ContinueDigest(cc->token, cc->session, item);
}
NSS_IMPLEMENT NSSItem *
@ -900,8 +937,7 @@ NSSCryptoContext_FinishDigest
NSSArena *arenaOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
return nssToken_FinishDigest(cc->token, cc->session, rvOpt, arenaOpt);
}
NSS_IMPLEMENT NSSCryptoContext *

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

@ -35,7 +35,7 @@
#define PKI_H
#ifdef DEBUG
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.6 $ $Date: 2001-10-17 14:40:22 $ $Name: $";
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
@ -54,27 +54,6 @@ nssCertificate_AddRef
NSSCertificate *c
);
NSS_EXTERN NSSCertificate *
nssCertificate_CreateFromHandle
(
NSSArena *arenaOpt,
CK_OBJECT_HANDLE object,
nssSession *session,
NSSSlot *slot
);
NSS_EXTERN NSSUTF8 *
NSSCertificate_GetLabel
(
NSSCertificate *c
);
NSS_EXTERN NSSItem *
NSSCertificate_GetID
(
NSSCertificate *c
);
PR_END_EXTERN_C
#endif /* PKI_H */

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Date: 2001-11-08 20:46:08 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.5 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
#endif /* DEBUG */
/*
@ -51,10 +51,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Da
#include "dev.h"
#endif /* DEV_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifndef DEVNSS3HACK_H
#include "dev3hack.h"
#endif /* DEVNSS3HACK_H */
@ -71,12 +67,20 @@ static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Da
NSSTrustDomain *g_default_trust_domain = NULL;
NSSCryptoContext *g_default_crypto_context = NULL;
NSSTrustDomain *
STAN_GetDefaultTrustDomain()
{
return g_default_trust_domain;
}
NSSCryptoContext *
STAN_GetDefaultCryptoContext()
{
return g_default_crypto_context;
}
NSS_IMPLEMENT void
STAN_LoadDefaultNSS3TrustDomain
(
@ -103,6 +107,7 @@ STAN_LoadDefaultNSS3TrustDomain
}
td->tokens = nssList_CreateIterator(td->tokenList);
g_default_trust_domain = td;
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
}
NSS_IMPLEMENT PRStatus
@ -136,7 +141,7 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
return NULL;
}
secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
if (!secrv) {
if (secrv != SECSuccess) {
return NULL;
}
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
@ -299,6 +304,28 @@ nssDecodedPKIXCertificate_Create
return rvDC;
}
static nssDecodedCert *
create_decoded_pkix_cert_from_nss3cert
(
NSSArena *arenaOpt,
CERTCertificate *cc
)
{
nssDecodedCert *rvDC;
rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
rvDC->type = NSSCertificateType_PKIX;
rvDC->data = (void *)cc;
rvDC->getIdentifier = nss3certificate_getIdentifier;
rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
rvDC->matchIdentifier = nss3certificate_matchIdentifier;
rvDC->getUsage = nss3certificate_getUsage;
rvDC->isValidAtTime = nss3certificate_isValidAtTime;
rvDC->isNewerThan = nss3certificate_isNewerThan;
rvDC->matchUsage = nss3certificate_matchUsage;
rvDC->getEmailAddress = nss3certificate_getEmailAddress;
return rvDC;
}
NSS_IMPLEMENT PRStatus
nssDecodedPKIXCertificate_Destroy
(
@ -336,10 +363,15 @@ get_nss3trust_from_cktrust(CK_TRUST t)
}
static CERTCertTrust *
nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, NSSToken *token,
CERTCertificate *cc)
{
CERTCertTrust *rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
unsigned int client;
NSSTrust *t = nssToken_FindTrustForCert(token, NULL, c);
if (!t) {
return NULL;
}
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
client = get_nss3trust_from_cktrust(t->clientAuth);
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
@ -357,26 +389,39 @@ nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
return rvTrust;
}
static nssPKIObjectInstance *
get_cert_instance(NSSCertificate *c)
{
nssPKIObjectInstance *instance;
instance = NULL;
nssList_GetArray(c->object.instanceList, (void **)&instance, 1);
return instance;
}
static void
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
{
nssPKIObjectInstance *instance = get_cert_instance(c);
/* fill other fields needed by NSS3 functions using CERTCertificate */
/* handle */
cc->pkcs11ID = c->handle;
/* nickname */
cc->nickname = PL_strdup(c->nickname);
/* slot (ownSlot ?) (addref ?) */
if (c->token) {
cc->slot = c->token->pk11slot;
if (!cc->nickname && c->nickname) {
PRStatus nssrv;
int len = nssUTF8_Size(c->nickname, &nssrv);
cc->nickname = PORT_ArenaAlloc(cc->arena, len);
memcpy(cc->nickname, c->nickname, len-1);
cc->nickname[len-1] = '\0';
}
/* trust */
cc->trust = nssTrust_GetCERTCertTrust(&c->trust, cc);
cc->referenceCount++;
if (instance) {
nssCryptokiInstance *cryptoki = &instance->cryptoki;
/* slot (ownSlot ?) (addref ?) */
cc->slot = cryptoki->token->pk11slot;
/* pkcs11ID */
cc->pkcs11ID = cryptoki->handle;
/* trust */
cc->trust = nssTrust_GetCERTCertTrustForCert(c, cryptoki->token, cc);
/* database handle is now the trust domain */
cc->dbhandle = instance->trustDomain;
}
/* subjectList ? */
/* pkcs11ID */
cc->pkcs11ID = c->handle;
/* database handle is now the trust domain */
cc->dbhandle = c->trustDomain;
/* pointer back */
cc->nssCertificate = c;
}
@ -396,6 +441,11 @@ STAN_GetCERTCertificate(NSSCertificate *c)
cc = (CERTCertificate *)dc->data;
if (!cc->nssCertificate) {
fill_CERTCertificateFields(c, cc);
} else if (!cc->trust) {
nssPKIObjectInstance *instance = get_cert_instance(c);
cc->trust = nssTrust_GetCERTCertTrustForCert(c,
instance->cryptoki.token,
cc);
}
return cc;
}
@ -428,13 +478,13 @@ NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *cc)
{
NSSCertificate *c;
nssPKIObject *object;
nssPKIObjectInstance *instance;
NSSArena *arena;
c = cc->nssCertificate;
if (c) {
return c;
}
/* i don't think this should happen. but if it can, need to create
* NSSCertificate from CERTCertificate values here. */
/* Yup, it can happen. */
@ -442,24 +492,35 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
if (!arena) {
return NULL;
}
c = NSSCertificate_Create(arena);
c = nss_ZNEW(arena, NSSCertificate);
if (!c) {
goto loser;
}
object = &c->object;
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
c->type = NSSCertificateType_PKIX;
c->arena = arena;
object->arena = arena;
object->refCount = 1;
object->instanceList = nssList_Create(arena, PR_TRUE);
object->instances = nssList_CreateIterator(object->instanceList);
nssItem_Create(arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
nssItem_Create(arena,
&c->subject, cc->derSubject.len, cc->derSubject.data);
nssItem_Create(arena,
&c->serial, cc->serialNumber.len, cc->serialNumber.data);
if (PR_TRUE) {
/* CERTCertificate stores serial numbers decoded. I need the DER
* here. sigh.
*/
SECItem derSerial;
CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
PORT_Free(derSerial.data);
}
if (cc->nickname) {
c->nickname = nssUTF8_Create(arena,
nssStringType_UTF8String,
(NSSUTF8 *)cc->nickname,
PORT_Strlen(cc->nickname));
nssStringType_UTF8String,
(NSSUTF8 *)cc->nickname,
PORT_Strlen(cc->nickname));
}
if (cc->emailAddr) {
c->email = nssUTF8_Create(arena,
@ -467,19 +528,15 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
(NSSUTF8 *)cc->emailAddr,
PORT_Strlen(cc->emailAddr));
}
c->trustDomain = (NSSTrustDomain *)cc->dbhandle;
instance = nss_ZNEW(arena, nssPKIObjectInstance);
instance->trustDomain = (NSSTrustDomain *)cc->dbhandle;
if (cc->slot) {
c->token = PK11Slot_GetNSSToken(cc->slot);
c->slot = c->token->slot;
instance->cryptoki.token = PK11Slot_GetNSSToken(cc->slot);
instance->cryptoki.handle = cc->pkcs11ID;
}
nssList_Add(object->instanceList, instance);
c->decoding = create_decoded_pkix_cert_from_nss3cert(arena, cc);
cc->nssCertificate = c;
if (cc->trust) {
CERTCertTrust *trust = cc->trust;
c->trust.serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
c->trust.clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
c->trust.emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
c->trust.codeSigning= get_stan_trust(trust->objectSigningFlags, PR_FALSE);
}
return c;
loser:
nssArena_Destroy(arena);
@ -487,47 +544,31 @@ loser:
}
NSS_EXTERN PRStatus
STAN_ChangeCertTrust(NSSCertificate *c, CERTCertTrust *trust)
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
{
CERTCertificate *cc = STAN_GetCERTCertificate(c);
PRStatus nssrv;
NSSCertificate *c = STAN_GetNSSCertificate(cc);
nssPKIObjectInstance *instance;
NSSTrust nssTrust;
/* Set the CERTCertificate's trust */
cc->trust = trust;
/* Set the NSSCerticate's trust */
nssTrust.certificate = c;
nssTrust.object.arena = nssArena_Create();
nssTrust.object.instanceList = nssList_Create(nssTrust.object.arena,
PR_FALSE);
nssTrust.object.instances = nssList_CreateIterator(
nssTrust.object.instanceList);
nssTrust.serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
nssTrust.clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
nssTrust.emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
nssTrust.codeSigning= get_stan_trust(trust->objectSigningFlags, PR_FALSE);
return nssCertificate_SetCertTrust(c, &nssTrust);
}
/* This is here to replace CERT_Traverse calls */
static PRStatus
traverse_certificates_by_template
(
NSSTrustDomain *td,
nssList *cachedList,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
)
{
PRStatus nssrv;
NSSToken *tok;
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, cachedList,
cktemplate, ctsize,
callback, arg);
if (nssrv == PR_FAILURE) {
return PR_FAILURE;
}
}
nssListIterator_Finish(td->tokens);
return PR_SUCCESS;
nssTrust.codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE);
instance = get_cert_instance(c);
/* maybe GetDefaultTrustToken()? */
nssrv = nssToken_ImportTrust(instance->cryptoki.token, NULL, &nssTrust,
instance->trustDomain, instance->cryptoContext);
nssArena_Destroy(nssTrust.object.arena);
return nssrv;
}
/* CERT_TraversePermCertsForSubject */
@ -541,22 +582,20 @@ nssTrustDomain_TraverseCertificatesBySubject
)
{
PRStatus nssrv;
nssList *subjectList;
CK_ATTRIBUTE subj_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
subjectList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
nssrv = traverse_certificates_by_template(td, subjectList,
subj_template, ctsize,
callback, arg);
nssList_Destroy(subjectList);
NSSArena *tmpArena;
NSSCertificate **subjectCerts;
NSSCertificate *c;
PRIntn i;
tmpArena = NSSArena_Create();
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL,
0, tmpArena);
if (subjectCerts) {
for (i=0, c = subjectCerts[i]; c; i++) {
nssrv = callback(c, arg);
if (nssrv != PR_SUCCESS) break;
}
}
nssArena_Destroy(tmpArena);
return nssrv;
}
@ -571,23 +610,20 @@ nssTrustDomain_TraverseCertificatesByNickname
)
{
PRStatus nssrv;
nssList *nickCerts;
CK_ATTRIBUTE nick_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
nick_template[1].pValue = (CK_VOID_PTR)nickname;
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(nickname, &nssrv);
nickCerts = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nickname, nickCerts);
nssrv = traverse_certificates_by_template(td, nickCerts,
nick_template, ctsize,
callback, arg);
nssList_Destroy(nickCerts);
NSSArena *tmpArena;
NSSCertificate **nickCerts;
NSSCertificate *c;
PRIntn i;
tmpArena = NSSArena_Create();
nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL,
0, tmpArena);
if (nickCerts) {
for (i=0, c = nickCerts[i]; c; i++) {
nssrv = callback(c, arg);
if (nssrv != PR_SUCCESS) break;
}
}
nssArena_Destroy(tmpArena);
return nssrv;
}
@ -601,23 +637,33 @@ nssTrustDomain_TraverseCertificates
)
{
PRStatus nssrv;
NSSToken *token;
nssList *certList;
CK_ATTRIBUTE cert_template[] =
{
{ CKA_CLASS, NULL, 0 },
};
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
nssTokenCertSearch search;
/* grab all cache certs (XXX please only do this here...)
* the alternative is to provide a callback through search that allows
* the token to query the cache for the cert during traversal.
*/
certList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsFromCache(td, certList);
nssrv = traverse_certificates_by_template(td, certList,
cert_template, ctsize,
callback, arg);
/* set the search criteria */
search.callback = callback;
search.cbarg = arg;
search.cached = certList;
search.trustDomain = td;
search.cryptoContext = NULL;
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificates(token, NULL, &search);
}
nssListIterator_Finish(td->tokens);
nssList_Destroy(certList);
return nssrv;
}
#if 0
static CK_CERTIFICATE_TYPE
get_cert_type(NSSCertificateType nssType)
{
@ -629,6 +675,7 @@ get_cert_type(NSSCertificateType nssType)
* type CK_CERTIFICATE_TYPE */
}
}
#endif
NSS_IMPLEMENT NSSToken *
STAN_GetInternalToken(void)
@ -643,6 +690,7 @@ nssTrustDomain_AddTempCertToPerm
NSSCertificate *c
)
{
#if 0
NSSToken *token;
CK_CERTIFICATE_TYPE cert_type;
CK_ATTRIBUTE cert_template[] =
@ -679,4 +727,6 @@ nssTrustDomain_AddTempCertToPerm
c->slot = token->slot;
/* Do the trust object */
return PR_SUCCESS;
#endif
return PR_FAILURE;
}

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

@ -35,7 +35,7 @@
#define PKINSS3HACK_H
#ifdef DEBUG
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.1 $ $Date: 2001-11-08 00:15:20 $ $Name: $";
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKIT_H
@ -57,6 +57,9 @@ PR_BEGIN_EXTERN_C
NSS_EXTERN NSSTrustDomain *
STAN_GetDefaultTrustDomain();
NSSCryptoContext *
STAN_GetDefaultCryptoContext();
NSS_IMPLEMENT void
STAN_LoadDefaultNSS3TrustDomain
(
@ -76,7 +79,7 @@ NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *c);
NSS_EXTERN PRStatus
STAN_ChangeCertTrust(NSSCertificate *c, CERTCertTrust *trust);
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
/* exposing this */
NSS_EXTERN NSSCertificate *

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

@ -35,7 +35,7 @@
#define PKIM_H
#ifdef DEBUG
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.6 $ $Date: 2001-10-19 20:06:28 $ $Name: $";
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
#endif /* DEBUG */
#ifndef BASE_H
@ -129,13 +129,20 @@ nssTrustDomain_AddCertsToCache
PRUint32 numCerts
);
NSS_EXTERN PRStatus
NSS_EXTERN void
nssTrustDomain_RemoveCertFromCache
(
NSSTrustDomain *td,
NSSCertificate *cert
);
NSS_EXTERN void
nssTrustDomain_FlushCache
(
NSSTrustDomain *td,
PRFloat64 threshold
);
/*
* Remove all certs for the given token from the cache. This is
* needed if the token is removed.

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

@ -35,7 +35,7 @@
#define PKIT_H
#ifdef DEBUG
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $Date: 2001-11-05 17:29:27 $ $Name: $";
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:44 $ $Name: $";
#endif /* DEBUG */
/*
@ -55,12 +55,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $D
#ifdef NSS_3_4_CODE
#include "certt.h"
#include "pkcs11t.h"
#define NSSCKT_H
#include "ckt.h"
#else
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
#endif /* NSS_3_4_CODE */
#ifndef NSSPKIT_H
@ -71,27 +65,46 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $D
#include "nssdevt.h"
#endif /* NSSDEVT_H */
PR_BEGIN_EXTERN_C
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
typedef enum {
NSSCertificateType_Unknown = 0,
NSSCertificateType_PKIX = 1
} NSSCertificateType;
PR_BEGIN_EXTERN_C
typedef struct nssDecodedCertStr nssDecodedCert;
typedef struct nssPKIObjectInstanceStr nssPKIObjectInstance;
typedef struct nssPKIObjectStr nssPKIObject;
struct nssPKIObjectInstanceStr
{
nssCryptokiInstance cryptoki;
NSSTrustDomain *trustDomain;
NSSCryptoContext *cryptoContext;
};
struct nssPKIObjectStr
{
PRInt32 refCount;
NSSArena *arena;
nssList *instanceList; /* list of nssPKIObjectInstance */
nssListIterator *instances;
};
struct NSSTrustStr
{
CK_TRUST serverAuth;
CK_TRUST clientAuth;
CK_TRUST emailProtection;
CK_TRUST codeSigning;
struct nssPKIObjectStr object;
NSSCertificate *certificate;
nssTrustLevel serverAuth;
nssTrustLevel clientAuth;
nssTrustLevel emailProtection;
nssTrustLevel codeSigning;
};
struct NSSCertificateStr
{
PRInt32 refCount;
NSSArena *arena;
struct nssPKIObjectStr object;
NSSCertificateType type;
NSSItem id;
NSSBER encoding;
@ -100,12 +113,6 @@ struct NSSCertificateStr
NSSDER serial;
NSSUTF8 *nickname;
NSSASCII7 *email;
NSSSlot *slot;
NSSToken *token;
NSSTrustDomain *trustDomain;
NSSCryptoContext *cryptoContext;
NSSTrust trust;
CK_OBJECT_HANDLE handle;
nssDecodedCert *decoding;
};
@ -134,6 +141,9 @@ struct NSSCryptoContextStr
{
PRInt32 refCount;
NSSArena *arena;
NSSTrustDomain *td;
NSSToken *token;
nssSession *session;
};
struct NSSTimeStr;

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

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.16 $ $Date: 2001-11-20 18:28:47 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.17 $ $Date: 2001-11-28 16:23:44 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
@ -114,7 +114,8 @@ NSSTrustDomain_Destroy
if (--td->refCount == 0) {
/* Destroy each token in the list of tokens */
if (td->tokens) {
nssList_DestroyElements(td->tokenList, token_destructor);
nssList_Clear(td->tokenList, token_destructor);
nssList_Destroy(td->tokenList);
}
/* Destroy the trust domain */
nssArena_Destroy(td->arena);
@ -354,12 +355,10 @@ NSSTrustDomain_ImportEncodedPublicKey
}
struct get_best_cert_arg_str {
NSSTrustDomain *td;
NSSCertificate *cert;
NSSTime *time;
NSSUsage *usage;
NSSPolicies *policies;
nssList *cached;
};
static PRStatus
@ -400,59 +399,9 @@ get_best_cert(NSSCertificate *c, void *arg)
return PR_SUCCESS;
}
static NSSCertificate *
find_best_cert_for_template
(
NSSTrustDomain *td,
NSSToken *token,
struct get_best_cert_arg_str *best,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
PRStatus nssrv;
NSSToken *tok;
if (token) {
nssrv = nssToken_TraverseCertificatesByTemplate(token, NULL,
best->cached,
cktemplate, ctsize,
get_best_cert, best);
} else {
/* we need to lock the iterator */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL,
best->cached,
cktemplate, ctsize,
get_best_cert,
best);
}
nssListIterator_Finish(td->tokens);
}
/* Cache the cert before returning */
/*nssTrustDomain_AddCertsToCache(td, &best->cert, 1);*/
/* rjr handle orphanned certs in cache for now. real fix will be Ian's
* crypto object */
if (best->cert == NULL) {
if (nssList_Count(best->cached) >= 1) {
NSSCertificate * candidate;
nssList_GetArray(best->cached,&candidate,1);
if (candidate) {
best->cert = nssCertificate_AddRef(candidate);
}
}
}
return best->cert;
}
struct collect_arg_str {
nssList *list;
PRUint32 maximum;
NSSArena *arena;
NSSCertificate **rvOpt;
};
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
@ -471,105 +420,6 @@ collect_certs(NSSCertificate *c, void *arg)
return PR_SUCCESS;
}
static NSSCertificate **
find_all_certs_for_template
(
NSSTrustDomain *td,
NSSToken *token,
struct collect_arg_str *ca,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
NSSCertificate **certs = NULL;
PRStatus nssrv;
PRUint32 count;
NSSToken *tok;
if (token) {
nssrv = nssToken_TraverseCertificatesByTemplate(token, NULL, ca->list,
cktemplate, ctsize,
collect_certs, ca);
} else {
/* we need to lock the iterator */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL,
ca->list,
cktemplate, ctsize,
collect_certs, ca);
}
nssListIterator_Finish(td->tokens);
}
count = nssList_Count(ca->list);
if (ca->rvOpt) {
certs = ca->rvOpt;
} else {
certs = nss_ZNEWARRAY(ca->arena, NSSCertificate *, count + 1);
}
nssrv = nssList_GetArray(ca->list, (void **)certs, count);
/* Cache the certs before returning */
/*nssTrustDomain_AddCertsToCache(td, certs, count);*/
return certs;
}
/* XXX
* This is really a hack for PK11_ calls that want to specify the token to
* do lookups on (see PK11_FindCertFromNickname). I don't think this
* is something we want to keep.
*/
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_FindBestCertificateByNicknameForToken
(
NSSTrustDomain *td,
NSSToken *token,
NSSUTF8 *name,
NSSTime *timeOpt, /* NULL for "now" */
NSSUsage *usage,
NSSPolicies *policiesOpt /* NULL for none */
)
{
NSSCertificate *rvCert = NULL;
PRStatus nssrv;
struct get_best_cert_arg_str best;
CK_ATTRIBUTE nick_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
CK_ULONG ctsize;
nssList *nameList;
/* set up the search template */
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
nick_template[1].pValue = (CK_VOID_PTR)name;
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
/* set the criteria for determining the best cert */
best.td = td;
best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage;
best.policies = policiesOpt;
/* find all matching certs in the cache */
nameList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
best.cached = nameList;
/* now find the best cert on tokens */
rvCert = find_best_cert_for_template(td, token,
&best, nick_template, ctsize);
if (!rvCert) {
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
nick_template[1].ulValueLen++;
rvCert = find_best_cert_for_template(td, token,
&best, nick_template, ctsize);
}
nssList_Destroy(nameList);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateByNickname
(
@ -580,23 +430,12 @@ NSSTrustDomain_FindBestCertificateByNickname
NSSPolicies *policiesOpt /* NULL for none */
)
{
NSSCertificate *rvCert = NULL;
PRStatus nssrv;
NSSToken *token;
nssTokenCertSearch search;
struct get_best_cert_arg_str best;
CK_ATTRIBUTE nick_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
CK_ULONG ctsize;
nssList *nameList;
/* set up the search template */
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
nick_template[1].pValue = (CK_VOID_PTR)name;
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
/* set the criteria for determining the best cert */
best.td = td;
best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage;
@ -604,62 +443,26 @@ NSSTrustDomain_FindBestCertificateByNickname
/* find all matching certs in the cache */
nameList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
best.cached = nameList;
/* now find the best cert on tokens */
rvCert = find_best_cert_for_template(td, NULL,
&best, nick_template, ctsize);
if (!rvCert) {
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
nick_template[1].ulValueLen++;
rvCert = find_best_cert_for_template(td, NULL,
&best, nick_template, ctsize);
}
nssList_Destroy(nameList);
return rvCert;
}
/* XXX
* This is really a hack for PK11_ calls that want to specify the token to
* do lookups on (see PK11_FindCertsFromNickname). I don't think this
* is something we want to keep.
*/
NSS_IMPLEMENT NSSCertificate **
nssTrustDomain_FindCertificatesByNicknameForToken
(
NSSTrustDomain *td,
NSSToken *token,
NSSUTF8 *name,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt
)
{
NSSCertificate **rvCerts = NULL;
PRStatus nssrv;
CK_ATTRIBUTE nick_template[] =
/* set the search criteria */
search.callback = get_best_cert;
search.cbarg = &best;
search.cached = nameList;
search.trustDomain = td;
search.cryptoContext = NULL;
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
nssList *nickCerts;
struct collect_arg_str ca;
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
nick_template[1].pValue = (CK_VOID_PTR)name;
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
nickCerts = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nickCerts);
ca.list = nickCerts;
ca.maximum = maximumOpt;
ca.arena = arenaOpt;
ca.rvOpt = rvOpt;
rvCerts = find_all_certs_for_template(td, token,
&ca, nick_template, ctsize);
nssList_Destroy(nickCerts);
return rvCerts;
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
name, &search);
}
nssListIterator_Finish(td->tokens);
nssList_Destroy(nameList);
if (best.cert) {
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
}
return best.cert;
}
NSS_IMPLEMENT NSSCertificate **
@ -673,28 +476,45 @@ NSSTrustDomain_FindCertificatesByNickname
)
{
NSSCertificate **rvCerts = NULL;
NSSToken *token;
PRUint32 count;
PRStatus nssrv;
CK_ATTRIBUTE nick_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 }
};
nssList *nickCerts;
nssList *nameList;
struct collect_arg_str ca;
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
nick_template[1].pValue = (CK_VOID_PTR)name;
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
nickCerts = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nickCerts);
ca.list = nickCerts;
nssTokenCertSearch search;
/* set up the collection */
nameList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
ca.list = nameList;
ca.maximum = maximumOpt;
ca.arena = arenaOpt;
ca.rvOpt = rvOpt;
rvCerts = find_all_certs_for_template(td, NULL,
&ca, nick_template, ctsize);
nssList_Destroy(nickCerts);
/* set the search criteria */
search.callback = collect_certs;
search.cbarg = &ca;
search.cached = nameList;
search.trustDomain = td;
search.cryptoContext = NULL;
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
name, &search);
}
nssListIterator_Finish(td->tokens);
count = nssList_Count(nameList);
if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt;
if (count > 0) {
if (rvOpt) {
nssList_GetArray(nameList, (void **)rvOpt, count);
rvOpt[count] = NULL;
} else {
rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
nssList_GetArray(nameList, (void **)rvCerts, count);
}
nssTrustDomain_AddCertsToCache(td, rvCerts, count);
}
nssList_Destroy(nameList);
return rvCerts;
}
@ -708,44 +528,29 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
{
NSSCertificate *rvCert = NULL;
NSSToken *tok;
CK_ULONG ctsize;
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
/* Set the unique id */
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, serialNumber);
/* Try the cache */
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
issuer,
serialNumber);
if (!rvCert) {
/* Not cached, look for it on tokens */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
object = nssToken_FindObjectByTemplate(tok, NULL,
cert_template, ctsize);
if (object != CK_INVALID_HANDLE) {
/* Could not find cert, so create it */
rvCert = nssCertificate_CreateFromHandle(NULL, object,
tok->defaultSession,
tok->slot);
if (rvCert) {
/* cache it */
/*nssTrustDomain_AddCertsToCache(td, &rvCert, 1);*/
}
break;
}
}
nssListIterator_Finish(td->tokens);
if (rvCert) {
return rvCert;
}
/* Not cached, look for it on tokens */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
NULL,
issuer,
serialNumber);
if (rvCert) {
/* cache it */
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
break;
}
}
nssListIterator_Finish(td->tokens);
return rvCert;
}
@ -759,31 +564,39 @@ NSSTrustDomain_FindBestCertificateBySubject
NSSPolicies *policiesOpt
)
{
NSSCertificate *rvCert = NULL;
PRStatus nssrv;
NSSToken *token;
nssList *subjectList;
CK_ATTRIBUTE subj_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
struct get_best_cert_arg_str best;
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
best.td = td;
nssTokenCertSearch search;
/* set the criteria for determining the best cert */
best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage;
best.policies = policiesOpt;
/* find all matching certs in the cache */
subjectList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
best.cached = subjectList;
/* now find the best cert on tokens */
rvCert = find_best_cert_for_template(td, NULL,
&best, subj_template, ctsize);
/* set the search criteria */
search.callback = get_best_cert;
search.cbarg = &best;
search.cached = subjectList;
search.trustDomain = td;
search.cryptoContext = NULL;
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
subject, &search);
}
nssListIterator_Finish(td->tokens);
nssList_Destroy(subjectList);
return rvCert;
if (best.cert) {
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
}
return best.cert;
}
NSS_IMPLEMENT NSSCertificate **
@ -796,26 +609,45 @@ NSSTrustDomain_FindCertificatesBySubject
NSSArena *arenaOpt
)
{
PRStatus nssrv;
NSSCertificate **rvCerts = NULL;
NSSToken *token;
PRUint32 count;
nssList *subjectList;
struct collect_arg_str ca;
CK_ATTRIBUTE subj_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
nssTokenCertSearch search;
/* set up the collection */
subjectList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
ca.list = subjectList;
ca.maximum = maximumOpt;
ca.arena = arenaOpt;
ca.rvOpt = rvOpt;
rvCerts = find_all_certs_for_template(td, NULL,
&ca, subj_template, ctsize);
/* set the search criteria */
search.callback = collect_certs;
search.cbarg = &ca;
search.cached = subjectList;
search.trustDomain = td;
search.cryptoContext = NULL;
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
subject, &search);
}
nssListIterator_Finish(td->tokens);
count = nssList_Count(subjectList);
if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt;
if (count > 0) {
if (rvOpt) {
nssList_GetArray(subjectList, (void **)rvOpt, count);
rvOpt[count] = NULL;
} else {
rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
nssList_GetArray(subjectList, (void **)rvCerts, count);
}
nssTrustDomain_AddCertsToCache(td, rvCerts, count);
}
nssList_Destroy(subjectList);
return rvCerts;
}
@ -857,39 +689,25 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
{
NSSCertificate *rvCert = NULL;
NSSToken *tok;
CK_ULONG ctsize;
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_VALUE, NULL, 0 }
};
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, encodedCertificate);
/* Try the cache */
rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate);
if (!rvCert) {
/* Not cached, look for it on tokens */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
object = nssToken_FindObjectByTemplate(tok, NULL,
cert_template, ctsize);
if (object != CK_INVALID_HANDLE) {
/* found it */
rvCert = nssCertificate_CreateFromHandle(NULL, object,
tok->defaultSession,
tok->slot);
if (rvCert) {
/* cache it */
/*nssTrustDomain_AddCertsToCache(td, &rvCert, 1);*/
}
break;
}
}
nssListIterator_Finish(td->tokens);
if (rvCert) {
return rvCert;
}
/* Not cached, look for it on tokens */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
encodedCertificate);
if (rvCert) {
/* cache it */
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
break;
}
}
nssListIterator_Finish(td->tokens);
return rvCert;
}
@ -903,23 +721,12 @@ NSSTrustDomain_FindCertificateByEmail
NSSPolicies *policiesOpt
)
{
NSSCertificate *rvCert = NULL;
PRStatus nssrv;
NSSToken *token;
struct get_best_cert_arg_str best;
CK_ATTRIBUTE email_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
};
CK_ULONG ctsize;
nssTokenCertSearch search;
nssList *emailList;
/* set up the search template */
ctsize = (CK_ULONG)(sizeof(email_template) / sizeof(email_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(email_template, 0, &g_ck_class_cert);
email_template[1].pValue = (CK_VOID_PTR)email;
email_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(email, &nssrv);
/* set the criteria for determining the best cert */
best.td = td;
best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage;
@ -927,20 +734,26 @@ NSSTrustDomain_FindCertificateByEmail
/* find all matching certs in the cache */
emailList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(td, email, emailList);
best.cached = emailList;
/* now find the best cert on tokens */
rvCert = find_best_cert_for_template(td, NULL,
&best, email_template, ctsize);
if (!rvCert) {
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
email_template[1].ulValueLen++;
rvCert = find_best_cert_for_template(td, NULL,
&best, email_template, ctsize);
/* set the search criteria */
search.callback = get_best_cert;
search.cbarg = &best;
search.cached = emailList;
search.trustDomain = td;
search.cryptoContext = NULL;
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificatesByEmail(token, NULL,
email, &search);
}
nssListIterator_Finish(td->tokens);
nssList_Destroy(emailList);
return rvCert;
if (best.cert) {
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
}
return best.cert;
}
NSS_IMPLEMENT NSSCertificate **
@ -1072,17 +885,26 @@ NSSTrustDomain_TraverseCertificates
)
{
PRStatus nssrv;
NSSToken *tok;
/* we need to lock the iterator */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
NSSToken *token;
nssList *certList;
nssTokenCertSearch search;
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
/* set the search criteria */
search.callback = callback;
search.cbarg = arg;
search.cached = certList;
search.trustDomain = td;
search.cryptoContext = NULL;
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_TraverseCertificates(tok, NULL, callback, arg);
nssrv = nssToken_TraverseCertificates(token, NULL, &search);
}
nssListIterator_Finish(td->tokens);
return NULL; /* should return array of nssrv's ? */
nssList_Destroy(certList);
return NULL;
}
NSS_IMPLEMENT PRStatus
@ -1149,8 +971,18 @@ NSSTrustDomain_CreateCryptoContext
NSSCallback *uhhOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
NSSArena *arena;
NSSCryptoContext *rvCC;
arena = NSSArena_Create();
if (!arena) {
return NULL;
}
rvCC = nss_ZNEW(arena, NSSCryptoContext);
if (!rvCC) {
return NULL;
}
rvCC->td = td;
return rvCC;
}
NSS_IMPLEMENT NSSCryptoContext *