зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
88ef1ac939
Коммит
c3cb1b39dc
|
@ -35,7 +35,7 @@
|
||||||
#define BASE_H
|
#define BASE_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -562,6 +562,12 @@ nssItem_Create
|
||||||
const void *data
|
const void *data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NSS_EXTERN void
|
||||||
|
nssItem_Destroy
|
||||||
|
(
|
||||||
|
NSSItem *item
|
||||||
|
);
|
||||||
|
|
||||||
NSS_EXTERN NSSItem *
|
NSS_EXTERN NSSItem *
|
||||||
nssItem_Duplicate
|
nssItem_Duplicate
|
||||||
(
|
(
|
||||||
|
@ -831,8 +837,8 @@ nssList_Destroy
|
||||||
nssList *list
|
nssList *list
|
||||||
);
|
);
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN void
|
||||||
nssList_DestroyElements
|
nssList_Clear
|
||||||
(
|
(
|
||||||
nssList *list,
|
nssList *list,
|
||||||
nssListElementDestructorFunc destructor
|
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 *
|
NSS_EXTERN nssHash *
|
||||||
nssHash_CreatePointer
|
nssHash_CreatePointer
|
||||||
(
|
(
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -112,7 +112,7 @@ nss_compare_items(const void *v1, const void *v2)
|
||||||
* nssHash_create
|
* nssHash_create
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static nssHash *
|
NSS_IMPLEMENT nssHash *
|
||||||
nssHash_Create
|
nssHash_Create
|
||||||
(
|
(
|
||||||
NSSArena *arenaOpt,
|
NSSArena *arenaOpt,
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -116,6 +116,19 @@ nssItem_Create
|
||||||
return (NSSItem *)NULL;
|
return (NSSItem *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSS_IMPLEMENT void
|
||||||
|
nssItem_Destroy
|
||||||
|
(
|
||||||
|
NSSItem *item
|
||||||
|
)
|
||||||
|
{
|
||||||
|
nss_ClearErrorStack();
|
||||||
|
|
||||||
|
nss_ZFreeIf(item->data);
|
||||||
|
nss_ZFreeIf(item);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nssItem_Duplicate
|
* nssItem_Duplicate
|
||||||
*
|
*
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -138,8 +138,17 @@ nssList_Create
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssList_Destroy(nssList *list)
|
nssList_Destroy(nssList *list)
|
||||||
{
|
{
|
||||||
if (list->lock) PZ_DestroyLock(list->lock);
|
PZLock *lock = list->lock;
|
||||||
NSSArena_Destroy(list->arena);
|
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;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,22 +171,23 @@ nssList_GetCompareFunction(nssList *list)
|
||||||
return list->compareFunc;
|
return list->compareFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT void
|
||||||
nssList_DestroyElements(nssList *list, nssListElementDestructorFunc destructor)
|
nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
|
||||||
{
|
{
|
||||||
PRCList *link;
|
PRCList *link;
|
||||||
nssListElement *node;
|
nssListElement *node, *tmp;
|
||||||
NSSLIST_LOCK_IF(list);
|
NSSLIST_LOCK_IF(list);
|
||||||
node = list->head;
|
node = list->head;
|
||||||
while (node && list->count > 0) {
|
while (node && list->count > 0) {
|
||||||
(*destructor)(node->data);
|
if (destructor) (*destructor)(node->data);
|
||||||
link = &node->link;
|
link = &node->link;
|
||||||
node = (nssListElement *)PR_NEXT_LINK(link);
|
tmp = (nssListElement *)PR_NEXT_LINK(link);
|
||||||
PR_REMOVE_LINK(link);
|
PR_REMOVE_LINK(link);
|
||||||
|
nss_ZFreeIf(node);
|
||||||
|
node = tmp;
|
||||||
--list->count;
|
--list->count;
|
||||||
}
|
}
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
return nssList_Destroy(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PRStatus
|
static PRStatus
|
||||||
|
@ -271,7 +281,7 @@ nssList_Get(nssList *list, void *data)
|
||||||
NSSLIST_LOCK_IF(list);
|
NSSLIST_LOCK_IF(list);
|
||||||
node = nsslist_get_matching_element(list, data);
|
node = nsslist_get_matching_element(list, data);
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
return node->data;
|
return (node) ? node->data : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRUint32
|
NSS_IMPLEMENT PRUint32
|
||||||
|
@ -286,14 +296,14 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
|
||||||
nssListIterator *iter;
|
nssListIterator *iter;
|
||||||
void *el;
|
void *el;
|
||||||
PRUint32 i = 0;
|
PRUint32 i = 0;
|
||||||
|
PR_ASSERT(maxElements > 0);
|
||||||
iter = nssList_CreateIterator(list);
|
iter = nssList_CreateIterator(list);
|
||||||
for (el = nssListIterator_Start(iter); el != NULL;
|
for (el = nssListIterator_Start(iter); el != NULL;
|
||||||
el = nssListIterator_Next(iter))
|
el = nssListIterator_Next(iter))
|
||||||
{
|
{
|
||||||
rvArray[i++] = el;
|
rvArray[i++] = el;
|
||||||
if (maxElements > 0 && i == maxElements) break;
|
if (i == maxElements) break;
|
||||||
}
|
}
|
||||||
rvArray[i] = NULL;
|
|
||||||
nssListIterator_Finish(iter);
|
nssListIterator_Finish(iter);
|
||||||
nssListIterator_Destroy(iter);
|
nssListIterator_Destroy(iter);
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
|
|
@ -116,8 +116,7 @@ CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||||
/* XXX store it on a writeable token */
|
/* XXX store it on a writeable token */
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
NSSCertificate *c = STAN_GetNSSCertificate(cert);
|
ret = STAN_ChangeCertTrust(cert, trust);
|
||||||
ret = STAN_ChangeCertTrust(c, trust);
|
|
||||||
rv = (ret == PR_SUCCESS) ? SECSuccess : SECFailure;
|
rv = (ret == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
@ -141,7 +140,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
||||||
}
|
}
|
||||||
if (c->nickname && strcmp(nickname, c->nickname) != 0) {
|
if (c->nickname && strcmp(nickname, c->nickname) != 0) {
|
||||||
nss_ZFreeIf(c->nickname);
|
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);
|
PORT_Free(cert->nickname);
|
||||||
cert->nickname = PORT_Strdup(nickname);
|
cert->nickname = PORT_Strdup(nickname);
|
||||||
}
|
}
|
||||||
|
@ -168,6 +167,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
|
||||||
char *nickname, PRBool isperm, PRBool copyDER)
|
char *nickname, PRBool isperm, PRBool copyDER)
|
||||||
{
|
{
|
||||||
NSSCertificate *c;
|
NSSCertificate *c;
|
||||||
|
NSSCryptoContext *context;
|
||||||
nssDecodedCert *dc;
|
nssDecodedCert *dc;
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
CERTCertificate *cc;
|
CERTCertificate *cc;
|
||||||
|
@ -175,13 +175,19 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
c = NSSCertificate_Create(arena);
|
c = nss_ZNEW(arena, NSSCertificate);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
NSSITEM_FROM_SECITEM(&c->encoding, derCert);
|
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);
|
cc = STAN_GetCERTCertificate(c);
|
||||||
c->arena = arena;
|
|
||||||
nssItem_Create(arena,
|
nssItem_Create(arena,
|
||||||
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
|
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
|
||||||
nssItem_Create(arena,
|
nssItem_Create(arena,
|
||||||
|
@ -200,12 +206,13 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
|
||||||
(NSSUTF8 *)cc->emailAddr,
|
(NSSUTF8 *)cc->emailAddr,
|
||||||
PORT_Strlen(cc->emailAddr));
|
PORT_Strlen(cc->emailAddr));
|
||||||
}
|
}
|
||||||
c->trustDomain = handle;
|
context = STAN_GetDefaultCryptoContext();
|
||||||
cc->dbhandle = handle;
|
NSSCryptoContext_ImportCertificate(context, c);
|
||||||
nssTrustDomain_AddCertsToCache(handle, &c, 1);
|
/* This is a hack to work around the fact that an instance of the cert
|
||||||
cc->istemp = 1;
|
* doesn't really exist until the import
|
||||||
cc->isperm = 0;
|
*/
|
||||||
|
cc->nssCertificate = NULL;
|
||||||
|
cc = STAN_GetCERTCertificate(c);
|
||||||
return cc;
|
return cc;
|
||||||
loser:
|
loser:
|
||||||
nssArena_Destroy(arena);
|
nssArena_Destroy(arena);
|
||||||
|
@ -363,10 +370,13 @@ CERT_DestroyCertificate(CERTCertificate *cert)
|
||||||
CERT_UnlockCertRefCount(cert);
|
CERT_UnlockCertRefCount(cert);
|
||||||
if ( ( refCount == 0 ) && !cert->keepSession ) {
|
if ( ( refCount == 0 ) && !cert->keepSession ) {
|
||||||
PRArenaPool *arena = cert->arena;
|
PRArenaPool *arena = cert->arena;
|
||||||
if ( cert->istemp ) {
|
|
||||||
/* uncache the cert ? */
|
|
||||||
}
|
|
||||||
/* delete the NSSCertificate */
|
/* 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
|
/* zero cert before freeing. Any stale references to this cert
|
||||||
* after this point will probably cause an exception. */
|
* after this point will probably cause an exception. */
|
||||||
PORT_Memset(cert, 0, sizeof *cert);
|
PORT_Memset(cert, 0, sizeof *cert);
|
||||||
|
|
|
@ -417,9 +417,13 @@ loser:
|
||||||
nss_ZFreeIf(nssTime);
|
nss_ZFreeIf(nssTime);
|
||||||
if (status == PR_SUCCESS) {
|
if (status == PR_SUCCESS) {
|
||||||
/* if it's a root, the chain will only have one cert */
|
/* if it's a root, the chain will only have one cert */
|
||||||
NSSCertificate *issuer = chain[1] ? chain[1] : chain[0];
|
if (!chain[1]) {
|
||||||
CERTCertificate *rvc = STAN_GetCERTCertificate(issuer);
|
/* need to dupe since caller expects new cert */
|
||||||
return rvc;
|
return CERT_DupCertificate(cert);
|
||||||
|
} else {
|
||||||
|
/* this is the only instance */
|
||||||
|
return STAN_GetCERTCertificate(chain[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,13 +32,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef PKIT_H
|
|
||||||
#include "pkit.h"
|
|
||||||
#endif /* PKIT_H */
|
|
||||||
|
|
||||||
#ifndef DEV_H
|
#ifndef DEV_H
|
||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
#endif /* DEV_H */
|
#endif /* DEV_H */
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define DEV_H
|
#define DEV_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef DEVT_H
|
#ifndef DEVT_H
|
||||||
|
@ -64,10 +64,6 @@ static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.13 $ $Da
|
||||||
* |-----------|---> NSSSlot <--> NSSToken
|
* |-----------|---> NSSSlot <--> NSSToken
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DEVT_H
|
|
||||||
#include "devt.h"
|
|
||||||
#endif /* DEVT_H */
|
|
||||||
|
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
|
|
||||||
NSS_EXTERN NSSModule *
|
NSS_EXTERN NSSModule *
|
||||||
|
@ -248,16 +244,24 @@ nssToken_GetName
|
||||||
NSSToken *tok
|
NSSToken *tok
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Given a raw attribute template, import an object
|
NSS_EXTERN PRStatus
|
||||||
* (certificate, public key, private key, symmetric key)
|
nssToken_ImportCertificate
|
||||||
*/
|
|
||||||
NSS_EXTERN CK_OBJECT_HANDLE
|
|
||||||
nssToken_ImportObject
|
|
||||||
(
|
(
|
||||||
NSSToken *tok,
|
NSSToken *tok,
|
||||||
nssSession *sessionOpt,
|
nssSession *sessionOpt,
|
||||||
CK_ATTRIBUTE_PTR objectTemplate,
|
NSSCertificate *cert,
|
||||||
CK_ULONG otsize
|
NSSTrustDomain *td,
|
||||||
|
NSSCryptoContext *cc
|
||||||
|
);
|
||||||
|
|
||||||
|
NSS_EXTERN PRStatus
|
||||||
|
nssToken_ImportTrust
|
||||||
|
(
|
||||||
|
NSSToken *tok,
|
||||||
|
nssSession *sessionOpt,
|
||||||
|
NSSTrust *trust,
|
||||||
|
NSSTrustDomain *trustDomain,
|
||||||
|
NSSCryptoContext *cryptoContext
|
||||||
);
|
);
|
||||||
|
|
||||||
NSS_EXTERN NSSPublicKey *
|
NSS_EXTERN NSSPublicKey *
|
||||||
|
@ -280,30 +284,15 @@ nssToken_GenerateSymmetricKey
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN PRStatus
|
||||||
nssToken_DeleteStoredObject
|
nssToken_DeleteStoredObject
|
||||||
(
|
(
|
||||||
NSSToken *tok,
|
nssCryptokiInstance *instance
|
||||||
nssSession *sessionOpt,
|
|
||||||
CK_OBJECT_HANDLE object
|
|
||||||
);
|
);
|
||||||
|
|
||||||
NSS_EXTERN CK_OBJECT_HANDLE
|
NSS_EXTERN NSSTrust *
|
||||||
nssToken_FindObjectByTemplate
|
nssToken_FindTrustForCert
|
||||||
(
|
(
|
||||||
NSSToken *tok,
|
NSSToken *token,
|
||||||
nssSession *sessionOpt,
|
nssSession *sessionOpt,
|
||||||
CK_ATTRIBUTE_PTR cktemplate,
|
NSSCertificate *c
|
||||||
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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN PRStatus
|
||||||
|
@ -311,8 +300,95 @@ nssToken_TraverseCertificates
|
||||||
(
|
(
|
||||||
NSSToken *tok,
|
NSSToken *tok,
|
||||||
nssSession *sessionOpt,
|
nssSession *sessionOpt,
|
||||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
nssTokenCertSearch *search
|
||||||
void *arg
|
);
|
||||||
|
|
||||||
|
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
|
NSS_EXTERN PRStatus
|
||||||
|
@ -342,9 +418,17 @@ nssSession_IsReadWrite
|
||||||
nssSession *s
|
nssSession *s
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef DEBUG
|
NSS_EXTERN NSSAlgorithmAndParameters *
|
||||||
void nssModule_Debug(NSSModule *m);
|
NSSAlgorithmAndParameters_CreateSHA1Digest
|
||||||
#endif
|
(
|
||||||
|
NSSArena *arenaOpt
|
||||||
|
);
|
||||||
|
|
||||||
|
NSS_EXTERN NSSAlgorithmAndParameters *
|
||||||
|
NSSAlgorithmAndParameters_CreateMD5Digest
|
||||||
|
(
|
||||||
|
NSSArena *arenaOpt
|
||||||
|
);
|
||||||
|
|
||||||
PR_END_EXTERN_C
|
PR_END_EXTERN_C
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#include "nspr.h"
|
#include "nspr.h"
|
||||||
|
@ -367,12 +367,6 @@ nssModule_TraverseCertificates
|
||||||
void *arg
|
void *arg
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PRUint32 i;
|
|
||||||
for (i=0; i<mod->numSlots; i++) {
|
|
||||||
/* might as well skip straight to token, right? or is this slot? */
|
|
||||||
nssToken_TraverseCertificates(mod->slots[i]->token,
|
|
||||||
NULL, callback, arg);
|
|
||||||
}
|
|
||||||
return NULL;
|
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
|
#define DEVT_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -60,12 +60,18 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.6 $ $D
|
||||||
#include "nssckt.h"
|
#include "nssckt.h"
|
||||||
#endif /* NSSCKT_H */
|
#endif /* NSSCKT_H */
|
||||||
|
|
||||||
|
#ifndef BASET_H
|
||||||
|
#include "baset.h"
|
||||||
|
#endif /* BASET_H */
|
||||||
|
|
||||||
#ifdef NSS_3_4_CODE
|
#ifdef NSS_3_4_CODE
|
||||||
#include "secmodt.h"
|
#include "secmodt.h"
|
||||||
#endif /* NSS_3_4_CODE */
|
#endif /* NSS_3_4_CODE */
|
||||||
|
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
|
|
||||||
|
typedef struct nssSessionStr nssSession;
|
||||||
|
|
||||||
/* The list of boolean flags used to describe properties of a
|
/* The list of boolean flags used to describe properties of a
|
||||||
* module.
|
* module.
|
||||||
*/
|
*/
|
||||||
|
@ -138,6 +144,47 @@ struct nssSessionStr
|
||||||
PRBool isRW;
|
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
|
PR_END_EXTERN_C
|
||||||
|
|
||||||
#endif /* DEVT_H */
|
#endif /* DEVT_H */
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef DEV_H
|
#ifndef DEV_H
|
||||||
|
@ -43,23 +43,10 @@ static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.2 $ $Da
|
||||||
#include "devm.h"
|
#include "devm.h"
|
||||||
#endif /* DEVM_H */
|
#endif /* DEVM_H */
|
||||||
|
|
||||||
/* for the cache... */
|
|
||||||
#ifndef PKI_H
|
|
||||||
#include "pki.h"
|
|
||||||
#endif /* PKI_H */
|
|
||||||
|
|
||||||
#ifndef NSSCKEPV_H
|
#ifndef NSSCKEPV_H
|
||||||
#include "nssckepv.h"
|
#include "nssckepv.h"
|
||||||
#endif /* 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
|
#ifndef CKHELPER_H
|
||||||
#include "ckhelper.h"
|
#include "ckhelper.h"
|
||||||
#endif /* CKHELPER_H */
|
#endif /* CKHELPER_H */
|
||||||
|
@ -207,330 +194,191 @@ nssToken_GetName
|
||||||
return tok->name;
|
return tok->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT NSSItem *
|
||||||
nssToken_DeleteStoredObject
|
nssToken_Digest
|
||||||
(
|
(
|
||||||
NSSToken *tok,
|
NSSToken *tok,
|
||||||
nssSession *sessionOpt,
|
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_RV ckrv;
|
||||||
|
CK_ULONG digestLen;
|
||||||
|
CK_BYTE_PTR digest;
|
||||||
|
NSSItem *rvItem = NULL;
|
||||||
nssSession *session;
|
nssSession *session;
|
||||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||||
hSession = session->handle;
|
|
||||||
nssSession_EnterMonitor(session);
|
nssSession_EnterMonitor(session);
|
||||||
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
|
ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
|
||||||
if (ckrv != CKR_OK) {
|
if (ckrv != CKR_OK) {
|
||||||
nssSession_ExitMonitor(session);
|
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) {
|
if (ckrv != CKR_OK) {
|
||||||
nssSession_ExitMonitor(session);
|
nssSession_ExitMonitor(session);
|
||||||
return CK_INVALID_HANDLE;
|
return NULL;
|
||||||
}
|
}
|
||||||
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
|
#endif
|
||||||
nssSession_ExitMonitor(session);
|
digestLen = 0; /* XXX for now */
|
||||||
if (ckrv != CKR_OK) {
|
digest = NULL;
|
||||||
return CK_INVALID_HANDLE;
|
if (rvOpt) {
|
||||||
}
|
if (rvOpt->size > 0 && rvOpt->size < digestLen) {
|
||||||
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) {
|
|
||||||
nssSession_ExitMonitor(session);
|
nssSession_ExitMonitor(session);
|
||||||
goto loser;
|
/* the error should be bad args */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if (count == OBJECT_STACK_SIZE) {
|
if (rvOpt->data) {
|
||||||
if (!objectList) {
|
digest = rvOpt->data;
|
||||||
objectArena = NSSArena_Create();
|
}
|
||||||
objectList = nssList_Create(objectArena, PR_FALSE);
|
digestLen = rvOpt->size;
|
||||||
}
|
}
|
||||||
objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
|
if (!digest) {
|
||||||
OBJECT_STACK_SIZE);
|
digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
|
||||||
nssList_Add(objectList, objectStack);
|
if (!digest) {
|
||||||
} else {
|
nssSession_ExitMonitor(session);
|
||||||
break;
|
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);
|
nssSession_ExitMonitor(session);
|
||||||
if (ckrv != CKR_OK) {
|
if (ckrv != CKR_OK) {
|
||||||
goto loser;
|
nss_ZFreeIf(digest);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if (objectList) {
|
if (!rvOpt) {
|
||||||
nssListIterator *objects;
|
rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
|
||||||
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++) {
|
return rvItem;
|
||||||
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
|
NSS_IMPLEMENT PRStatus
|
||||||
nssToken_TraverseCertificates
|
nssToken_BeginDigest
|
||||||
(
|
(
|
||||||
NSSToken *tok,
|
NSSToken *tok,
|
||||||
nssSession *sessionOpt,
|
nssSession *sessionOpt,
|
||||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
NSSAlgorithmAndParameters *ap
|
||||||
void *arg
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PRStatus nssrv;
|
CK_RV ckrv;
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
|
||||||
nssToken_TraverseCertificatesByTemplate
|
|
||||||
(
|
|
||||||
NSSToken *tok,
|
|
||||||
nssSession *sessionOpt,
|
|
||||||
nssList *cachedList,
|
|
||||||
CK_ATTRIBUTE_PTR cktemplate,
|
|
||||||
CK_ULONG ctsize,
|
|
||||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
|
||||||
void *arg
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PRStatus rv;
|
|
||||||
nssSession *session;
|
nssSession *session;
|
||||||
struct cert_callback_str ccb;
|
|
||||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||||
/* this isn't really traversal, it's find by template ... */
|
nssSession_EnterMonitor(session);
|
||||||
if (cachedList) {
|
ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
|
||||||
ccb.cachedCerts = nssList_CreateIterator(cachedList);
|
nssSession_ExitMonitor(session);
|
||||||
} else {
|
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
|
||||||
ccb.cachedCerts = NULL;
|
}
|
||||||
}
|
|
||||||
ccb.callback = callback;
|
NSS_IMPLEMENT PRStatus
|
||||||
ccb.arg = arg;
|
nssToken_ContinueDigest
|
||||||
rv = nsstoken_TraverseObjects(tok, session,
|
(
|
||||||
cktemplate, ctsize,
|
NSSToken *tok,
|
||||||
retrieve_cert, (void *)&ccb);
|
nssSession *sessionOpt,
|
||||||
return rv;
|
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
|
# may use your version of this file under either the MPL or the
|
||||||
# GPL.
|
# 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 = ../../..
|
CORE_DEPTH = ../../..
|
||||||
|
|
||||||
|
@ -48,9 +48,10 @@ MODULE = security
|
||||||
|
|
||||||
CSRCS = \
|
CSRCS = \
|
||||||
devmod.c \
|
devmod.c \
|
||||||
devslot.c \
|
devslot.c \
|
||||||
devtoken.c \
|
devobject.c \
|
||||||
devutil.c \
|
devtoken.c \
|
||||||
|
devutil.c \
|
||||||
ckhelper.c \
|
ckhelper.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define NSSDEVT_H
|
#define NSSDEVT_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -64,8 +64,6 @@ typedef struct NSSSlotStr NSSSlot;
|
||||||
|
|
||||||
typedef struct NSSTokenStr NSSToken;
|
typedef struct NSSTokenStr NSSToken;
|
||||||
|
|
||||||
typedef struct nssSessionStr nssSession;
|
|
||||||
|
|
||||||
PR_END_EXTERN_C
|
PR_END_EXTERN_C
|
||||||
|
|
||||||
#endif /* NSSDEVT_H */
|
#endif /* NSSDEVT_H */
|
||||||
|
|
|
@ -58,8 +58,9 @@
|
||||||
#include "pki3hack.h"
|
#include "pki3hack.h"
|
||||||
#include "dev3hack.h"
|
#include "dev3hack.h"
|
||||||
|
|
||||||
/*#include "dev.h" */
|
#include "dev.h"
|
||||||
#include "nsspki.h"
|
#include "nsspki.h"
|
||||||
|
#include "pkim.h"
|
||||||
#include "pkitm.h"
|
#include "pkitm.h"
|
||||||
|
|
||||||
#define PK11_SEARCH_CHUNKSIZE 10
|
#define PK11_SEARCH_CHUNKSIZE 10
|
||||||
|
@ -1135,6 +1136,23 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
|
||||||
return objID;
|
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 *
|
CERTCertificate *
|
||||||
PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
||||||
|
@ -1167,19 +1185,34 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
||||||
/* find token by name */
|
/* find token by name */
|
||||||
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
|
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
|
||||||
if (token) {
|
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 */
|
/* find best cert on token */
|
||||||
cert = nssTrustDomain_FindBestCertificateByNicknameForToken(
|
nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||||
defaultTD,
|
(NSSUTF8 *)nickname,
|
||||||
token,
|
&search);
|
||||||
(NSSUTF8 *)nickname,
|
nssList_Destroy(certList);
|
||||||
NULL,
|
|
||||||
&usage,
|
|
||||||
NULL);
|
|
||||||
if (!cert) {
|
if (!cert) {
|
||||||
/* don't have a "for token" here yet... */
|
certList = nssList_Create(NULL, PR_FALSE);
|
||||||
cert = NSSTrustDomain_FindCertificateByEmail(defaultTD,
|
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(
|
||||||
(NSSASCII7 *)nickname,
|
defaultTD,
|
||||||
NULL, &usage, NULL);
|
nickname,
|
||||||
|
certList);
|
||||||
|
search.cached = certList;
|
||||||
|
nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||||
|
(NSSASCII7 *)nickname,
|
||||||
|
&search);
|
||||||
|
nssList_Destroy(certList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1206,6 +1239,15 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
||||||
#endif
|
#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 *
|
CERTCertList *
|
||||||
PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
||||||
#ifdef NSS_CLASSIC
|
#ifdef NSS_CLASSIC
|
||||||
|
@ -1233,11 +1275,13 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
||||||
PORT_Free(certID);
|
PORT_Free(certID);
|
||||||
return certList;
|
return certList;
|
||||||
#else
|
#else
|
||||||
|
PRStatus nssrv;
|
||||||
char *delimit = NULL;
|
char *delimit = NULL;
|
||||||
char *tokenName;
|
char *tokenName;
|
||||||
CERTCertList *certList = CERT_NewCertList();
|
int i;
|
||||||
|
CERTCertList *certList = NULL;
|
||||||
NSSCertificate **foundCerts;
|
NSSCertificate **foundCerts;
|
||||||
NSSCertificate **pCerts;
|
NSSCertificate *c;
|
||||||
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
|
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
|
||||||
if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
|
if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
|
||||||
NSSToken *token;
|
NSSToken *token;
|
||||||
|
@ -1247,14 +1291,25 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
||||||
/* find token by name */
|
/* find token by name */
|
||||||
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
|
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
|
||||||
if (token) {
|
if (token) {
|
||||||
/* find best cert on token */
|
nssTokenCertSearch search;
|
||||||
foundCerts = nssTrustDomain_FindCertificatesByNicknameForToken(
|
PRUint32 count;
|
||||||
defaultTD,
|
nssList *nameList;
|
||||||
token,
|
nameList = nssList_Create(NULL, PR_FALSE);
|
||||||
(NSSUTF8 *)nickname,
|
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
|
||||||
NULL,
|
nickname,
|
||||||
0,
|
nameList);
|
||||||
NULL);
|
/* 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 = ':';
|
*delimit = ':';
|
||||||
} else {
|
} else {
|
||||||
|
@ -1265,17 +1320,17 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
pCerts = foundCerts;
|
if (foundCerts) {
|
||||||
while (pCerts != NULL) {
|
certList = CERT_NewCertList();
|
||||||
NSSCertificate *c = *pCerts;
|
for (i=0, c = *foundCerts; c; c = foundCerts[++i]) {
|
||||||
CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
|
CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
|
||||||
pCerts++;
|
}
|
||||||
|
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;
|
return certList;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1482,10 +1537,22 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||||
PORT_SetError( PK11_MapError(crv) );
|
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) {
|
if (cert->slot == NULL) {
|
||||||
cert->slot = PK11_ReferenceSlot(slot);
|
cert->slot = PK11_ReferenceSlot(slot);
|
||||||
if (cert->nssCertificate) {
|
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 {
|
} else {
|
||||||
cert->nssCertificate = STAN_GetNSSCertificate(cert);
|
cert->nssCertificate = STAN_GetNSSCertificate(cert);
|
||||||
}
|
}
|
||||||
|
@ -2262,31 +2329,29 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
|
||||||
|
|
||||||
return PK11_TraverseSlot(slot, &callarg);
|
return PK11_TraverseSlot(slot, &callarg);
|
||||||
#else
|
#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;
|
struct nss3_cert_cbstr pk11cb;
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
NSSToken *tok;
|
NSSToken *token;
|
||||||
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
|
NSSDER subject;
|
||||||
CK_ATTRIBUTE theTemplate[] = {
|
NSSTrustDomain *td;
|
||||||
{ CKA_CLASS, NULL, 0 },
|
nssList *subjectList;
|
||||||
{ CKA_SUBJECT, NULL, 0 },
|
nssTokenCertSearch search;
|
||||||
};
|
|
||||||
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);
|
|
||||||
pk11cb.callback = callback;
|
pk11cb.callback = callback;
|
||||||
pk11cb.arg = arg;
|
pk11cb.arg = arg;
|
||||||
tok = PK11Slot_GetNSSToken(slot);
|
td = STAN_GetDefaultTrustDomain();
|
||||||
if (tok) {
|
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
|
||||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, NULL,
|
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||||
theTemplate, templateSize,
|
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, subjectList);
|
||||||
convert_cert, &pk11cb);
|
/* set the search criteria */
|
||||||
} else {
|
search.callback = convert_cert;
|
||||||
return SECFailure;
|
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;
|
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2328,31 +2393,37 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
|
||||||
|
|
||||||
return PK11_TraverseSlot(slot, &callarg);
|
return PK11_TraverseSlot(slot, &callarg);
|
||||||
#else
|
#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;
|
struct nss3_cert_cbstr pk11cb;
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
NSSToken *tok;
|
NSSToken *token;
|
||||||
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
|
NSSTrustDomain *td;
|
||||||
CK_ATTRIBUTE theTemplate[] = {
|
NSSUTF8 *nick;
|
||||||
{ CKA_CLASS, NULL, 0 },
|
PRBool created = PR_FALSE;
|
||||||
{ CKA_LABEL, NULL, 0 },
|
nssTokenCertSearch search;
|
||||||
};
|
nssList *nameList;
|
||||||
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);
|
|
||||||
pk11cb.callback = callback;
|
pk11cb.callback = callback;
|
||||||
pk11cb.arg = arg;
|
pk11cb.arg = arg;
|
||||||
tok = PK11Slot_GetNSSToken(slot);
|
if (nickname->data[nickname->len-1] != '\0') {
|
||||||
if (tok) {
|
nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
|
||||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, NULL,
|
nickname->data, nickname->len-1);
|
||||||
theTemplate, templateSize,
|
created = PR_TRUE;
|
||||||
convert_cert, &pk11cb);
|
|
||||||
} else {
|
} 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;
|
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2387,17 +2458,29 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
|
||||||
callarg.templateCount = templateSize;
|
callarg.templateCount = templateSize;
|
||||||
return PK11_TraverseSlot(slot, &callarg);
|
return PK11_TraverseSlot(slot, &callarg);
|
||||||
#else
|
#else
|
||||||
|
PRStatus nssrv;
|
||||||
|
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
|
||||||
struct nss3_cert_cbstr pk11cb;
|
struct nss3_cert_cbstr pk11cb;
|
||||||
NSSToken *tok;
|
NSSToken *tok;
|
||||||
|
nssList *certList = nssList_Create(NULL, PR_FALSE);
|
||||||
|
nssTokenCertSearch search;
|
||||||
pk11cb.callback = callback;
|
pk11cb.callback = callback;
|
||||||
pk11cb.arg = arg;
|
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);
|
tok = PK11Slot_GetNSSToken(slot);
|
||||||
if (tok) {
|
if (tok) {
|
||||||
return (SECStatus)nssToken_TraverseCertificates(tok, NULL,
|
nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
|
||||||
convert_cert, &pk11cb);
|
|
||||||
} else {
|
} else {
|
||||||
return SECFailure;
|
nssrv = PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
nssList_Destroy(certList);
|
||||||
|
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2441,12 +2524,11 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
||||||
CERTCertificate *rvCert = NULL;
|
CERTCertificate *rvCert = NULL;
|
||||||
NSSCertificate *c;
|
NSSCertificate *c;
|
||||||
NSSDER derCert;
|
NSSDER derCert;
|
||||||
derCert.data = (void *)cert->derCert.data;
|
NSSToken *tok;
|
||||||
derCert.size = (PRUint32)cert->derCert.len;
|
tok = PK11Slot_GetNSSToken(slot);
|
||||||
|
NSSITEM_FROM_SECITEM(&derCert, &cert->derCert);
|
||||||
/* XXX login to slots */
|
/* XXX login to slots */
|
||||||
c = NSSTrustDomain_FindCertificateByEncodedCertificate(
|
c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert);
|
||||||
STAN_GetDefaultTrustDomain(),
|
|
||||||
&derCert);
|
|
||||||
if (c) {
|
if (c) {
|
||||||
rvCert = STAN_GetCERTCertificate(c);
|
rvCert = STAN_GetCERTCertificate(c);
|
||||||
}
|
}
|
||||||
|
@ -2803,7 +2885,11 @@ isOnList(CERTCertList *certList,CERTCertificate *cert)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
static SECStatus
|
static SECStatus
|
||||||
|
#ifdef NSS_CLASSIC
|
||||||
pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
||||||
|
#else
|
||||||
|
pk11ListCertCallback(CERTCertificate *cert, void *arg)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct listCertsStr *listCertP = (struct listCertsStr *)arg;
|
struct listCertsStr *listCertP = (struct listCertsStr *)arg;
|
||||||
CERTCertificate *newCert = NULL;
|
CERTCertificate *newCert = NULL;
|
||||||
|
@ -2821,11 +2907,15 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
||||||
if (!isUnique && cert->nickname) {
|
if (!isUnique && cert->nickname) {
|
||||||
nickname = PORT_ArenaStrdup(listCertP->certList->arena,cert->nickname);
|
nickname = PORT_ArenaStrdup(listCertP->certList->arena,cert->nickname);
|
||||||
}
|
}
|
||||||
|
#ifdef NSS_CLASSIC
|
||||||
if (derCert == NULL) {
|
if (derCert == NULL) {
|
||||||
newCert=CERT_DupCertificate(cert);
|
newCert=CERT_DupCertificate(cert);
|
||||||
} else {
|
} else {
|
||||||
newCert=CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),&cert->derCert);
|
newCert=CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),&cert->derCert);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
newCert=CERT_DupCertificate(cert);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (newCert == NULL) return SECSuccess;
|
if (newCert == NULL) return SECSuccess;
|
||||||
|
|
||||||
|
@ -2870,13 +2960,6 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SECStatus
|
|
||||||
pk11ListCertCallbackStub(CERTCertificate *cert, void *arg)
|
|
||||||
{
|
|
||||||
return pk11ListCertCallback(cert, NULL, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CERTCertList *
|
CERTCertList *
|
||||||
PK11_ListCerts(PK11CertListType type, void *pwarg)
|
PK11_ListCerts(PK11CertListType type, void *pwarg)
|
||||||
|
@ -2904,8 +2987,7 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
|
||||||
certList = CERT_NewCertList();
|
certList = CERT_NewCertList();
|
||||||
listCerts.type = type;
|
listCerts.type = type;
|
||||||
listCerts.certList = certList;
|
listCerts.certList = certList;
|
||||||
/* XXX need to fix, this callback is of a different form */
|
pk11cb.callback = pk11ListCertCallback;
|
||||||
pk11cb.callback = pk11ListCertCallbackStub;
|
|
||||||
pk11cb.arg = &listCerts;
|
pk11cb.arg = &listCerts;
|
||||||
NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
|
NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
|
||||||
return certList;
|
return certList;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef NSSPKI_H
|
#ifndef NSSPKI_H
|
||||||
|
@ -51,17 +51,9 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $
|
||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
#endif /* DEV_H */
|
#endif /* DEV_H */
|
||||||
|
|
||||||
#ifndef CKHELPER_H
|
|
||||||
#include "ckhelper.h"
|
|
||||||
#endif /* CKHELPER_H */
|
|
||||||
|
|
||||||
#ifndef CKT_H
|
|
||||||
#ifdef NSS_3_4_CODE
|
#ifdef NSS_3_4_CODE
|
||||||
#include "pki3hack.h"
|
#include "pki3hack.h"
|
||||||
#define NSSCKT_H
|
|
||||||
#endif
|
#endif
|
||||||
#include "ckt.h"
|
|
||||||
#endif /* CKT_H */
|
|
||||||
|
|
||||||
#ifndef BASE_H
|
#ifndef BASE_H
|
||||||
#include "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;
|
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 *
|
NSS_IMPLEMENT NSSCertificate *
|
||||||
nssCertificate_AddRef
|
nssCertificate_AddRef
|
||||||
(
|
(
|
||||||
|
@ -107,350 +68,29 @@ nssCertificate_AddRef
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifdef NSS_3_4_CODE
|
#ifdef NSS_3_4_CODE
|
||||||
|
/*
|
||||||
CERTCertificate *cc = STAN_GetCERTCertificate(c);
|
CERTCertificate *cc = STAN_GetCERTCertificate(c);
|
||||||
CERT_DupCertificate(cc);
|
CERT_DupCertificate(cc);
|
||||||
|
*/
|
||||||
#else
|
#else
|
||||||
c->refCount++;
|
c->refCount++;
|
||||||
#endif
|
#endif
|
||||||
return c;
|
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
|
NSS_IMPLEMENT PRStatus
|
||||||
NSSCertificate_Destroy
|
NSSCertificate_Destroy
|
||||||
(
|
(
|
||||||
NSSCertificate *c
|
NSSCertificate *c
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifdef NSS_3_4_CODE
|
||||||
|
return NSSArena_Destroy(c->object.arena);
|
||||||
|
#else
|
||||||
if (--c->refCount == 0) {
|
if (--c->refCount == 0) {
|
||||||
return NSSArena_Destroy(c->arena);
|
return NSSArena_Destroy(c->arena);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,13 +101,24 @@ NSSCertificate_DeleteStoredObject
|
||||||
NSSCallback *uhh
|
NSSCallback *uhh
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* delete it from storage, but leave it in memory */
|
/* this needs more thought on what will happen when there are multiple
|
||||||
/* according to PKCS#11 2.11 section 13.2, the token must know how
|
* instances
|
||||||
* to handle deletion when there are multiple threads attempting to use
|
|
||||||
* the same object.
|
|
||||||
*/
|
*/
|
||||||
/* XXX use callback to log in if neccessary */
|
/* 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
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -538,10 +189,6 @@ nssCertificate_GetDecoding
|
||||||
if (!c->decoding) {
|
if (!c->decoding) {
|
||||||
c->decoding = nssDecodedCert_Create(NULL, &c->encoding, c->type);
|
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;
|
return c->decoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,8 +197,10 @@ find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
|
||||||
{
|
{
|
||||||
NSSCertificate *rvCert = NULL;
|
NSSCertificate *rvCert = NULL;
|
||||||
NSSCertificate **subjectCerts;
|
NSSCertificate **subjectCerts;
|
||||||
|
NSSTrustDomain *td;
|
||||||
|
td = NSSCertificate_GetTrustDomain(c);
|
||||||
/* Find all certs with this cert's issuer as the subject */
|
/* Find all certs with this cert's issuer as the subject */
|
||||||
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(c->trustDomain,
|
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td,
|
||||||
&c->issuer,
|
&c->issuer,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
|
@ -599,7 +248,17 @@ NSSCertificate_BuildChain
|
||||||
nssList *chain;
|
nssList *chain;
|
||||||
NSSItem *issuerID;
|
NSSItem *issuerID;
|
||||||
NSSCertificate **rvChain;
|
NSSCertificate **rvChain;
|
||||||
|
NSSTrustDomain *td;
|
||||||
nssDecodedCert *dc;
|
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);
|
chain = nssList_Create(NULL, PR_FALSE);
|
||||||
nssList_Add(chain, c);
|
nssList_Add(chain, c);
|
||||||
if (statusOpt) *statusOpt = PR_SUCCESS;
|
if (statusOpt) *statusOpt = PR_SUCCESS;
|
||||||
|
@ -620,7 +279,7 @@ NSSCertificate_BuildChain
|
||||||
PRBool tmpca = usage->nss3lookingForCA;
|
PRBool tmpca = usage->nss3lookingForCA;
|
||||||
usage->nss3lookingForCA = PR_TRUE;
|
usage->nss3lookingForCA = PR_TRUE;
|
||||||
#endif
|
#endif
|
||||||
c = NSSTrustDomain_FindBestCertificateBySubject(c->trustDomain,
|
c = NSSTrustDomain_FindBestCertificateBySubject(td,
|
||||||
&c->issuer,
|
&c->issuer,
|
||||||
timeOpt,
|
timeOpt,
|
||||||
usage,
|
usage,
|
||||||
|
@ -641,8 +300,8 @@ finish:
|
||||||
if (rvOpt) {
|
if (rvOpt) {
|
||||||
rvChain = rvOpt;
|
rvChain = rvOpt;
|
||||||
} else {
|
} else {
|
||||||
rvChain = nss_ZNEWARRAY(arenaOpt,
|
rvLimit = nssList_Count(chain);
|
||||||
NSSCertificate *, nssList_Count(chain) + 1);
|
rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1);
|
||||||
}
|
}
|
||||||
nssList_GetArray(chain, (void **)rvChain, rvLimit);
|
nssList_GetArray(chain, (void **)rvChain, rvLimit);
|
||||||
nssList_Destroy(chain);
|
nssList_Destroy(chain);
|
||||||
|
@ -656,12 +315,15 @@ NSSCertificate_GetTrustDomain
|
||||||
NSSCertificate *c
|
NSSCertificate *c
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if 0
|
PRStatus nssrv = PR_SUCCESS;
|
||||||
if (c->trustDomain) {
|
nssPKIObjectInstance *instance;
|
||||||
return nssTrustDomain_AddRef(c->trustDomain);
|
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 *
|
NSS_IMPLEMENT NSSToken *
|
||||||
|
@ -671,9 +333,6 @@ NSSCertificate_GetToken
|
||||||
PRStatus *statusOpt
|
PRStatus *statusOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (c->token) {
|
|
||||||
return nssToken_AddRef(c->token);
|
|
||||||
}
|
|
||||||
return (NSSToken *)NULL;
|
return (NSSToken *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,11 +343,6 @@ NSSCertificate_GetSlot
|
||||||
PRStatus *statusOpt
|
PRStatus *statusOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (c->token) {
|
|
||||||
return nssToken_GetSlot(c->token);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return (NSSSlot *)NULL;
|
return (NSSSlot *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,11 +353,6 @@ NSSCertificate_GetModule
|
||||||
PRStatus *statusOpt
|
PRStatus *statusOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (c->token) {
|
|
||||||
return nssToken_GetModule(c->token);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return (NSSModule *)NULL;
|
return (NSSModule *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,15 +448,14 @@ NSSCertificate_GetPublicKey
|
||||||
NSSCertificate *c
|
NSSCertificate *c
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
CK_ATTRIBUTE pubktemplate[] = {
|
CK_ATTRIBUTE pubktemplate[] = {
|
||||||
{ CKA_CLASS, NULL, 0 },
|
{ CKA_CLASS, NULL, 0 },
|
||||||
{ CKA_ID, NULL, 0 },
|
{ CKA_ID, NULL, 0 },
|
||||||
{ CKA_SUBJECT, NULL, 0 }
|
{ CKA_SUBJECT, NULL, 0 }
|
||||||
};
|
};
|
||||||
#if 0
|
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
|
CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
|
||||||
#endif
|
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
|
NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
|
||||||
if (c->id.size > 0) {
|
if (c->id.size > 0) {
|
||||||
/* CKA_ID */
|
/* CKA_ID */
|
||||||
|
@ -824,7 +472,6 @@ NSSCertificate_GetPublicKey
|
||||||
return (NSSPublicKey *)NULL;
|
return (NSSPublicKey *)NULL;
|
||||||
}
|
}
|
||||||
/* Try the cert's token first */
|
/* Try the cert's token first */
|
||||||
#if 0
|
|
||||||
if (c->token) {
|
if (c->token) {
|
||||||
nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
|
nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,13 +32,26 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef NSSPKI_H
|
#ifndef NSSPKI_H
|
||||||
#include "nsspki.h"
|
#include "nsspki.h"
|
||||||
#endif /* 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;
|
extern const NSSError NSS_ERROR_NOT_FOUND;
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -91,8 +104,28 @@ NSSCryptoContext_ImportCertificate
|
||||||
NSSCertificate *c
|
NSSCertificate *c
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
NSSToken *token;
|
||||||
return PR_FAILURE;
|
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 *
|
NSS_IMPLEMENT NSSCertificate *
|
||||||
|
@ -428,10 +461,10 @@ struct token_session_str {
|
||||||
nssSession *session;
|
nssSession *session;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef nodef
|
||||||
static nssSession *
|
static nssSession *
|
||||||
get_token_session(NSSCryptoContext *cc, NSSToken *tok)
|
get_token_session(NSSCryptoContext *cc, NSSToken *tok)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
struct token_session_str *ts;
|
struct token_session_str *ts;
|
||||||
for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
|
for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
|
||||||
ts != (struct token_session_str *)NULL;
|
ts != (struct token_session_str *)NULL;
|
||||||
|
@ -450,8 +483,8 @@ get_token_session(NSSCryptoContext *cc, NSSToken *tok)
|
||||||
nssList_AddElement(cc->sessionList, (void *)ts);
|
nssList_AddElement(cc->sessionList, (void *)ts);
|
||||||
}
|
}
|
||||||
return ts->session;
|
return ts->session;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSItem *
|
NSS_IMPLEMENT NSSItem *
|
||||||
NSSCryptoContext_Decrypt
|
NSSCryptoContext_Decrypt
|
||||||
|
@ -516,6 +549,7 @@ NSSCryptoContext_Decrypt
|
||||||
}
|
}
|
||||||
return rvData;
|
return rvData;
|
||||||
#endif
|
#endif
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -864,8 +898,8 @@ NSSCryptoContext_Digest
|
||||||
NSSArena *arenaOpt
|
NSSArena *arenaOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
return nssToken_Digest(cc->token, cc->session, apOpt,
|
||||||
return NULL;
|
data, rvOpt, arenaOpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -876,8 +910,7 @@ NSSCryptoContext_BeginDigest
|
||||||
NSSCallback *uhhOpt
|
NSSCallback *uhhOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
return nssToken_BeginDigest(cc->token, cc->session, apOpt);
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -888,8 +921,12 @@ NSSCryptoContext_ContinueDigest
|
||||||
NSSItem *item
|
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 *
|
NSS_IMPLEMENT NSSItem *
|
||||||
|
@ -900,8 +937,7 @@ NSSCryptoContext_FinishDigest
|
||||||
NSSArena *arenaOpt
|
NSSArena *arenaOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
return nssToken_FinishDigest(cc->token, cc->session, rvOpt, arenaOpt);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCryptoContext *
|
NSS_IMPLEMENT NSSCryptoContext *
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define PKI_H
|
#define PKI_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef PKIT_H
|
#ifndef PKIT_H
|
||||||
|
@ -54,27 +54,6 @@ nssCertificate_AddRef
|
||||||
NSSCertificate *c
|
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
|
PR_END_EXTERN_C
|
||||||
|
|
||||||
#endif /* PKI_H */
|
#endif /* PKI_H */
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -51,10 +51,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Da
|
||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
#endif /* DEV_H */
|
#endif /* DEV_H */
|
||||||
|
|
||||||
#ifndef CKHELPER_H
|
|
||||||
#include "ckhelper.h"
|
|
||||||
#endif /* CKHELPER_H */
|
|
||||||
|
|
||||||
#ifndef DEVNSS3HACK_H
|
#ifndef DEVNSS3HACK_H
|
||||||
#include "dev3hack.h"
|
#include "dev3hack.h"
|
||||||
#endif /* DEVNSS3HACK_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;
|
NSSTrustDomain *g_default_trust_domain = NULL;
|
||||||
|
|
||||||
|
NSSCryptoContext *g_default_crypto_context = NULL;
|
||||||
|
|
||||||
NSSTrustDomain *
|
NSSTrustDomain *
|
||||||
STAN_GetDefaultTrustDomain()
|
STAN_GetDefaultTrustDomain()
|
||||||
{
|
{
|
||||||
return g_default_trust_domain;
|
return g_default_trust_domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSSCryptoContext *
|
||||||
|
STAN_GetDefaultCryptoContext()
|
||||||
|
{
|
||||||
|
return g_default_crypto_context;
|
||||||
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
STAN_LoadDefaultNSS3TrustDomain
|
STAN_LoadDefaultNSS3TrustDomain
|
||||||
(
|
(
|
||||||
|
@ -103,6 +107,7 @@ STAN_LoadDefaultNSS3TrustDomain
|
||||||
}
|
}
|
||||||
td->tokens = nssList_CreateIterator(td->tokenList);
|
td->tokens = nssList_CreateIterator(td->tokenList);
|
||||||
g_default_trust_domain = td;
|
g_default_trust_domain = td;
|
||||||
|
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -136,7 +141,7 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
|
secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
|
||||||
if (!secrv) {
|
if (secrv != SECSuccess) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
|
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
|
||||||
|
@ -299,6 +304,28 @@ nssDecodedPKIXCertificate_Create
|
||||||
return rvDC;
|
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
|
NSS_IMPLEMENT PRStatus
|
||||||
nssDecodedPKIXCertificate_Destroy
|
nssDecodedPKIXCertificate_Destroy
|
||||||
(
|
(
|
||||||
|
@ -336,10 +363,15 @@ get_nss3trust_from_cktrust(CK_TRUST t)
|
||||||
}
|
}
|
||||||
|
|
||||||
static CERTCertTrust *
|
static CERTCertTrust *
|
||||||
nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
|
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, NSSToken *token,
|
||||||
|
CERTCertificate *cc)
|
||||||
{
|
{
|
||||||
CERTCertTrust *rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
|
CERTCertTrust *rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
|
||||||
unsigned int client;
|
unsigned int client;
|
||||||
|
NSSTrust *t = nssToken_FindTrustForCert(token, NULL, c);
|
||||||
|
if (!t) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
|
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
|
||||||
client = get_nss3trust_from_cktrust(t->clientAuth);
|
client = get_nss3trust_from_cktrust(t->clientAuth);
|
||||||
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
|
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
|
||||||
|
@ -357,26 +389,39 @@ nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
|
||||||
return rvTrust;
|
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
|
static void
|
||||||
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
|
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
|
||||||
{
|
{
|
||||||
|
nssPKIObjectInstance *instance = get_cert_instance(c);
|
||||||
/* fill other fields needed by NSS3 functions using CERTCertificate */
|
/* fill other fields needed by NSS3 functions using CERTCertificate */
|
||||||
/* handle */
|
if (!cc->nickname && c->nickname) {
|
||||||
cc->pkcs11ID = c->handle;
|
PRStatus nssrv;
|
||||||
/* nickname */
|
int len = nssUTF8_Size(c->nickname, &nssrv);
|
||||||
cc->nickname = PL_strdup(c->nickname);
|
cc->nickname = PORT_ArenaAlloc(cc->arena, len);
|
||||||
/* slot (ownSlot ?) (addref ?) */
|
memcpy(cc->nickname, c->nickname, len-1);
|
||||||
if (c->token) {
|
cc->nickname[len-1] = '\0';
|
||||||
cc->slot = c->token->pk11slot;
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
/* trust */
|
|
||||||
cc->trust = nssTrust_GetCERTCertTrust(&c->trust, cc);
|
|
||||||
cc->referenceCount++;
|
|
||||||
/* subjectList ? */
|
/* subjectList ? */
|
||||||
/* pkcs11ID */
|
|
||||||
cc->pkcs11ID = c->handle;
|
|
||||||
/* database handle is now the trust domain */
|
|
||||||
cc->dbhandle = c->trustDomain;
|
|
||||||
/* pointer back */
|
/* pointer back */
|
||||||
cc->nssCertificate = c;
|
cc->nssCertificate = c;
|
||||||
}
|
}
|
||||||
|
@ -396,6 +441,11 @@ STAN_GetCERTCertificate(NSSCertificate *c)
|
||||||
cc = (CERTCertificate *)dc->data;
|
cc = (CERTCertificate *)dc->data;
|
||||||
if (!cc->nssCertificate) {
|
if (!cc->nssCertificate) {
|
||||||
fill_CERTCertificateFields(c, cc);
|
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;
|
return cc;
|
||||||
}
|
}
|
||||||
|
@ -428,13 +478,13 @@ NSS_EXTERN NSSCertificate *
|
||||||
STAN_GetNSSCertificate(CERTCertificate *cc)
|
STAN_GetNSSCertificate(CERTCertificate *cc)
|
||||||
{
|
{
|
||||||
NSSCertificate *c;
|
NSSCertificate *c;
|
||||||
|
nssPKIObject *object;
|
||||||
|
nssPKIObjectInstance *instance;
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
|
|
||||||
c = cc->nssCertificate;
|
c = cc->nssCertificate;
|
||||||
if (c) {
|
if (c) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* i don't think this should happen. but if it can, need to create
|
/* i don't think this should happen. but if it can, need to create
|
||||||
* NSSCertificate from CERTCertificate values here. */
|
* NSSCertificate from CERTCertificate values here. */
|
||||||
/* Yup, it can happen. */
|
/* Yup, it can happen. */
|
||||||
|
@ -442,24 +492,35 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
c = NSSCertificate_Create(arena);
|
c = nss_ZNEW(arena, NSSCertificate);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
object = &c->object;
|
||||||
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
|
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
|
||||||
c->type = NSSCertificateType_PKIX;
|
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,
|
nssItem_Create(arena,
|
||||||
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
|
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
|
||||||
nssItem_Create(arena,
|
nssItem_Create(arena,
|
||||||
&c->subject, cc->derSubject.len, cc->derSubject.data);
|
&c->subject, cc->derSubject.len, cc->derSubject.data);
|
||||||
nssItem_Create(arena,
|
if (PR_TRUE) {
|
||||||
&c->serial, cc->serialNumber.len, cc->serialNumber.data);
|
/* 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) {
|
if (cc->nickname) {
|
||||||
c->nickname = nssUTF8_Create(arena,
|
c->nickname = nssUTF8_Create(arena,
|
||||||
nssStringType_UTF8String,
|
nssStringType_UTF8String,
|
||||||
(NSSUTF8 *)cc->nickname,
|
(NSSUTF8 *)cc->nickname,
|
||||||
PORT_Strlen(cc->nickname));
|
PORT_Strlen(cc->nickname));
|
||||||
}
|
}
|
||||||
if (cc->emailAddr) {
|
if (cc->emailAddr) {
|
||||||
c->email = nssUTF8_Create(arena,
|
c->email = nssUTF8_Create(arena,
|
||||||
|
@ -467,19 +528,15 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
|
||||||
(NSSUTF8 *)cc->emailAddr,
|
(NSSUTF8 *)cc->emailAddr,
|
||||||
PORT_Strlen(cc->emailAddr));
|
PORT_Strlen(cc->emailAddr));
|
||||||
}
|
}
|
||||||
c->trustDomain = (NSSTrustDomain *)cc->dbhandle;
|
instance = nss_ZNEW(arena, nssPKIObjectInstance);
|
||||||
|
instance->trustDomain = (NSSTrustDomain *)cc->dbhandle;
|
||||||
if (cc->slot) {
|
if (cc->slot) {
|
||||||
c->token = PK11Slot_GetNSSToken(cc->slot);
|
instance->cryptoki.token = PK11Slot_GetNSSToken(cc->slot);
|
||||||
c->slot = c->token->slot;
|
instance->cryptoki.handle = cc->pkcs11ID;
|
||||||
}
|
}
|
||||||
|
nssList_Add(object->instanceList, instance);
|
||||||
|
c->decoding = create_decoded_pkix_cert_from_nss3cert(arena, cc);
|
||||||
cc->nssCertificate = c;
|
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;
|
return c;
|
||||||
loser:
|
loser:
|
||||||
nssArena_Destroy(arena);
|
nssArena_Destroy(arena);
|
||||||
|
@ -487,47 +544,31 @@ loser:
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
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;
|
NSSTrust nssTrust;
|
||||||
/* Set the CERTCertificate's trust */
|
/* Set the CERTCertificate's trust */
|
||||||
cc->trust = trust;
|
cc->trust = trust;
|
||||||
/* Set the NSSCerticate's 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.serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
|
||||||
nssTrust.clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
|
nssTrust.clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
|
||||||
nssTrust.emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
|
nssTrust.emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
|
||||||
nssTrust.codeSigning= get_stan_trust(trust->objectSigningFlags, PR_FALSE);
|
nssTrust.codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE);
|
||||||
return nssCertificate_SetCertTrust(c, &nssTrust);
|
instance = get_cert_instance(c);
|
||||||
}
|
/* maybe GetDefaultTrustToken()? */
|
||||||
|
nssrv = nssToken_ImportTrust(instance->cryptoki.token, NULL, &nssTrust,
|
||||||
/* This is here to replace CERT_Traverse calls */
|
instance->trustDomain, instance->cryptoContext);
|
||||||
static PRStatus
|
nssArena_Destroy(nssTrust.object.arena);
|
||||||
traverse_certificates_by_template
|
return nssrv;
|
||||||
(
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CERT_TraversePermCertsForSubject */
|
/* CERT_TraversePermCertsForSubject */
|
||||||
|
@ -541,22 +582,20 @@ nssTrustDomain_TraverseCertificatesBySubject
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
nssList *subjectList;
|
NSSArena *tmpArena;
|
||||||
CK_ATTRIBUTE subj_template[] =
|
NSSCertificate **subjectCerts;
|
||||||
{
|
NSSCertificate *c;
|
||||||
{ CKA_CLASS, NULL, 0 },
|
PRIntn i;
|
||||||
{ CKA_SUBJECT, NULL, 0 }
|
tmpArena = NSSArena_Create();
|
||||||
};
|
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL,
|
||||||
CK_ULONG ctsize;
|
0, tmpArena);
|
||||||
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
|
if (subjectCerts) {
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
|
for (i=0, c = subjectCerts[i]; c; i++) {
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
|
nssrv = callback(c, arg);
|
||||||
subjectList = nssList_Create(NULL, PR_FALSE);
|
if (nssrv != PR_SUCCESS) break;
|
||||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
}
|
||||||
nssrv = traverse_certificates_by_template(td, subjectList,
|
}
|
||||||
subj_template, ctsize,
|
nssArena_Destroy(tmpArena);
|
||||||
callback, arg);
|
|
||||||
nssList_Destroy(subjectList);
|
|
||||||
return nssrv;
|
return nssrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,23 +610,20 @@ nssTrustDomain_TraverseCertificatesByNickname
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
nssList *nickCerts;
|
NSSArena *tmpArena;
|
||||||
CK_ATTRIBUTE nick_template[] =
|
NSSCertificate **nickCerts;
|
||||||
{
|
NSSCertificate *c;
|
||||||
{ CKA_CLASS, NULL, 0 },
|
PRIntn i;
|
||||||
{ CKA_LABEL, NULL, 0 }
|
tmpArena = NSSArena_Create();
|
||||||
};
|
nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL,
|
||||||
CK_ULONG ctsize;
|
0, tmpArena);
|
||||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
if (nickCerts) {
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
for (i=0, c = nickCerts[i]; c; i++) {
|
||||||
nick_template[1].pValue = (CK_VOID_PTR)nickname;
|
nssrv = callback(c, arg);
|
||||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(nickname, &nssrv);
|
if (nssrv != PR_SUCCESS) break;
|
||||||
nickCerts = nssList_Create(NULL, PR_FALSE);
|
}
|
||||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nickname, nickCerts);
|
}
|
||||||
nssrv = traverse_certificates_by_template(td, nickCerts,
|
nssArena_Destroy(tmpArena);
|
||||||
nick_template, ctsize,
|
|
||||||
callback, arg);
|
|
||||||
nssList_Destroy(nickCerts);
|
|
||||||
return nssrv;
|
return nssrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,23 +637,33 @@ nssTrustDomain_TraverseCertificates
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
|
NSSToken *token;
|
||||||
nssList *certList;
|
nssList *certList;
|
||||||
CK_ATTRIBUTE cert_template[] =
|
nssTokenCertSearch search;
|
||||||
{
|
/* grab all cache certs (XXX please only do this here...)
|
||||||
{ CKA_CLASS, NULL, 0 },
|
* the alternative is to provide a callback through search that allows
|
||||||
};
|
* the token to query the cache for the cert during traversal.
|
||||||
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);
|
|
||||||
certList = nssList_Create(NULL, PR_FALSE);
|
certList = nssList_Create(NULL, PR_FALSE);
|
||||||
(void)nssTrustDomain_GetCertsFromCache(td, certList);
|
(void)nssTrustDomain_GetCertsFromCache(td, certList);
|
||||||
nssrv = traverse_certificates_by_template(td, certList,
|
/* set the search criteria */
|
||||||
cert_template, ctsize,
|
search.callback = callback;
|
||||||
callback, arg);
|
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);
|
nssList_Destroy(certList);
|
||||||
return nssrv;
|
return nssrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static CK_CERTIFICATE_TYPE
|
static CK_CERTIFICATE_TYPE
|
||||||
get_cert_type(NSSCertificateType nssType)
|
get_cert_type(NSSCertificateType nssType)
|
||||||
{
|
{
|
||||||
|
@ -629,6 +675,7 @@ get_cert_type(NSSCertificateType nssType)
|
||||||
* type CK_CERTIFICATE_TYPE */
|
* type CK_CERTIFICATE_TYPE */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSToken *
|
NSS_IMPLEMENT NSSToken *
|
||||||
STAN_GetInternalToken(void)
|
STAN_GetInternalToken(void)
|
||||||
|
@ -643,6 +690,7 @@ nssTrustDomain_AddTempCertToPerm
|
||||||
NSSCertificate *c
|
NSSCertificate *c
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
NSSToken *token;
|
NSSToken *token;
|
||||||
CK_CERTIFICATE_TYPE cert_type;
|
CK_CERTIFICATE_TYPE cert_type;
|
||||||
CK_ATTRIBUTE cert_template[] =
|
CK_ATTRIBUTE cert_template[] =
|
||||||
|
@ -679,4 +727,6 @@ nssTrustDomain_AddTempCertToPerm
|
||||||
c->slot = token->slot;
|
c->slot = token->slot;
|
||||||
/* Do the trust object */
|
/* Do the trust object */
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
#endif
|
||||||
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define PKINSS3HACK_H
|
#define PKINSS3HACK_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef NSSPKIT_H
|
#ifndef NSSPKIT_H
|
||||||
|
@ -57,6 +57,9 @@ PR_BEGIN_EXTERN_C
|
||||||
NSS_EXTERN NSSTrustDomain *
|
NSS_EXTERN NSSTrustDomain *
|
||||||
STAN_GetDefaultTrustDomain();
|
STAN_GetDefaultTrustDomain();
|
||||||
|
|
||||||
|
NSSCryptoContext *
|
||||||
|
STAN_GetDefaultCryptoContext();
|
||||||
|
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
STAN_LoadDefaultNSS3TrustDomain
|
STAN_LoadDefaultNSS3TrustDomain
|
||||||
(
|
(
|
||||||
|
@ -76,7 +79,7 @@ NSS_EXTERN NSSCertificate *
|
||||||
STAN_GetNSSCertificate(CERTCertificate *c);
|
STAN_GetNSSCertificate(CERTCertificate *c);
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN PRStatus
|
||||||
STAN_ChangeCertTrust(NSSCertificate *c, CERTCertTrust *trust);
|
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
|
||||||
|
|
||||||
/* exposing this */
|
/* exposing this */
|
||||||
NSS_EXTERN NSSCertificate *
|
NSS_EXTERN NSSCertificate *
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define PKIM_H
|
#define PKIM_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef BASE_H
|
#ifndef BASE_H
|
||||||
|
@ -129,13 +129,20 @@ nssTrustDomain_AddCertsToCache
|
||||||
PRUint32 numCerts
|
PRUint32 numCerts
|
||||||
);
|
);
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN void
|
||||||
nssTrustDomain_RemoveCertFromCache
|
nssTrustDomain_RemoveCertFromCache
|
||||||
(
|
(
|
||||||
NSSTrustDomain *td,
|
NSSTrustDomain *td,
|
||||||
NSSCertificate *cert
|
NSSCertificate *cert
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NSS_EXTERN void
|
||||||
|
nssTrustDomain_FlushCache
|
||||||
|
(
|
||||||
|
NSSTrustDomain *td,
|
||||||
|
PRFloat64 threshold
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove all certs for the given token from the cache. This is
|
* Remove all certs for the given token from the cache. This is
|
||||||
* needed if the token is removed.
|
* needed if the token is removed.
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#define PKIT_H
|
#define PKIT_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#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
|
#ifdef NSS_3_4_CODE
|
||||||
#include "certt.h"
|
#include "certt.h"
|
||||||
#include "pkcs11t.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 */
|
#endif /* NSS_3_4_CODE */
|
||||||
|
|
||||||
#ifndef NSSPKIT_H
|
#ifndef NSSPKIT_H
|
||||||
|
@ -71,27 +65,46 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $D
|
||||||
#include "nssdevt.h"
|
#include "nssdevt.h"
|
||||||
#endif /* NSSDEVT_H */
|
#endif /* NSSDEVT_H */
|
||||||
|
|
||||||
PR_BEGIN_EXTERN_C
|
#ifndef DEVT_H
|
||||||
|
#include "devt.h"
|
||||||
|
#endif /* DEVT_H */
|
||||||
|
|
||||||
typedef enum {
|
PR_BEGIN_EXTERN_C
|
||||||
NSSCertificateType_Unknown = 0,
|
|
||||||
NSSCertificateType_PKIX = 1
|
|
||||||
} NSSCertificateType;
|
|
||||||
|
|
||||||
typedef struct nssDecodedCertStr nssDecodedCert;
|
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
|
struct NSSTrustStr
|
||||||
{
|
{
|
||||||
CK_TRUST serverAuth;
|
struct nssPKIObjectStr object;
|
||||||
CK_TRUST clientAuth;
|
NSSCertificate *certificate;
|
||||||
CK_TRUST emailProtection;
|
nssTrustLevel serverAuth;
|
||||||
CK_TRUST codeSigning;
|
nssTrustLevel clientAuth;
|
||||||
|
nssTrustLevel emailProtection;
|
||||||
|
nssTrustLevel codeSigning;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NSSCertificateStr
|
struct NSSCertificateStr
|
||||||
{
|
{
|
||||||
PRInt32 refCount;
|
struct nssPKIObjectStr object;
|
||||||
NSSArena *arena;
|
|
||||||
NSSCertificateType type;
|
NSSCertificateType type;
|
||||||
NSSItem id;
|
NSSItem id;
|
||||||
NSSBER encoding;
|
NSSBER encoding;
|
||||||
|
@ -100,12 +113,6 @@ struct NSSCertificateStr
|
||||||
NSSDER serial;
|
NSSDER serial;
|
||||||
NSSUTF8 *nickname;
|
NSSUTF8 *nickname;
|
||||||
NSSASCII7 *email;
|
NSSASCII7 *email;
|
||||||
NSSSlot *slot;
|
|
||||||
NSSToken *token;
|
|
||||||
NSSTrustDomain *trustDomain;
|
|
||||||
NSSCryptoContext *cryptoContext;
|
|
||||||
NSSTrust trust;
|
|
||||||
CK_OBJECT_HANDLE handle;
|
|
||||||
nssDecodedCert *decoding;
|
nssDecodedCert *decoding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,6 +141,9 @@ struct NSSCryptoContextStr
|
||||||
{
|
{
|
||||||
PRInt32 refCount;
|
PRInt32 refCount;
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
|
NSSTrustDomain *td;
|
||||||
|
NSSToken *token;
|
||||||
|
nssSession *session;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NSSTimeStr;
|
struct NSSTimeStr;
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -32,7 +32,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#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 */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#ifndef NSSPKI_H
|
#ifndef NSSPKI_H
|
||||||
|
@ -114,7 +114,8 @@ NSSTrustDomain_Destroy
|
||||||
if (--td->refCount == 0) {
|
if (--td->refCount == 0) {
|
||||||
/* Destroy each token in the list of tokens */
|
/* Destroy each token in the list of tokens */
|
||||||
if (td->tokens) {
|
if (td->tokens) {
|
||||||
nssList_DestroyElements(td->tokenList, token_destructor);
|
nssList_Clear(td->tokenList, token_destructor);
|
||||||
|
nssList_Destroy(td->tokenList);
|
||||||
}
|
}
|
||||||
/* Destroy the trust domain */
|
/* Destroy the trust domain */
|
||||||
nssArena_Destroy(td->arena);
|
nssArena_Destroy(td->arena);
|
||||||
|
@ -354,12 +355,10 @@ NSSTrustDomain_ImportEncodedPublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
struct get_best_cert_arg_str {
|
struct get_best_cert_arg_str {
|
||||||
NSSTrustDomain *td;
|
|
||||||
NSSCertificate *cert;
|
NSSCertificate *cert;
|
||||||
NSSTime *time;
|
NSSTime *time;
|
||||||
NSSUsage *usage;
|
NSSUsage *usage;
|
||||||
NSSPolicies *policies;
|
NSSPolicies *policies;
|
||||||
nssList *cached;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PRStatus
|
static PRStatus
|
||||||
|
@ -400,59 +399,9 @@ get_best_cert(NSSCertificate *c, void *arg)
|
||||||
return PR_SUCCESS;
|
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 {
|
struct collect_arg_str {
|
||||||
nssList *list;
|
nssList *list;
|
||||||
PRUint32 maximum;
|
PRUint32 maximum;
|
||||||
NSSArena *arena;
|
|
||||||
NSSCertificate **rvOpt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
|
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
|
||||||
|
@ -471,105 +420,6 @@ collect_certs(NSSCertificate *c, void *arg)
|
||||||
return PR_SUCCESS;
|
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 *
|
NSS_IMPLEMENT NSSCertificate *
|
||||||
NSSTrustDomain_FindBestCertificateByNickname
|
NSSTrustDomain_FindBestCertificateByNickname
|
||||||
(
|
(
|
||||||
|
@ -580,23 +430,12 @@ NSSTrustDomain_FindBestCertificateByNickname
|
||||||
NSSPolicies *policiesOpt /* NULL for none */
|
NSSPolicies *policiesOpt /* NULL for none */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NSSCertificate *rvCert = NULL;
|
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
|
NSSToken *token;
|
||||||
|
nssTokenCertSearch search;
|
||||||
struct get_best_cert_arg_str best;
|
struct get_best_cert_arg_str best;
|
||||||
CK_ATTRIBUTE nick_template[] =
|
|
||||||
{
|
|
||||||
{ CKA_CLASS, NULL, 0 },
|
|
||||||
{ CKA_LABEL, NULL, 0 }
|
|
||||||
};
|
|
||||||
CK_ULONG ctsize;
|
|
||||||
nssList *nameList;
|
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 */
|
/* set the criteria for determining the best cert */
|
||||||
best.td = td;
|
|
||||||
best.cert = NULL;
|
best.cert = NULL;
|
||||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||||
best.usage = usage;
|
best.usage = usage;
|
||||||
|
@ -604,62 +443,26 @@ NSSTrustDomain_FindBestCertificateByNickname
|
||||||
/* find all matching certs in the cache */
|
/* find all matching certs in the cache */
|
||||||
nameList = nssList_Create(NULL, PR_FALSE);
|
nameList = nssList_Create(NULL, PR_FALSE);
|
||||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||||
best.cached = nameList;
|
/* set the search criteria */
|
||||||
/* now find the best cert on tokens */
|
search.callback = get_best_cert;
|
||||||
rvCert = find_best_cert_for_template(td, NULL,
|
search.cbarg = &best;
|
||||||
&best, nick_template, ctsize);
|
search.cached = nameList;
|
||||||
if (!rvCert) {
|
search.trustDomain = td;
|
||||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
search.cryptoContext = NULL;
|
||||||
* whether the '\0' should be included. XXX Is that still true?
|
/* traverse the tokens */
|
||||||
*/
|
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||||
nick_template[1].ulValueLen++;
|
token != (NSSToken *)NULL;
|
||||||
rvCert = find_best_cert_for_template(td, NULL,
|
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||||
&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[] =
|
|
||||||
{
|
{
|
||||||
{ CKA_CLASS, NULL, 0 },
|
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||||
{ CKA_LABEL, NULL, 0 }
|
name, &search);
|
||||||
};
|
}
|
||||||
nssList *nickCerts;
|
nssListIterator_Finish(td->tokens);
|
||||||
struct collect_arg_str ca;
|
nssList_Destroy(nameList);
|
||||||
CK_ULONG ctsize;
|
if (best.cert) {
|
||||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
}
|
||||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
return best.cert;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCertificate **
|
NSS_IMPLEMENT NSSCertificate **
|
||||||
|
@ -673,28 +476,45 @@ NSSTrustDomain_FindCertificatesByNickname
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NSSCertificate **rvCerts = NULL;
|
NSSCertificate **rvCerts = NULL;
|
||||||
|
NSSToken *token;
|
||||||
|
PRUint32 count;
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
CK_ATTRIBUTE nick_template[] =
|
nssList *nameList;
|
||||||
{
|
|
||||||
{ CKA_CLASS, NULL, 0 },
|
|
||||||
{ CKA_LABEL, NULL, 0 }
|
|
||||||
};
|
|
||||||
nssList *nickCerts;
|
|
||||||
struct collect_arg_str ca;
|
struct collect_arg_str ca;
|
||||||
CK_ULONG ctsize;
|
nssTokenCertSearch search;
|
||||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
/* set up the collection */
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
nameList = nssList_Create(NULL, PR_FALSE);
|
||||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
ca.list = nameList;
|
||||||
nickCerts = nssList_Create(NULL, PR_FALSE);
|
|
||||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nickCerts);
|
|
||||||
ca.list = nickCerts;
|
|
||||||
ca.maximum = maximumOpt;
|
ca.maximum = maximumOpt;
|
||||||
ca.arena = arenaOpt;
|
/* set the search criteria */
|
||||||
ca.rvOpt = rvOpt;
|
search.callback = collect_certs;
|
||||||
rvCerts = find_all_certs_for_template(td, NULL,
|
search.cbarg = &ca;
|
||||||
&ca, nick_template, ctsize);
|
search.cached = nameList;
|
||||||
nssList_Destroy(nickCerts);
|
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;
|
return rvCerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,44 +528,29 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
|
||||||
{
|
{
|
||||||
NSSCertificate *rvCert = NULL;
|
NSSCertificate *rvCert = NULL;
|
||||||
NSSToken *tok;
|
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 */
|
/* Try the cache */
|
||||||
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
|
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
|
||||||
issuer,
|
issuer,
|
||||||
serialNumber);
|
serialNumber);
|
||||||
if (!rvCert) {
|
if (rvCert) {
|
||||||
/* Not cached, look for it on tokens */
|
return rvCert;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
/* 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;
|
return rvCert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,31 +564,39 @@ NSSTrustDomain_FindBestCertificateBySubject
|
||||||
NSSPolicies *policiesOpt
|
NSSPolicies *policiesOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NSSCertificate *rvCert = NULL;
|
PRStatus nssrv;
|
||||||
|
NSSToken *token;
|
||||||
nssList *subjectList;
|
nssList *subjectList;
|
||||||
CK_ATTRIBUTE subj_template[] =
|
|
||||||
{
|
|
||||||
{ CKA_CLASS, NULL, 0 },
|
|
||||||
{ CKA_SUBJECT, NULL, 0 }
|
|
||||||
};
|
|
||||||
struct get_best_cert_arg_str best;
|
struct get_best_cert_arg_str best;
|
||||||
CK_ULONG ctsize;
|
nssTokenCertSearch search;
|
||||||
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
|
/* set the criteria for determining the best cert */
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
|
|
||||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
|
|
||||||
best.td = td;
|
|
||||||
best.cert = NULL;
|
best.cert = NULL;
|
||||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||||
best.usage = usage;
|
best.usage = usage;
|
||||||
best.policies = policiesOpt;
|
best.policies = policiesOpt;
|
||||||
|
/* find all matching certs in the cache */
|
||||||
subjectList = nssList_Create(NULL, PR_FALSE);
|
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
||||||
best.cached = subjectList;
|
/* set the search criteria */
|
||||||
/* now find the best cert on tokens */
|
search.callback = get_best_cert;
|
||||||
rvCert = find_best_cert_for_template(td, NULL,
|
search.cbarg = &best;
|
||||||
&best, subj_template, ctsize);
|
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);
|
nssList_Destroy(subjectList);
|
||||||
return rvCert;
|
if (best.cert) {
|
||||||
|
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
|
||||||
|
}
|
||||||
|
return best.cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCertificate **
|
NSS_IMPLEMENT NSSCertificate **
|
||||||
|
@ -796,26 +609,45 @@ NSSTrustDomain_FindCertificatesBySubject
|
||||||
NSSArena *arenaOpt
|
NSSArena *arenaOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
PRStatus nssrv;
|
||||||
NSSCertificate **rvCerts = NULL;
|
NSSCertificate **rvCerts = NULL;
|
||||||
|
NSSToken *token;
|
||||||
|
PRUint32 count;
|
||||||
nssList *subjectList;
|
nssList *subjectList;
|
||||||
struct collect_arg_str ca;
|
struct collect_arg_str ca;
|
||||||
CK_ATTRIBUTE subj_template[] =
|
nssTokenCertSearch search;
|
||||||
{
|
/* set up the collection */
|
||||||
{ 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);
|
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
||||||
ca.list = subjectList;
|
ca.list = subjectList;
|
||||||
ca.maximum = maximumOpt;
|
ca.maximum = maximumOpt;
|
||||||
ca.arena = arenaOpt;
|
/* set the search criteria */
|
||||||
ca.rvOpt = rvOpt;
|
search.callback = collect_certs;
|
||||||
rvCerts = find_all_certs_for_template(td, NULL,
|
search.cbarg = &ca;
|
||||||
&ca, subj_template, ctsize);
|
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);
|
nssList_Destroy(subjectList);
|
||||||
return rvCerts;
|
return rvCerts;
|
||||||
}
|
}
|
||||||
|
@ -857,39 +689,25 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
|
||||||
{
|
{
|
||||||
NSSCertificate *rvCert = NULL;
|
NSSCertificate *rvCert = NULL;
|
||||||
NSSToken *tok;
|
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 */
|
/* Try the cache */
|
||||||
rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate);
|
rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate);
|
||||||
if (!rvCert) {
|
if (rvCert) {
|
||||||
/* Not cached, look for it on tokens */
|
return rvCert;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
/* 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;
|
return rvCert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,23 +721,12 @@ NSSTrustDomain_FindCertificateByEmail
|
||||||
NSSPolicies *policiesOpt
|
NSSPolicies *policiesOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NSSCertificate *rvCert = NULL;
|
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
|
NSSToken *token;
|
||||||
struct get_best_cert_arg_str best;
|
struct get_best_cert_arg_str best;
|
||||||
CK_ATTRIBUTE email_template[] =
|
nssTokenCertSearch search;
|
||||||
{
|
|
||||||
{ CKA_CLASS, NULL, 0 },
|
|
||||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
|
|
||||||
};
|
|
||||||
CK_ULONG ctsize;
|
|
||||||
nssList *emailList;
|
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 */
|
/* set the criteria for determining the best cert */
|
||||||
best.td = td;
|
|
||||||
best.cert = NULL;
|
best.cert = NULL;
|
||||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||||
best.usage = usage;
|
best.usage = usage;
|
||||||
|
@ -927,20 +734,26 @@ NSSTrustDomain_FindCertificateByEmail
|
||||||
/* find all matching certs in the cache */
|
/* find all matching certs in the cache */
|
||||||
emailList = nssList_Create(NULL, PR_FALSE);
|
emailList = nssList_Create(NULL, PR_FALSE);
|
||||||
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(td, email, emailList);
|
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(td, email, emailList);
|
||||||
best.cached = emailList;
|
/* set the search criteria */
|
||||||
/* now find the best cert on tokens */
|
search.callback = get_best_cert;
|
||||||
rvCert = find_best_cert_for_template(td, NULL,
|
search.cbarg = &best;
|
||||||
&best, email_template, ctsize);
|
search.cached = emailList;
|
||||||
if (!rvCert) {
|
search.trustDomain = td;
|
||||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
search.cryptoContext = NULL;
|
||||||
* whether the '\0' should be included. XXX Is that still true?
|
/* traverse the tokens */
|
||||||
*/
|
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||||
email_template[1].ulValueLen++;
|
token != (NSSToken *)NULL;
|
||||||
rvCert = find_best_cert_for_template(td, NULL,
|
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||||
&best, email_template, ctsize);
|
{
|
||||||
|
nssrv = nssToken_TraverseCertificatesByEmail(token, NULL,
|
||||||
|
email, &search);
|
||||||
}
|
}
|
||||||
|
nssListIterator_Finish(td->tokens);
|
||||||
nssList_Destroy(emailList);
|
nssList_Destroy(emailList);
|
||||||
return rvCert;
|
if (best.cert) {
|
||||||
|
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
|
||||||
|
}
|
||||||
|
return best.cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCertificate **
|
NSS_IMPLEMENT NSSCertificate **
|
||||||
|
@ -1072,17 +885,26 @@ NSSTrustDomain_TraverseCertificates
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PRStatus nssrv;
|
PRStatus nssrv;
|
||||||
NSSToken *tok;
|
NSSToken *token;
|
||||||
|
nssList *certList;
|
||||||
/* we need to lock the iterator */
|
nssTokenCertSearch search;
|
||||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
|
||||||
tok != (NSSToken *)NULL;
|
/* set the search criteria */
|
||||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
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);
|
nssListIterator_Finish(td->tokens);
|
||||||
return NULL; /* should return array of nssrv's ? */
|
nssList_Destroy(certList);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
|
@ -1149,8 +971,18 @@ NSSTrustDomain_CreateCryptoContext
|
||||||
NSSCallback *uhhOpt
|
NSSCallback *uhhOpt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
NSSArena *arena;
|
||||||
return NULL;
|
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 *
|
NSS_IMPLEMENT NSSCryptoContext *
|
||||||
|
|
Загрузка…
Ссылка в новой задаче