зеркало из 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
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.9 $ $Date: 2001-10-15 17:13:31 $ $Name: $";
|
||||
static const char BASE_CVS_ID[] = "@(#) $RCSfile: base.h,v $ $Revision: 1.10 $ $Date: 2001-11-28 16:23:34 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -562,6 +562,12 @@ nssItem_Create
|
|||
const void *data
|
||||
);
|
||||
|
||||
NSS_EXTERN void
|
||||
nssItem_Destroy
|
||||
(
|
||||
NSSItem *item
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSItem *
|
||||
nssItem_Duplicate
|
||||
(
|
||||
|
@ -831,8 +837,8 @@ nssList_Destroy
|
|||
nssList *list
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssList_DestroyElements
|
||||
NSS_EXTERN void
|
||||
nssList_Clear
|
||||
(
|
||||
nssList *list,
|
||||
nssListElementDestructorFunc destructor
|
||||
|
@ -1004,6 +1010,16 @@ nssListIterator_Finish
|
|||
*
|
||||
*/
|
||||
|
||||
NSS_EXTERN nssHash *
|
||||
nssHash_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRUint32 numBuckets,
|
||||
PLHashFunction keyHash,
|
||||
PLHashComparator keyCompare,
|
||||
PLHashComparator valueCompare
|
||||
);
|
||||
|
||||
NSS_EXTERN nssHash *
|
||||
nssHash_CreatePointer
|
||||
(
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.3 $ $Date: 2001-10-08 19:26:02 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.4 $ $Date: 2001-11-28 16:23:34 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -112,7 +112,7 @@ nss_compare_items(const void *v1, const void *v2)
|
|||
* nssHash_create
|
||||
*
|
||||
*/
|
||||
static nssHash *
|
||||
NSS_IMPLEMENT nssHash *
|
||||
nssHash_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: item.c,v $ $Revision: 1.1 $ $Date: 2000-03-31 19:50:14 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: item.c,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:35 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -116,6 +116,19 @@ nssItem_Create
|
|||
return (NSSItem *)NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nssItem_Destroy
|
||||
(
|
||||
NSSItem *item
|
||||
)
|
||||
{
|
||||
nss_ClearErrorStack();
|
||||
|
||||
nss_ZFreeIf(item->data);
|
||||
nss_ZFreeIf(item);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* nssItem_Duplicate
|
||||
*
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: list.c,v $ $Revision: 1.7 $ $Date: 2001-11-16 19:36:43 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: list.c,v $ $Revision: 1.8 $ $Date: 2001-11-28 16:23:35 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -138,8 +138,17 @@ nssList_Create
|
|||
NSS_IMPLEMENT PRStatus
|
||||
nssList_Destroy(nssList *list)
|
||||
{
|
||||
if (list->lock) PZ_DestroyLock(list->lock);
|
||||
NSSArena_Destroy(list->arena);
|
||||
PZLock *lock = list->lock;
|
||||
if (list->arena) {
|
||||
NSSArena_Destroy(list->arena);
|
||||
list = NULL;
|
||||
} else {
|
||||
nssList_Clear(list, NULL);
|
||||
}
|
||||
if (lock) {
|
||||
PZ_DestroyLock(lock);
|
||||
}
|
||||
nss_ZFreeIf(list);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -162,22 +171,23 @@ nssList_GetCompareFunction(nssList *list)
|
|||
return list->compareFunc;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssList_DestroyElements(nssList *list, nssListElementDestructorFunc destructor)
|
||||
NSS_IMPLEMENT void
|
||||
nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
|
||||
{
|
||||
PRCList *link;
|
||||
nssListElement *node;
|
||||
nssListElement *node, *tmp;
|
||||
NSSLIST_LOCK_IF(list);
|
||||
node = list->head;
|
||||
while (node && list->count > 0) {
|
||||
(*destructor)(node->data);
|
||||
if (destructor) (*destructor)(node->data);
|
||||
link = &node->link;
|
||||
node = (nssListElement *)PR_NEXT_LINK(link);
|
||||
tmp = (nssListElement *)PR_NEXT_LINK(link);
|
||||
PR_REMOVE_LINK(link);
|
||||
nss_ZFreeIf(node);
|
||||
node = tmp;
|
||||
--list->count;
|
||||
}
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return nssList_Destroy(list);
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
|
@ -271,7 +281,7 @@ nssList_Get(nssList *list, void *data)
|
|||
NSSLIST_LOCK_IF(list);
|
||||
node = nsslist_get_matching_element(list, data);
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return node->data;
|
||||
return (node) ? node->data : NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRUint32
|
||||
|
@ -286,14 +296,14 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
|
|||
nssListIterator *iter;
|
||||
void *el;
|
||||
PRUint32 i = 0;
|
||||
PR_ASSERT(maxElements > 0);
|
||||
iter = nssList_CreateIterator(list);
|
||||
for (el = nssListIterator_Start(iter); el != NULL;
|
||||
el = nssListIterator_Next(iter))
|
||||
{
|
||||
rvArray[i++] = el;
|
||||
if (maxElements > 0 && i == maxElements) break;
|
||||
if (i == maxElements) break;
|
||||
}
|
||||
rvArray[i] = NULL;
|
||||
nssListIterator_Finish(iter);
|
||||
nssListIterator_Destroy(iter);
|
||||
return PR_SUCCESS;
|
||||
|
|
|
@ -116,8 +116,7 @@ CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
/* XXX store it on a writeable token */
|
||||
goto done;
|
||||
} else {
|
||||
NSSCertificate *c = STAN_GetNSSCertificate(cert);
|
||||
ret = STAN_ChangeCertTrust(c, trust);
|
||||
ret = STAN_ChangeCertTrust(cert, trust);
|
||||
rv = (ret == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||
}
|
||||
done:
|
||||
|
@ -141,7 +140,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
|||
}
|
||||
if (c->nickname && strcmp(nickname, c->nickname) != 0) {
|
||||
nss_ZFreeIf(c->nickname);
|
||||
c->nickname = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->arena);
|
||||
c->nickname = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena);
|
||||
PORT_Free(cert->nickname);
|
||||
cert->nickname = PORT_Strdup(nickname);
|
||||
}
|
||||
|
@ -168,6 +167,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
|
|||
char *nickname, PRBool isperm, PRBool copyDER)
|
||||
{
|
||||
NSSCertificate *c;
|
||||
NSSCryptoContext *context;
|
||||
nssDecodedCert *dc;
|
||||
NSSArena *arena;
|
||||
CERTCertificate *cc;
|
||||
|
@ -175,13 +175,19 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
|
|||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
c = NSSCertificate_Create(arena);
|
||||
c = nss_ZNEW(arena, NSSCertificate);
|
||||
if (!c) {
|
||||
goto loser;
|
||||
}
|
||||
NSSITEM_FROM_SECITEM(&c->encoding, derCert);
|
||||
c->object.arena = arena;
|
||||
c->object.refCount = 1;
|
||||
c->object.instanceList = nssList_Create(arena, PR_TRUE);
|
||||
c->object.instances = nssList_CreateIterator(c->object.instanceList);
|
||||
/* Forces a decoding of the cert in order to obtain the parts used
|
||||
* below
|
||||
*/
|
||||
cc = STAN_GetCERTCertificate(c);
|
||||
c->arena = arena;
|
||||
nssItem_Create(arena,
|
||||
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
|
||||
nssItem_Create(arena,
|
||||
|
@ -200,12 +206,13 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
|
|||
(NSSUTF8 *)cc->emailAddr,
|
||||
PORT_Strlen(cc->emailAddr));
|
||||
}
|
||||
c->trustDomain = handle;
|
||||
cc->dbhandle = handle;
|
||||
nssTrustDomain_AddCertsToCache(handle, &c, 1);
|
||||
cc->istemp = 1;
|
||||
cc->isperm = 0;
|
||||
|
||||
context = STAN_GetDefaultCryptoContext();
|
||||
NSSCryptoContext_ImportCertificate(context, c);
|
||||
/* This is a hack to work around the fact that an instance of the cert
|
||||
* doesn't really exist until the import
|
||||
*/
|
||||
cc->nssCertificate = NULL;
|
||||
cc = STAN_GetCERTCertificate(c);
|
||||
return cc;
|
||||
loser:
|
||||
nssArena_Destroy(arena);
|
||||
|
@ -363,10 +370,13 @@ CERT_DestroyCertificate(CERTCertificate *cert)
|
|||
CERT_UnlockCertRefCount(cert);
|
||||
if ( ( refCount == 0 ) && !cert->keepSession ) {
|
||||
PRArenaPool *arena = cert->arena;
|
||||
if ( cert->istemp ) {
|
||||
/* uncache the cert ? */
|
||||
}
|
||||
/* delete the NSSCertificate */
|
||||
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
|
||||
NSSCertificate *tmp = STAN_GetNSSCertificate(cert);
|
||||
if (tmp) {
|
||||
nssTrustDomain_RemoveCertFromCache(td, tmp);
|
||||
NSSCertificate_Destroy(tmp);
|
||||
}
|
||||
/* zero cert before freeing. Any stale references to this cert
|
||||
* after this point will probably cause an exception. */
|
||||
PORT_Memset(cert, 0, sizeof *cert);
|
||||
|
|
|
@ -417,9 +417,13 @@ loser:
|
|||
nss_ZFreeIf(nssTime);
|
||||
if (status == PR_SUCCESS) {
|
||||
/* if it's a root, the chain will only have one cert */
|
||||
NSSCertificate *issuer = chain[1] ? chain[1] : chain[0];
|
||||
CERTCertificate *rvc = STAN_GetCERTCertificate(issuer);
|
||||
return rvc;
|
||||
if (!chain[1]) {
|
||||
/* need to dupe since caller expects new cert */
|
||||
return CERT_DupCertificate(cert);
|
||||
} else {
|
||||
/* this is the only instance */
|
||||
return STAN_GetCERTCertificate(chain[1]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
|
@ -32,13 +32,9 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.10 $ $Date: 2001-11-07 16:15:28 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.11 $ $Date: 2001-11-28 16:23:38 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef PKIT_H
|
||||
#include "pkit.h"
|
||||
#endif /* PKIT_H */
|
||||
|
||||
#ifndef DEV_H
|
||||
#include "dev.h"
|
||||
#endif /* DEV_H */
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define DEV_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.13 $ $Date: 2001-11-09 00:36:10 $ $Name: $";
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.14 $ $Date: 2001-11-28 16:23:38 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEVT_H
|
||||
|
@ -64,10 +64,6 @@ static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.13 $ $Da
|
|||
* |-----------|---> NSSSlot <--> NSSToken
|
||||
*/
|
||||
|
||||
#ifndef DEVT_H
|
||||
#include "devt.h"
|
||||
#endif /* DEVT_H */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
NSS_EXTERN NSSModule *
|
||||
|
@ -248,16 +244,24 @@ nssToken_GetName
|
|||
NSSToken *tok
|
||||
);
|
||||
|
||||
/* Given a raw attribute template, import an object
|
||||
* (certificate, public key, private key, symmetric key)
|
||||
*/
|
||||
NSS_EXTERN CK_OBJECT_HANDLE
|
||||
nssToken_ImportObject
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_ImportCertificate
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR objectTemplate,
|
||||
CK_ULONG otsize
|
||||
NSSCertificate *cert,
|
||||
NSSTrustDomain *td,
|
||||
NSSCryptoContext *cc
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_ImportTrust
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSTrust *trust,
|
||||
NSSTrustDomain *trustDomain,
|
||||
NSSCryptoContext *cryptoContext
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSPublicKey *
|
||||
|
@ -280,30 +284,15 @@ nssToken_GenerateSymmetricKey
|
|||
NSS_EXTERN PRStatus
|
||||
nssToken_DeleteStoredObject
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_OBJECT_HANDLE object
|
||||
nssCryptokiInstance *instance
|
||||
);
|
||||
|
||||
NSS_EXTERN CK_OBJECT_HANDLE
|
||||
nssToken_FindObjectByTemplate
|
||||
NSS_EXTERN NSSTrust *
|
||||
nssToken_FindTrustForCert
|
||||
(
|
||||
NSSToken *tok,
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_TraverseCertificatesByTemplate
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
nssList *cachedList,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
NSSCertificate *c
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
|
@ -311,8 +300,95 @@ nssToken_TraverseCertificates
|
|||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
nssTokenCertSearch *search
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_TraverseCertificatesBySubject
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSDER *subject,
|
||||
nssTokenCertSearch *search
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_TraverseCertificatesByNickname
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSUTF8 *name,
|
||||
nssTokenCertSearch *search
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_TraverseCertificatesByEmail
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSASCII7 *email,
|
||||
nssTokenCertSearch *search
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
nssToken_FindCertificateByIssuerAndSerialNumber
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSDER *issuer,
|
||||
NSSDER *serial
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
nssToken_FindCertificateByEncodedCertificate
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSBER *encodedCertificate
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSTrust *
|
||||
nssToken_FindTrustForCert
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *session,
|
||||
NSSCertificate *c
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSItem *
|
||||
nssToken_Digest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSAlgorithmAndParameters *ap,
|
||||
NSSItem *data,
|
||||
NSSItem *rvOpt,
|
||||
NSSArena *arenaOpt
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_BeginDigest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSAlgorithmAndParameters *ap
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssToken_ContinueDigest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSItem *item
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSItem *
|
||||
nssToken_FinishDigest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSItem *rvOpt,
|
||||
NSSArena *arenaOpt
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
|
@ -342,9 +418,17 @@ nssSession_IsReadWrite
|
|||
nssSession *s
|
||||
);
|
||||
|
||||
#ifdef DEBUG
|
||||
void nssModule_Debug(NSSModule *m);
|
||||
#endif
|
||||
NSS_EXTERN NSSAlgorithmAndParameters *
|
||||
NSSAlgorithmAndParameters_CreateSHA1Digest
|
||||
(
|
||||
NSSArena *arenaOpt
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSAlgorithmAndParameters *
|
||||
NSSAlgorithmAndParameters_CreateMD5Digest
|
||||
(
|
||||
NSSArena *arenaOpt
|
||||
);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devmod.c,v $ $Revision: 1.1 $ $Date: 2001-11-08 00:14:52 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devmod.c,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#include "nspr.h"
|
||||
|
@ -367,12 +367,6 @@ nssModule_TraverseCertificates
|
|||
void *arg
|
||||
)
|
||||
{
|
||||
PRUint32 i;
|
||||
for (i=0; i<mod->numSlots; i++) {
|
||||
/* might as well skip straight to token, right? or is this slot? */
|
||||
nssToken_TraverseCertificates(mod->slots[i]->token,
|
||||
NULL, callback, arg);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,950 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.1 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
#include "dev.h"
|
||||
#endif /* DEV_H */
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
#endif /* DEVM_H */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
#include "nssckepv.h"
|
||||
#endif /* NSSCKEPV_H */
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
/* XXX */
|
||||
#ifndef PKIT_H
|
||||
#include "pkit.h"
|
||||
#endif /* PKIT_H */
|
||||
|
||||
#ifdef NSS_3_4_CODE
|
||||
#include "pkim.h" /* for cert decoding */
|
||||
#endif
|
||||
|
||||
/* The number of object handles to grab during each call to C_FindObjects */
|
||||
#define OBJECT_STACK_SIZE 16
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_DeleteStoredObject
|
||||
(
|
||||
nssCryptokiInstance *instance
|
||||
)
|
||||
{
|
||||
CK_RV ckrv;
|
||||
PRStatus nssrv;
|
||||
PRBool createdSession;
|
||||
NSSToken *token = instance->token;
|
||||
nssSession *session = NULL;
|
||||
if (nssCKObject_IsAttributeTrue(instance->handle, CKA_TOKEN,
|
||||
token->defaultSession,
|
||||
token->slot, &nssrv)) {
|
||||
if (nssSession_IsReadWrite(token->defaultSession)) {
|
||||
session = token->defaultSession;
|
||||
} else {
|
||||
session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
|
||||
createdSession = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (session == NULL) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(token)->C_DestroyObject(session->handle, instance->handle);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (createdSession) {
|
||||
nssSession_Destroy(session);
|
||||
}
|
||||
if (ckrv != CKR_OK) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static CK_OBJECT_HANDLE
|
||||
import_object
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR objectTemplate,
|
||||
CK_ULONG otsize
|
||||
)
|
||||
{
|
||||
nssSession *session = NULL;
|
||||
PRBool createdSession = PR_FALSE;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_RV ckrv;
|
||||
if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
|
||||
if (sessionOpt) {
|
||||
if (!nssSession_IsReadWrite(sessionOpt)) {
|
||||
return CK_INVALID_HANDLE;
|
||||
} else {
|
||||
session = sessionOpt;
|
||||
}
|
||||
} else if (nssSession_IsReadWrite(tok->defaultSession)) {
|
||||
session = tok->defaultSession;
|
||||
} else {
|
||||
session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
|
||||
createdSession = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
}
|
||||
if (session == NULL) {
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
|
||||
objectTemplate, otsize,
|
||||
&object);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (createdSession) {
|
||||
nssSession_Destroy(session);
|
||||
}
|
||||
if (ckrv != CKR_OK) {
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
static CK_OBJECT_HANDLE
|
||||
find_object_by_template
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
)
|
||||
{
|
||||
CK_SESSION_HANDLE hSession;
|
||||
CK_OBJECT_HANDLE rvObject;
|
||||
CK_ULONG count;
|
||||
CK_RV ckrv;
|
||||
nssSession *session;
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
hSession = session->handle;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (ckrv != CKR_OK) {
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
return rvObject;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
traverse_objects_by_template
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG otsize,
|
||||
PRStatus (*callback)(NSSToken *t, nssSession *session,
|
||||
CK_OBJECT_HANDLE h, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
NSSSlot *slot;
|
||||
PRStatus cbrv;
|
||||
PRUint32 i;
|
||||
CK_RV ckrv;
|
||||
CK_ULONG count;
|
||||
CK_OBJECT_HANDLE *objectStack;
|
||||
CK_OBJECT_HANDLE startOS[OBJECT_STACK_SIZE];
|
||||
CK_SESSION_HANDLE hSession;
|
||||
NSSArena *objectArena = NULL;
|
||||
nssSession *session;
|
||||
nssList *objectList = NULL;
|
||||
slot = tok->slot;
|
||||
objectStack = startOS;
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
hSession = session->handle;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(slot)->C_FindObjectsInit(hSession, obj_template, otsize);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
goto loser;
|
||||
}
|
||||
while (PR_TRUE) {
|
||||
ckrv = CKAPI(slot)->C_FindObjects(hSession, objectStack,
|
||||
OBJECT_STACK_SIZE, &count);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
goto loser;
|
||||
}
|
||||
if (count == OBJECT_STACK_SIZE) {
|
||||
if (!objectList) {
|
||||
objectArena = NSSArena_Create();
|
||||
objectList = nssList_Create(objectArena, PR_FALSE);
|
||||
}
|
||||
objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
|
||||
OBJECT_STACK_SIZE);
|
||||
nssList_Add(objectList, objectStack);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
if (objectList) {
|
||||
nssListIterator *objects;
|
||||
objects = nssList_CreateIterator(objectList);
|
||||
for (objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Start(objects);
|
||||
objectStack != NULL;
|
||||
objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Next(objects)) {
|
||||
for (i=0; i<count; i++) {
|
||||
cbrv = (*callback)(tok, session, objectStack[i], arg);
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(objects);
|
||||
count = OBJECT_STACK_SIZE;
|
||||
}
|
||||
for (i=0; i<count; i++) {
|
||||
cbrv = (*callback)(tok, session, startOS[i], arg);
|
||||
}
|
||||
if (objectArena)
|
||||
NSSArena_Destroy(objectArena);
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
if (objectArena)
|
||||
NSSArena_Destroy(objectArena);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
add_object_instance
|
||||
(
|
||||
nssPKIObject *object,
|
||||
NSSToken *t,
|
||||
CK_OBJECT_HANDLE h,
|
||||
NSSTrustDomain *td,
|
||||
NSSCryptoContext *cc
|
||||
)
|
||||
{
|
||||
nssPKIObjectInstance *oi;
|
||||
oi = nss_ZNEW(object->arena, nssPKIObjectInstance);
|
||||
if (!oi) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
oi->cryptoki.handle = h;
|
||||
oi->cryptoki.token = t;
|
||||
oi->trustDomain = td;
|
||||
oi->cryptoContext = cc;
|
||||
nssList_Add(object->instanceList, oi);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NSS_3_4_CODE
|
||||
static void make_nss3_nickname(NSSCertificate *c)
|
||||
{
|
||||
/* In NSS 3.4, the semantic is that nickname = token name + label */
|
||||
PRStatus utf8rv;
|
||||
NSSUTF8 *tokenName;
|
||||
NSSUTF8 *label;
|
||||
char *fullname;
|
||||
PRUint32 len, tlen;
|
||||
tokenName = nssToken_GetName(c->token);
|
||||
label = c->nickname ? c->nickname : c->email;
|
||||
if (!label) return;
|
||||
tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */
|
||||
tlen += 1; /* : */
|
||||
len = nssUTF8_Length(label, &utf8rv); /* label */
|
||||
len += 1; /* \0 */
|
||||
len += tlen;
|
||||
fullname = nss_ZAlloc(c->arena, len);
|
||||
utf8rv = nssUTF8_CopyIntoFixedBuffer(tokenName, fullname, tlen, ':');
|
||||
utf8rv = nssUTF8_CopyIntoFixedBuffer(label, fullname + tlen,
|
||||
len - tlen, '\0');
|
||||
nss_ZFreeIf(c->nickname);
|
||||
c->nickname = nssUTF8_Create(c->arena,
|
||||
nssStringType_UTF8String,
|
||||
fullname, len);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static NSSCertificateType
|
||||
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
|
||||
{
|
||||
CK_CERTIFICATE_TYPE ckCertType;
|
||||
ckCertType = *((CK_ULONG *)attrib->pValue);
|
||||
switch (ckCertType) {
|
||||
case CKC_X_509:
|
||||
return NSSCertificateType_PKIX;
|
||||
break;
|
||||
default:
|
||||
return NSSCertificateType_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a certificate from an object handle. */
|
||||
static NSSCertificate *
|
||||
get_token_cert
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
CK_OBJECT_HANDLE handle
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert;
|
||||
nssPKIObject *object;
|
||||
NSSArena *arena;
|
||||
nssSession *session;
|
||||
PRStatus nssrv;
|
||||
CK_ULONG template_size;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
|
||||
{ CKA_ID, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
|
||||
};
|
||||
template_size = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
session = (sessionOpt) ? sessionOpt : token->defaultSession;
|
||||
arena = nssArena_Create();
|
||||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
rvCert = nss_ZNEW(arena, NSSCertificate);
|
||||
if (!rvCert) {
|
||||
goto loser;
|
||||
}
|
||||
object = &rvCert->object;
|
||||
object->arena = arena;
|
||||
object->refCount = 1;
|
||||
object->instanceList = nssList_Create(arena, PR_TRUE);
|
||||
if (!object->instanceList) {
|
||||
goto loser;
|
||||
}
|
||||
object->instances = nssList_CreateIterator(object->instanceList);
|
||||
if (!object->instances) {
|
||||
goto loser;
|
||||
}
|
||||
nssrv = nssCKObject_GetAttributes(handle,
|
||||
cert_template, template_size,
|
||||
arena, session, token->slot);
|
||||
if (nssrv) {
|
||||
goto loser;
|
||||
}
|
||||
rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->id);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[3], &rvCert->issuer);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->serial);
|
||||
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[5], rvCert->nickname);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->subject);
|
||||
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email);
|
||||
#ifdef NSS_3_4_CODE
|
||||
/* nss 3.4 database doesn't associate email address with cert */
|
||||
if (!rvCert->email) {
|
||||
nssDecodedCert *dc;
|
||||
NSSASCII7 *email;
|
||||
dc = nssCertificate_GetDecoding(rvCert);
|
||||
email = dc->getEmailAddress(dc);
|
||||
if (email) rvCert->email = nssUTF8_Duplicate(email, arena);
|
||||
}
|
||||
/*make_nss3_nickname(rvCert);*/
|
||||
#endif
|
||||
return rvCert;
|
||||
loser:
|
||||
nssArena_Destroy(arena);
|
||||
return (NSSCertificate *)NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_ImportCertificate
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSCertificate *cert,
|
||||
NSSTrustDomain *td,
|
||||
NSSCryptoContext *cc
|
||||
)
|
||||
{
|
||||
CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
CK_ATTRIBUTE cert_tmpl[] = {
|
||||
{ CKA_TOKEN, NULL, 0 },
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
|
||||
{ CKA_ID, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize = sizeof(cert_tmpl)/sizeof(cert_tmpl[0]);
|
||||
if (td) {
|
||||
/* trust domain == token object */
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 0, &g_ck_true);
|
||||
} else {
|
||||
/* crypto context == session object */
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 0, &g_ck_false);
|
||||
}
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 1, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR( cert_tmpl, 2, cert_type);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 3, &cert->id);
|
||||
NSS_CK_SET_ATTRIBUTE_UTF8(cert_tmpl, 4, cert->nickname);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 5, &cert->encoding);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 6, &cert->issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 7, &cert->subject);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 8, &cert->serial);
|
||||
/* Import the certificate onto the token */
|
||||
handle = import_object(tok, sessionOpt, cert_tmpl, ctsize);
|
||||
if (handle == CK_INVALID_HANDLE) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return add_object_instance(&cert->object, tok, handle, td, cc);
|
||||
}
|
||||
|
||||
struct cert_search_index_str
|
||||
{
|
||||
NSSDER issuer;
|
||||
NSSDER serial;
|
||||
};
|
||||
|
||||
static PRBool
|
||||
compare_cert_by_issuer_sn(void *a, void *b)
|
||||
{
|
||||
NSSCertificate *c = (NSSCertificate *)a;
|
||||
struct cert_search_index_str *csi = (struct cert_search_index_str *)b;
|
||||
return (nssItem_Equal(&c->issuer, &csi->issuer, NULL) &&
|
||||
nssItem_Equal(&c->serial, &csi->serial, NULL));
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
PRBool found;
|
||||
nssTokenCertSearch *search = (nssTokenCertSearch *)arg;
|
||||
NSSCertificate *cert = NULL;
|
||||
struct cert_search_index_str csi;
|
||||
nssListIterator *instances;
|
||||
nssPKIObjectInstance *oi;
|
||||
CK_ATTRIBUTE issuersn_tmpl[] = {
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ist_size = sizeof(issuersn_tmpl) / sizeof(issuersn_tmpl[0]);
|
||||
if (search->cached) {
|
||||
nssrv = nssCKObject_GetAttributes(h, issuersn_tmpl, ist_size,
|
||||
NULL, session, t->slot);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&issuersn_tmpl[0], &csi.issuer);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&issuersn_tmpl[1], &csi.serial);
|
||||
cert = (NSSCertificate *)nssList_Get(search->cached, &csi);
|
||||
nss_ZFreeIf(csi.issuer.data);
|
||||
nss_ZFreeIf(csi.serial.data);
|
||||
}
|
||||
found = PR_FALSE;
|
||||
if (cert) {
|
||||
instances = cert->object.instances;
|
||||
for (oi = (nssPKIObjectInstance *)nssListIterator_Start(instances);
|
||||
oi != (nssPKIObjectInstance *)NULL;
|
||||
oi = (nssPKIObjectInstance *)nssListIterator_Next(instances))
|
||||
{
|
||||
if (oi->cryptoki.handle == h && oi->cryptoki.token == t) {
|
||||
found = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(instances);
|
||||
} else {
|
||||
cert = get_token_cert(t, session, h);
|
||||
if (!cert) return PR_FAILURE;
|
||||
}
|
||||
if (!found) {
|
||||
nssrv = add_object_instance(&cert->object, t, h,
|
||||
search->trustDomain,
|
||||
search->cryptoContext);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
return nssrv;
|
||||
}
|
||||
}
|
||||
return (*search->callback)(cert, search->cbarg);
|
||||
}
|
||||
|
||||
/* traverse all certificates - this should only happen if the token
|
||||
* has been marked as "traversable"
|
||||
*/
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_TraverseCertificates
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
nssTokenCertSearch *search
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
/* this is really traversal - the template is all certs */
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
|
||||
nssrv = traverse_objects_by_template(token, sessionOpt,
|
||||
cert_template, ctsize,
|
||||
retrieve_cert, search);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_TraverseCertificatesBySubject
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSDER *subject,
|
||||
nssTokenCertSearch *search
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
CK_ATTRIBUTE subj_tmpl[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 }
|
||||
};
|
||||
CK_ULONG stsize = (CK_ULONG)(sizeof(subj_tmpl) / sizeof(subj_tmpl[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_tmpl, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_tmpl, 1, subject);
|
||||
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
|
||||
/* now traverse the token certs matching this template */
|
||||
nssrv = traverse_objects_by_template(token, sessionOpt,
|
||||
subj_tmpl, stsize,
|
||||
retrieve_cert, search);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_TraverseCertificatesByNickname
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSUTF8 *name,
|
||||
nssTokenCertSearch *search
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
CK_ATTRIBUTE nick_tmpl[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ntsize = sizeof(nick_tmpl) / sizeof(nick_tmpl[0]);
|
||||
/* set up the search template */
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_tmpl, 0, &g_ck_class_cert);
|
||||
nick_tmpl[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_tmpl[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
|
||||
/* now traverse the token certs matching this template */
|
||||
nssrv = traverse_objects_by_template(token, sessionOpt,
|
||||
nick_tmpl, ntsize,
|
||||
retrieve_cert, search);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
return nssrv;
|
||||
}
|
||||
#if 0
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
* im - this is not needed by the current softoken. However, I'm
|
||||
* leaving it in until I have surveyed more tokens to see if it needed.
|
||||
*/
|
||||
nick_tmpl[1].ulValueLen++;
|
||||
nssrv = traverse_objects_by_template(token, sessionOpt,
|
||||
nick_tmpl, ntsize,
|
||||
retrieve_cert, search);
|
||||
#endif
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_TraverseCertificatesByEmail
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSASCII7 *email,
|
||||
nssTokenCertSearch *search
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
CK_ATTRIBUTE email_tmpl[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG etsize = sizeof(email_tmpl) / sizeof(email_tmpl[0]);
|
||||
/* set up the search template */
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(email_tmpl, 0, &g_ck_class_cert);
|
||||
email_tmpl[1].pValue = (CK_VOID_PTR)email;
|
||||
email_tmpl[1].ulValueLen = (CK_ULONG)nssUTF8_Length(email, &nssrv);
|
||||
nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn);
|
||||
/* now traverse the token certs matching this template */
|
||||
nssrv = traverse_objects_by_template(token, sessionOpt,
|
||||
email_tmpl, etsize,
|
||||
retrieve_cert, search);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
return nssrv;
|
||||
}
|
||||
#if 0
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
*/
|
||||
email_tmpl[1].ulValueLen++;
|
||||
nssrv = traverse_objects_by_template(token, sessionOpt,
|
||||
email_tmpl, etsize,
|
||||
retrieve_cert, search);
|
||||
#endif
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
/* XXX these next two need to create instances as needed */
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssToken_FindCertificateByIssuerAndSerialNumber
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSDER *issuer,
|
||||
NSSDER *serial
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
nssSession *session;
|
||||
PRBool tokenObject;
|
||||
PRStatus nssrv;
|
||||
CK_ULONG ctsize;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 }
|
||||
};
|
||||
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
/* Set the unique id */
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, serial);
|
||||
/* get the object handle */
|
||||
object = find_object_by_template(token, sessionOpt, cert_template, ctsize);
|
||||
if (object == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
session = (sessionOpt) ? sessionOpt : token->defaultSession;
|
||||
rvCert = get_token_cert(token, sessionOpt, object);
|
||||
if (rvCert) {
|
||||
NSSTrustDomain *td;
|
||||
NSSCryptoContext *cc;
|
||||
tokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN,
|
||||
session, token->slot,
|
||||
&nssrv);
|
||||
if (tokenObject) {
|
||||
td = token->trustDomain;
|
||||
cc = NULL;
|
||||
} else {
|
||||
td = NULL;
|
||||
cc = NULL; /* XXX how to recover the crypto context from
|
||||
* the token?
|
||||
*/
|
||||
}
|
||||
add_object_instance(&rvCert->object, token, object, td, cc);
|
||||
}
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssToken_FindCertificateByEncodedCertificate
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSBER *encodedCertificate
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
nssSession *session;
|
||||
PRBool tokenObject;
|
||||
PRStatus nssrv;
|
||||
CK_ULONG ctsize;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 }
|
||||
};
|
||||
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, encodedCertificate);
|
||||
/* get the object handle */
|
||||
object = find_object_by_template(token, sessionOpt, cert_template, ctsize);
|
||||
if (object == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
session = (sessionOpt) ? sessionOpt : token->defaultSession;
|
||||
rvCert = get_token_cert(token, sessionOpt, object);
|
||||
if (rvCert) {
|
||||
NSSTrustDomain *td;
|
||||
NSSCryptoContext *cc;
|
||||
tokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN,
|
||||
session, token->slot,
|
||||
&nssrv);
|
||||
if (tokenObject) {
|
||||
td = token->trustDomain;
|
||||
cc = NULL;
|
||||
} else {
|
||||
td = NULL;
|
||||
cc = NULL; /* XXX how to recover the crypto context from
|
||||
* the token?
|
||||
*/
|
||||
}
|
||||
add_object_instance(&rvCert->object, token, object, td, cc);
|
||||
}
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
static void
|
||||
sha1_hash(NSSToken *token, NSSItem *input, NSSItem *output)
|
||||
{
|
||||
NSSAlgorithmAndParameters *ap;
|
||||
ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
|
||||
(void)nssToken_Digest(token, NULL, ap, input, output, NULL);
|
||||
nss_ZFreeIf(ap);
|
||||
}
|
||||
|
||||
static void
|
||||
md5_hash(NSSToken *token, NSSItem *input, NSSItem *output)
|
||||
{
|
||||
NSSAlgorithmAndParameters *ap;
|
||||
ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
|
||||
(void)nssToken_Digest(token, NULL, ap, input, output, NULL);
|
||||
nss_ZFreeIf(ap);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_ImportTrust
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSTrust *trust,
|
||||
NSSTrustDomain *trustDomain,
|
||||
NSSCryptoContext *cryptoContext
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
|
||||
CK_ATTRIBUTE trust_tmpl[] = {
|
||||
{ CKA_TOKEN, NULL, 0 },
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 },
|
||||
{ CKA_CERT_SHA1_HASH, NULL, 0 },
|
||||
{ CKA_CERT_MD5_HASH, NULL, 0 },
|
||||
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
|
||||
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
|
||||
};
|
||||
CK_ULONG tsize = sizeof(trust_tmpl) / sizeof(trust_tmpl[0]);
|
||||
PRUint8 sha1[20]; /* this is cheating... */
|
||||
PRUint8 md5[16];
|
||||
NSSItem sha1_result, md5_result;
|
||||
NSSCertificate *c = trust->certificate;
|
||||
sha1_result.data = sha1; sha1_result.size = sizeof sha1;
|
||||
md5_result.data = md5; md5_result.size = sizeof md5;
|
||||
sha1_hash(tok, &c->encoding, &sha1_result);
|
||||
md5_hash(tok, &c->encoding, &md5_result);
|
||||
if (trustDomain) {
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 0, &g_ck_true);
|
||||
} else {
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 0, &g_ck_false);
|
||||
}
|
||||
NSS_CK_SET_ATTRIBUTE_VAR( trust_tmpl, 1, tobjc);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 2, &c->issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 3, &c->serial);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 4, &sha1_result);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 5, &md5_result);
|
||||
/* now set the trust values */
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 6, trust->serverAuth);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 7, trust->clientAuth);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 8, trust->emailProtection);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 9, trust->codeSigning);
|
||||
/* import the trust object onto the token */
|
||||
handle = import_object(tok, NULL, trust_tmpl, tsize);
|
||||
if (handle != CK_INVALID_HANDLE) {
|
||||
nssrv = add_object_instance(&trust->object, tok, handle,
|
||||
trustDomain, cryptoContext);
|
||||
} else {
|
||||
nssrv = PR_FAILURE;
|
||||
}
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
static CK_OBJECT_HANDLE
|
||||
get_cert_trust_handle
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *session,
|
||||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
|
||||
CK_ATTRIBUTE tobj_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_CERT_SHA1_HASH, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 }
|
||||
};
|
||||
CK_ULONG tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
|
||||
PRUint8 sha1[20]; /* this is cheating... */
|
||||
NSSItem sha1_result;
|
||||
sha1_result.data = sha1; sha1_result.size = sizeof sha1;
|
||||
sha1_hash(token, &c->encoding, &sha1_result);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR( tobj_template, 0, tobjc);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 1, &sha1_result);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial);
|
||||
#ifdef NSS_3_4_CODE
|
||||
if (PK11_HasRootCerts(token->pk11slot)) {
|
||||
tobj_size -= 2;
|
||||
}
|
||||
/*
|
||||
* we need to arrange for the built-in token to lose the bottom 2
|
||||
* attributes so that old built-in tokens will continue to work.
|
||||
*/
|
||||
#endif
|
||||
return find_object_by_template(token, session,
|
||||
tobj_template, tobj_size);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSTrust *
|
||||
nssToken_FindTrustForCert
|
||||
(
|
||||
NSSToken *token,
|
||||
nssSession *sessionOpt,
|
||||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
NSSTrust *rvTrust;
|
||||
nssSession *session;
|
||||
NSSArena *arena;
|
||||
nssPKIObject *object;
|
||||
CK_TRUST saTrust, caTrust, epTrust, csTrust;
|
||||
CK_OBJECT_HANDLE tobjID;
|
||||
CK_ATTRIBUTE trust_template[] = {
|
||||
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
|
||||
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
|
||||
};
|
||||
CK_ULONG trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
|
||||
session = (sessionOpt) ? sessionOpt : token->defaultSession;
|
||||
tobjID = get_cert_trust_handle(token, session, c);
|
||||
if (tobjID == CK_INVALID_HANDLE) {
|
||||
return NULL;
|
||||
}
|
||||
/* Then use the trust object to find the trust settings */
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, saTrust);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, caTrust);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, epTrust);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, csTrust);
|
||||
nssrv = nssCKObject_GetAttributes(tobjID,
|
||||
trust_template, trust_size,
|
||||
NULL, session, token->slot);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
arena = nssArena_Create();
|
||||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
rvTrust = nss_ZNEW(arena, NSSTrust);
|
||||
if (!rvTrust) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
object = &rvTrust->object;
|
||||
object->arena = arena;
|
||||
object->refCount = 1;
|
||||
object->instanceList = nssList_Create(arena, PR_TRUE);
|
||||
if (!object->instanceList) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
object->instances = nssList_CreateIterator(object->instanceList);
|
||||
if (!object->instances) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
/* need to figure out trust domain and/or crypto context */
|
||||
nssrv = add_object_instance(object, token, tobjID,
|
||||
token->trustDomain, NULL);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
nssArena_Destroy(arena);
|
||||
return NULL;
|
||||
}
|
||||
rvTrust->serverAuth = saTrust;
|
||||
rvTrust->clientAuth = caTrust;
|
||||
rvTrust->emailProtection = epTrust;
|
||||
rvTrust->codeSigning = csTrust;
|
||||
return rvTrust;
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
#define DEVT_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.6 $ $Date: 2001-11-08 00:14:53 $ $Name: $";
|
||||
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -60,12 +60,18 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.6 $ $D
|
|||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
#ifndef BASET_H
|
||||
#include "baset.h"
|
||||
#endif /* BASET_H */
|
||||
|
||||
#ifdef NSS_3_4_CODE
|
||||
#include "secmodt.h"
|
||||
#endif /* NSS_3_4_CODE */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct nssSessionStr nssSession;
|
||||
|
||||
/* The list of boolean flags used to describe properties of a
|
||||
* module.
|
||||
*/
|
||||
|
@ -138,6 +144,47 @@ struct nssSessionStr
|
|||
PRBool isRW;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NSSCertificateType_Unknown = 0,
|
||||
NSSCertificateType_PKIX = 1
|
||||
} NSSCertificateType;
|
||||
|
||||
#ifdef nodef
|
||||
typedef enum {
|
||||
nssTrustLevel_Unknown = 0,
|
||||
nssTrustLevel_NotTrusted = 1,
|
||||
nssTrustLevel_Trusted = 2,
|
||||
nssTrustLevel_TrustedDelegator = 3,
|
||||
nssTrustLevel_Valid = 4
|
||||
} nssTrustLevel;
|
||||
#else
|
||||
typedef CK_ULONG nssTrustLevel; /* for now */
|
||||
#endif
|
||||
|
||||
typedef struct nssCryptokiInstanceStr nssCryptokiInstance;
|
||||
|
||||
struct nssCryptokiInstanceStr
|
||||
{
|
||||
CK_OBJECT_HANDLE handle;
|
||||
NSSToken *token;
|
||||
};
|
||||
|
||||
typedef struct nssTokenCertSearchStr nssTokenCertSearch;
|
||||
|
||||
struct nssTokenCertSearchStr
|
||||
{
|
||||
PRStatus (* callback)(NSSCertificate *c, void *arg);
|
||||
void *cbarg;
|
||||
nssList *cached;
|
||||
NSSTrustDomain *trustDomain;
|
||||
NSSCryptoContext *cryptoContext;
|
||||
};
|
||||
|
||||
struct NSSAlgorithmAndParametersStr
|
||||
{
|
||||
CK_MECHANISM mechanism;
|
||||
};
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* DEVT_H */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.2 $ $Date: 2001-11-09 00:36:12 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.3 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
|
@ -43,23 +43,10 @@ static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.2 $ $Da
|
|||
#include "devm.h"
|
||||
#endif /* DEVM_H */
|
||||
|
||||
/* for the cache... */
|
||||
#ifndef PKI_H
|
||||
#include "pki.h"
|
||||
#endif /* PKI_H */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
#include "nssckepv.h"
|
||||
#endif /* NSSCKEPV_H */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
#include "nsspki.h"
|
||||
#endif /* NSSPKI_H */
|
||||
|
||||
#ifndef PKI_H
|
||||
#include "pki.h"
|
||||
#endif /* PKI_H */
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
@ -207,330 +194,191 @@ nssToken_GetName
|
|||
return tok->name;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_DeleteStoredObject
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
nssToken_Digest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_OBJECT_HANDLE object
|
||||
NSSAlgorithmAndParameters *ap,
|
||||
NSSItem *data,
|
||||
NSSItem *rvOpt,
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
nssSession *session = NULL;
|
||||
CK_RV ckrv;
|
||||
PRStatus nssrv;
|
||||
PRBool createdSession;
|
||||
if (nssCKObject_IsAttributeTrue(object, CKA_TOKEN, tok->defaultSession,
|
||||
tok->slot, &nssrv)) {
|
||||
if (sessionOpt) {
|
||||
if (!nssSession_IsReadWrite(sessionOpt)) {
|
||||
return PR_FAILURE;;
|
||||
} else {
|
||||
session = sessionOpt;
|
||||
}
|
||||
} else if (nssSession_IsReadWrite(tok->defaultSession)) {
|
||||
session = tok->defaultSession;
|
||||
} else {
|
||||
session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
|
||||
createdSession = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (session == NULL) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok->slot)->C_DestroyObject(session->handle, object);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (createdSession) {
|
||||
nssSession_Destroy(session);
|
||||
}
|
||||
if (ckrv != CKR_OK) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT CK_OBJECT_HANDLE
|
||||
nssToken_ImportObject
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR objectTemplate,
|
||||
CK_ULONG otsize
|
||||
)
|
||||
{
|
||||
nssSession *session = NULL;
|
||||
PRBool createdSession = PR_FALSE;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_RV ckrv;
|
||||
|
||||
if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
|
||||
if (sessionOpt) {
|
||||
if (!nssSession_IsReadWrite(sessionOpt)) {
|
||||
return CK_INVALID_HANDLE;
|
||||
} else {
|
||||
session = sessionOpt;
|
||||
}
|
||||
} else if (nssSession_IsReadWrite(tok->defaultSession)) {
|
||||
session = tok->defaultSession;
|
||||
} else {
|
||||
session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
|
||||
createdSession = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (session == NULL) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok->slot)->C_CreateObject(session->handle,
|
||||
objectTemplate, otsize,
|
||||
&object);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (createdSession) {
|
||||
nssSession_Destroy(session);
|
||||
}
|
||||
if (ckrv != CKR_OK) {
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT CK_OBJECT_HANDLE
|
||||
nssToken_FindObjectByTemplate
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
)
|
||||
{
|
||||
CK_SESSION_HANDLE hSession;
|
||||
CK_OBJECT_HANDLE rvObject;
|
||||
CK_ULONG count;
|
||||
CK_RV ckrv;
|
||||
CK_ULONG digestLen;
|
||||
CK_BYTE_PTR digest;
|
||||
NSSItem *rvItem = NULL;
|
||||
nssSession *session;
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
hSession = session->handle;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
|
||||
ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return CK_INVALID_HANDLE;
|
||||
return NULL;
|
||||
}
|
||||
ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
|
||||
#if 0
|
||||
/* XXX the standard says this should work, but it doesn't */
|
||||
ckrv = CKAPI(tok)->C_Digest(session->handle, NULL, 0, NULL, &digestLen);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return CK_INVALID_HANDLE;
|
||||
return NULL;
|
||||
}
|
||||
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (ckrv != CKR_OK) {
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
return rvObject;
|
||||
}
|
||||
|
||||
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
|
||||
|
||||
struct collect_arg_str
|
||||
{
|
||||
NSSArena *arena;
|
||||
nssList *list;
|
||||
PRUint32 maximum;
|
||||
};
|
||||
|
||||
static PRStatus
|
||||
collect_certs_callback(NSSToken *t, nssSession *session,
|
||||
CK_OBJECT_HANDLE h, void *arg)
|
||||
{
|
||||
NSSCertificate *cert;
|
||||
struct collect_arg_str *ca = (struct collect_arg_str *)arg;
|
||||
cert = nssCertificate_CreateFromHandle(ca->arena, h, session, t->slot);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
/* addref */
|
||||
nssList_Add(ca->list, (void *)cert);
|
||||
if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) {
|
||||
/* signal the end of collection) */
|
||||
nss_SetError(NSS_ERROR_MAXIMUM_FOUND);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
struct cert_callback_str {
|
||||
nssListIterator *cachedCerts;
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static PRStatus
|
||||
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
|
||||
{
|
||||
NSSCertificate *cert = NULL;
|
||||
NSSCertificate *c;
|
||||
struct cert_callback_str *ccb = (struct cert_callback_str *)arg;
|
||||
if (ccb->cachedCerts) {
|
||||
for (c = (NSSCertificate *)nssListIterator_Start(ccb->cachedCerts);
|
||||
c != (NSSCertificate *)NULL;
|
||||
c = (NSSCertificate *)nssListIterator_Next(ccb->cachedCerts))
|
||||
{
|
||||
if (c->handle == h && c->token == t) {
|
||||
/* this is enough, right? */
|
||||
cert = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(ccb->cachedCerts);
|
||||
}
|
||||
if (!cert) {
|
||||
/* Could not find cert, so create it */
|
||||
cert = nssCertificate_CreateFromHandle(NULL, h, session, t->slot);
|
||||
if (!cert) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
/* Got the cert, feed it to the callback */
|
||||
return (*ccb->callback)(cert, ccb->arg);
|
||||
loser:
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
#define OBJECT_STACK_SIZE 16
|
||||
|
||||
static PRStatus
|
||||
nsstoken_TraverseObjects
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *session,
|
||||
CK_ATTRIBUTE_PTR obj_template,
|
||||
CK_ULONG otsize,
|
||||
PRStatus (*callback)(NSSToken *t, nssSession *session,
|
||||
CK_OBJECT_HANDLE h, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
NSSSlot *slot;
|
||||
PRStatus cbrv;
|
||||
PRUint32 i;
|
||||
CK_RV ckrv;
|
||||
CK_ULONG count;
|
||||
CK_OBJECT_HANDLE *objectStack;
|
||||
CK_OBJECT_HANDLE startOS[OBJECT_STACK_SIZE];
|
||||
CK_SESSION_HANDLE hSession;
|
||||
NSSArena *objectArena = NULL;
|
||||
nssList *objectList = NULL;
|
||||
slot = tok->slot;
|
||||
hSession = session->handle;
|
||||
objectStack = startOS;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(slot)->C_FindObjectsInit(hSession, obj_template, otsize);
|
||||
if (ckrv != CKR_OK) {
|
||||
nssSession_ExitMonitor(session);
|
||||
goto loser;
|
||||
}
|
||||
while (PR_TRUE) {
|
||||
ckrv = CKAPI(slot)->C_FindObjects(hSession, objectStack,
|
||||
OBJECT_STACK_SIZE, &count);
|
||||
if (ckrv != CKR_OK) {
|
||||
#endif
|
||||
digestLen = 0; /* XXX for now */
|
||||
digest = NULL;
|
||||
if (rvOpt) {
|
||||
if (rvOpt->size > 0 && rvOpt->size < digestLen) {
|
||||
nssSession_ExitMonitor(session);
|
||||
goto loser;
|
||||
/* the error should be bad args */
|
||||
return NULL;
|
||||
}
|
||||
if (count == OBJECT_STACK_SIZE) {
|
||||
if (!objectList) {
|
||||
objectArena = NSSArena_Create();
|
||||
objectList = nssList_Create(objectArena, PR_FALSE);
|
||||
}
|
||||
objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
|
||||
OBJECT_STACK_SIZE);
|
||||
nssList_Add(objectList, objectStack);
|
||||
} else {
|
||||
break;
|
||||
if (rvOpt->data) {
|
||||
digest = rvOpt->data;
|
||||
}
|
||||
digestLen = rvOpt->size;
|
||||
}
|
||||
if (!digest) {
|
||||
digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
|
||||
if (!digest) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
|
||||
ckrv = CKAPI(tok)->C_Digest(session->handle,
|
||||
(CK_BYTE_PTR)data->data,
|
||||
(CK_ULONG)data->size,
|
||||
(CK_BYTE_PTR)digest,
|
||||
&digestLen);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (ckrv != CKR_OK) {
|
||||
goto loser;
|
||||
nss_ZFreeIf(digest);
|
||||
return NULL;
|
||||
}
|
||||
if (objectList) {
|
||||
nssListIterator *objects;
|
||||
objects = nssList_CreateIterator(objectList);
|
||||
for (objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Start(objects);
|
||||
objectStack != NULL;
|
||||
objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Next(objects)) {
|
||||
for (i=0; i<count; i++) {
|
||||
cbrv = (*callback)(tok, session, objectStack[i], arg);
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(objects);
|
||||
count = OBJECT_STACK_SIZE;
|
||||
if (!rvOpt) {
|
||||
rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
|
||||
}
|
||||
for (i=0; i<count; i++) {
|
||||
cbrv = (*callback)(tok, session, startOS[i], arg);
|
||||
}
|
||||
if (objectArena)
|
||||
NSSArena_Destroy(objectArena);
|
||||
return PR_SUCCESS;
|
||||
loser:
|
||||
if (objectArena)
|
||||
NSSArena_Destroy(objectArena);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_TraverseCertificates
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
/* this is really traversal - the template is all certs */
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, sessionOpt, NULL,
|
||||
cert_template, ctsize,
|
||||
callback, arg);
|
||||
return nssrv;
|
||||
return rvItem;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_TraverseCertificatesByTemplate
|
||||
nssToken_BeginDigest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
nssList *cachedList,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
NSSAlgorithmAndParameters *ap
|
||||
)
|
||||
{
|
||||
PRStatus rv;
|
||||
CK_RV ckrv;
|
||||
nssSession *session;
|
||||
struct cert_callback_str ccb;
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
/* this isn't really traversal, it's find by template ... */
|
||||
if (cachedList) {
|
||||
ccb.cachedCerts = nssList_CreateIterator(cachedList);
|
||||
} else {
|
||||
ccb.cachedCerts = NULL;
|
||||
}
|
||||
ccb.callback = callback;
|
||||
ccb.arg = arg;
|
||||
rv = nsstoken_TraverseObjects(tok, session,
|
||||
cktemplate, ctsize,
|
||||
retrieve_cert, (void *)&ccb);
|
||||
return rv;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok)->C_DigestInit(session->handle, &ap->mechanism);
|
||||
nssSession_ExitMonitor(session);
|
||||
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssToken_ContinueDigest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSItem *item
|
||||
)
|
||||
{
|
||||
CK_RV ckrv;
|
||||
nssSession *session;
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok)->C_DigestUpdate(session->handle,
|
||||
(CK_BYTE_PTR)item->data,
|
||||
(CK_ULONG)item->size);
|
||||
nssSession_ExitMonitor(session);
|
||||
return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
nssToken_FinishDigest
|
||||
(
|
||||
NSSToken *tok,
|
||||
nssSession *sessionOpt,
|
||||
NSSItem *rvOpt,
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
CK_RV ckrv;
|
||||
CK_ULONG digestLen;
|
||||
CK_BYTE_PTR digest;
|
||||
NSSItem *rvItem = NULL;
|
||||
nssSession *session;
|
||||
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
|
||||
nssSession_EnterMonitor(session);
|
||||
ckrv = CKAPI(tok)->C_DigestFinal(session->handle, NULL, &digestLen);
|
||||
if (ckrv != CKR_OK || digestLen == 0) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return NULL;
|
||||
}
|
||||
digest = NULL;
|
||||
if (rvOpt) {
|
||||
if (rvOpt->size > 0 && rvOpt->size < digestLen) {
|
||||
nssSession_ExitMonitor(session);
|
||||
/* the error should be bad args */
|
||||
return NULL;
|
||||
}
|
||||
if (rvOpt->data) {
|
||||
digest = rvOpt->data;
|
||||
}
|
||||
digestLen = rvOpt->size;
|
||||
}
|
||||
if (!digest) {
|
||||
digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
|
||||
if (!digest) {
|
||||
nssSession_ExitMonitor(session);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ckrv = CKAPI(tok)->C_DigestFinal(session->handle, digest, &digestLen);
|
||||
nssSession_ExitMonitor(session);
|
||||
if (ckrv != CKR_OK) {
|
||||
nss_ZFreeIf(digest);
|
||||
return NULL;
|
||||
}
|
||||
if (!rvOpt) {
|
||||
rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
|
||||
}
|
||||
return rvItem;
|
||||
}
|
||||
|
||||
/* XXX of course this doesn't belong here */
|
||||
NSS_IMPLEMENT NSSAlgorithmAndParameters *
|
||||
NSSAlgorithmAndParameters_CreateSHA1Digest
|
||||
(
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
NSSAlgorithmAndParameters *rvAP = NULL;
|
||||
rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
|
||||
if (rvAP) {
|
||||
rvAP->mechanism.mechanism = CKM_SHA_1;
|
||||
rvAP->mechanism.pParameter = NULL;
|
||||
rvAP->mechanism.ulParameterLen = 0;
|
||||
}
|
||||
return rvAP;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSAlgorithmAndParameters *
|
||||
NSSAlgorithmAndParameters_CreateMD5Digest
|
||||
(
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
NSSAlgorithmAndParameters *rvAP = NULL;
|
||||
rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
|
||||
if (rvAP) {
|
||||
rvAP->mechanism.mechanism = CKM_MD5;
|
||||
rvAP->mechanism.pParameter = NULL;
|
||||
rvAP->mechanism.ulParameterLen = 0;
|
||||
}
|
||||
return rvAP;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.3 $ $Date: 2001-11-08 00:14:53 $ $Name: $"
|
||||
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.4 $ $Date: 2001-11-28 16:23:39 $ $Name: $"
|
||||
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
|
@ -48,9 +48,10 @@ MODULE = security
|
|||
|
||||
CSRCS = \
|
||||
devmod.c \
|
||||
devslot.c \
|
||||
devtoken.c \
|
||||
devutil.c \
|
||||
devslot.c \
|
||||
devobject.c \
|
||||
devtoken.c \
|
||||
devutil.c \
|
||||
ckhelper.c \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define NSSDEVT_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char NSSDEVT_CVS_ID[] = "@(#) $RCSfile: nssdevt.h,v $ $Revision: 1.2 $ $Date: 2001-11-08 00:14:54 $ $Name: $";
|
||||
static const char NSSDEVT_CVS_ID[] = "@(#) $RCSfile: nssdevt.h,v $ $Revision: 1.3 $ $Date: 2001-11-28 16:23:39 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -64,8 +64,6 @@ typedef struct NSSSlotStr NSSSlot;
|
|||
|
||||
typedef struct NSSTokenStr NSSToken;
|
||||
|
||||
typedef struct nssSessionStr nssSession;
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* NSSDEVT_H */
|
||||
|
|
|
@ -58,8 +58,9 @@
|
|||
#include "pki3hack.h"
|
||||
#include "dev3hack.h"
|
||||
|
||||
/*#include "dev.h" */
|
||||
#include "dev.h"
|
||||
#include "nsspki.h"
|
||||
#include "pkim.h"
|
||||
#include "pkitm.h"
|
||||
|
||||
#define PK11_SEARCH_CHUNKSIZE 10
|
||||
|
@ -1135,6 +1136,23 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
|
|||
return objID;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
get_newest_cert(NSSCertificate *c, void *arg)
|
||||
{
|
||||
nssDecodedCert *dc, *founddc;
|
||||
NSSCertificate **cfound = (NSSCertificate **)arg;
|
||||
if (!*cfound) {
|
||||
*cfound = c;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
dc = nssCertificate_GetDecoding(c);
|
||||
founddc = nssCertificate_GetDecoding(*cfound);
|
||||
if (!founddc->isNewerThan(founddc, dc)) {
|
||||
*cfound = c;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
CERTCertificate *
|
||||
PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
||||
|
@ -1167,19 +1185,34 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
|||
/* find token by name */
|
||||
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
|
||||
if (token) {
|
||||
nssTokenCertSearch search;
|
||||
nssList *certList;
|
||||
certList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
|
||||
nickname,
|
||||
certList);
|
||||
/* set the search criteria */
|
||||
search.callback = get_newest_cert;
|
||||
search.cbarg = (void *)&cert;
|
||||
search.cached = certList;
|
||||
search.trustDomain = defaultTD;
|
||||
search.cryptoContext = NULL;
|
||||
/* find best cert on token */
|
||||
cert = nssTrustDomain_FindBestCertificateByNicknameForToken(
|
||||
defaultTD,
|
||||
token,
|
||||
(NSSUTF8 *)nickname,
|
||||
NULL,
|
||||
&usage,
|
||||
NULL);
|
||||
nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
(NSSUTF8 *)nickname,
|
||||
&search);
|
||||
nssList_Destroy(certList);
|
||||
if (!cert) {
|
||||
/* don't have a "for token" here yet... */
|
||||
cert = NSSTrustDomain_FindCertificateByEmail(defaultTD,
|
||||
(NSSASCII7 *)nickname,
|
||||
NULL, &usage, NULL);
|
||||
certList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(
|
||||
defaultTD,
|
||||
nickname,
|
||||
certList);
|
||||
search.cached = certList;
|
||||
nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
(NSSASCII7 *)nickname,
|
||||
&search);
|
||||
nssList_Destroy(certList);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1206,6 +1239,15 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
collect_certs(NSSCertificate *c, void *arg)
|
||||
{
|
||||
nssList *list = (nssList *)arg;
|
||||
/* Add the cert to the return list */
|
||||
nssList_AddUnique(list, (void *)c);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
CERTCertList *
|
||||
PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
||||
#ifdef NSS_CLASSIC
|
||||
|
@ -1233,11 +1275,13 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
|||
PORT_Free(certID);
|
||||
return certList;
|
||||
#else
|
||||
PRStatus nssrv;
|
||||
char *delimit = NULL;
|
||||
char *tokenName;
|
||||
CERTCertList *certList = CERT_NewCertList();
|
||||
int i;
|
||||
CERTCertList *certList = NULL;
|
||||
NSSCertificate **foundCerts;
|
||||
NSSCertificate **pCerts;
|
||||
NSSCertificate *c;
|
||||
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
|
||||
if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
|
||||
NSSToken *token;
|
||||
|
@ -1247,14 +1291,25 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
|||
/* find token by name */
|
||||
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
|
||||
if (token) {
|
||||
/* find best cert on token */
|
||||
foundCerts = nssTrustDomain_FindCertificatesByNicknameForToken(
|
||||
defaultTD,
|
||||
token,
|
||||
(NSSUTF8 *)nickname,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
nssTokenCertSearch search;
|
||||
PRUint32 count;
|
||||
nssList *nameList;
|
||||
nameList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
|
||||
nickname,
|
||||
nameList);
|
||||
/* set the search criteria */
|
||||
search.callback = collect_certs;
|
||||
search.cbarg = nameList;
|
||||
search.cached = nameList;
|
||||
search.trustDomain = defaultTD;
|
||||
search.cryptoContext = NULL;
|
||||
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
nickname, &search);
|
||||
count = nssList_Count(nameList);
|
||||
foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
|
||||
nssList_GetArray(nameList, (void **)foundCerts, count);
|
||||
nssList_Destroy(nameList);
|
||||
}
|
||||
*delimit = ':';
|
||||
} else {
|
||||
|
@ -1265,17 +1320,17 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
|
|||
0,
|
||||
NULL);
|
||||
}
|
||||
pCerts = foundCerts;
|
||||
while (pCerts != NULL) {
|
||||
NSSCertificate *c = *pCerts;
|
||||
CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
|
||||
pCerts++;
|
||||
if (foundCerts) {
|
||||
certList = CERT_NewCertList();
|
||||
for (i=0, c = *foundCerts; c; c = foundCerts[++i]) {
|
||||
CERT_AddCertToListTail(certList, STAN_GetCERTCertificate(c));
|
||||
}
|
||||
if (CERT_LIST_HEAD(certList) == NULL) {
|
||||
CERT_DestroyCertList(certList);
|
||||
certList = NULL;
|
||||
}
|
||||
nss_ZFreeIf(foundCerts);
|
||||
}
|
||||
if (CERT_LIST_HEAD(certList) == NULL) {
|
||||
CERT_DestroyCertList(certList);
|
||||
certList = NULL;
|
||||
}
|
||||
nss_ZFreeIf(foundCerts);
|
||||
return certList;
|
||||
#endif
|
||||
}
|
||||
|
@ -1482,10 +1537,22 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
|||
PORT_SetError( PK11_MapError(crv) );
|
||||
}
|
||||
|
||||
if (!cert->nickname && nickname) {
|
||||
cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
|
||||
}
|
||||
|
||||
cert->pkcs11ID = certID;
|
||||
cert->dbhandle = STAN_GetDefaultTrustDomain();
|
||||
if (cert->slot == NULL) {
|
||||
cert->slot = PK11_ReferenceSlot(slot);
|
||||
if (cert->nssCertificate) {
|
||||
cert->nssCertificate->token = slot->nssToken;
|
||||
nssPKIObjectInstance *instance;
|
||||
NSSCertificate *c = cert->nssCertificate;
|
||||
instance = nss_ZNEW(c->object.arena, nssPKIObjectInstance);
|
||||
instance->cryptoki.token = slot->nssToken;
|
||||
instance->cryptoki.handle = cert->pkcs11ID;
|
||||
instance->trustDomain = cert->dbhandle;
|
||||
nssList_Add(c->object.instanceList, instance);
|
||||
} else {
|
||||
cert->nssCertificate = STAN_GetNSSCertificate(cert);
|
||||
}
|
||||
|
@ -2262,31 +2329,29 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
|
|||
|
||||
return PK11_TraverseSlot(slot, &callarg);
|
||||
#else
|
||||
/* Alas, stan isn't really made for this... perhaps collect all matching
|
||||
* subject certs on the token and then pass the certs to the callback?
|
||||
*/
|
||||
struct nss3_cert_cbstr pk11cb;
|
||||
PRStatus nssrv;
|
||||
NSSToken *tok;
|
||||
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
|
||||
CK_ATTRIBUTE theTemplate[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
};
|
||||
CK_ATTRIBUTE *attr = theTemplate;
|
||||
CK_ULONG templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
|
||||
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
|
||||
PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
|
||||
NSSToken *token;
|
||||
NSSDER subject;
|
||||
NSSTrustDomain *td;
|
||||
nssList *subjectList;
|
||||
nssTokenCertSearch search;
|
||||
pk11cb.callback = callback;
|
||||
pk11cb.arg = arg;
|
||||
tok = PK11Slot_GetNSSToken(slot);
|
||||
if (tok) {
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, NULL,
|
||||
theTemplate, templateSize,
|
||||
convert_cert, &pk11cb);
|
||||
} else {
|
||||
return SECFailure;
|
||||
}
|
||||
td = STAN_GetDefaultTrustDomain();
|
||||
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
|
||||
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, subjectList);
|
||||
/* set the search criteria */
|
||||
search.callback = convert_cert;
|
||||
search.cbarg = &pk11cb;
|
||||
search.cached = subjectList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
token = PK11Slot_GetNSSToken(slot);
|
||||
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
|
||||
&subject, &search);
|
||||
nssList_Destroy(subjectList);
|
||||
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
@ -2328,31 +2393,37 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
|
|||
|
||||
return PK11_TraverseSlot(slot, &callarg);
|
||||
#else
|
||||
/* Alas, stan isn't really made for this... perhaps collect all matching
|
||||
* subject certs on the token and then pass the certs to the callback?
|
||||
*/
|
||||
struct nss3_cert_cbstr pk11cb;
|
||||
PRStatus nssrv;
|
||||
NSSToken *tok;
|
||||
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
|
||||
CK_ATTRIBUTE theTemplate[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 },
|
||||
};
|
||||
CK_ATTRIBUTE *attr = theTemplate;
|
||||
CK_ULONG templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
|
||||
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
|
||||
PK11_SETATTRS(attr,CKA_LABEL,nickname->data,nickname->len);
|
||||
NSSToken *token;
|
||||
NSSTrustDomain *td;
|
||||
NSSUTF8 *nick;
|
||||
PRBool created = PR_FALSE;
|
||||
nssTokenCertSearch search;
|
||||
nssList *nameList;
|
||||
pk11cb.callback = callback;
|
||||
pk11cb.arg = arg;
|
||||
tok = PK11Slot_GetNSSToken(slot);
|
||||
if (tok) {
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, NULL,
|
||||
theTemplate, templateSize,
|
||||
convert_cert, &pk11cb);
|
||||
if (nickname->data[nickname->len-1] != '\0') {
|
||||
nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
|
||||
nickname->data, nickname->len-1);
|
||||
created = PR_TRUE;
|
||||
} else {
|
||||
return SECFailure;
|
||||
nick = (NSSUTF8 *)nickname->data;
|
||||
}
|
||||
td = STAN_GetDefaultTrustDomain();
|
||||
nameList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
|
||||
/* set the search criteria */
|
||||
search.callback = convert_cert;
|
||||
search.cbarg = &pk11cb;
|
||||
search.cached = nameList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
token = PK11Slot_GetNSSToken(slot);
|
||||
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
nick, &search);
|
||||
nssList_Destroy(nameList);
|
||||
if (created) nss_ZFreeIf(nick);
|
||||
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
@ -2387,17 +2458,29 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
|
|||
callarg.templateCount = templateSize;
|
||||
return PK11_TraverseSlot(slot, &callarg);
|
||||
#else
|
||||
PRStatus nssrv;
|
||||
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
|
||||
struct nss3_cert_cbstr pk11cb;
|
||||
NSSToken *tok;
|
||||
nssList *certList = nssList_Create(NULL, PR_FALSE);
|
||||
nssTokenCertSearch search;
|
||||
pk11cb.callback = callback;
|
||||
pk11cb.arg = arg;
|
||||
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
|
||||
/* set the search criteria */
|
||||
search.callback = convert_cert;
|
||||
search.cbarg = &pk11cb;
|
||||
search.cached = certList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
tok = PK11Slot_GetNSSToken(slot);
|
||||
if (tok) {
|
||||
return (SECStatus)nssToken_TraverseCertificates(tok, NULL,
|
||||
convert_cert, &pk11cb);
|
||||
nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
|
||||
} else {
|
||||
return SECFailure;
|
||||
nssrv = PR_FAILURE;
|
||||
}
|
||||
nssList_Destroy(certList);
|
||||
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2441,12 +2524,11 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
|||
CERTCertificate *rvCert = NULL;
|
||||
NSSCertificate *c;
|
||||
NSSDER derCert;
|
||||
derCert.data = (void *)cert->derCert.data;
|
||||
derCert.size = (PRUint32)cert->derCert.len;
|
||||
NSSToken *tok;
|
||||
tok = PK11Slot_GetNSSToken(slot);
|
||||
NSSITEM_FROM_SECITEM(&derCert, &cert->derCert);
|
||||
/* XXX login to slots */
|
||||
c = NSSTrustDomain_FindCertificateByEncodedCertificate(
|
||||
STAN_GetDefaultTrustDomain(),
|
||||
&derCert);
|
||||
c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert);
|
||||
if (c) {
|
||||
rvCert = STAN_GetCERTCertificate(c);
|
||||
}
|
||||
|
@ -2803,7 +2885,11 @@ isOnList(CERTCertList *certList,CERTCertificate *cert)
|
|||
return PR_FALSE;
|
||||
}
|
||||
static SECStatus
|
||||
#ifdef NSS_CLASSIC
|
||||
pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
||||
#else
|
||||
pk11ListCertCallback(CERTCertificate *cert, void *arg)
|
||||
#endif
|
||||
{
|
||||
struct listCertsStr *listCertP = (struct listCertsStr *)arg;
|
||||
CERTCertificate *newCert = NULL;
|
||||
|
@ -2821,11 +2907,15 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
|||
if (!isUnique && cert->nickname) {
|
||||
nickname = PORT_ArenaStrdup(listCertP->certList->arena,cert->nickname);
|
||||
}
|
||||
#ifdef NSS_CLASSIC
|
||||
if (derCert == NULL) {
|
||||
newCert=CERT_DupCertificate(cert);
|
||||
} else {
|
||||
newCert=CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),&cert->derCert);
|
||||
}
|
||||
#else
|
||||
newCert=CERT_DupCertificate(cert);
|
||||
#endif
|
||||
|
||||
if (newCert == NULL) return SECSuccess;
|
||||
|
||||
|
@ -2870,13 +2960,6 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
pk11ListCertCallbackStub(CERTCertificate *cert, void *arg)
|
||||
{
|
||||
return pk11ListCertCallback(cert, NULL, arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CERTCertList *
|
||||
PK11_ListCerts(PK11CertListType type, void *pwarg)
|
||||
|
@ -2904,8 +2987,7 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
|
|||
certList = CERT_NewCertList();
|
||||
listCerts.type = type;
|
||||
listCerts.certList = certList;
|
||||
/* XXX need to fix, this callback is of a different form */
|
||||
pk11cb.callback = pk11ListCertCallbackStub;
|
||||
pk11cb.callback = pk11ListCertCallback;
|
||||
pk11cb.arg = &listCerts;
|
||||
NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
|
||||
return certList;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $ $Date: 2001-11-20 18:28:46 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.17 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -51,17 +51,9 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $
|
|||
#include "dev.h"
|
||||
#endif /* DEV_H */
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef CKT_H
|
||||
#ifdef NSS_3_4_CODE
|
||||
#include "pki3hack.h"
|
||||
#define NSSCKT_H
|
||||
#endif
|
||||
#include "ckt.h"
|
||||
#endif /* CKT_H */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
|
@ -69,37 +61,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.16 $
|
|||
|
||||
extern const NSSError NSS_ERROR_NOT_FOUND;
|
||||
|
||||
/* Hm, sadly, I'm using PK11_HashBuf... Need to get crypto context going to
|
||||
* get rid of that
|
||||
*/
|
||||
#ifndef NSS_3_4_CODE
|
||||
#define NSS_3_4_CODE
|
||||
#endif /* NSS_3_4_CODE */
|
||||
#include "pk11func.h"
|
||||
#include "hasht.h"
|
||||
|
||||
/* I assume the following accessors into cert fields will be needed.
|
||||
* We need to be able to return basic cert info, however, these are
|
||||
* really PKCS#11 fields, so maybe not these in particular (mcgreer)
|
||||
*/
|
||||
NSS_IMPLEMENT NSSUTF8 *
|
||||
NSSCertificate_GetLabel
|
||||
(
|
||||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
return c->nickname;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
NSSCertificate_GetID
|
||||
(
|
||||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
return &c->id;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssCertificate_AddRef
|
||||
(
|
||||
|
@ -107,350 +68,29 @@ nssCertificate_AddRef
|
|||
)
|
||||
{
|
||||
#ifdef NSS_3_4_CODE
|
||||
/*
|
||||
CERTCertificate *cc = STAN_GetCERTCertificate(c);
|
||||
CERT_DupCertificate(cc);
|
||||
*/
|
||||
#else
|
||||
c->refCount++;
|
||||
#endif
|
||||
return c;
|
||||
}
|
||||
|
||||
/* NSS needs access to this function, but does anyone else? */
|
||||
/* XXX for the 3.4 hack anyway, yes */
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
NSSCertificate_Create
|
||||
(
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
NSSArena *arena;
|
||||
NSSCertificate *rvCert;
|
||||
arena = (arenaOpt) ? arenaOpt : nssArena_Create();
|
||||
if (!arena) {
|
||||
goto loser;
|
||||
}
|
||||
arena = NSSArena_Create();
|
||||
if(!arena) {
|
||||
return (NSSCertificate *)NULL;
|
||||
}
|
||||
rvCert = nss_ZNEW(arena, NSSCertificate);
|
||||
if (!rvCert) {
|
||||
goto loser;
|
||||
}
|
||||
rvCert->refCount = 1;
|
||||
if (!arenaOpt) {
|
||||
rvCert->arena = arena;
|
||||
}
|
||||
rvCert->handle = CK_INVALID_HANDLE;
|
||||
return rvCert;
|
||||
loser:
|
||||
if (!arenaOpt && arena) {
|
||||
nssArena_Destroy(arena);
|
||||
}
|
||||
return (NSSCertificate *)NULL;
|
||||
}
|
||||
|
||||
static NSSCertificateType
|
||||
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
|
||||
{
|
||||
CK_CERTIFICATE_TYPE ckCertType;
|
||||
ckCertType = *((CK_ULONG *)attrib->pValue);
|
||||
switch (ckCertType) {
|
||||
case CKC_X_509:
|
||||
return NSSCertificateType_PKIX;
|
||||
break;
|
||||
default:
|
||||
return NSSCertificateType_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
static CK_OBJECT_HANDLE
|
||||
get_cert_trust_handle
|
||||
(
|
||||
NSSCertificate *c,
|
||||
nssSession *session
|
||||
)
|
||||
{
|
||||
CK_ULONG tobj_size;
|
||||
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
|
||||
CK_ATTRIBUTE tobj_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_CERT_SHA1_HASH, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 }
|
||||
};
|
||||
unsigned char sha1_hash[SHA1_LENGTH];
|
||||
tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 0, tobjc);
|
||||
/* First, use the SHA-1 hash of the cert to locate the trust object */
|
||||
/* XXX get rid of this PK11_ call! */
|
||||
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, c->encoding.data, c->encoding.size);
|
||||
tobj_template[1].pValue = (CK_VOID_PTR)sha1_hash;
|
||||
tobj_template[1].ulValueLen = (CK_ULONG)SHA1_LENGTH;
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial);
|
||||
#ifdef NSS_3_4_CODE
|
||||
if (PK11_HasRootCerts(c->token->pk11slot)) {
|
||||
tobj_size -= 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* we need to arrange for the built-in token to loose the bottom 2
|
||||
* attributes so that old built-in tokens will continue to work.
|
||||
*/
|
||||
return nssToken_FindObjectByTemplate(c->token, session,
|
||||
tobj_template, tobj_size);
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
nssCertificate_GetCertTrust
|
||||
(
|
||||
NSSCertificate *c,
|
||||
nssSession *session
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
CK_TRUST saTrust, caTrust, epTrust, csTrust;
|
||||
CK_OBJECT_HANDLE tobjID;
|
||||
CK_ULONG trust_size;
|
||||
CK_ATTRIBUTE trust_template[] = {
|
||||
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
|
||||
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
|
||||
};
|
||||
trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
|
||||
tobjID = get_cert_trust_handle(c, session);
|
||||
if (tobjID == CK_INVALID_HANDLE) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
/* Then use the trust object to find the trust settings */
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, saTrust);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, caTrust);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, epTrust);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, csTrust);
|
||||
nssrv = nssCKObject_GetAttributes(tobjID,
|
||||
trust_template, trust_size,
|
||||
NULL, session, c->slot);
|
||||
c->trust.serverAuth = saTrust;
|
||||
c->trust.clientAuth = caTrust;
|
||||
c->trust.emailProtection = epTrust;
|
||||
c->trust.codeSigning = csTrust;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef NSS_3_4_CODE
|
||||
static void make_nss3_nickname(NSSCertificate *c)
|
||||
{
|
||||
/* In NSS 3.4, the semantic is that nickname = token name + label */
|
||||
PRStatus utf8rv;
|
||||
NSSUTF8 *tokenName;
|
||||
NSSUTF8 *label;
|
||||
char *fullname;
|
||||
PRUint32 len, tlen;
|
||||
tokenName = nssToken_GetName(c->token);
|
||||
label = c->nickname ? c->nickname : c->email;
|
||||
if (!label) return;
|
||||
tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */
|
||||
tlen += 1; /* : */
|
||||
len = nssUTF8_Length(label, &utf8rv); /* label */
|
||||
len += 1; /* \0 */
|
||||
len += tlen;
|
||||
fullname = nss_ZAlloc(c->arena, len);
|
||||
utf8rv = nssUTF8_CopyIntoFixedBuffer(tokenName, fullname, tlen, ':');
|
||||
utf8rv = nssUTF8_CopyIntoFixedBuffer(label, fullname + tlen,
|
||||
len - tlen, '\0');
|
||||
nss_ZFreeIf(c->nickname);
|
||||
c->nickname = nssUTF8_Create(c->arena,
|
||||
nssStringType_UTF8String,
|
||||
fullname, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a certificate from an object handle. */
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssCertificate_CreateFromHandle
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_OBJECT_HANDLE object,
|
||||
nssSession *session,
|
||||
NSSSlot *slot
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert;
|
||||
PRStatus nssrv;
|
||||
CK_ULONG template_size;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CERTIFICATE_TYPE, NULL, 0 },
|
||||
{ CKA_ID, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 },
|
||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
|
||||
};
|
||||
template_size = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
rvCert = NSSCertificate_Create(arenaOpt);
|
||||
if (!rvCert) {
|
||||
return (NSSCertificate *)NULL;
|
||||
}
|
||||
rvCert->handle = object;
|
||||
/* clean this up */
|
||||
rvCert->slot = slot;
|
||||
rvCert->token = slot->token;
|
||||
rvCert->trustDomain = slot->token->trustDomain;
|
||||
nssrv = nssCKObject_GetAttributes(object, cert_template, template_size,
|
||||
rvCert->arena, session, slot);
|
||||
if (nssrv) {
|
||||
/* okay, but if failed because one of the attributes could not be
|
||||
* found, do it gracefully (i.e., catch the error).
|
||||
*/
|
||||
goto loser;
|
||||
}
|
||||
rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->id);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding);
|
||||
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[3], rvCert->nickname);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->issuer);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject);
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->serial);
|
||||
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email);
|
||||
nssCertificate_GetCertTrust(rvCert, session);
|
||||
#ifdef NSS_3_4_CODE
|
||||
/* nss 3.4 database doesn't associate email address with cert */
|
||||
if (!rvCert->email) {
|
||||
nssDecodedCert *dc;
|
||||
NSSASCII7 *email;
|
||||
dc = nssCertificate_GetDecoding(rvCert);
|
||||
email = dc->getEmailAddress(dc);
|
||||
if (email) rvCert->email = nssUTF8_Duplicate(email, rvCert->arena);
|
||||
}
|
||||
make_nss3_nickname(rvCert);
|
||||
#endif
|
||||
return rvCert;
|
||||
loser:
|
||||
NSSCertificate_Destroy(rvCert);
|
||||
return (NSSCertificate *)NULL;
|
||||
}
|
||||
|
||||
static CK_OBJECT_HANDLE
|
||||
create_cert_trust_object
|
||||
(
|
||||
NSSCertificate *c,
|
||||
NSSTrust *trust
|
||||
)
|
||||
{
|
||||
CK_ULONG tobj_size;
|
||||
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
|
||||
CK_ATTRIBUTE tobj_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_TOKEN, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 },
|
||||
{ CKA_CERT_SHA1_HASH, NULL, 0 },
|
||||
{ CKA_CERT_MD5_HASH, NULL, 0 },
|
||||
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
|
||||
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
|
||||
};
|
||||
unsigned char sha1_hash[SHA1_LENGTH];
|
||||
unsigned char md5_hash[MD5_LENGTH];
|
||||
tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR( tobj_template, 0, tobjc);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 1, &g_ck_true);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial);
|
||||
/* First, use the SHA-1 hash of the cert to locate the trust object */
|
||||
/* XXX get rid of this PK11_ call! */
|
||||
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, c->encoding.data, c->encoding.size);
|
||||
tobj_template[4].pValue = (CK_VOID_PTR)sha1_hash;
|
||||
tobj_template[4].ulValueLen = (CK_ULONG)SHA1_LENGTH;
|
||||
PK11_HashBuf(SEC_OID_MD5, md5_hash, c->encoding.data, c->encoding.size);
|
||||
tobj_template[5].pValue = (CK_VOID_PTR)md5_hash;
|
||||
tobj_template[5].ulValueLen = (CK_ULONG)MD5_LENGTH;
|
||||
/* now set the trust values */
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 6, trust->serverAuth);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 7, trust->clientAuth);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 8, trust->emailProtection);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(tobj_template, 9, trust->codeSigning);
|
||||
return nssToken_ImportObject(c->token, NULL, tobj_template, tobj_size);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssCertificate_SetCertTrust
|
||||
(
|
||||
NSSCertificate *c,
|
||||
NSSTrust *trust
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
nssSession *session;
|
||||
PRBool createdSession;
|
||||
CK_OBJECT_HANDLE tobjID;
|
||||
CK_ULONG trust_size;
|
||||
CK_ATTRIBUTE trust_template[] = {
|
||||
{ CKA_TRUST_SERVER_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_CLIENT_AUTH, NULL, 0 },
|
||||
{ CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
|
||||
{ CKA_TRUST_CODE_SIGNING, NULL, 0 }
|
||||
};
|
||||
trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
|
||||
if (!c->token) {
|
||||
/* must live on a token already */
|
||||
return PR_FAILURE;
|
||||
}
|
||||
session = c->token->defaultSession;
|
||||
tobjID = get_cert_trust_handle(c, session);
|
||||
if (tobjID == CK_INVALID_HANDLE) {
|
||||
/* trust object doesn't exist yet, create one */
|
||||
tobjID = create_cert_trust_object(c, trust);
|
||||
if (tobjID == CK_INVALID_HANDLE) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
c->trust.serverAuth = trust->serverAuth;
|
||||
c->trust.clientAuth = trust->clientAuth;
|
||||
c->trust.emailProtection = trust->emailProtection;
|
||||
c->trust.codeSigning = trust->codeSigning;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, trust->serverAuth);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, trust->clientAuth);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, trust->emailProtection);
|
||||
NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, trust->codeSigning);
|
||||
/* changing cert trust requires rw session XXX session objects */
|
||||
createdSession = PR_FALSE;
|
||||
if (!nssSession_IsReadWrite(session)) {
|
||||
createdSession = PR_TRUE;
|
||||
session = nssSlot_CreateSession(c->slot, NULL, PR_TRUE);
|
||||
}
|
||||
nssrv = nssCKObject_SetAttributes(tobjID,
|
||||
trust_template, trust_size,
|
||||
session, c->slot);
|
||||
if (createdSession) {
|
||||
nssSession_Destroy(session);
|
||||
}
|
||||
if (nssrv == PR_FAILURE) {
|
||||
return nssrv;
|
||||
}
|
||||
c->trust.serverAuth = trust->serverAuth;
|
||||
c->trust.clientAuth = trust->clientAuth;
|
||||
c->trust.emailProtection = trust->emailProtection;
|
||||
c->trust.codeSigning = trust->codeSigning;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
NSSCertificate_Destroy
|
||||
(
|
||||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
#ifdef NSS_3_4_CODE
|
||||
return NSSArena_Destroy(c->object.arena);
|
||||
#else
|
||||
if (--c->refCount == 0) {
|
||||
return NSSArena_Destroy(c->arena);
|
||||
}
|
||||
#endif
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -461,13 +101,24 @@ NSSCertificate_DeleteStoredObject
|
|||
NSSCallback *uhh
|
||||
)
|
||||
{
|
||||
/* delete it from storage, but leave it in memory */
|
||||
/* according to PKCS#11 2.11 section 13.2, the token must know how
|
||||
* to handle deletion when there are multiple threads attempting to use
|
||||
* the same object.
|
||||
/* this needs more thought on what will happen when there are multiple
|
||||
* instances
|
||||
*/
|
||||
/* XXX use callback to log in if neccessary */
|
||||
return nssToken_DeleteStoredObject(c->token, NULL, c->handle);
|
||||
PRStatus nssrv = PR_SUCCESS;
|
||||
nssPKIObjectInstance *instance;
|
||||
nssListIterator *instances = c->object.instances;
|
||||
for (instance = (nssPKIObjectInstance *)nssListIterator_Start(instances);
|
||||
instance != (nssPKIObjectInstance *)NULL;
|
||||
instance = (nssPKIObjectInstance *)nssListIterator_Next(instances))
|
||||
{
|
||||
nssrv = nssToken_DeleteStoredObject(&instance->cryptoki);
|
||||
if (nssrv != PR_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(instances);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -538,10 +189,6 @@ nssCertificate_GetDecoding
|
|||
if (!c->decoding) {
|
||||
c->decoding = nssDecodedCert_Create(NULL, &c->encoding, c->type);
|
||||
}
|
||||
#ifdef NSS_3_4_CODE
|
||||
/* cause the trust bits to get updated in the encoded cert */
|
||||
(void) STAN_GetCERTCertificate(c);
|
||||
#endif
|
||||
return c->decoding;
|
||||
}
|
||||
|
||||
|
@ -550,8 +197,10 @@ find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
|
|||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
NSSCertificate **subjectCerts;
|
||||
NSSTrustDomain *td;
|
||||
td = NSSCertificate_GetTrustDomain(c);
|
||||
/* Find all certs with this cert's issuer as the subject */
|
||||
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(c->trustDomain,
|
||||
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td,
|
||||
&c->issuer,
|
||||
NULL,
|
||||
0,
|
||||
|
@ -599,7 +248,17 @@ NSSCertificate_BuildChain
|
|||
nssList *chain;
|
||||
NSSItem *issuerID;
|
||||
NSSCertificate **rvChain;
|
||||
NSSTrustDomain *td;
|
||||
nssDecodedCert *dc;
|
||||
td = NSSCertificate_GetTrustDomain(c);
|
||||
#ifdef NSS_3_4_CODE
|
||||
/* This goes down as a 3.4 hack. This function will need to be able to
|
||||
* search both crypto contexts and trust domains for the chain.
|
||||
*/
|
||||
if (!td) {
|
||||
td = STAN_GetDefaultTrustDomain();
|
||||
}
|
||||
#endif
|
||||
chain = nssList_Create(NULL, PR_FALSE);
|
||||
nssList_Add(chain, c);
|
||||
if (statusOpt) *statusOpt = PR_SUCCESS;
|
||||
|
@ -620,7 +279,7 @@ NSSCertificate_BuildChain
|
|||
PRBool tmpca = usage->nss3lookingForCA;
|
||||
usage->nss3lookingForCA = PR_TRUE;
|
||||
#endif
|
||||
c = NSSTrustDomain_FindBestCertificateBySubject(c->trustDomain,
|
||||
c = NSSTrustDomain_FindBestCertificateBySubject(td,
|
||||
&c->issuer,
|
||||
timeOpt,
|
||||
usage,
|
||||
|
@ -641,8 +300,8 @@ finish:
|
|||
if (rvOpt) {
|
||||
rvChain = rvOpt;
|
||||
} else {
|
||||
rvChain = nss_ZNEWARRAY(arenaOpt,
|
||||
NSSCertificate *, nssList_Count(chain) + 1);
|
||||
rvLimit = nssList_Count(chain);
|
||||
rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1);
|
||||
}
|
||||
nssList_GetArray(chain, (void **)rvChain, rvLimit);
|
||||
nssList_Destroy(chain);
|
||||
|
@ -656,12 +315,15 @@ NSSCertificate_GetTrustDomain
|
|||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
if (c->trustDomain) {
|
||||
return nssTrustDomain_AddRef(c->trustDomain);
|
||||
PRStatus nssrv = PR_SUCCESS;
|
||||
nssPKIObjectInstance *instance;
|
||||
nssList *instances = c->object.instanceList;
|
||||
nssrv = nssList_GetArray(instances, (void **)&instance, 1);
|
||||
if (nssrv == PR_SUCCESS) {
|
||||
return instance->trustDomain;
|
||||
} else {
|
||||
return (NSSTrustDomain *)NULL;
|
||||
}
|
||||
#endif
|
||||
return (NSSTrustDomain *)NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSToken *
|
||||
|
@ -671,9 +333,6 @@ NSSCertificate_GetToken
|
|||
PRStatus *statusOpt
|
||||
)
|
||||
{
|
||||
if (c->token) {
|
||||
return nssToken_AddRef(c->token);
|
||||
}
|
||||
return (NSSToken *)NULL;
|
||||
}
|
||||
|
||||
|
@ -684,11 +343,6 @@ NSSCertificate_GetSlot
|
|||
PRStatus *statusOpt
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
if (c->token) {
|
||||
return nssToken_GetSlot(c->token);
|
||||
}
|
||||
#endif
|
||||
return (NSSSlot *)NULL;
|
||||
}
|
||||
|
||||
|
@ -699,11 +353,6 @@ NSSCertificate_GetModule
|
|||
PRStatus *statusOpt
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
if (c->token) {
|
||||
return nssToken_GetModule(c->token);
|
||||
}
|
||||
#endif
|
||||
return (NSSModule *)NULL;
|
||||
}
|
||||
|
||||
|
@ -799,15 +448,14 @@ NSSCertificate_GetPublicKey
|
|||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
CK_ATTRIBUTE pubktemplate[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_ID, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 }
|
||||
};
|
||||
#if 0
|
||||
PRStatus nssrv;
|
||||
CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
|
||||
#endif
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
|
||||
if (c->id.size > 0) {
|
||||
/* CKA_ID */
|
||||
|
@ -824,7 +472,6 @@ NSSCertificate_GetPublicKey
|
|||
return (NSSPublicKey *)NULL;
|
||||
}
|
||||
/* Try the cert's token first */
|
||||
#if 0
|
||||
if (c->token) {
|
||||
nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
|
||||
}
|
||||
|
|
|
@ -32,13 +32,26 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.4 $ $Date: 2001-10-11 18:41:50 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.5 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
#include "nsspki.h"
|
||||
#endif /* NSSPKI_H */
|
||||
|
||||
#ifndef PKIT_H
|
||||
#include "pkit.h"
|
||||
#endif /* PKIT_H */
|
||||
|
||||
#ifndef DEV_H
|
||||
#include "dev.h"
|
||||
#endif /* DEV_H */
|
||||
|
||||
#ifdef NSS_3_4_CODE
|
||||
#include "pk11func.h"
|
||||
#include "dev3hack.h"
|
||||
#endif
|
||||
|
||||
extern const NSSError NSS_ERROR_NOT_FOUND;
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -91,8 +104,28 @@ NSSCryptoContext_ImportCertificate
|
|||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return PR_FAILURE;
|
||||
NSSToken *token;
|
||||
nssSession *session = NULL;
|
||||
#ifdef NSS_3_4_CODE
|
||||
/* XXX hack alert - what this needs to do is find the preferred
|
||||
* token for cert storage
|
||||
*/
|
||||
if (PR_TRUE) {
|
||||
PK11SlotInfo *slot = PK11_GetInternalSlot();
|
||||
token = PK11Slot_GetNSSToken(slot);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* question - are there multiple available tokens for the crypto context?
|
||||
* in that case, it needs to store a session for each one
|
||||
*/
|
||||
#ifdef nodef
|
||||
session = get_token_session(cc, tok);
|
||||
if (!session) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
return nssToken_ImportCertificate(token, session, c, NULL, cc);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
|
@ -428,10 +461,10 @@ struct token_session_str {
|
|||
nssSession *session;
|
||||
};
|
||||
|
||||
#ifdef nodef
|
||||
static nssSession *
|
||||
get_token_session(NSSCryptoContext *cc, NSSToken *tok)
|
||||
{
|
||||
#if 0
|
||||
struct token_session_str *ts;
|
||||
for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
|
||||
ts != (struct token_session_str *)NULL;
|
||||
|
@ -450,8 +483,8 @@ get_token_session(NSSCryptoContext *cc, NSSToken *tok)
|
|||
nssList_AddElement(cc->sessionList, (void *)ts);
|
||||
}
|
||||
return ts->session;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
NSSCryptoContext_Decrypt
|
||||
|
@ -516,6 +549,7 @@ NSSCryptoContext_Decrypt
|
|||
}
|
||||
return rvData;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -864,8 +898,8 @@ NSSCryptoContext_Digest
|
|||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
return nssToken_Digest(cc->token, cc->session, apOpt,
|
||||
data, rvOpt, arenaOpt);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -876,8 +910,7 @@ NSSCryptoContext_BeginDigest
|
|||
NSSCallback *uhhOpt
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return PR_FAILURE;
|
||||
return nssToken_BeginDigest(cc->token, cc->session, apOpt);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -888,8 +921,12 @@ NSSCryptoContext_ContinueDigest
|
|||
NSSItem *item
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return PR_FAILURE;
|
||||
/*
|
||||
NSSAlgorithmAndParameters *ap;
|
||||
ap = (apOpt) ? apOpt : cc->ap;
|
||||
*/
|
||||
/* why apOpt? can't change it at this point... */
|
||||
return nssToken_ContinueDigest(cc->token, cc->session, item);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
|
@ -900,8 +937,7 @@ NSSCryptoContext_FinishDigest
|
|||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
return nssToken_FinishDigest(cc->token, cc->session, rvOpt, arenaOpt);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCryptoContext *
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKI_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.6 $ $Date: 2001-10-17 14:40:22 $ $Name: $";
|
||||
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef PKIT_H
|
||||
|
@ -54,27 +54,6 @@ nssCertificate_AddRef
|
|||
NSSCertificate *c
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
nssCertificate_CreateFromHandle
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_OBJECT_HANDLE object,
|
||||
nssSession *session,
|
||||
NSSSlot *slot
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSUTF8 *
|
||||
NSSCertificate_GetLabel
|
||||
(
|
||||
NSSCertificate *c
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSItem *
|
||||
NSSCertificate_GetID
|
||||
(
|
||||
NSSCertificate *c
|
||||
);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* PKI_H */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Date: 2001-11-08 20:46:08 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.5 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -51,10 +51,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Da
|
|||
#include "dev.h"
|
||||
#endif /* DEV_H */
|
||||
|
||||
#ifndef CKHELPER_H
|
||||
#include "ckhelper.h"
|
||||
#endif /* CKHELPER_H */
|
||||
|
||||
#ifndef DEVNSS3HACK_H
|
||||
#include "dev3hack.h"
|
||||
#endif /* DEVNSS3HACK_H */
|
||||
|
@ -71,12 +67,20 @@ static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.4 $ $Da
|
|||
|
||||
NSSTrustDomain *g_default_trust_domain = NULL;
|
||||
|
||||
NSSCryptoContext *g_default_crypto_context = NULL;
|
||||
|
||||
NSSTrustDomain *
|
||||
STAN_GetDefaultTrustDomain()
|
||||
{
|
||||
return g_default_trust_domain;
|
||||
}
|
||||
|
||||
NSSCryptoContext *
|
||||
STAN_GetDefaultCryptoContext()
|
||||
{
|
||||
return g_default_crypto_context;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
STAN_LoadDefaultNSS3TrustDomain
|
||||
(
|
||||
|
@ -103,6 +107,7 @@ STAN_LoadDefaultNSS3TrustDomain
|
|||
}
|
||||
td->tokens = nssList_CreateIterator(td->tokenList);
|
||||
g_default_trust_domain = td;
|
||||
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -136,7 +141,7 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
|
|||
return NULL;
|
||||
}
|
||||
secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
|
||||
if (!secrv) {
|
||||
if (secrv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
|
||||
|
@ -299,6 +304,28 @@ nssDecodedPKIXCertificate_Create
|
|||
return rvDC;
|
||||
}
|
||||
|
||||
static nssDecodedCert *
|
||||
create_decoded_pkix_cert_from_nss3cert
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CERTCertificate *cc
|
||||
)
|
||||
{
|
||||
nssDecodedCert *rvDC;
|
||||
rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
|
||||
rvDC->type = NSSCertificateType_PKIX;
|
||||
rvDC->data = (void *)cc;
|
||||
rvDC->getIdentifier = nss3certificate_getIdentifier;
|
||||
rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
|
||||
rvDC->matchIdentifier = nss3certificate_matchIdentifier;
|
||||
rvDC->getUsage = nss3certificate_getUsage;
|
||||
rvDC->isValidAtTime = nss3certificate_isValidAtTime;
|
||||
rvDC->isNewerThan = nss3certificate_isNewerThan;
|
||||
rvDC->matchUsage = nss3certificate_matchUsage;
|
||||
rvDC->getEmailAddress = nss3certificate_getEmailAddress;
|
||||
return rvDC;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssDecodedPKIXCertificate_Destroy
|
||||
(
|
||||
|
@ -336,10 +363,15 @@ get_nss3trust_from_cktrust(CK_TRUST t)
|
|||
}
|
||||
|
||||
static CERTCertTrust *
|
||||
nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
|
||||
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, NSSToken *token,
|
||||
CERTCertificate *cc)
|
||||
{
|
||||
CERTCertTrust *rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
|
||||
unsigned int client;
|
||||
NSSTrust *t = nssToken_FindTrustForCert(token, NULL, c);
|
||||
if (!t) {
|
||||
return NULL;
|
||||
}
|
||||
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
|
||||
client = get_nss3trust_from_cktrust(t->clientAuth);
|
||||
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
|
||||
|
@ -357,26 +389,39 @@ nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
|
|||
return rvTrust;
|
||||
}
|
||||
|
||||
static nssPKIObjectInstance *
|
||||
get_cert_instance(NSSCertificate *c)
|
||||
{
|
||||
nssPKIObjectInstance *instance;
|
||||
instance = NULL;
|
||||
nssList_GetArray(c->object.instanceList, (void **)&instance, 1);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
|
||||
{
|
||||
nssPKIObjectInstance *instance = get_cert_instance(c);
|
||||
/* fill other fields needed by NSS3 functions using CERTCertificate */
|
||||
/* handle */
|
||||
cc->pkcs11ID = c->handle;
|
||||
/* nickname */
|
||||
cc->nickname = PL_strdup(c->nickname);
|
||||
/* slot (ownSlot ?) (addref ?) */
|
||||
if (c->token) {
|
||||
cc->slot = c->token->pk11slot;
|
||||
if (!cc->nickname && c->nickname) {
|
||||
PRStatus nssrv;
|
||||
int len = nssUTF8_Size(c->nickname, &nssrv);
|
||||
cc->nickname = PORT_ArenaAlloc(cc->arena, len);
|
||||
memcpy(cc->nickname, c->nickname, len-1);
|
||||
cc->nickname[len-1] = '\0';
|
||||
}
|
||||
/* trust */
|
||||
cc->trust = nssTrust_GetCERTCertTrust(&c->trust, cc);
|
||||
cc->referenceCount++;
|
||||
if (instance) {
|
||||
nssCryptokiInstance *cryptoki = &instance->cryptoki;
|
||||
/* slot (ownSlot ?) (addref ?) */
|
||||
cc->slot = cryptoki->token->pk11slot;
|
||||
/* pkcs11ID */
|
||||
cc->pkcs11ID = cryptoki->handle;
|
||||
/* trust */
|
||||
cc->trust = nssTrust_GetCERTCertTrustForCert(c, cryptoki->token, cc);
|
||||
/* database handle is now the trust domain */
|
||||
cc->dbhandle = instance->trustDomain;
|
||||
}
|
||||
/* subjectList ? */
|
||||
/* pkcs11ID */
|
||||
cc->pkcs11ID = c->handle;
|
||||
/* database handle is now the trust domain */
|
||||
cc->dbhandle = c->trustDomain;
|
||||
/* pointer back */
|
||||
cc->nssCertificate = c;
|
||||
}
|
||||
|
@ -396,6 +441,11 @@ STAN_GetCERTCertificate(NSSCertificate *c)
|
|||
cc = (CERTCertificate *)dc->data;
|
||||
if (!cc->nssCertificate) {
|
||||
fill_CERTCertificateFields(c, cc);
|
||||
} else if (!cc->trust) {
|
||||
nssPKIObjectInstance *instance = get_cert_instance(c);
|
||||
cc->trust = nssTrust_GetCERTCertTrustForCert(c,
|
||||
instance->cryptoki.token,
|
||||
cc);
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
@ -428,13 +478,13 @@ NSS_EXTERN NSSCertificate *
|
|||
STAN_GetNSSCertificate(CERTCertificate *cc)
|
||||
{
|
||||
NSSCertificate *c;
|
||||
nssPKIObject *object;
|
||||
nssPKIObjectInstance *instance;
|
||||
NSSArena *arena;
|
||||
|
||||
c = cc->nssCertificate;
|
||||
if (c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
/* i don't think this should happen. but if it can, need to create
|
||||
* NSSCertificate from CERTCertificate values here. */
|
||||
/* Yup, it can happen. */
|
||||
|
@ -442,24 +492,35 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
|
|||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
c = NSSCertificate_Create(arena);
|
||||
c = nss_ZNEW(arena, NSSCertificate);
|
||||
if (!c) {
|
||||
goto loser;
|
||||
}
|
||||
object = &c->object;
|
||||
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
|
||||
c->type = NSSCertificateType_PKIX;
|
||||
c->arena = arena;
|
||||
object->arena = arena;
|
||||
object->refCount = 1;
|
||||
object->instanceList = nssList_Create(arena, PR_TRUE);
|
||||
object->instances = nssList_CreateIterator(object->instanceList);
|
||||
nssItem_Create(arena,
|
||||
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
|
||||
nssItem_Create(arena,
|
||||
&c->subject, cc->derSubject.len, cc->derSubject.data);
|
||||
nssItem_Create(arena,
|
||||
&c->serial, cc->serialNumber.len, cc->serialNumber.data);
|
||||
if (PR_TRUE) {
|
||||
/* CERTCertificate stores serial numbers decoded. I need the DER
|
||||
* here. sigh.
|
||||
*/
|
||||
SECItem derSerial;
|
||||
CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
|
||||
nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
|
||||
PORT_Free(derSerial.data);
|
||||
}
|
||||
if (cc->nickname) {
|
||||
c->nickname = nssUTF8_Create(arena,
|
||||
nssStringType_UTF8String,
|
||||
(NSSUTF8 *)cc->nickname,
|
||||
PORT_Strlen(cc->nickname));
|
||||
nssStringType_UTF8String,
|
||||
(NSSUTF8 *)cc->nickname,
|
||||
PORT_Strlen(cc->nickname));
|
||||
}
|
||||
if (cc->emailAddr) {
|
||||
c->email = nssUTF8_Create(arena,
|
||||
|
@ -467,19 +528,15 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
|
|||
(NSSUTF8 *)cc->emailAddr,
|
||||
PORT_Strlen(cc->emailAddr));
|
||||
}
|
||||
c->trustDomain = (NSSTrustDomain *)cc->dbhandle;
|
||||
instance = nss_ZNEW(arena, nssPKIObjectInstance);
|
||||
instance->trustDomain = (NSSTrustDomain *)cc->dbhandle;
|
||||
if (cc->slot) {
|
||||
c->token = PK11Slot_GetNSSToken(cc->slot);
|
||||
c->slot = c->token->slot;
|
||||
instance->cryptoki.token = PK11Slot_GetNSSToken(cc->slot);
|
||||
instance->cryptoki.handle = cc->pkcs11ID;
|
||||
}
|
||||
nssList_Add(object->instanceList, instance);
|
||||
c->decoding = create_decoded_pkix_cert_from_nss3cert(arena, cc);
|
||||
cc->nssCertificate = c;
|
||||
if (cc->trust) {
|
||||
CERTCertTrust *trust = cc->trust;
|
||||
c->trust.serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
|
||||
c->trust.clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
|
||||
c->trust.emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
|
||||
c->trust.codeSigning= get_stan_trust(trust->objectSigningFlags, PR_FALSE);
|
||||
}
|
||||
return c;
|
||||
loser:
|
||||
nssArena_Destroy(arena);
|
||||
|
@ -487,47 +544,31 @@ loser:
|
|||
}
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
STAN_ChangeCertTrust(NSSCertificate *c, CERTCertTrust *trust)
|
||||
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
|
||||
{
|
||||
CERTCertificate *cc = STAN_GetCERTCertificate(c);
|
||||
PRStatus nssrv;
|
||||
NSSCertificate *c = STAN_GetNSSCertificate(cc);
|
||||
nssPKIObjectInstance *instance;
|
||||
NSSTrust nssTrust;
|
||||
/* Set the CERTCertificate's trust */
|
||||
cc->trust = trust;
|
||||
/* Set the NSSCerticate's trust */
|
||||
nssTrust.certificate = c;
|
||||
nssTrust.object.arena = nssArena_Create();
|
||||
nssTrust.object.instanceList = nssList_Create(nssTrust.object.arena,
|
||||
PR_FALSE);
|
||||
nssTrust.object.instances = nssList_CreateIterator(
|
||||
nssTrust.object.instanceList);
|
||||
nssTrust.serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
|
||||
nssTrust.clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
|
||||
nssTrust.emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
|
||||
nssTrust.codeSigning= get_stan_trust(trust->objectSigningFlags, PR_FALSE);
|
||||
return nssCertificate_SetCertTrust(c, &nssTrust);
|
||||
}
|
||||
|
||||
/* This is here to replace CERT_Traverse calls */
|
||||
static PRStatus
|
||||
traverse_certificates_by_template
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
nssList *cachedList,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize,
|
||||
PRStatus (*callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
NSSToken *tok;
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL, cachedList,
|
||||
cktemplate, ctsize,
|
||||
callback, arg);
|
||||
if (nssrv == PR_FAILURE) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
return PR_SUCCESS;
|
||||
nssTrust.codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE);
|
||||
instance = get_cert_instance(c);
|
||||
/* maybe GetDefaultTrustToken()? */
|
||||
nssrv = nssToken_ImportTrust(instance->cryptoki.token, NULL, &nssTrust,
|
||||
instance->trustDomain, instance->cryptoContext);
|
||||
nssArena_Destroy(nssTrust.object.arena);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
/* CERT_TraversePermCertsForSubject */
|
||||
|
@ -541,22 +582,20 @@ nssTrustDomain_TraverseCertificatesBySubject
|
|||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
nssList *subjectList;
|
||||
CK_ATTRIBUTE subj_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
|
||||
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
||||
nssrv = traverse_certificates_by_template(td, subjectList,
|
||||
subj_template, ctsize,
|
||||
callback, arg);
|
||||
nssList_Destroy(subjectList);
|
||||
NSSArena *tmpArena;
|
||||
NSSCertificate **subjectCerts;
|
||||
NSSCertificate *c;
|
||||
PRIntn i;
|
||||
tmpArena = NSSArena_Create();
|
||||
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL,
|
||||
0, tmpArena);
|
||||
if (subjectCerts) {
|
||||
for (i=0, c = subjectCerts[i]; c; i++) {
|
||||
nssrv = callback(c, arg);
|
||||
if (nssrv != PR_SUCCESS) break;
|
||||
}
|
||||
}
|
||||
nssArena_Destroy(tmpArena);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
|
@ -571,23 +610,20 @@ nssTrustDomain_TraverseCertificatesByNickname
|
|||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
nssList *nickCerts;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)nickname;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(nickname, &nssrv);
|
||||
nickCerts = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nickname, nickCerts);
|
||||
nssrv = traverse_certificates_by_template(td, nickCerts,
|
||||
nick_template, ctsize,
|
||||
callback, arg);
|
||||
nssList_Destroy(nickCerts);
|
||||
NSSArena *tmpArena;
|
||||
NSSCertificate **nickCerts;
|
||||
NSSCertificate *c;
|
||||
PRIntn i;
|
||||
tmpArena = NSSArena_Create();
|
||||
nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL,
|
||||
0, tmpArena);
|
||||
if (nickCerts) {
|
||||
for (i=0, c = nickCerts[i]; c; i++) {
|
||||
nssrv = callback(c, arg);
|
||||
if (nssrv != PR_SUCCESS) break;
|
||||
}
|
||||
}
|
||||
nssArena_Destroy(tmpArena);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
|
@ -601,23 +637,33 @@ nssTrustDomain_TraverseCertificates
|
|||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
NSSToken *token;
|
||||
nssList *certList;
|
||||
CK_ATTRIBUTE cert_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
nssTokenCertSearch search;
|
||||
/* grab all cache certs (XXX please only do this here...)
|
||||
* the alternative is to provide a callback through search that allows
|
||||
* the token to query the cache for the cert during traversal.
|
||||
*/
|
||||
certList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsFromCache(td, certList);
|
||||
nssrv = traverse_certificates_by_template(td, certList,
|
||||
cert_template, ctsize,
|
||||
callback, arg);
|
||||
/* set the search criteria */
|
||||
search.callback = callback;
|
||||
search.cbarg = arg;
|
||||
search.cached = certList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificates(token, NULL, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
nssList_Destroy(certList);
|
||||
return nssrv;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static CK_CERTIFICATE_TYPE
|
||||
get_cert_type(NSSCertificateType nssType)
|
||||
{
|
||||
|
@ -629,6 +675,7 @@ get_cert_type(NSSCertificateType nssType)
|
|||
* type CK_CERTIFICATE_TYPE */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
NSS_IMPLEMENT NSSToken *
|
||||
STAN_GetInternalToken(void)
|
||||
|
@ -643,6 +690,7 @@ nssTrustDomain_AddTempCertToPerm
|
|||
NSSCertificate *c
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
NSSToken *token;
|
||||
CK_CERTIFICATE_TYPE cert_type;
|
||||
CK_ATTRIBUTE cert_template[] =
|
||||
|
@ -679,4 +727,6 @@ nssTrustDomain_AddTempCertToPerm
|
|||
c->slot = token->slot;
|
||||
/* Do the trust object */
|
||||
return PR_SUCCESS;
|
||||
#endif
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKINSS3HACK_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.1 $ $Date: 2001-11-08 00:15:20 $ $Name: $";
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.2 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKIT_H
|
||||
|
@ -57,6 +57,9 @@ PR_BEGIN_EXTERN_C
|
|||
NSS_EXTERN NSSTrustDomain *
|
||||
STAN_GetDefaultTrustDomain();
|
||||
|
||||
NSSCryptoContext *
|
||||
STAN_GetDefaultCryptoContext();
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
STAN_LoadDefaultNSS3TrustDomain
|
||||
(
|
||||
|
@ -76,7 +79,7 @@ NSS_EXTERN NSSCertificate *
|
|||
STAN_GetNSSCertificate(CERTCertificate *c);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
STAN_ChangeCertTrust(NSSCertificate *c, CERTCertTrust *trust);
|
||||
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
|
||||
|
||||
/* exposing this */
|
||||
NSS_EXTERN NSSCertificate *
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKIM_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.6 $ $Date: 2001-10-19 20:06:28 $ $Name: $";
|
||||
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:43 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef BASE_H
|
||||
|
@ -129,13 +129,20 @@ nssTrustDomain_AddCertsToCache
|
|||
PRUint32 numCerts
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSS_EXTERN void
|
||||
nssTrustDomain_RemoveCertFromCache
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSCertificate *cert
|
||||
);
|
||||
|
||||
NSS_EXTERN void
|
||||
nssTrustDomain_FlushCache
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
PRFloat64 threshold
|
||||
);
|
||||
|
||||
/*
|
||||
* Remove all certs for the given token from the cache. This is
|
||||
* needed if the token is removed.
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKIT_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $Date: 2001-11-05 17:29:27 $ $Name: $";
|
||||
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:44 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -55,12 +55,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $D
|
|||
#ifdef NSS_3_4_CODE
|
||||
#include "certt.h"
|
||||
#include "pkcs11t.h"
|
||||
#define NSSCKT_H
|
||||
#include "ckt.h"
|
||||
#else
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
#endif /* NSS_3_4_CODE */
|
||||
|
||||
#ifndef NSSPKIT_H
|
||||
|
@ -71,27 +65,46 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.6 $ $D
|
|||
#include "nssdevt.h"
|
||||
#endif /* NSSDEVT_H */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
#ifndef DEVT_H
|
||||
#include "devt.h"
|
||||
#endif /* DEVT_H */
|
||||
|
||||
typedef enum {
|
||||
NSSCertificateType_Unknown = 0,
|
||||
NSSCertificateType_PKIX = 1
|
||||
} NSSCertificateType;
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct nssDecodedCertStr nssDecodedCert;
|
||||
|
||||
typedef struct nssPKIObjectInstanceStr nssPKIObjectInstance;
|
||||
|
||||
typedef struct nssPKIObjectStr nssPKIObject;
|
||||
|
||||
struct nssPKIObjectInstanceStr
|
||||
{
|
||||
nssCryptokiInstance cryptoki;
|
||||
NSSTrustDomain *trustDomain;
|
||||
NSSCryptoContext *cryptoContext;
|
||||
};
|
||||
|
||||
struct nssPKIObjectStr
|
||||
{
|
||||
PRInt32 refCount;
|
||||
NSSArena *arena;
|
||||
nssList *instanceList; /* list of nssPKIObjectInstance */
|
||||
nssListIterator *instances;
|
||||
};
|
||||
|
||||
struct NSSTrustStr
|
||||
{
|
||||
CK_TRUST serverAuth;
|
||||
CK_TRUST clientAuth;
|
||||
CK_TRUST emailProtection;
|
||||
CK_TRUST codeSigning;
|
||||
struct nssPKIObjectStr object;
|
||||
NSSCertificate *certificate;
|
||||
nssTrustLevel serverAuth;
|
||||
nssTrustLevel clientAuth;
|
||||
nssTrustLevel emailProtection;
|
||||
nssTrustLevel codeSigning;
|
||||
};
|
||||
|
||||
struct NSSCertificateStr
|
||||
{
|
||||
PRInt32 refCount;
|
||||
NSSArena *arena;
|
||||
struct nssPKIObjectStr object;
|
||||
NSSCertificateType type;
|
||||
NSSItem id;
|
||||
NSSBER encoding;
|
||||
|
@ -100,12 +113,6 @@ struct NSSCertificateStr
|
|||
NSSDER serial;
|
||||
NSSUTF8 *nickname;
|
||||
NSSASCII7 *email;
|
||||
NSSSlot *slot;
|
||||
NSSToken *token;
|
||||
NSSTrustDomain *trustDomain;
|
||||
NSSCryptoContext *cryptoContext;
|
||||
NSSTrust trust;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
nssDecodedCert *decoding;
|
||||
};
|
||||
|
||||
|
@ -134,6 +141,9 @@ struct NSSCryptoContextStr
|
|||
{
|
||||
PRInt32 refCount;
|
||||
NSSArena *arena;
|
||||
NSSTrustDomain *td;
|
||||
NSSToken *token;
|
||||
nssSession *session;
|
||||
};
|
||||
|
||||
struct NSSTimeStr;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.16 $ $Date: 2001-11-20 18:28:47 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.17 $ $Date: 2001-11-28 16:23:44 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -114,7 +114,8 @@ NSSTrustDomain_Destroy
|
|||
if (--td->refCount == 0) {
|
||||
/* Destroy each token in the list of tokens */
|
||||
if (td->tokens) {
|
||||
nssList_DestroyElements(td->tokenList, token_destructor);
|
||||
nssList_Clear(td->tokenList, token_destructor);
|
||||
nssList_Destroy(td->tokenList);
|
||||
}
|
||||
/* Destroy the trust domain */
|
||||
nssArena_Destroy(td->arena);
|
||||
|
@ -354,12 +355,10 @@ NSSTrustDomain_ImportEncodedPublicKey
|
|||
}
|
||||
|
||||
struct get_best_cert_arg_str {
|
||||
NSSTrustDomain *td;
|
||||
NSSCertificate *cert;
|
||||
NSSTime *time;
|
||||
NSSUsage *usage;
|
||||
NSSPolicies *policies;
|
||||
nssList *cached;
|
||||
};
|
||||
|
||||
static PRStatus
|
||||
|
@ -400,59 +399,9 @@ get_best_cert(NSSCertificate *c, void *arg)
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static NSSCertificate *
|
||||
find_best_cert_for_template
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
struct get_best_cert_arg_str *best,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
NSSToken *tok;
|
||||
if (token) {
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(token, NULL,
|
||||
best->cached,
|
||||
cktemplate, ctsize,
|
||||
get_best_cert, best);
|
||||
} else {
|
||||
/* we need to lock the iterator */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL,
|
||||
best->cached,
|
||||
cktemplate, ctsize,
|
||||
get_best_cert,
|
||||
best);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
}
|
||||
/* Cache the cert before returning */
|
||||
/*nssTrustDomain_AddCertsToCache(td, &best->cert, 1);*/
|
||||
/* rjr handle orphanned certs in cache for now. real fix will be Ian's
|
||||
* crypto object */
|
||||
if (best->cert == NULL) {
|
||||
if (nssList_Count(best->cached) >= 1) {
|
||||
NSSCertificate * candidate;
|
||||
|
||||
nssList_GetArray(best->cached,&candidate,1);
|
||||
if (candidate) {
|
||||
best->cert = nssCertificate_AddRef(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
return best->cert;
|
||||
}
|
||||
|
||||
struct collect_arg_str {
|
||||
nssList *list;
|
||||
PRUint32 maximum;
|
||||
NSSArena *arena;
|
||||
NSSCertificate **rvOpt;
|
||||
};
|
||||
|
||||
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
|
||||
|
@ -471,105 +420,6 @@ collect_certs(NSSCertificate *c, void *arg)
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static NSSCertificate **
|
||||
find_all_certs_for_template
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
struct collect_arg_str *ca,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
)
|
||||
{
|
||||
NSSCertificate **certs = NULL;
|
||||
PRStatus nssrv;
|
||||
PRUint32 count;
|
||||
NSSToken *tok;
|
||||
if (token) {
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(token, NULL, ca->list,
|
||||
cktemplate, ctsize,
|
||||
collect_certs, ca);
|
||||
} else {
|
||||
/* we need to lock the iterator */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesByTemplate(tok, NULL,
|
||||
ca->list,
|
||||
cktemplate, ctsize,
|
||||
collect_certs, ca);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
}
|
||||
count = nssList_Count(ca->list);
|
||||
if (ca->rvOpt) {
|
||||
certs = ca->rvOpt;
|
||||
} else {
|
||||
certs = nss_ZNEWARRAY(ca->arena, NSSCertificate *, count + 1);
|
||||
}
|
||||
nssrv = nssList_GetArray(ca->list, (void **)certs, count);
|
||||
/* Cache the certs before returning */
|
||||
/*nssTrustDomain_AddCertsToCache(td, certs, count);*/
|
||||
return certs;
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* This is really a hack for PK11_ calls that want to specify the token to
|
||||
* do lookups on (see PK11_FindCertFromNickname). I don't think this
|
||||
* is something we want to keep.
|
||||
*/
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssTrustDomain_FindBestCertificateByNicknameForToken
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
NSSUTF8 *name,
|
||||
NSSTime *timeOpt, /* NULL for "now" */
|
||||
NSSUsage *usage,
|
||||
NSSPolicies *policiesOpt /* NULL for none */
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
PRStatus nssrv;
|
||||
struct get_best_cert_arg_str best;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
nssList *nameList;
|
||||
/* set up the search template */
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
/* set the criteria for determining the best cert */
|
||||
best.td = td;
|
||||
best.cert = NULL;
|
||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||
best.usage = usage;
|
||||
best.policies = policiesOpt;
|
||||
/* find all matching certs in the cache */
|
||||
nameList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||
best.cached = nameList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, token,
|
||||
&best, nick_template, ctsize);
|
||||
if (!rvCert) {
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
*/
|
||||
nick_template[1].ulValueLen++;
|
||||
rvCert = find_best_cert_for_template(td, token,
|
||||
&best, nick_template, ctsize);
|
||||
}
|
||||
nssList_Destroy(nameList);
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
NSSTrustDomain_FindBestCertificateByNickname
|
||||
(
|
||||
|
@ -580,23 +430,12 @@ NSSTrustDomain_FindBestCertificateByNickname
|
|||
NSSPolicies *policiesOpt /* NULL for none */
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
PRStatus nssrv;
|
||||
NSSToken *token;
|
||||
nssTokenCertSearch search;
|
||||
struct get_best_cert_arg_str best;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
nssList *nameList;
|
||||
/* set up the search template */
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
/* set the criteria for determining the best cert */
|
||||
best.td = td;
|
||||
best.cert = NULL;
|
||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||
best.usage = usage;
|
||||
|
@ -604,62 +443,26 @@ NSSTrustDomain_FindBestCertificateByNickname
|
|||
/* find all matching certs in the cache */
|
||||
nameList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||
best.cached = nameList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, nick_template, ctsize);
|
||||
if (!rvCert) {
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
*/
|
||||
nick_template[1].ulValueLen++;
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, nick_template, ctsize);
|
||||
}
|
||||
nssList_Destroy(nameList);
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* This is really a hack for PK11_ calls that want to specify the token to
|
||||
* do lookups on (see PK11_FindCertsFromNickname). I don't think this
|
||||
* is something we want to keep.
|
||||
*/
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
nssTrustDomain_FindCertificatesByNicknameForToken
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
NSSUTF8 *name,
|
||||
NSSCertificate *rvOpt[],
|
||||
PRUint32 maximumOpt, /* 0 for no max */
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
NSSCertificate **rvCerts = NULL;
|
||||
PRStatus nssrv;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
/* set the search criteria */
|
||||
search.callback = get_best_cert;
|
||||
search.cbarg = &best;
|
||||
search.cached = nameList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
/* traverse the tokens */
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
nssList *nickCerts;
|
||||
struct collect_arg_str ca;
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
nickCerts = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nickCerts);
|
||||
ca.list = nickCerts;
|
||||
ca.maximum = maximumOpt;
|
||||
ca.arena = arenaOpt;
|
||||
ca.rvOpt = rvOpt;
|
||||
rvCerts = find_all_certs_for_template(td, token,
|
||||
&ca, nick_template, ctsize);
|
||||
nssList_Destroy(nickCerts);
|
||||
return rvCerts;
|
||||
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
name, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
nssList_Destroy(nameList);
|
||||
if (best.cert) {
|
||||
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
|
||||
}
|
||||
return best.cert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
|
@ -673,28 +476,45 @@ NSSTrustDomain_FindCertificatesByNickname
|
|||
)
|
||||
{
|
||||
NSSCertificate **rvCerts = NULL;
|
||||
NSSToken *token;
|
||||
PRUint32 count;
|
||||
PRStatus nssrv;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
nssList *nickCerts;
|
||||
nssList *nameList;
|
||||
struct collect_arg_str ca;
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
nickCerts = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nickCerts);
|
||||
ca.list = nickCerts;
|
||||
nssTokenCertSearch search;
|
||||
/* set up the collection */
|
||||
nameList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||
ca.list = nameList;
|
||||
ca.maximum = maximumOpt;
|
||||
ca.arena = arenaOpt;
|
||||
ca.rvOpt = rvOpt;
|
||||
rvCerts = find_all_certs_for_template(td, NULL,
|
||||
&ca, nick_template, ctsize);
|
||||
nssList_Destroy(nickCerts);
|
||||
/* set the search criteria */
|
||||
search.callback = collect_certs;
|
||||
search.cbarg = &ca;
|
||||
search.cached = nameList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
/* traverse the tokens */
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
name, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
count = nssList_Count(nameList);
|
||||
if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt;
|
||||
if (count > 0) {
|
||||
if (rvOpt) {
|
||||
nssList_GetArray(nameList, (void **)rvOpt, count);
|
||||
rvOpt[count] = NULL;
|
||||
} else {
|
||||
rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
|
||||
nssList_GetArray(nameList, (void **)rvCerts, count);
|
||||
}
|
||||
nssTrustDomain_AddCertsToCache(td, rvCerts, count);
|
||||
}
|
||||
nssList_Destroy(nameList);
|
||||
return rvCerts;
|
||||
}
|
||||
|
||||
|
@ -708,44 +528,29 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
|
|||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
NSSToken *tok;
|
||||
CK_ULONG ctsize;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_ISSUER, NULL, 0 },
|
||||
{ CKA_SERIAL_NUMBER, NULL, 0 }
|
||||
};
|
||||
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
/* Set the unique id */
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, issuer);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, serialNumber);
|
||||
/* Try the cache */
|
||||
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
|
||||
issuer,
|
||||
serialNumber);
|
||||
if (!rvCert) {
|
||||
/* Not cached, look for it on tokens */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
object = nssToken_FindObjectByTemplate(tok, NULL,
|
||||
cert_template, ctsize);
|
||||
if (object != CK_INVALID_HANDLE) {
|
||||
/* Could not find cert, so create it */
|
||||
rvCert = nssCertificate_CreateFromHandle(NULL, object,
|
||||
tok->defaultSession,
|
||||
tok->slot);
|
||||
if (rvCert) {
|
||||
/* cache it */
|
||||
/*nssTrustDomain_AddCertsToCache(td, &rvCert, 1);*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
if (rvCert) {
|
||||
return rvCert;
|
||||
}
|
||||
/* Not cached, look for it on tokens */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
|
||||
NULL,
|
||||
issuer,
|
||||
serialNumber);
|
||||
if (rvCert) {
|
||||
/* cache it */
|
||||
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
|
@ -759,31 +564,39 @@ NSSTrustDomain_FindBestCertificateBySubject
|
|||
NSSPolicies *policiesOpt
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
PRStatus nssrv;
|
||||
NSSToken *token;
|
||||
nssList *subjectList;
|
||||
CK_ATTRIBUTE subj_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 }
|
||||
};
|
||||
struct get_best_cert_arg_str best;
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
|
||||
best.td = td;
|
||||
nssTokenCertSearch search;
|
||||
/* set the criteria for determining the best cert */
|
||||
best.cert = NULL;
|
||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||
best.usage = usage;
|
||||
best.policies = policiesOpt;
|
||||
/* find all matching certs in the cache */
|
||||
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
||||
best.cached = subjectList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, subj_template, ctsize);
|
||||
/* set the search criteria */
|
||||
search.callback = get_best_cert;
|
||||
search.cbarg = &best;
|
||||
search.cached = subjectList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
/* traverse the tokens */
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
|
||||
subject, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
nssList_Destroy(subjectList);
|
||||
return rvCert;
|
||||
if (best.cert) {
|
||||
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
|
||||
}
|
||||
return best.cert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
|
@ -796,26 +609,45 @@ NSSTrustDomain_FindCertificatesBySubject
|
|||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
NSSCertificate **rvCerts = NULL;
|
||||
NSSToken *token;
|
||||
PRUint32 count;
|
||||
nssList *subjectList;
|
||||
struct collect_arg_str ca;
|
||||
CK_ATTRIBUTE subj_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_SUBJECT, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
|
||||
nssTokenCertSearch search;
|
||||
/* set up the collection */
|
||||
subjectList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
||||
ca.list = subjectList;
|
||||
ca.maximum = maximumOpt;
|
||||
ca.arena = arenaOpt;
|
||||
ca.rvOpt = rvOpt;
|
||||
rvCerts = find_all_certs_for_template(td, NULL,
|
||||
&ca, subj_template, ctsize);
|
||||
/* set the search criteria */
|
||||
search.callback = collect_certs;
|
||||
search.cbarg = &ca;
|
||||
search.cached = subjectList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
/* traverse the tokens */
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
|
||||
subject, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
count = nssList_Count(subjectList);
|
||||
if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt;
|
||||
if (count > 0) {
|
||||
if (rvOpt) {
|
||||
nssList_GetArray(subjectList, (void **)rvOpt, count);
|
||||
rvOpt[count] = NULL;
|
||||
} else {
|
||||
rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
|
||||
nssList_GetArray(subjectList, (void **)rvCerts, count);
|
||||
}
|
||||
nssTrustDomain_AddCertsToCache(td, rvCerts, count);
|
||||
}
|
||||
nssList_Destroy(subjectList);
|
||||
return rvCerts;
|
||||
}
|
||||
|
@ -857,39 +689,25 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
|
|||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
NSSToken *tok;
|
||||
CK_ULONG ctsize;
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_ATTRIBUTE cert_template[] = {
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_VALUE, NULL, 0 }
|
||||
};
|
||||
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, encodedCertificate);
|
||||
/* Try the cache */
|
||||
rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate);
|
||||
if (!rvCert) {
|
||||
/* Not cached, look for it on tokens */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
object = nssToken_FindObjectByTemplate(tok, NULL,
|
||||
cert_template, ctsize);
|
||||
if (object != CK_INVALID_HANDLE) {
|
||||
/* found it */
|
||||
rvCert = nssCertificate_CreateFromHandle(NULL, object,
|
||||
tok->defaultSession,
|
||||
tok->slot);
|
||||
if (rvCert) {
|
||||
/* cache it */
|
||||
/*nssTrustDomain_AddCertsToCache(td, &rvCert, 1);*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
if (rvCert) {
|
||||
return rvCert;
|
||||
}
|
||||
/* Not cached, look for it on tokens */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
|
||||
encodedCertificate);
|
||||
if (rvCert) {
|
||||
/* cache it */
|
||||
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
|
@ -903,23 +721,12 @@ NSSTrustDomain_FindCertificateByEmail
|
|||
NSSPolicies *policiesOpt
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
PRStatus nssrv;
|
||||
NSSToken *token;
|
||||
struct get_best_cert_arg_str best;
|
||||
CK_ATTRIBUTE email_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_NETSCAPE_EMAIL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
nssTokenCertSearch search;
|
||||
nssList *emailList;
|
||||
/* set up the search template */
|
||||
ctsize = (CK_ULONG)(sizeof(email_template) / sizeof(email_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(email_template, 0, &g_ck_class_cert);
|
||||
email_template[1].pValue = (CK_VOID_PTR)email;
|
||||
email_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(email, &nssrv);
|
||||
/* set the criteria for determining the best cert */
|
||||
best.td = td;
|
||||
best.cert = NULL;
|
||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||
best.usage = usage;
|
||||
|
@ -927,20 +734,26 @@ NSSTrustDomain_FindCertificateByEmail
|
|||
/* find all matching certs in the cache */
|
||||
emailList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(td, email, emailList);
|
||||
best.cached = emailList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, email_template, ctsize);
|
||||
if (!rvCert) {
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
*/
|
||||
email_template[1].ulValueLen++;
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, email_template, ctsize);
|
||||
/* set the search criteria */
|
||||
search.callback = get_best_cert;
|
||||
search.cbarg = &best;
|
||||
search.cached = emailList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
/* traverse the tokens */
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificatesByEmail(token, NULL,
|
||||
email, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
nssList_Destroy(emailList);
|
||||
return rvCert;
|
||||
if (best.cert) {
|
||||
nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
|
||||
}
|
||||
return best.cert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
|
@ -1072,17 +885,26 @@ NSSTrustDomain_TraverseCertificates
|
|||
)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
NSSToken *tok;
|
||||
|
||||
/* we need to lock the iterator */
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
NSSToken *token;
|
||||
nssList *certList;
|
||||
nssTokenCertSearch search;
|
||||
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
|
||||
/* set the search criteria */
|
||||
search.callback = callback;
|
||||
search.cbarg = arg;
|
||||
search.cached = certList;
|
||||
search.trustDomain = td;
|
||||
search.cryptoContext = NULL;
|
||||
/* traverse the tokens */
|
||||
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
token != (NSSToken *)NULL;
|
||||
token = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_TraverseCertificates(tok, NULL, callback, arg);
|
||||
nssrv = nssToken_TraverseCertificates(token, NULL, &search);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
return NULL; /* should return array of nssrv's ? */
|
||||
nssList_Destroy(certList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
|
@ -1149,8 +971,18 @@ NSSTrustDomain_CreateCryptoContext
|
|||
NSSCallback *uhhOpt
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
NSSArena *arena;
|
||||
NSSCryptoContext *rvCC;
|
||||
arena = NSSArena_Create();
|
||||
if (!arena) {
|
||||
return NULL;
|
||||
}
|
||||
rvCC = nss_ZNEW(arena, NSSCryptoContext);
|
||||
if (!rvCC) {
|
||||
return NULL;
|
||||
}
|
||||
rvCC->td = td;
|
||||
return rvCC;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCryptoContext *
|
||||
|
|
Загрузка…
Ссылка в новой задаче