bug 135521, change cert lookups on tokens to be actual finds instead of traversals

This commit is contained in:
ian.mcgreer%sun.com 2002-04-15 15:22:11 +00:00
Родитель 0cc80c4e02
Коммит a7256cf9ec
24 изменённых файлов: 2390 добавлений и 1974 удалений

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

@ -135,17 +135,17 @@ SECStatus
__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
CERTCertTrust *trust)
{
PRStatus nssrv;
NSSUTF8 *stanNick;
PK11SlotInfo *slot;
NSSToken *internal;
NSSCryptoContext *context;
nssCryptokiObject *permInstance;
NSSCertificate *c = STAN_GetNSSCertificate(cert);
context = c->object.cryptoContext;
if (!context) {
return SECFailure; /* wasn't a temp cert */
}
stanNick = NSSCertificate_GetNickname(c, NULL);
stanNick = nssCertificate_GetNickname(c, NULL);
if (stanNick && nickname && strcmp(nickname, stanNick) != 0) {
/* take the new nickname */
cert->nickname = NULL;
@ -157,15 +157,23 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
/* Delete the temp instance */
nssCertificateStore_Remove(context->certStore, c);
c->object.cryptoContext = NULL;
/* the perm instance will assume the reference */
nssList_Clear(c->object.instanceList, NULL);
/* Import the perm instance onto the internal token */
slot = PK11_GetInternalKeySlot();
internal = PK11Slot_GetNSSToken(slot);
nssrv = nssToken_ImportCertificate(internal, NULL, c, stanNick, PR_TRUE);
if (nssrv != PR_SUCCESS) {
permInstance = nssToken_ImportCertificate(internal, NULL,
NSSCertificateType_PKIX,
&c->id,
stanNick,
&c->encoding,
&c->issuer,
&c->subject,
&c->serial,
PR_TRUE);
PK11_FreeSlot(slot);
if (!permInstance) {
return SECFailure;
}
nssPKIObject_AddInstance(&c->object, permInstance);
/* reset the CERTCertificate fields */
cert->nssCertificate = NULL;
cert = STAN_GetCERTCertificate(c); /* will return same pointer */
@ -188,11 +196,11 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
{
PRStatus nssrv;
NSSCertificate *c;
NSSCryptoContext *context;
NSSArena *arena;
CERTCertificate *cc;
NSSCertificate *tempCert;
nssPKIObject *pkio;
NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext();
NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain();
if (!isperm) {
NSSDER encoding;
NSSITEM_FROM_SECITEM(&encoding, derCert);
@ -208,27 +216,24 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
return STAN_GetCERTCertificate(c);
}
}
arena = NSSArena_Create();
if (!arena) {
pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC);
if (!pkio) {
return NULL;
}
c = nss_ZNEW(arena, NSSCertificate);
c = nss_ZNEW(pkio->arena, NSSCertificate);
if (!c) {
nssArena_Destroy(arena);
nssPKIObject_Destroy(pkio);
return NULL;
}
c->object = *pkio;
NSSITEM_FROM_SECITEM(&c->encoding, derCert);
nssrv = nssPKIObject_Initialize(&c->object, arena, NULL, NULL);
if (nssrv != PR_SUCCESS) {
goto loser;
}
/* Forces a decoding of the cert in order to obtain the parts used
* below
*/
cc = STAN_GetCERTCertificate(c);
nssItem_Create(arena,
nssItem_Create(c->object.arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
nssItem_Create(arena,
nssItem_Create(c->object.arena,
&c->subject, cc->derSubject.len, cc->derSubject.data);
if (PR_TRUE) {
/* CERTCertificate stores serial numbers decoded. I need the DER
@ -237,31 +242,30 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
SECItem derSerial = { 0 };
CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
if (!derSerial.data) goto loser;
nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data);
PORT_Free(derSerial.data);
}
if (nickname) {
c->object.tempName = nssUTF8_Create(arena,
c->object.tempName = nssUTF8_Create(c->object.arena,
nssStringType_UTF8String,
(NSSUTF8 *)nickname,
PORT_Strlen(nickname));
}
if (cc->emailAddr) {
c->email = nssUTF8_Create(arena,
c->email = nssUTF8_Create(c->object.arena,
nssStringType_PrintableString,
(NSSUTF8 *)cc->emailAddr,
PORT_Strlen(cc->emailAddr));
}
context = STAN_GetDefaultCryptoContext();
/* this function cannot detect if the cert exists as a temp cert now, but
* didn't when CERT_NewTemp was first called.
*/
nssrv = NSSCryptoContext_ImportCertificate(context, c);
nssrv = NSSCryptoContext_ImportCertificate(gCC, c);
if (nssrv != PR_SUCCESS) {
goto loser;
}
/* so find the entry in the temp store */
tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(context,
tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(gCC,
&c->issuer,
&c->serial);
/* destroy the copy */
@ -273,7 +277,6 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
} else {
return NULL;
}
c->object.trustDomain = STAN_GetDefaultTrustDomain();
cc->istemp = PR_TRUE;
cc->isperm = PR_FALSE;
return cc;
@ -308,17 +311,18 @@ CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndS
static NSSCertificate *
get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp)
{
nssBestCertificateCB best;
NSSUsage usage;
NSSCertificate *arr[3];
if (!ct) {
return nssCertificate_AddRef(cp);
} else if (!cp) {
return nssCertificate_AddRef(ct);
}
arr[0] = ct;
arr[1] = cp;
arr[2] = NULL;
usage.anyUsage = PR_TRUE;
nssBestCertificate_SetArgs(&best, NULL, &usage, NULL);
if (ct) {
nssBestCertificate_Callback(ct, (void *)&best);
}
if (cp) {
nssBestCertificate_Callback(cp, (void *)&best);
}
return best.cert;
return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL);
}
CERTCertificate *

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.19 $ $Date: 2002/04/09 17:58:00 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.20 $ $Date: 2002/04/15 15:22:00 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSCKEPV_H
@ -287,7 +287,6 @@ nssCKObject_IsTokenObjectTemplate
return PR_FALSE;
}
#ifdef PURE_STAN_BUILD
static NSSCertificateType
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
@ -358,10 +357,14 @@ nssCryptokiCertificate_GetAttributes
return PR_SUCCESS;
}
#ifdef PURE_STAN_BUILD
status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
certObject, CKO_CERTIFICATE,
cert_template, template_size);
if (status != PR_SUCCESS) {
#else
if (PR_TRUE) {
#endif
session = sessionOpt ?
sessionOpt :
@ -402,6 +405,7 @@ nssCryptokiCertificate_GetAttributes
return PR_SUCCESS;
}
#ifdef PURE_STAN_BUILD
static NSSKeyPairType
nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
@ -523,6 +527,7 @@ nssCryptokiPublicKey_GetAttributes
}
return PR_SUCCESS;
}
#endif /* PURE_STAN_BUILD */
static nssTrustLevel
get_nss_trust
@ -572,11 +577,15 @@ nssCryptokiTrust_GetAttributes
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust);
NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
#ifdef PURE_STAN_BUILD
status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
trustObject,
CKO_NETSCAPE_TRUST,
trust_template, trust_size);
if (status != PR_SUCCESS) {
#else
if (PR_TRUE) {
#endif
session = sessionOpt ?
sessionOpt :
nssToken_GetDefaultSession(trustObject->token);
@ -598,6 +607,7 @@ nssCryptokiTrust_GetAttributes
return PR_SUCCESS;
}
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus
nssCryptokiCRL_GetAttributes
(

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

@ -41,7 +41,7 @@
#define CKHELPER_H
#ifdef DEBUG
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.14 $ $Date: 2002/04/04 20:00:21 $ $Name: $";
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.15 $ $Date: 2002/04/15 15:22:00 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSCKT_H
@ -86,6 +86,12 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
(pattr)->ulValueLen = (CK_ULONG)sizeof(var); \
(pattr)++;
#define NSS_CK_SET_ATTRIBUTE_NULL(pattr, kind) \
(pattr)->type = kind; \
(pattr)->pValue = (CK_VOID_PTR)NULL; \
(pattr)->ulValueLen = 0; \
(pattr)++;
#define NSS_CK_TEMPLATE_FINISH(_template, attr, size) \
size = (attr) - (_template); \
PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0]));
@ -127,7 +133,7 @@ nssCKObject_GetAttributes
CK_ULONG count,
NSSArena *arenaOpt,
nssSession *session,
NSSSlot *slot
NSSSlot *slot
);
/* Get a single attribute as an item. */

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

@ -41,7 +41,7 @@
*/
#ifdef DEBUG
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.22 $ $Date: 2002/04/04 20:00:21 $ $Name: $";
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.23 $ $Date: 2002/04/15 15:22:00 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSCKT_H
@ -421,7 +421,6 @@ nssToken_NeedsPINInitialization
NSSToken *token
);
#ifdef PURE_STAN_BUILD
NSS_EXTERN nssCryptokiObject *
nssToken_ImportCertificate
(
@ -603,8 +602,6 @@ nssToken_FindPublicKeyByID
NSSItem *keyID
);
#endif /* PURE_STAN_BUILD */
NSS_EXTERN NSSItem *
nssToken_Digest
(
@ -903,26 +900,18 @@ nssSlotList_GetBestSlotForAlgorithmsAndParameters
NSSAlgorithmAndParameters **ap
);
#ifndef PURE_STAN_BUILD
/* XXX the following remain while merging new work */
#ifdef NSS_3_4_CODE
NSS_EXTERN PRStatus
nssToken_ImportCertificate
NSS_EXTERN PRBool
nssToken_IsPresent
(
NSSToken *tok,
nssSession *sessionOpt,
NSSCertificate *cert,
NSSUTF8 *nickname,
PRBool asTokenObject
NSSToken *token
);
NSS_EXTERN PRStatus
nssToken_ImportTrust
NSS_EXTERN nssSession *
nssToken_GetDefaultSession
(
NSSToken *tok,
nssSession *sessionOpt,
NSSTrust *trust,
PRBool asTokenObject
NSSToken *token
);
NSS_EXTERN PRStatus
@ -949,96 +938,13 @@ nssToken_SetHasCrls
NSSToken *tok
);
/* Permanently remove an object from the token. */
NSS_EXTERN PRStatus
nssToken_DeleteStoredObject
nssToken_GetTrustOrder
(
nssCryptokiInstance *instance
NSSToken *tok
);
NSS_EXTERN NSSTrust *
nssToken_FindTrustForCert
(
NSSToken *token,
nssSession *sessionOpt,
NSSCertificate *c,
nssTokenSearchType searchType
);
NSS_EXTERN PRStatus
nssToken_TraverseCertificates
(
NSSToken *tok,
nssSession *sessionOpt,
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,
nssTokenSearchType searchType
);
NSS_EXTERN NSSCertificate *
nssToken_FindCertificateByEncodedCertificate
(
NSSToken *token,
nssSession *sessionOpt,
NSSBER *encodedCertificate,
nssTokenSearchType searchType
);
NSS_EXTERN NSSTrust *
nssToken_FindTrustForCert
(
NSSToken *token,
nssSession *session,
NSSCertificate *c,
nssTokenSearchType searchType
);
/* exposing this for the smart card cache code */
NSS_EXTERN nssCryptokiInstance *
nssCryptokiInstance_Create
(
NSSArena *arena,
NSSToken *t,
CK_OBJECT_HANDLE h,
PRBool isTokenObject
);
#endif /* !PURE_STAN_BUILD */
#endif
PR_END_EXTERN_C

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

@ -35,7 +35,7 @@
#define DEVT_H
#ifdef DEBUG
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.15 $ $Date: 2002/04/05 15:19:37 $ $Name: $";
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.16 $ $Date: 2002/04/15 15:22:01 $ $Name: $";
#endif /* DEBUG */
/*
@ -144,7 +144,7 @@ typedef enum {
NSSCertificateType_PKIX = 1
} NSSCertificateType;
#ifdef NSS_3_4_CODE
#ifdef nodef
/* the current definition of NSSTrust depends on this value being CK_ULONG */
typedef CK_ULONG nssTrustLevel;
#else
@ -175,7 +175,8 @@ typedef struct nssTokenCertSearchStr nssTokenCertSearch;
typedef enum {
nssTokenSearchType_AllObjects = 0,
nssTokenSearchType_SessionOnly = 1,
nssTokenSearchType_TokenOnly = 2
nssTokenSearchType_TokenOnly = 2,
nssTokenSearchType_TokenForced = 3
} nssTokenSearchType;
struct nssTokenCertSearchStr

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.11 $ $Date: 2002/04/04 20:00:22 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.12 $ $Date: 2002/04/15 15:22:01 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSCKEPV_H
@ -48,6 +48,8 @@ static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.11 $ $D
#endif /* CKHELPER_H */
#ifdef NSS_3_4_CODE
#include "pk11func.h"
#include "dev3hack.h"
#endif
/* The number of object handles to grab during each call to C_FindObjects */
@ -254,7 +256,6 @@ nssToken_NeedsPINInitialization
return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED));
}
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus
nssToken_DeleteStoredObject
(
@ -267,9 +268,11 @@ nssToken_DeleteStoredObject
NSSToken *token = instance->token;
nssSession *session = NULL;
void *epv = nssToken_GetCryptokiEPV(instance->token);
#ifdef PURE_STAN_BUILD
if (token->cache) {
status = nssTokenObjectCache_RemoveObject(token->cache, instance);
}
#endif
if (instance->isTokenObject) {
if (nssSession_IsReadWrite(token->defaultSession)) {
session = token->defaultSession;
@ -304,6 +307,7 @@ import_object
{
nssSession *session = NULL;
PRBool createdSession = PR_FALSE;
nssCryptokiObject *object = NULL;
CK_OBJECT_HANDLE handle;
CK_RV ckrv;
void *epv = nssToken_GetCryptokiEPV(tok);
@ -331,13 +335,13 @@ import_object
objectTemplate, otsize,
&handle);
nssSession_ExitMonitor(session);
if (ckrv == CKR_OK) {
object = nssCryptokiObject_Create(tok, session, handle);
}
if (createdSession) {
nssSession_Destroy(session);
}
if (ckrv != CKR_OK) {
return CK_INVALID_HANDLE;
}
return nssCryptokiObject_Create(tok, session, handle);
return object;
}
static nssCryptokiObject **
@ -421,8 +425,11 @@ find_objects
}
/* bump the number of found objects */
numHandles += count;
if (maximumOpt == 0 || numHandles < arraySize) {
/* either reached maximum, or no more objects to get */
if (maximumOpt > 0 || numHandles < arraySize) {
/* When a maximum is provided, the search is done all at once,
* so the search is finished. If the number returned was less
* than the number sought, the search is finished.
*/
break;
}
/* the array is filled, double it and continue */
@ -469,6 +476,7 @@ find_objects_by_template
CK_OBJECT_CLASS objclass;
nssCryptokiObject **objects = NULL;
PRUint32 i;
#ifdef PURE_STAN_BUILD
for (i=0; i<otsize; i++) {
if (obj_template[i].type == CKA_CLASS) {
objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
@ -487,6 +495,7 @@ find_objects_by_template
maximumOpt);
if (statusOpt) *statusOpt = PR_SUCCESS;
}
#endif /* PURE_STAN_BUILD */
/* Either they are not cached, or cache failed; look on token. */
if (!objects) {
objects = find_objects(token, sessionOpt,
@ -538,11 +547,13 @@ nssToken_ImportCertificate
NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
/* Import the certificate onto the token */
rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);
#ifdef PURE_STAN_BUILD
if (rvObject && tok->cache) {
nssTokenObjectCache_ImportObject(tok->cache, rvObject,
CKO_CERTIFICATE,
cert_tmpl, ctsize);
}
#endif
return rvObject;
}
@ -909,7 +920,12 @@ static void
sha1_hash(NSSItem *input, NSSItem *output)
{
NSSAlgorithmAndParameters *ap;
#ifdef NSS_3_4_CODE
PK11SlotInfo *internal = PK11_GetInternalSlot();
NSSToken *token = PK11Slot_GetNSSToken(internal);
#else
NSSToken *token = nss_GetDefaultCryptoToken();
#endif
ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
(void)nssToken_Digest(token, NULL, ap, input, output, NULL);
#ifdef NSS_3_4_CODE
@ -922,7 +938,12 @@ static void
md5_hash(NSSItem *input, NSSItem *output)
{
NSSAlgorithmAndParameters *ap;
#ifdef NSS_3_4_CODE
PK11SlotInfo *internal = PK11_GetInternalSlot();
NSSToken *token = PK11Slot_GetNSSToken(internal);
#else
NSSToken *token = nss_GetDefaultCryptoToken();
#endif
ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
(void)nssToken_Digest(token, NULL, ap, input, output, NULL);
#ifdef NSS_3_4_CODE
@ -1001,16 +1022,13 @@ nssToken_ImportTrust
NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize);
/* import the trust object onto the token */
object = import_object(tok, sessionOpt, trust_tmpl, tsize);
#ifdef PURE_STAN_BUILD
if (object && tok->cache) {
nssTokenObjectCache_ImportObject(tok->cache, object,
CKO_CERTIFICATE,
trust_tmpl, tsize);
}
/* XXX
if (object) {
tok->hasNoTrust = PR_FALSE;
}
*/
#endif
return object;
}
@ -1144,11 +1162,13 @@ nssToken_ImportCRL
/* import the crl object onto the token */
object = import_object(token, sessionOpt, crl_tmpl, crlsize);
#ifdef PURE_STAN_BUILD
if (object && token->cache) {
nssTokenObjectCache_ImportObject(token->cache, object,
CKO_CERTIFICATE,
crl_tmpl, crlsize);
}
#endif
return object;
}
@ -1191,6 +1211,7 @@ nssToken_FindCRLs
return objects;
}
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus
nssToken_GetCachedObjectAttributes
(
@ -1209,7 +1230,7 @@ nssToken_GetCachedObjectAttributes
object, objclass,
atemplate, atlen);
}
#endif /* PURE_STAN_BUILD */
#endif
NSS_IMPLEMENT NSSItem *
nssToken_Digest
@ -1370,3 +1391,92 @@ nssToken_FinishDigest
return rvItem;
}
#ifdef NSS_3_4_CODE
NSS_IMPLEMENT PRStatus
nssToken_SetTrustCache
(
NSSToken *token
)
{
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE tobj_template[2];
CK_ULONG tobj_size;
nssCryptokiObject **objects;
nssSession *session = token->defaultSession;
NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
objects = find_objects_by_template(token, session,
tobj_template, tobj_size, 1, NULL);
token->hasNoTrust = PR_FALSE;
if (objects) {
nssCryptokiObjectArray_Destroy(objects);
} else {
token->hasNoTrust = PR_TRUE;
}
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
nssToken_SetCrlCache
(
NSSToken *token
)
{
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_CRL;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE tobj_template[2];
CK_ULONG tobj_size;
nssCryptokiObject **objects;
nssSession *session = token->defaultSession;
NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
objects = find_objects_by_template(token, session,
tobj_template, tobj_size, 1, NULL);
token->hasNoCrls = PR_TRUE;
if (objects) {
nssCryptokiObjectArray_Destroy(objects);
} else {
token->hasNoCrls = PR_TRUE;
}
return PR_SUCCESS;
}
NSS_IMPLEMENT PRBool
nssToken_HasCrls
(
NSSToken *tok
)
{
return !tok->hasNoCrls;
}
NSS_IMPLEMENT PRStatus
nssToken_SetHasCrls
(
NSSToken *tok
)
{
tok->hasNoCrls = PR_FALSE;
return PR_SUCCESS;
}
NSS_IMPLEMENT PRBool
nssToken_IsPresent
(
NSSToken *token
)
{
return nssSlot_IsTokenPresent(token->slot);
}
#endif

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.2 $ $Date: 2002/04/04 20:00:23 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.3 $ $Date: 2002/04/15 15:22:01 $ $Name: $";
#endif /* DEBUG */
#ifndef DEVM_H
@ -43,7 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.2 $ $Dat
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT nssCryptokiObject *
nssCryptokiObject_Create
(
@ -161,6 +160,7 @@ nssSlotArray_Clone
return rvSlots;
}
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT void
nssModuleArray_Destroy
(
@ -175,6 +175,7 @@ nssModuleArray_Destroy
nss_ZFreeIf(modules);
}
}
#endif
NSS_IMPLEMENT void
nssSlotArray_Destroy
@ -239,6 +240,7 @@ nssCryptokiObjectArray_Destroy
}
}
#ifdef PURE_STAN_BUILD
/*
* Slot lists
*/

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

@ -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.6 $ $Date: 2002/04/04 20:00:23 $ $Name: $"
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.7 $ $Date: 2002/04/15 15:22:01 $ $Name: $"
CORE_DEPTH = ../../..
@ -50,7 +50,6 @@ MODULE = security
CSRCS = \
devmod.c \
devslot.c \
devobject.c \
devtoken.c \
devutil.c \
ckhelper.c \

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.10 $ $Date: 2002/04/04 20:00:26 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.11 $ $Date: 2002/04/15 15:22:04 $ $Name: $";
#endif /* DEBUG */
#ifndef NSS_3_4_CODE
@ -173,6 +173,15 @@ nssSlot_IsPermanent
return slot->pk11slot->isPerm;
}
NSS_IMPLEMENT PRBool
nssSlot_IsFriendly
(
NSSSlot *slot
)
{
return PK11_IsFriendly(slot->pk11slot);
}
NSS_IMPLEMENT PRStatus
nssToken_Refresh(NSSToken *token)
{
@ -203,6 +212,19 @@ nssSlot_Refresh
return nssToken_Refresh(slot->token);
}
NSS_IMPLEMENT PRStatus
nssToken_GetTrustOrder
(
NSSToken *tok
)
{
PK11SlotInfo *slot;
SECMODModule *module;
slot = tok->pk11slot;
module = PK11_GetModule(slot);
return module->trustOrder;
}
NSSTrustDomain *

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

@ -89,50 +89,6 @@ static PRStatus convert_cert(NSSCertificate *c, void *arg)
return (secrv) ? PR_FAILURE : PR_SUCCESS;
}
static PRStatus convert_and_cache_cert(NSSCertificate *c, void *arg)
{
PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
struct nss3_cert_cbstr *nss3cb = (struct nss3_cert_cbstr *)arg;
NSSCertificate *cp = nssCertificate_AddRef(c);
/* The cert coming in has been retrieved from a token. It was not in
* the cache when the search was begun. But it may be in the cache now,
* and if it isn't, it will be, because it is going to be cracked into
* a CERTCertificate and fed into the callback.
*/
nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1);
/* This is why the hack of copying the cert was done above. The pointer
* c passed to this function is provided by retrieve_cert. That function
* will destroy the pointer once this function returns. Since c is a local
* copy, there is no way to notify retrieve_cert if it has changed. That
* would happen if the above call to add it to the cache found the cert
* already there. In that case, the pointer c passed to the callback
* below will be the cached cert, and the pointer c that retrieve_cert
* has will be the same as the copy made above. Thus, retrieve_cert will
* destroy the reference to the copy, the callback will use the reference
* to the cached entry, and everyone should be happy.
*/
nssrv = convert_cert(c, arg);
/* This function owns a reference to the cert, either from the AddRef
* or by getting it from the cache.
*/
CERT_DestroyCertificate(STAN_GetCERTCertificate(c));
return nssrv;
}
/* this is redeclared from trustdomain.c, but this code is just 3.4 glue
* anyway
*/
static void cert_destructor(void *el)
{
NSSCertificate *c = (NSSCertificate *)el;
CERTCertificate *cert = STAN_GetCERTCertificate(c);
/* It's already been obtained as a CERTCertificate, so it must
* be destroyed as one
*/
CERT_DestroyCertificate(cert);
}
void
PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
{
@ -1215,58 +1171,6 @@ 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 = nssCertificate_AddRef(c);
return PR_SUCCESS;
}
dc = nssCertificate_GetDecoding(c);
founddc = nssCertificate_GetDecoding(*cfound);
if (!founddc->isNewerThan(founddc, dc)) {
CERT_DestroyCertificate(STAN_GetCERTCertificate(*cfound));
*cfound = nssCertificate_AddRef(c);
}
return PR_SUCCESS;
}
struct token_cbstr {
NSSToken *token;
PRStatus (* callback)(NSSCertificate *c, void *arg);
void *cbarg;
};
/* This callback matches all certs on a given token. It is used to filter
* cert lists to only those certs on a particular token.
*/
static PRStatus
token_callback(NSSCertificate *c, void *arg)
{
nssListIterator *instances;
nssCryptokiInstance *instance;
PRBool isToken = PR_FALSE;
struct token_cbstr *token_cb = (struct token_cbstr *)arg;
instances = c->object.instances;
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
if (instance->token == token_cb->token) {
isToken = PR_TRUE;
break;
}
}
nssListIterator_Finish(instances);
if (isToken) {
return (*token_cb->callback)(c, token_cb->cbarg);
} else {
return PR_SUCCESS;
}
}
/* match all token certs with a nickname */
static nssList *
filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname)
@ -1286,7 +1190,7 @@ filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname)
cert != (NSSCertificate *)NULL;
cert = (NSSCertificate *)nssListIterator_Next(certs))
{
NSSUTF8 *tokenNick = NSSCertificate_GetNickname(cert, token);
NSSUTF8 *tokenNick = nssCertificate_GetNickname(cert, token);
if (!tokenNick) continue;
if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) {
nssList_Add(rvList, nssCertificate_AddRef(cert));
@ -1334,6 +1238,38 @@ filter_token_certs_email(NSSToken *token, NSSASCII7 *email)
return rvList;
}
static void
transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
nssPKIObjectCollection *collection)
{
NSSCertificate **certs;
PRUint32 i, count;
NSSToken **tokens, **tp;
count = nssList_Count(certList);
if (count == 0) {
return;
}
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
if (!certs) {
return;
}
nssList_GetArray(certList, (void **)certs, count);
for (i=0; i<count; i++) {
tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL);
if (tokens) {
for (tp = tokens; *tp; tp++) {
if (*tp == token) {
nssPKIObjectCollection_AddObject(collection,
(nssPKIObject *)certs[i]);
}
}
nssTokenArray_Destroy(tokens);
}
CERT_DestroyCertificate(STAN_GetCERTCertificate(certs[i]));
}
nss_ZFreeIf(certs);
}
CERTCertificate *
PK11_FindCertFromNickname(char *nickname, void *wincx) {
#ifdef NSS_CLASSIC
@ -1349,8 +1285,10 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
PORT_Free(certID);
return cert;
#else
PRStatus status;
CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL;
NSSCertificate **certs = NULL;
NSSUsage usage;
NSSToken *token;
PK11SlotInfo *slot = NULL;
@ -1375,111 +1313,89 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot);
}
if (token) {
nssTokenCertSearch search;
struct token_cbstr token_cb;
nssList *certList;
nssCryptokiObject **instances;
nssPKIObjectCollection *collection;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
if (!PK11_IsPresent(slot)) {
return NULL;
goto loser;
}
if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
PK11_FreeSlot(slot);
return NULL;
goto loser;
}
}
/* find best cert on token */
collection = nssCertificateCollection_Create(defaultTD, NULL);
if (!collection) {
goto loser;
}
if (!nssToken_SearchCerts(token, NULL)) {
/* token certs are in cache, filter the list of token certs to
* match the nickname
*/
certList = filter_token_certs_nickname(token, nickname);
if (certList) {
nssCertificateList_DoCallback(certList,
get_newest_cert,
(void *)&cert);
}
transfer_token_certs_to_collection(certList, token, collection);
nssList_Destroy(certList);
} else {
/* find matching certs on the token */
certList = nssList_Create(NULL, PR_FALSE);
if (!certList) return NULL;
/* first, get all matching certs from the cache */
if (!certList) {
nssPKIObjectCollection_Destroy(collection);
goto loser;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname,
certList);
/* set the search criteria */
token_cb.callback = get_newest_cert;
token_cb.cbarg = (void *)&cert;
token_cb.token = token;
search.callback = token_callback;
search.cbarg = &token_cb;
search.cached = certList;
search.searchType = nssTokenSearchType_TokenOnly;
/* now search the token */
nssToken_TraverseCertificatesByNickname(token, NULL,
(NSSUTF8 *)nickname,
&search);
/* filter the list of cached certs for only those on the token */
nssCertificateList_DoCallback(certList,
token_callback,
&token_cb);
}
if (certList) {
nssList_Clear(certList, cert_destructor);
nssList_Destroy(certList);
transfer_token_certs_to_collection(certList, token, collection);
instances = nssToken_FindCertificatesByNickname(token,
NULL,
nickname,
tokenOnly,
0,
&status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
/* if it wasn't found, repeat the process for email address */
if (!cert) {
if (nssPKIObjectCollection_Count(collection) == 0) {
if (!nssToken_SearchCerts(token, NULL)) {
certList = filter_token_certs_email(token, nickname);
if (certList) {
nssCertificateList_DoCallback(certList,
get_newest_cert,
(void *)&cert);
}
transfer_token_certs_to_collection(certList, token, collection);
nssList_Destroy(certList);
} else {
certList = nssList_Create(NULL, PR_FALSE);
if (!certList) return NULL;
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(
defaultTD,
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
nickname,
certList);
search.cached = certList;
nssToken_TraverseCertificatesByEmail(token, NULL,
(NSSASCII7 *)nickname,
&search);
nssCertificateList_DoCallback(certList,
token_callback,
&token_cb);
}
if (certList) {
nssList_Clear(certList, cert_destructor);
nssList_Destroy(certList);
transfer_token_certs_to_collection(certList, token, collection);
instances = nssToken_FindCertificatesByEmail(token,
NULL,
nickname,
tokenOnly,
0,
&status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
}
if (cert) {
(void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1);
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
if (certs) {
cert = nssCertificateArray_FindBestCertificate(certs, NULL,
&usage, NULL);
rvCert = STAN_GetCERTCertificate(cert);
nssCertificateArray_Destroy(certs);
}
nssList_Destroy(certList);
}
if (slot) {
PK11_FreeSlot(slot);
}
if (nickCopy) PORT_Free(nickCopy);
return rvCert;
#endif
}
static PRStatus
collect_certs(NSSCertificate *c, void *arg)
{
nssList *list = (nssList *)arg;
/* Add the cert to the return list if not present */
if (!nssList_Get(list, (void *)c)) {
nssCertificate_AddRef(c);
nssList_Add(list, (void *)c);
loser:
if (slot) {
PK11_FreeSlot(slot);
}
return PR_SUCCESS;
if (nickCopy) PORT_Free(nickCopy);
return NULL;
#endif
}
CERTCertList *
@ -1509,12 +1425,12 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
PORT_Free(certID);
return certList;
#else
PRStatus nssrv;
char *nickCopy;
char *delimit = NULL;
char *tokenName;
int i;
CERTCertList *certList = NULL;
nssPKIObjectCollection *collection = NULL;
NSSCertificate **foundCerts = NULL;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
NSSCertificate *c;
@ -1538,8 +1454,6 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot);
}
if (token) {
nssTokenCertSearch search;
PRUint32 count;
nssList *nameList;
if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
@ -1547,28 +1461,40 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
return NULL;
}
}
collection = nssCertificateCollection_Create(defaultTD, NULL);
if (!collection) {
PK11_FreeSlot(slot);
return NULL;
}
if (!nssToken_SearchCerts(token, NULL)) {
nameList = filter_token_certs_nickname(token, nickname);
transfer_token_certs_to_collection(nameList, token, collection);
} else {
PRStatus status;
nssCryptokiObject **instances;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) return NULL;
if (!nameList) {
PK11_FreeSlot(slot);
return NULL;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname,
nameList);
/* set the search criteria */
search.callback = collect_certs;
search.cbarg = nameList;
search.cached = nameList;
search.searchType = nssTokenSearchType_TokenOnly;
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
nickname, &search);
}
if (nameList) {
count = nssList_Count(nameList);
foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
nssList_GetArray(nameList, (void **)foundCerts, count);
nssList_Destroy(nameList);
transfer_token_certs_to_collection(nameList, token, collection);
instances = nssToken_FindCertificatesByNickname(token,
NULL,
nickname,
tokenOnly,
0,
&status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
nssList_Destroy(nameList);
foundCerts = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
}
if (slot) {
PK11_FreeSlot(slot);
@ -1815,10 +1741,7 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
instance->token = slot->nssToken;
instance->handle = cert->pkcs11ID;
instance->isTokenObject = PR_TRUE;
nssList_Add(c->object.instanceList, instance);
/* XXX Fix this! */
nssListIterator_Destroy(c->object.instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
nssPKIObject_AddInstance(&c->object, instance);
} else {
cert->nssCertificate = STAN_GetNSSCertificate(cert);
}
@ -2629,40 +2552,6 @@ filter_token_certs_subject(NSSToken *token, NSSDER *subject)
return rvList;
}
/* remove all certs in a list that are not on the given token */
static void
filter_list_for_token_certs(nssList *certList, NSSToken *token)
{
nssListIterator *instances, *certs;
nssCryptokiInstance *instance;
NSSCertificate *c;
PRBool isToken = PR_FALSE;
certs = nssList_CreateIterator(certList);
if (!certs) return;
for (c = (NSSCertificate *)nssListIterator_Start(certs);
c != (NSSCertificate *)NULL;
c = (NSSCertificate *)nssListIterator_Next(certs)) {
instances = c->object.instances;
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
if (instance->token == token) {
isToken = PR_TRUE;
break;
}
}
nssListIterator_Finish(instances);
if (!isToken) {
/* safe since iterator is copied */
nssList_Remove(certList, c);
CERT_DestroyCertificate(STAN_GetCERTCertificate(c));
}
}
nssListIterator_Finish(certs);
nssListIterator_Destroy(certs);
}
SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
@ -2695,48 +2584,51 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg);
#else
struct nss3_cert_cbstr pk11cb;
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
NSSDER subject;
NSSTrustDomain *td;
nssList *subjectList;
nssTokenCertSearch search;
pk11cb.callback = callback;
pk11cb.arg = arg;
nssPKIObjectCollection *collection;
nssCryptokiObject **instances;
NSSCertificate **certs;
td = STAN_GetDefaultTrustDomain();
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
token = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!nssToken_SearchCerts(token, NULL)) {
subjectList = filter_token_certs_subject(token, &subject);
if (subjectList) {
nssrv = nssCertificateList_DoCallback(subjectList,
convert_cert, &pk11cb);
}
transfer_token_certs_to_collection(subjectList, token, collection);
} else {
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
subjectList = nssList_Create(NULL, PR_FALSE);
if (!subjectList) {
return SECFailure;
}
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
subjectList);
/* set the search criteria */
search.callback = convert_and_cache_cert;
search.cbarg = &pk11cb;
search.cached = subjectList;
search.searchType = nssTokenSearchType_TokenOnly;
pk11cb.cached = subjectList;
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
&subject, &search);
if (nssrv == PR_SUCCESS) {
filter_list_for_token_certs(subjectList, token);
nssrv = nssCertificateList_DoCallback(subjectList,
convert_cert, &pk11cb);
}
transfer_token_certs_to_collection(subjectList, token, collection);
instances = nssToken_FindCertificatesBySubject(token, NULL,
&subject,
tokenOnly, 0, &nssrv);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
if (subjectList) {
nssList_Clear(subjectList, cert_destructor);
nssList_Destroy(subjectList);
nssList_Destroy(subjectList);
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
if (certs) {
CERTCertificate *oldie;
NSSCertificate **cp;
for (cp = certs; *cp; cp++) {
oldie = STAN_GetCERTCertificate(*cp);
if ((*callback)(oldie, arg) != SECSuccess) {
nssrv = PR_FAILURE;
break;
}
}
nssCertificateArray_Destroy(certs);
}
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
@ -2785,7 +2677,9 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
NSSTrustDomain *td;
NSSUTF8 *nick;
PRBool created = PR_FALSE;
nssTokenCertSearch search;
nssCryptokiObject **instances;
nssPKIObjectCollection *collection;
NSSCertificate **certs;
nssList *nameList;
pk11cb.callback = callback;
pk11cb.arg = arg;
@ -2798,32 +2692,39 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
}
td = STAN_GetDefaultTrustDomain();
token = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!nssToken_SearchCerts(token, NULL)) {
nameList = filter_token_certs_nickname(token, nick);
if (nameList) {
nssrv = nssCertificateList_DoCallback(nameList,
convert_cert, &pk11cb);
}
transfer_token_certs_to_collection(nameList, token, collection);
} else {
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
nameList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
/* set the search criteria */
search.callback = convert_and_cache_cert;
search.cbarg = &pk11cb;
search.cached = nameList;
search.searchType = nssTokenSearchType_TokenOnly;
pk11cb.cached = nameList;
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
nick, &search);
if (nssrv == PR_SUCCESS) {
filter_list_for_token_certs(nameList, token);
nssrv = nssCertificateList_DoCallback(nameList,
convert_cert, &pk11cb);
if (!nameList) {
return SECFailure;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
transfer_token_certs_to_collection(nameList, token, collection);
instances = nssToken_FindCertificatesByNickname(token, NULL,
nick,
tokenOnly, 0, &nssrv);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
if (nameList) {
nssList_Clear(nameList, cert_destructor);
nssList_Destroy(nameList);
nssList_Destroy(nameList);
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
if (certs) {
CERTCertificate *oldie;
NSSCertificate **cp;
for (cp = certs; *cp; cp++) {
oldie = STAN_GetCERTCertificate(*cp);
if ((*callback)(oldie, arg) != SECSuccess) {
nssrv = PR_FAILURE;
break;
}
}
nssCertificateArray_Destroy(certs);
}
if (created) nss_ZFreeIf(nick);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
@ -2862,36 +2763,47 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
#else
PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
struct nss3_cert_cbstr pk11cb;
NSSToken *tok;
nssList *certList = NULL;
nssTokenCertSearch search;
pk11cb.callback = callback;
pk11cb.arg = arg;
nssCryptokiObject **instances;
nssPKIObjectCollection *collection;
NSSCertificate **certs;
tok = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
return SECFailure;
}
if (!nssToken_SearchCerts(tok, NULL)) {
certList = tok->certList;
nssrv = nssCertificateList_DoCallback(certList, convert_cert, &pk11cb);
certList = nssList_Clone(tok->certList);
transfer_token_certs_to_collection(certList, tok, collection);
} else {
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
certList = nssList_Create(NULL, PR_FALSE);
if (!certList) {
return SECFailure;
}
(void *)nssTrustDomain_GetCertsFromCache(td, certList);
/* set the search criteria */
search.callback = convert_and_cache_cert;
search.cbarg = &pk11cb;
search.cached = certList;
search.searchType = nssTokenSearchType_TokenOnly;
pk11cb.cached = certList;
nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
if (nssrv == PR_SUCCESS) {
filter_list_for_token_certs(certList, tok);
nssrv = nssCertificateList_DoCallback(certList,
convert_cert, &pk11cb);
transfer_token_certs_to_collection(certList, tok, collection);
instances = nssToken_FindCertificates(tok, NULL,
tokenOnly, 0, &nssrv);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
nssList_Destroy(certList);
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
if (certs) {
CERTCertificate *oldie;
NSSCertificate **cp;
for (cp = certs; *cp; cp++) {
oldie = STAN_GetCERTCertificate(*cp);
if ((*callback)(oldie, arg) != SECSuccess) {
nssrv = PR_FAILURE;
break;
}
}
nssList_Clear(certList, cert_destructor);
nssList_Destroy(certList);
nssCertificateArray_Destroy(certs);
}
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
@ -2973,11 +2885,24 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
if (!nssToken_SearchCerts(tok, NULL)) {
c = filter_token_certs_DER(tok, &derCert);
} else {
c = nssTrustDomain_GetCertByDERFromCache(td, &derCert);
if (!c) {
c = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
&derCert,
nssTokenSearchType_TokenOnly);
c = NSSTrustDomain_FindCertificateByEncodedCertificate(td, &derCert);
if (c) {
PRBool isToken = PR_FALSE;
NSSToken **tp;
NSSToken **tokens = nssPKIObject_GetTokens(&c->object, NULL);
if (tokens) {
for (tp = tokens; *tp; tp++) {
if (*tp == tok) {
isToken = PR_TRUE;
break;
}
}
if (!isToken) {
NSSCertificate_Destroy(c);
c = NULL;
}
nssTokenArray_Destroy(tokens);
}
}
}
if (c) {

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.11 $ $Date: 2002/02/04 22:34:22 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.12 $ $Date: 2002/04/15 15:22:07 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
@ -43,78 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.11 $
#include "pkim.h"
#endif /* PKIM_H */
/* XXX
* move this to a more appropriate location
*/
NSS_IMPLEMENT PRStatus
nssPKIObject_Initialize
(
struct nssPKIObjectBaseStr *object,
NSSArena *arena,
NSSTrustDomain *td,
NSSCryptoContext *cc
)
{
object->arena = arena;
object->trustDomain = td;
object->cryptoContext = cc;
object->lock = PZ_NewLock(nssILockOther);
if (!object->lock) {
return PR_FAILURE;
}
object->instanceList = nssList_Create(arena, PR_TRUE);
if (!object->instanceList) {
PZ_DestroyLock(object->lock);
return PR_FAILURE;
}
object->instances = nssList_CreateIterator(object->instanceList);
if (!object->instances) {
nssList_Destroy(object->instanceList);
PZ_DestroyLock(object->lock);
return PR_FAILURE;
}
object->refCount = 1;
return PR_SUCCESS;
}
/* XXX
* move this to a more appropriate location
*/
NSS_IMPLEMENT void
nssPKIObject_AddRef
(
struct nssPKIObjectBaseStr *object
)
{
PZ_Lock(object->lock);
object->refCount++;
PZ_Unlock(object->lock);
}
/* XXX
* move this to a more appropriate location
*/
NSS_IMPLEMENT PRBool
nssPKIObject_Destroy
(
struct nssPKIObjectBaseStr *object
)
{
PRUint32 refCount;
PZ_Lock(object->lock);
PORT_Assert(object->refCount > 0);
refCount = --object->refCount;
PZ_Unlock(object->lock);
if (refCount == 0) {
PZ_DestroyLock(object->lock);
nssListIterator_Destroy(object->instances);
nssList_Destroy(object->instanceList);
nssArena_Destroy(object->arena);
return PR_TRUE;
}
return PR_FALSE;
}
#ifdef NSS_3_4_CODE
/* This is defined in nss3hack.c */
NSS_EXTERN nssDecodedCert *
@ -194,39 +122,3 @@ nssDecodedCert_Destroy
return PR_FAILURE;
}
/* Of course none of this belongs here */
/* how bad would it be to have a static now sitting around, updated whenever
* this was called? would avoid repeated allocs...
*/
NSS_IMPLEMENT NSSTime *
NSSTime_Now
(
NSSTime *timeOpt
)
{
return NSSTime_SetPRTime(timeOpt, PR_Now());
}
NSS_IMPLEMENT NSSTime *
NSSTime_SetPRTime
(
NSSTime *timeOpt,
PRTime prTime
)
{
NSSTime *rvTime;
rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime);
rvTime->prTime = prTime;
return rvTime;
}
NSS_IMPLEMENT PRTime
NSSTime_GetPRTime
(
NSSTime *time
)
{
return time->prTime;
}

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.33 $ $Date: 2002/03/07 22:07:55 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.34 $ $Date: 2002/04/15 15:22:07 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
@ -61,6 +61,40 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.33 $
extern const NSSError NSS_ERROR_NOT_FOUND;
/* Creates a certificate from a base object */
NSS_IMPLEMENT NSSCertificate *
nssCertificate_Create
(
nssPKIObject *object
)
{
PRStatus status;
NSSCertificate *rvCert;
/* mark? */
NSSArena *arena = object->arena;
PR_ASSERT(object->instances != NULL && object->numInstances > 0);
rvCert = nss_ZNEW(arena, NSSCertificate);
if (!rvCert) {
return (NSSCertificate *)NULL;
}
rvCert->object = *object;
/* XXX should choose instance based on some criteria */
status = nssCryptokiCertificate_GetAttributes(object->instances[0],
NULL, /* XXX sessionOpt */
arena,
&rvCert->type,
&rvCert->id,
&rvCert->encoding,
&rvCert->issuer,
&rvCert->serial,
&rvCert->subject,
&rvCert->email);
if (status != PR_SUCCESS) {
return (NSSCertificate *)NULL;
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef
(
@ -74,7 +108,7 @@ nssCertificate_AddRef
}
NSS_IMPLEMENT PRStatus
NSSCertificate_Destroy
nssCertificate_Destroy
(
NSSCertificate *c
)
@ -92,37 +126,84 @@ NSSCertificate_Destroy
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
NSSCertificate_Destroy
(
NSSCertificate *c
)
{
return nssCertificate_Destroy(c);
}
NSS_IMPLEMENT NSSDER *
nssCertificate_GetEncoding
(
NSSCertificate *c
)
{
if (c->encoding.size > 0 && c->encoding.data) {
return &c->encoding;
} else {
return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSDER *
nssCertificate_GetIssuer
(
NSSCertificate *c
)
{
if (c->issuer.size > 0 && c->issuer.data) {
return &c->issuer;
} else {
return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSDER *
nssCertificate_GetSerialNumber
(
NSSCertificate *c
)
{
if (c->serial.size > 0 && c->serial.data) {
return &c->serial;
} else {
return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSDER *
nssCertificate_GetSubject
(
NSSCertificate *c
)
{
if (c->subject.size > 0 && c->subject.data) {
return &c->subject;
} else {
return (NSSDER *)NULL;
}
}
NSS_IMPLEMENT NSSUTF8 *
NSSCertificate_GetNickname
nssCertificate_GetNickname
(
NSSCertificate *c,
NSSToken *tokenOpt
)
{
NSSUTF8 *rvNick = NULL;
nssCryptokiInstance *instance;
nssListIterator *instances = c->object.instances;
if (c->object.cryptoContext) {
return c->object.tempName;
}
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
if (tokenOpt) {
if (instance->token == tokenOpt) {
/* take the nickname on the given token */
rvNick = instance->label;
break;
}
} else {
/* take the first one */
rvNick = instance->label;
break;
}
}
nssListIterator_Finish(instances);
return rvNick;
return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
}
NSS_IMPLEMENT NSSASCII7 *
nssCertificate_GetEmailAddress
(
NSSCertificate *c
)
{
return c->email;
}
NSS_IMPLEMENT PRStatus
@ -132,39 +213,7 @@ NSSCertificate_DeleteStoredObject
NSSCallback *uhh
)
{
/* this needs more thought on what will happen when there are multiple
* instances
*/
/* XXX use callback to log in if neccessary */
PRStatus nssrv = PR_SUCCESS;
nssCryptokiInstance *instance;
nssListIterator *instances = c->object.instances;
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
/* XXX this should be fixed to understand read-only tokens, for
* now, to handle the builtins, just make the attempt.
*/
nssrv = nssToken_DeleteStoredObject(instance);
if (nssrv == PR_SUCCESS) {
nssList_Remove(c->object.instanceList, instance);
#ifdef NSS_3_4_CODE
if (instance->token->certList) {
/* If the cert has been cached locally on the token, remove
* that reference
*/
nssList_Remove(instance->token->certList, c);
NSSCertificate_Destroy(c);
}
#endif
}
}
nssListIterator_Finish(instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
nssListIterator_Destroy(instances);
/* XXX for now, always success */
return PR_SUCCESS;
return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
}
NSS_IMPLEMENT PRStatus
@ -238,85 +287,171 @@ nssCertificate_GetDecoding
return c->decoding;
}
static void
nssCertificateArray_Destroy
(
NSSCertificate **certArray
)
{
NSSCertificate **ci;
ci = certArray;
while (ci && *ci) {
NSSCertificate_Destroy(*ci);
ci++;
}
nss_ZFreeIf(certArray);
}
static NSSCertificate *
filter_subject_certs_for_id(NSSCertificate **subjectCerts, NSSItem *id)
filter_subject_certs_for_id
(
NSSCertificate **subjectCerts,
NSSItem *id
)
{
NSSCertificate **si;
NSSCertificate *rvCert = NULL;
nssDecodedCert *dcp;
/* walk the subject certs */
si = subjectCerts;
while (*si) {
for (si = subjectCerts; *si; si++) {
dcp = nssCertificate_GetDecoding(*si);
if (dcp->matchIdentifier(dcp, id)) {
/* this cert has the correct identifier */
rvCert = nssCertificate_AddRef(*si);
break;
}
si++;
}
return rvCert;
}
static NSSCertificate *
find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
find_cert_issuer
(
NSSCertificate *c,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt
)
{
NSSCertificate *rvCert = NULL;
NSSCertificate **subjectCerts = NULL;
NSSArena *arena;
NSSCertificate **certs = NULL;
NSSCertificate **ccIssuers = NULL;
NSSCertificate **tdIssuers = NULL;
NSSCertificate *issuer = NULL;
NSSTrustDomain *td;
NSSCryptoContext *cc;
/* Find all certs with this cert's issuer as the subject */
cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */
td = NSSCertificate_GetTrustDomain(c);
#ifdef NSS_3_4_CODE
if (!td) {
td = STAN_GetDefaultTrustDomain();
}
#endif
arena = nssArena_Create();
if (!arena) {
return (NSSCertificate *)NULL;
}
if (cc) {
subjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc,
&c->issuer,
NULL,
0,
NULL);
if (subjectCerts) {
rvCert = filter_subject_certs_for_id(subjectCerts, id);
nssCertificateArray_Destroy(subjectCerts);
}
ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
&c->issuer,
NULL,
0,
arena);
}
if (!rvCert) {
/* The general behavior of NSS <3.4 seems to be that if the search
* turns up empty in the temp db, fall back to the perm db,
* irregardless of whether or not the cert itself is perm or temp.
* This is replicated here.
*/
td = NSSCertificate_GetTrustDomain(c);
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td,
&c->issuer,
NULL,
0,
NULL);
if (subjectCerts) {
rvCert = filter_subject_certs_for_id(subjectCerts, id);
nssCertificateArray_Destroy(subjectCerts);
tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
&c->issuer,
NULL,
0,
arena);
certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
if (certs) {
nssDecodedCert *dc = NULL;
NSSItem *issuerID = NULL;
dc = nssCertificate_GetDecoding(c);
if (dc) {
issuerID = dc->getIssuerIdentifier(dc);
}
if (issuerID) {
issuer = filter_subject_certs_for_id(certs, issuerID);
nssItem_Destroy(issuerID);
} else {
issuer = nssCertificateArray_FindBestCertificate(certs,
timeOpt,
usage,
policiesOpt);
}
nssCertificateArray_Destroy(certs);
}
return rvCert;
nssArena_Destroy(arena);
return issuer;
}
/* XXX review based on CERT_FindCertIssuer
* this function is not using the authCertIssuer field as a fallback
* if authority key id does not exist
*/
NSS_IMPLEMENT NSSCertificate **
nssCertificate_BuildChain
(
NSSCertificate *c,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt,
NSSCertificate **rvOpt,
PRUint32 rvLimit,
NSSArena *arenaOpt,
PRStatus *statusOpt
)
{
PRStatus status;
NSSCertificate **rvChain;
#ifdef NSS_3_4_CODE
NSSCertificate *cp;
#endif
NSSTrustDomain *td;
nssPKIObjectCollection *collection;
td = NSSCertificate_GetTrustDomain(c);
#ifdef NSS_3_4_CODE
if (!td) {
td = STAN_GetDefaultTrustDomain();
}
#endif
if (statusOpt) *statusOpt = PR_SUCCESS;
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
if (statusOpt) *statusOpt = PR_FAILURE;
return (NSSCertificate **)NULL;
}
nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
if (rvLimit == 1) {
goto finish;
}
while (!nssItem_Equal(&c->subject, &c->issuer, &status)) {
#ifdef NSS_3_4_CODE
cp = c;
#endif
c = find_cert_issuer(c, timeOpt, usage, policiesOpt);
#ifdef NSS_3_4_CODE
if (!c) {
PRBool tmpca = usage->nss3lookingForCA;
usage->nss3lookingForCA = PR_TRUE;
c = find_cert_issuer(cp, timeOpt, usage, policiesOpt);
if (!c && !usage->anyUsage) {
usage->anyUsage = PR_TRUE;
c = find_cert_issuer(cp, timeOpt, usage, policiesOpt);
usage->anyUsage = PR_FALSE;
}
usage->nss3lookingForCA = tmpca;
}
#endif /* NSS_3_4_CODE */
if (c) {
nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
nssCertificate_Destroy(c); /* collection has it */
if (rvLimit > 0 &&
nssPKIObjectCollection_Count(collection) == rvLimit)
{
break;
}
} else {
nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
if (statusOpt) *statusOpt = PR_FAILURE;
break;
}
}
finish:
rvChain = nssPKIObjectCollection_GetCertificates(collection,
rvOpt,
rvLimit,
arenaOpt);
nssPKIObjectCollection_Destroy(collection);
return rvChain;
}
NSS_IMPLEMENT NSSCertificate **
NSSCertificate_BuildChain
(
@ -330,129 +465,26 @@ NSSCertificate_BuildChain
PRStatus *statusOpt
)
{
PRStatus nssrv;
nssList *chain;
NSSItem *issuerID;
NSSCertificate **rvChain;
NSSTrustDomain *td;
NSSCryptoContext *cc;
nssDecodedCert *dc;
NSSCertificate *ct, *cp;
cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */
td = NSSCertificate_GetTrustDomain(c);
#ifdef NSS_3_4_CODE
if (!td) {
td = STAN_GetDefaultTrustDomain();
}
#endif
chain = nssList_Create(NULL, PR_FALSE);
nssList_Add(chain, nssCertificate_AddRef(c));
if (statusOpt) *statusOpt = PR_SUCCESS;
if (rvLimit == 1) goto finish;
while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) {
dc = nssCertificate_GetDecoding(c);
issuerID = dc->getIssuerIdentifier(dc);
if (issuerID) {
c = find_issuer_cert_for_identifier(c, issuerID);
nssItem_Destroy(issuerID);
issuerID = NULL;
if (!c) {
nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
if (statusOpt) *statusOpt = PR_FAILURE;
goto finish;
}
} else {
nssBestCertificateCB best;
NSSDER *issuer = &c->issuer;
#ifdef NSS_3_4_CODE
PRBool tmpca = usage->nss3lookingForCA;
usage->nss3lookingForCA = PR_TRUE;
#endif
c = ct = cp = NULL;
if (cc) {
ct = NSSCryptoContext_FindBestCertificateBySubject(cc,
issuer,
timeOpt,
usage,
policiesOpt);
/* Mimic functionality from CERT_FindCertIssuer. If a matching
* cert (based on trust & usage) cannot be found, just take the
* newest cert with the correct subject.
*/
if (!ct && !usage->anyUsage) {
usage->anyUsage = PR_TRUE;
ct = NSSCryptoContext_FindBestCertificateBySubject(cc,
issuer,
timeOpt,
usage,
policiesOpt);
usage->anyUsage = PR_FALSE;
}
}
cp = NSSTrustDomain_FindBestCertificateBySubject(td,
issuer,
timeOpt,
usage,
policiesOpt);
/* Mimic functionality from CERT_FindCertIssuer. If a matching
* cert (based on trust & usage) cannot be found, just take the
* newest cert with the correct subject.
*/
if (!cp && !usage->anyUsage) {
usage->anyUsage = PR_TRUE;
cp = NSSTrustDomain_FindBestCertificateBySubject(td,
issuer,
timeOpt,
usage,
policiesOpt);
usage->anyUsage = PR_FALSE;
}
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
/* Take the better of the best temp and best perm cert, according
* to the given usage
*/
if (ct) {
nssBestCertificate_Callback(ct, (void *)&best);
}
if (cp) {
nssBestCertificate_Callback(cp, (void *)&best);
}
if (!best.cert) {
best.usage->anyUsage = PR_TRUE;
/* Take the newest of the best temp and best perm cert */
if (ct) {
nssBestCertificate_Callback(ct, (void *)&best);
}
if (cp) {
nssBestCertificate_Callback(cp, (void *)&best);
}
}
if (ct) NSSCertificate_Destroy(ct);
if (cp) NSSCertificate_Destroy(cp);
c = best.cert;
#ifdef NSS_3_4_CODE
usage->nss3lookingForCA = tmpca;
#endif
if (!c) {
nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
if (statusOpt) *statusOpt = PR_FAILURE;
goto finish;
}
}
nssList_Add(chain, c);
if (nssList_Count(chain) == rvLimit) goto finish;
}
finish:
if (rvOpt) {
rvChain = rvOpt;
} else {
rvLimit = nssList_Count(chain);
rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1);
}
nssList_GetArray(chain, (void **)rvChain, rvLimit);
nssList_Destroy(chain);
/* XXX now, the question is, cache all certs in the chain? */
return rvChain;
return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
rvOpt, rvLimit, arenaOpt, statusOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
nssCertificate_GetCryptoContext
(
NSSCertificate *c
)
{
return c->object.cryptoContext;
}
NSS_IMPLEMENT NSSTrustDomain *
nssCertificate_GetTrustDomain
(
NSSCertificate *c
)
{
return c->object.trustDomain;
}
NSS_IMPLEMENT NSSTrustDomain *
@ -461,7 +493,7 @@ NSSCertificate_GetTrustDomain
NSSCertificate *c
)
{
return c->object.trustDomain;
return nssCertificate_GetTrustDomain(c);
}
NSS_IMPLEMENT NSSToken *
@ -825,22 +857,24 @@ nssSMIMEProfile_Create
NSSItem *profileData
)
{
PRStatus nssrv;
NSSArena *arena;
nssSMIMEProfile *rvProfile;
nssPKIObject *object;
NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
arena = nssArena_Create();
if (!arena) {
return NULL;
}
rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
if (!rvProfile) {
nssArena_Destroy(arena);
return NULL;
}
nssrv = nssPKIObject_Initialize(&rvProfile->object, arena, NULL, NULL);
if (nssrv != PR_SUCCESS) {
object = nssPKIObject_Create(arena, NULL, td, cc);
if (!object) {
goto loser;
}
rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
if (!rvProfile) {
goto loser;
}
rvProfile->object = *object;
rvProfile->certificate = cert;
rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
@ -852,8 +886,8 @@ nssSMIMEProfile_Create
}
return rvProfile;
loser:
nssPKIObject_Destroy(&rvProfile->object);
return NULL;
nssPKIObject_Destroy(object);
return (nssSMIMEProfile *)NULL;
}
/* execute a callback function on all members of a cert list */
@ -895,6 +929,65 @@ nssCertificateList_AddReferences
(void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
}
NSS_IMPLEMENT NSSTrust *
nssTrust_Create
(
nssPKIObject *object
)
{
PRStatus status;
PRUint32 i;
PRUint32 lastTrustOrder, myTrustOrder;
NSSTrust *rvt;
nssCryptokiObject *instance;
nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
lastTrustOrder = 1<<16; /* just make it big */
PR_ASSERT(object->instances != NULL && object->numInstances > 0);
rvt = nss_ZNEW(object->arena, NSSTrust);
if (!rvt) {
return (NSSTrust *)NULL;
}
rvt->object = *object;
/* trust has to peek into the base object members */
PZ_Lock(object->lock);
for (i=0; i<object->numInstances; i++) {
instance = object->instances[i];
myTrustOrder = nssToken_GetTrustOrder(instance->token);
status = nssCryptokiTrust_GetAttributes(instance, NULL,
&serverAuth,
&clientAuth,
&codeSigning,
&emailProtection);
if (status != PR_SUCCESS) {
PZ_Unlock(object->lock);
return (NSSTrust *)NULL;
}
if (rvt->serverAuth == nssTrustLevel_Unknown ||
myTrustOrder < lastTrustOrder)
{
rvt->serverAuth = serverAuth;
}
if (rvt->clientAuth == nssTrustLevel_Unknown ||
myTrustOrder < lastTrustOrder)
{
rvt->clientAuth = clientAuth;
}
if (rvt->emailProtection == nssTrustLevel_Unknown ||
myTrustOrder < lastTrustOrder)
{
rvt->emailProtection = emailProtection;
}
if (rvt->codeSigning == nssTrustLevel_Unknown ||
myTrustOrder < lastTrustOrder)
{
rvt->codeSigning = codeSigning;
}
lastTrustOrder = myTrustOrder;
}
PZ_Unlock(object->lock);
return rvt;
}
NSS_IMPLEMENT NSSTrust *
nssTrust_AddRef
(

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

@ -32,36 +32,59 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.9 $ $Date: 2002/02/06 19:58:54 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.10 $ $Date: 2002/04/15 15:22:08 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifndef PKISTORE_H
#include "pkistore.h"
#endif /* PKISTORE_H */
#ifdef NSS_3_4_CODE
#include "pk11func.h"
#include "dev3hack.h"
#include "pki1t.h"
#ifdef PURE_STAN_BUILD
struct NSSCryptoContextStr
{
PRInt32 refCount;
NSSArena *arena;
NSSTrustDomain *td;
NSSToken *token;
nssSession *session;
nssCertificateStore *certStore;
};
#endif
extern const NSSError NSS_ERROR_NOT_FOUND;
NSS_IMPLEMENT NSSCryptoContext *
nssCryptoContext_Create
(
NSSTrustDomain *td,
NSSCallback *uhhOpt
)
{
NSSArena *arena;
NSSCryptoContext *rvCC;
arena = NSSArena_Create();
if (!arena) {
return NULL;
}
rvCC = nss_ZNEW(arena, NSSCryptoContext);
if (!rvCC) {
return NULL;
}
rvCC->td = td;
rvCC->arena = arena;
return rvCC;
}
NSS_IMPLEMENT PRStatus
NSSCryptoContext_Destroy
(
@ -177,9 +200,11 @@ nssCryptoContext_ImportTrust
}
}
nssrv = nssCertificateStore_AddTrust(cc->certStore, trust);
#if 0
if (nssrv == PR_SUCCESS) {
trust->object.cryptoContext = cc;
}
#endif
return nssrv;
}
@ -198,9 +223,11 @@ nssCryptoContext_ImportSMIMEProfile
}
}
nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile);
#if 0
if (nssrv == PR_SUCCESS) {
profile->object.cryptoContext = cc;
}
#endif
return nssrv;
}
@ -214,36 +241,22 @@ NSSCryptoContext_FindBestCertificateByNickname
NSSPolicies *policiesOpt /* NULL for none */
)
{
PRIntn i;
NSSCertificate *c;
NSSCertificate **nickCerts;
nssBestCertificateCB best;
NSSCertificate **certs;
NSSCertificate *rvCert = NULL;
if (!cc->certStore) {
return NULL;
}
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
/* This could be improved by querying the store with a callback */
nickCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
name,
NULL,
0,
NULL);
if (nickCerts) {
PRStatus nssrv;
for (i=0, c = *nickCerts; c != NULL; c = nickCerts[++i]) {
nssrv = nssBestCertificate_Callback(c, &best);
NSSCertificate_Destroy(c);
if (nssrv != PR_SUCCESS) {
if (best.cert) {
NSSCertificate_Destroy(best.cert);
best.cert = NULL;
}
break;
}
}
nss_ZFreeIf(nickCerts);
certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
name,
NULL, 0, NULL);
if (certs) {
rvCert = nssCertificateArray_FindBestCertificate(certs,
timeOpt,
usage,
policiesOpt);
nssCertificateArray_Destroy(certs);
}
return best.cert;
return rvCert;
}
NSS_IMPLEMENT NSSCertificate **
@ -295,39 +308,26 @@ NSSCryptoContext_FindBestCertificateBySubject
NSSPolicies *policiesOpt
)
{
PRIntn i;
NSSCertificate *c;
NSSCertificate **subjectCerts;
nssBestCertificateCB best;
NSSCertificate **certs;
NSSCertificate *rvCert = NULL;
if (!cc->certStore) {
return NULL;
}
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
subjectCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
subject,
NULL,
0,
NULL);
if (subjectCerts) {
PRStatus nssrv;
for (i=0, c = *subjectCerts; c != NULL; c = subjectCerts[++i]) {
nssrv = nssBestCertificate_Callback(c, &best);
NSSCertificate_Destroy(c);
if (nssrv != PR_SUCCESS) {
if (best.cert) {
NSSCertificate_Destroy(best.cert);
best.cert = NULL;
}
break;
}
}
nss_ZFreeIf(subjectCerts);
certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
subject,
NULL, 0, NULL);
if (certs) {
rvCert = nssCertificateArray_FindBestCertificate(certs,
timeOpt,
usage,
policiesOpt);
nssCertificateArray_Destroy(certs);
}
return best.cert;
return rvCert;
}
NSS_IMPLEMENT NSSCertificate **
NSSCryptoContext_FindCertificatesBySubject
nssCryptoContext_FindCertificatesBySubject
(
NSSCryptoContext *cc,
NSSDER *subject,
@ -348,6 +348,21 @@ NSSCryptoContext_FindCertificatesBySubject
return rvCerts;
}
NSS_IMPLEMENT NSSCertificate **
NSSCryptoContext_FindCertificatesBySubject
(
NSSCryptoContext *cc,
NSSDER *subject,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt
)
{
return nssCryptoContext_FindCertificatesBySubject(cc, subject,
rvOpt, maximumOpt,
arenaOpt);
}
NSS_IMPLEMENT NSSCertificate *
NSSCryptoContext_FindBestCertificateByNameComponents
(
@ -401,35 +416,22 @@ NSSCryptoContext_FindBestCertificateByEmail
NSSPolicies *policiesOpt
)
{
PRIntn i;
NSSCertificate *c;
NSSCertificate **emailCerts;
nssBestCertificateCB best;
NSSCertificate **certs;
NSSCertificate *rvCert = NULL;
if (!cc->certStore) {
return NULL;
}
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt);
emailCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
email,
NULL,
0,
NULL);
if (emailCerts) {
PRStatus nssrv;
for (i=0, c = *emailCerts; c != NULL; c = emailCerts[++i]) {
nssrv = nssBestCertificate_Callback(c, &best);
NSSCertificate_Destroy(c);
if (nssrv != PR_SUCCESS) {
if (best.cert) {
NSSCertificate_Destroy(best.cert);
best.cert = NULL;
}
break;
}
}
nss_ZFreeIf(emailCerts);
certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
email,
NULL, 0, NULL);
if (certs) {
rvCert = nssCertificateArray_FindBestCertificate(certs,
timeOpt,
usage,
policiesOpt);
nssCertificateArray_Destroy(certs);
}
return best.cert;
return rvCert;
}
NSS_IMPLEMENT NSSCertificate **
@ -649,31 +651,6 @@ struct token_session_str {
nssSession *session;
};
#ifdef nodef
static nssSession *
get_token_session(NSSCryptoContext *cc, NSSToken *tok)
{
struct token_session_str *ts;
for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
ts != (struct token_session_str *)NULL;
ts = (struct token_session_str *)nssListIterator_Next(cc->sessions))
{
if (ts->token == tok) { /* will this need to be more general? */
break;
}
}
nssListIterator_Finish(cc->sessions);
if (!ts) {
/* need to create a session for this token. */
ts = nss_ZNEW(NULL, struct token_session_str);
ts->token = nssToken_AddRef(tok);
ts->session = nssSlot_CreateSession(tok->slot, cc->arena, PR_FALSE);
nssList_AddElement(cc->sessionList, (void *)ts);
}
return ts->session;
}
#endif
NSS_IMPLEMENT NSSItem *
NSSCryptoContext_Decrypt
(
@ -685,58 +662,7 @@ NSSCryptoContext_Decrypt
NSSArena *arenaOpt
)
{
#if 0
NSSToken *tok;
nssSession *session;
NSSItem *rvData;
PRUint32 dataLen;
NSSAlgorithmAndParameters *ap;
CK_RV ckrv;
ap = (apOpt) ? apOpt : cc->defaultAlgorithm;
/* Get the token for this operation */
tok = nssTrustDomain_GetCryptoToken(cc->trustDomain, ap);
if (!tok) {
return (NSSItem *)NULL;
}
/* Get the local session for this token */
session = get_token_session(cc, tok);
/* Get the key needed to decrypt */
keyHandle = get_decrypt_key(cc, ap);
/* Set up the decrypt operation */
ckrv = CKAPI(tok)->C_DecryptInit(session->handle,
&ap->mechanism, keyHandle);
if (ckrv != CKR_OK) {
/* handle PKCS#11 error */
return (NSSItem *)NULL;
}
/* Get the length of the output buffer */
ckrv = CKAPI(tok)->C_Decrypt(session->handle,
(CK_BYTE_PTR)encryptedData->data,
(CK_ULONG)encryptedData->size,
(CK_BYTE_PTR)NULL,
(CK_ULONG_PTR)&dataLen);
if (ckrv != CKR_OK) {
/* handle PKCS#11 error */
return (NSSItem *)NULL;
}
/* Alloc return value memory */
rvData = nssItem_Create(NULL, NULL, dataLen, NULL);
if (!rvItem) {
return (NSSItem *)NULL;
}
/* Do the decryption */
ckrv = CKAPI(tok)->C_Decrypt(cc->session->handle,
(CK_BYTE_PTR)encryptedData->data,
(CK_ULONG)encryptedData->size,
(CK_BYTE_PTR)rvData->data,
(CK_ULONG_PTR)&dataLen);
if (ckrv != CKR_OK) {
/* handle PKCS#11 error */
nssItem_ZFreeIf(rvData);
return (NSSItem *)NULL;
}
return rvData;
#endif
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}

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

@ -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.10 $ $Date: 2002/03/14 04:12:25 $ $Name: $"
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.11 $ $Date: 2002/04/15 15:22:08 $ $Name: $"
CORE_DEPTH = ../../..
@ -55,6 +55,7 @@ CSRCS = \
tdcache.c \
certdecode.c \
pkistore.c \
pkibase.c \
$(NULL)
ifndef PURE_STAN_BUILD

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

@ -35,32 +35,150 @@
#define PKI_H
#ifdef DEBUG
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.10 $ $Date: 2002/03/07 22:07:56 $ $Name: $";
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.11 $ $Date: 2002/04/15 15:22:09 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
PR_BEGIN_EXTERN_C
NSS_EXTERN NSSCallback *
nssTrustDomain_GetDefaultCallback
(
NSSTrustDomain *td,
PRStatus *statusOpt
);
NSS_EXTERN NSSCertificate **
nssTrustDomain_FindCertificatesBySubject
(
NSSTrustDomain *td,
NSSDER *subject,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt,
NSSArena *arenaOpt
);
NSS_EXTERN NSSTrust *
nssTrustDomain_FindTrustForCertificate
(
NSSTrustDomain *td,
NSSCertificate *c
);
NSS_EXTERN NSSCertificate *
nssCertificate_AddRef
(
NSSCertificate *c
);
NSS_EXTERN PRStatus
nssCertificate_Destroy
(
NSSCertificate *c
);
NSS_EXTERN NSSDER *
nssCertificate_GetEncoding
(
NSSCertificate *c
);
NSS_EXTERN NSSDER *
nssCertificate_GetIssuer
(
NSSCertificate *c
);
NSS_EXTERN NSSDER *
nssCertificate_GetSerialNumber
(
NSSCertificate *c
);
NSS_EXTERN NSSDER *
nssCertificate_GetSubject
(
NSSCertificate *c
);
NSS_EXTERN NSSUTF8 *
NSSCertificate_GetNickname
nssCertificate_GetNickname
(
NSSCertificate *c,
NSSToken *tokenOpt
);
NSS_EXTERN NSSASCII7 *
nssCertificate_GetEmailAddress
(
NSSCertificate *c
);
NSS_EXTERN PRBool
nssCertificate_IssuerAndSerialEqual
(
NSSCertificate *c1,
NSSCertificate *c2
);
NSS_EXTERN NSSPrivateKey *
nssPrivateKey_AddRef
(
NSSPrivateKey *vk
);
NSS_EXTERN PRStatus
nssPrivateKey_Destroy
(
NSSPrivateKey *vk
);
NSS_EXTERN NSSItem *
nssPrivateKey_GetID
(
NSSPrivateKey *vk
);
NSS_EXTERN NSSUTF8 *
nssPrivateKey_GetNickname
(
NSSPrivateKey *vk,
NSSToken *tokenOpt
);
NSS_EXTERN PRStatus
nssPublicKey_Destroy
(
NSSPublicKey *bk
);
NSS_EXTERN NSSItem *
nssPublicKey_GetID
(
NSSPublicKey *vk
);
NSS_EXTERN NSSCertificate **
nssCryptoContext_FindCertificatesBySubject
(
NSSCryptoContext *cc,
NSSDER *subject,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt
);
/* putting here for now, needs more thought */
NSS_EXTERN PRStatus
nssCryptoContext_ImportTrust

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.47 $ $Date: 2002/04/04 20:00:28 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.48 $ $Date: 2002/04/15 15:22:09 $ $Name: $";
#endif /* DEBUG */
/*
@ -124,13 +124,10 @@ cache_token_cert(NSSCertificate *c, void *arg)
/* The cert was already in the cache, from another token. Add this
* token's instance to the cert.
*/
nssCryptokiInstance *tokenInstance, *instance;
nssList_GetArray(cp->object.instanceList, (void **)&tokenInstance, 1);
instance = nssCryptokiInstance_Create(c->object.arena, token,
tokenInstance->handle, PR_TRUE);
nssList_Add(c->object.instanceList, instance);
nssListIterator_Destroy(c->object.instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
nssCryptokiObject **instance;
instance = nssPKIObject_GetInstances(&cp->object);
nssPKIObject_AddInstance(&c->object, *instance);
nss_ZFreeIf(instance);
}
/* This list reference persists with the token */
nssList_Add(token->certList, nssCertificate_AddRef(c));
@ -142,32 +139,11 @@ cache_token_cert(NSSCertificate *c, void *arg)
return PR_SUCCESS;
}
static void remove_token_instance(NSSCertificate *c, NSSToken *token)
{
nssListIterator *instances;
nssCryptokiInstance *instance, *rmInstance = NULL;
instances = c->object.instances;
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
if (instance->token == token) {
rmInstance = instance;
break;
}
}
nssListIterator_Finish(instances);
if (rmInstance) {
nssList_Remove(c->object.instanceList, rmInstance);
nssListIterator_Destroy(instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
}
}
static PRBool instance_destructor(NSSCertificate *c, NSSToken *token)
{
remove_token_instance(c, token);
if (nssList_Count(c->object.instanceList) == 0) {
nssPKIObject_RemoveInstanceForToken(&c->object, token);
/* XXX cheating, this code to be replaced anyway */
if (c->object.numInstances == 0) {
return PR_TRUE;
}
return PR_FALSE;
@ -238,6 +214,26 @@ nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances)
/* leave the list non-null to prevent it from being searched */
}
static void
add_token_certs_to_list(NSSToken *token)
{
nssCryptokiObject **objects, **op;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
objects = nssToken_FindCertificates(token, NULL, tokenOnly, 0, NULL);
if (!objects) {
return;
}
for (op = objects; *op; op++) {
nssPKIObject *pkiob = nssPKIObject_Create(NULL, *op,
token->trustDomain, NULL);
if (pkiob) {
NSSCertificate *c = nssCertificate_Create(pkiob);
nssList_Add(token->certList, c);
}
}
nss_ZFreeIf(objects);
}
/* create a list of local cert references for certain tokens */
NSS_IMPLEMENT PRStatus
nssToken_LoadCerts(NSSToken *token)
@ -263,7 +259,7 @@ nssToken_LoadCerts(NSSToken *token)
return PR_SUCCESS;
}
/* ignore the rv, just work without the list */
(void)nssToken_TraverseCertificates(token, NULL, &search);
add_token_certs_to_list(token);
(void)nssToken_SetTrustCache(token);
(void)nssToken_SetCrlCache(token);
@ -338,8 +334,6 @@ STAN_LoadDefaultNSS3TrustDomain
{
NSSTrustDomain *td;
NSSToken *token;
PK11SlotList *list;
PK11SlotListElement *le;
SECMODModuleList *mlp;
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
int i;
@ -461,6 +455,31 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
return rvKey;
}
NSS_IMPLEMENT PRStatus
nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
NSSDER *issuer, NSSDER *serial)
{
SECStatus secrv;
SECItem derCert;
SECItem derIssuer = { 0 };
SECItem derSerial = { 0 };
SECITEM_FROM_NSSITEM(&derCert, der);
secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
if (secrv != SECSuccess) {
return PR_FAILURE;
}
(void)nssItem_Create(arena, serial, derSerial.len, derSerial.data);
secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
if (secrv != SECSuccess) {
PORT_Free(derSerial.data);
return PR_FAILURE;
}
(void)nssItem_Create(arena, issuer, derIssuer.len, derIssuer.data);
PORT_Free(derSerial.data);
PORT_Free(derIssuer.data);
return PR_SUCCESS;
}
static NSSItem *
nss3certificate_getIdentifier(nssDecodedCert *dc)
{
@ -476,9 +495,7 @@ nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
CERTCertificate *c = (CERTCertificate *)dc->data;
CERTAuthKeyID *cAuthKeyID;
PRArenaPool *tmpArena = NULL;
SECItem issuerCertKey;
NSSItem *rvID = NULL;
SECStatus secrv;
tmpArena = PORT_NewArena(512);
cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c);
if (cAuthKeyID == NULL) {
@ -690,22 +707,21 @@ PK11_IsUserCert(PK11SlotInfo *, CERTCertificate *, CK_OBJECT_HANDLE);
/* see pk11cert.c:pk11_HandleTrustObject */
static unsigned int
get_nss3trust_from_cktrust(CK_TRUST t)
get_nss3trust_from_nss4trust(CK_TRUST t)
{
unsigned int rt = 0;
if (t == CKT_NETSCAPE_TRUSTED) {
if (t == nssTrustLevel_Trusted) {
rt |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
}
if (t == CKT_NETSCAPE_TRUSTED_DELEGATOR) {
if (t == nssTrustLevel_TrustedDelegator) {
rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA /*| CERTDB_NS_TRUSTED_CA*/;
}
if (t == CKT_NETSCAPE_VALID) {
if (t == nssTrustLevel_Valid) {
rt |= CERTDB_VALID_PEER;
}
if (t == CKT_NETSCAPE_VALID_DELEGATOR) {
if (t == nssTrustLevel_ValidDelegator) {
rt |= CERTDB_VALID_CA;
}
/* user */
return rt;
}
@ -719,95 +735,57 @@ cert_trust_from_stan_trust(NSSTrust *t, PRArenaPool *arena)
}
rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust));
if (!rvTrust) return NULL;
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
client = get_nss3trust_from_cktrust(t->clientAuth);
rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth);
client = get_nss3trust_from_nss4trust(t->clientAuth);
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA);
rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
}
rvTrust->sslFlags |= client;
rvTrust->emailFlags = get_nss3trust_from_cktrust(t->emailProtection);
rvTrust->objectSigningFlags = get_nss3trust_from_cktrust(t->codeSigning);
rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection);
rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning);
return rvTrust;
}
static int nsstoken_get_trust_order(NSSToken *token)
{
PK11SlotInfo *slot;
SECMODModule *module;
slot = token->pk11slot;
module = PK11_GetModule(slot);
return module->trustOrder;
}
/* check all cert instances for private key */
static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc)
{
PRBool isUser = PR_FALSE;
nssCryptokiInstance *instance;
nssListIterator *instances = c->object.instances;
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
nssCryptokiObject **ip;
nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
for (ip = instances; *ip; ip++) {
nssCryptokiObject *instance = *ip;
if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) {
isUser = PR_TRUE;
}
}
nssListIterator_Finish(instances);
nssCryptokiObjectArray_Destroy(instances);
return isUser;
}
CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{
CERTCertTrust *rvTrust;
CERTCertTrust *rvTrust = NULL;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
NSSToken *tok;
NSSTrust *tokenTrust;
NSSTrust t;
nssListIterator *tokens;
int lastTrustOrder, myTrustOrder;
tokens = nssList_CreateIterator(td->tokenList);
if (!tokens) return NULL;
lastTrustOrder = 1<<16; /* just make it big */
t.serverAuth = CKT_NETSCAPE_TRUST_UNKNOWN;
t.clientAuth = CKT_NETSCAPE_TRUST_UNKNOWN;
t.emailProtection = CKT_NETSCAPE_TRUST_UNKNOWN;
t.codeSigning = CKT_NETSCAPE_TRUST_UNKNOWN;
for (tok = (NSSToken *)nssListIterator_Start(tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(tokens))
{
tokenTrust = nssToken_FindTrustForCert(tok, NULL, c,
nssTokenSearchType_TokenOnly);
if (tokenTrust) {
myTrustOrder = nsstoken_get_trust_order(tok);
if (t.serverAuth == CKT_NETSCAPE_TRUST_UNKNOWN ||
myTrustOrder < lastTrustOrder) {
t.serverAuth = tokenTrust->serverAuth;
}
if (t.clientAuth == CKT_NETSCAPE_TRUST_UNKNOWN ||
myTrustOrder < lastTrustOrder) {
t.clientAuth = tokenTrust->clientAuth;
}
if (t.emailProtection == CKT_NETSCAPE_TRUST_UNKNOWN ||
myTrustOrder < lastTrustOrder) {
t.emailProtection = tokenTrust->emailProtection;
}
if (t.codeSigning == CKT_NETSCAPE_TRUST_UNKNOWN ||
myTrustOrder < lastTrustOrder) {
t.codeSigning = tokenTrust->codeSigning;
}
(void)nssTrust_Destroy(tokenTrust);
lastTrustOrder = myTrustOrder;
NSSTrust *t;
t = nssTrustDomain_FindTrustForCertificate(td, c);
if (t) {
rvTrust = cert_trust_from_stan_trust(t, cc->arena);
if (!rvTrust) {
nssTrust_Destroy(t);
return NULL;
}
nssTrust_Destroy(t);
}
nssListIterator_Finish(tokens);
nssListIterator_Destroy(tokens);
rvTrust = cert_trust_from_stan_trust(&t, cc->arena);
if (!rvTrust) return NULL;
if (is_user_cert(c, cc)) {
if (!rvTrust) {
rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
if (!rvTrust) {
return NULL;
}
memset(rvTrust, 0, sizeof(*rvTrust));
}
rvTrust->sslFlags |= CERTDB_USER;
rvTrust->emailFlags |= CERTDB_USER;
rvTrust->objectSigningFlags |= CERTDB_USER;
@ -818,15 +796,15 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
static nssCryptokiInstance *
get_cert_instance(NSSCertificate *c)
{
nssCryptokiInstance *instance, *ci;
nssListIterator *instances = c->object.instances;
nssCryptokiObject *instance, **ci;
nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
if (!instances) {
return NULL;
}
instance = NULL;
for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances);
ci != (nssCryptokiInstance *)NULL;
ci = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
for (ci = instances; *ci; ci++) {
if (!instance) {
instance = ci;
instance = nssCryptokiObject_Clone(*ci);
} else {
/* This only really works for two instances... But 3.4 can't
* handle more anyway. The logic is, if there are multiple
@ -834,11 +812,12 @@ get_cert_instance(NSSCertificate *c)
* a hardware device.
*/
if (PK11_IsInternal(instance->token->pk11slot)) {
instance = ci;
nssCryptokiObject_Destroy(instance);
instance = nssCryptokiObject_Clone(*ci);
}
}
}
nssListIterator_Finish(instances);
nssCryptokiObjectArray_Destroy(instances);
return instance;
}
@ -888,15 +867,18 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
}
} else if (instance) {
/* slot */
if (cc->slot) {
PK11_FreeSlot(cc->slot);
if (cc->slot != instance->token->pk11slot) {
if (cc->slot) {
PK11_FreeSlot(cc->slot);
}
cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
}
cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
cc->ownSlot = PR_TRUE;
/* pkcs11ID */
cc->pkcs11ID = instance->handle;
/* trust */
cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc);
nssCryptokiObject_Destroy(instance);
}
/* database handle is now the trust domain */
cc->dbhandle = c->object.trustDomain;
@ -947,28 +929,28 @@ STAN_GetCERTCertificate(NSSCertificate *c)
return stan_GetCERTCertificate(c, PR_FALSE);
}
static CK_TRUST
static nssTrustLevel
get_stan_trust(unsigned int t, PRBool isClientAuth)
{
if (isClientAuth) {
if (t & CERTDB_TRUSTED_CLIENT_CA) {
return CKT_NETSCAPE_TRUSTED_DELEGATOR;
return nssTrustLevel_TrustedDelegator;
}
} else {
if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) {
return CKT_NETSCAPE_TRUSTED_DELEGATOR;
return nssTrustLevel_TrustedDelegator;
}
}
if (t & CERTDB_TRUSTED) {
return CKT_NETSCAPE_TRUSTED;
return nssTrustLevel_Trusted;
}
if (t & CERTDB_VALID_CA) {
return CKT_NETSCAPE_VALID_DELEGATOR;
return nssTrustLevel_ValidDelegator;
}
if (t & CERTDB_VALID_PEER) {
return CKT_NETSCAPE_VALID;
return nssTrustLevel_Valid;
}
return CKT_NETSCAPE_UNTRUSTED;
return nssTrustLevel_NotTrusted;
}
NSS_EXTERN NSSCertificate *
@ -976,8 +958,8 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
{
NSSCertificate *c;
nssCryptokiInstance *instance;
nssPKIObject *pkiob;
NSSArena *arena;
PRStatus nssrv;
c = cc->nssCertificate;
if (c) {
return c;
@ -996,10 +978,12 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
}
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
c->type = NSSCertificateType_PKIX;
nssrv = nssPKIObject_Initialize(&c->object, arena, cc->dbhandle, NULL);
if (nssrv != PR_SUCCESS) {
nssPKIObject_Destroy(&c->object);
pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL);
if (!pkiob) {
nssArena_Destroy(arena);
return NULL;
}
c->object = *pkiob;
nssItem_Create(arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data);
nssItem_Create(arena,
@ -1021,7 +1005,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
}
if (cc->slot) {
instance = nss_ZNEW(arena, nssCryptokiInstance);
instance->token = PK11Slot_GetNSSToken(cc->slot);
instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
instance->handle = cc->pkcs11ID;
instance->isTokenObject = PR_TRUE;
if (cc->nickname) {
@ -1030,10 +1014,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
(NSSUTF8 *)cc->nickname,
PORT_Strlen(cc->nickname));
}
nssList_Add(c->object.instanceList, instance);
/* XXX Fix this! */
nssListIterator_Destroy(c->object.instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
nssPKIObject_AddInstance(&c->object, instance);
}
c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc);
cc->nssCertificate = c;
@ -1052,6 +1033,8 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
CERTCertTrust *oldTrust;
nssListIterator *tokens;
PRBool moving_object;
nssCryptokiObject *newInstance;
nssPKIObject *pkiob;
oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc);
if (oldTrust) {
if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) {
@ -1069,11 +1052,12 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
arena = nssArena_Create();
if (!arena) return PR_FAILURE;
nssTrust = nss_ZNEW(arena, NSSTrust);
nssrv = nssPKIObject_Initialize(&nssTrust->object, arena, NULL, NULL);
if (nssrv != PR_SUCCESS) {
nssPKIObject_Destroy(&nssTrust->object);
pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL);
if (!pkiob) {
nssArena_Destroy(arena);
return PR_FAILURE;
}
nssTrust->object = *pkiob;
nssTrust->certificate = c;
nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
@ -1087,7 +1071,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
nssTrust_Destroy(nssTrust);
return nssrv;
}
if (nssList_Count(c->object.instanceList) == 0) {
if (c->object.numInstances == 0) {
/* The context is the only instance, finished */
return nssrv;
}
@ -1115,11 +1099,33 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
/* this is kind of hacky. the softoken needs the cert
* object in order to store trust. forcing it to be perm
*/
NSSUTF8 *nickname = NSSCertificate_GetNickname(c, NULL);
nssrv = nssToken_ImportCertificate(tok, NULL, c, nickname, PR_TRUE);
if (nssrv != PR_SUCCESS) return nssrv;
NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
newInstance = nssToken_ImportCertificate(tok, NULL,
NSSCertificateType_PKIX,
&c->id,
nickname,
&c->encoding,
&c->issuer,
&c->subject,
&c->serial,
PR_TRUE);
if (!newInstance) {
return PR_FAILURE;
}
nssPKIObject_AddInstance(&c->object, newInstance);
}
newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding,
&c->issuer, &c->serial,
nssTrust->serverAuth,
nssTrust->clientAuth,
nssTrust->codeSigning,
nssTrust->emailProtection, PR_TRUE);
if (newInstance) {
nssCryptokiObject_Destroy(newInstance);
nssrv = PR_SUCCESS;
} else {
nssrv = PR_FAILURE;
}
nssrv = nssToken_ImportTrust(tok, NULL, nssTrust, PR_TRUE);
} else {
nssrv = PR_FAILURE;
}
@ -1183,103 +1189,6 @@ nssTrustDomain_TraverseCertificatesByNickname
return nssrv;
}
/* SEC_TraversePermCerts */
NSS_IMPLEMENT PRStatus
nssTrustDomain_TraverseCertificates
(
NSSTrustDomain *td,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
)
{
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
nssList *certList;
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);
/* set the search criteria */
search.callback = callback;
search.cbarg = arg;
search.cached = certList;
search.searchType = nssTokenSearchType_TokenOnly;
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)
{
switch (nssType) {
case NSSCertificateType_PKIX:
return CKC_X_509;
default:
return CK_INVALID_HANDLE; /* Not really! CK_INVALID_HANDLE is not a
* type CK_CERTIFICATE_TYPE */
}
}
#endif
/* CERT_AddTempCertToPerm */
NSS_EXTERN PRStatus
nssTrustDomain_AddTempCertToPerm
(
NSSCertificate *c
)
{
#if 0
NSSToken *token;
CK_CERTIFICATE_TYPE cert_type;
CK_ATTRIBUTE cert_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ 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 }
};
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0]));
/* XXX sanity checking needed */
cert_type = get_cert_type(c->type);
/* Set up the certificate object */
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_VAR( cert_template, 1, cert_type);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, &c->id);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 3, &c->encoding);
NSS_CK_SET_ATTRIBUTE_UTF8(cert_template, 4, c->nickname);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 5, &c->issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 6, &c->subject);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 7, &c->serial);
/* This is a hack, ignoring the 4.0 token ordering scheme */
token = STAN_GetInternalToken();
c->handle = nssToken_ImportObject(token, NULL, cert_template, ctsize);
if (c->handle == CK_INVALID_HANDLE) {
return PR_FAILURE;
}
c->token = token;
c->slot = token->slot;
/* Do the trust object */
return PR_SUCCESS;
#endif
return PR_FAILURE;
}
static void cert_dump_iter(const void *k, void *v, void *a)
{
NSSCertificate *c = (NSSCertificate *)k;

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

@ -35,7 +35,7 @@
#define PKINSS3HACK_H
#ifdef DEBUG
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.9 $ $Date: 2002/04/03 19:22:15 $ $Name: $";
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.10 $ $Date: 2002/04/15 15:22:10 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSDEVT_H
@ -125,6 +125,10 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc);
NSS_EXTERN PRStatus
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
NSS_EXTERN PRStatus
nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
NSSDER *issuer, NSSDER *serial);
/* exposing this */
NSS_EXTERN NSSCertificate *
NSSCertificate_Create

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.1 $ $Date: 2002/04/04 21:15:27 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.2 $ $Date: 2002/04/15 15:22:10 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
@ -43,6 +43,10 @@ static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.1 $ $Dat
#include "pkim.h"
#endif /* PKIM_H */
#ifdef NSS_3_4_CODE
#include "pki3hack.h"
#endif
NSS_IMPLEMENT nssPKIObject *
nssPKIObject_Create
(
@ -100,9 +104,13 @@ nssPKIObject_Destroy
nssPKIObject *object
)
{
PRUint32 i;
PR_ASSERT(object->refCount > 0);
PR_AtomicDecrement(&object->refCount);
if (object->refCount == 0) {
for (i=0; i<object->numInstances; i++) {
nssCryptokiObject_Destroy(object->instances[i]);
}
PZ_DestroyLock(object->lock);
nssArena_Destroy(object->arena);
return PR_TRUE;
@ -225,6 +233,7 @@ nssPKIObject_DeleteStoredObject
PZ_Lock(object->lock);
for (i=0; i<object->numInstances; i++) {
nssCryptokiObject *instance = object->instances[i];
#ifndef NSS_3_4_CODE
NSSSlot *slot = nssToken_GetSlot(instance->token);
/* If both the operation and the slot are friendly, login is
* not required. If either or both are not friendly, it is
@ -240,6 +249,9 @@ nssPKIObject_DeleteStoredObject
status = nssToken_DeleteStoredObject(instance);
}
}
#else
status = nssToken_DeleteStoredObject(instance);
#endif
object->instances[i] = NULL;
if (status == PR_SUCCESS) {
nssCryptokiObject_Destroy(instance);
@ -303,6 +315,31 @@ nssPKIObject_GetNicknameForToken
return nickname;
}
#ifdef NSS_3_4_CODE
NSS_IMPLEMENT nssCryptokiObject **
nssPKIObject_GetInstances
(
nssPKIObject *object
)
{
nssCryptokiObject **instances = NULL;
PRUint32 i;
if (object->numInstances == 0) {
return (nssCryptokiObject **)NULL;
}
PZ_Lock(object->lock);
instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *,
object->numInstances + 1);
if (instances) {
for (i=0; i<object->numInstances; i++) {
instances[i] = nssCryptokiObject_Clone(object->instances[i]);
}
}
PZ_Unlock(object->lock);
return instances;
}
#endif
NSS_IMPLEMENT void
nssCertificateArray_Destroy
(
@ -312,6 +349,13 @@ nssCertificateArray_Destroy
if (certs) {
NSSCertificate **certp;
for (certp = certs; *certp; certp++) {
#ifdef NSS_3_4_CODE
if ((*certp)->decoding) {
CERTCertificate *cc = STAN_GetCERTCertificate(*certp);
CERT_DestroyCertificate(cc);
continue;
}
#endif
nssCertificate_Destroy(*certp);
}
nss_ZFreeIf(certs);
@ -337,7 +381,7 @@ nssCertificateArray_Join
if (certs1 && certs2) {
NSSCertificate **certs, **cp;
PRUint32 count = 0;
PRUint32 count1;
PRUint32 count1 = 0;
cp = certs1;
while (*cp++) count1++;
count = count1;
@ -349,8 +393,9 @@ nssCertificateArray_Join
nss_ZFreeIf(certs2);
return (NSSCertificate **)NULL;
}
cp = certs2;
while (*cp++) certs[count1++] = *cp;
for (cp = certs2; *cp; cp++, count1++) {
certs[count1] = *cp;
}
nss_ZFreeIf(certs2);
return certs;
} else if (certs1) {
@ -655,36 +700,50 @@ add_object_instance
PRUint32 i;
PRStatus status;
pkiObjectCollectionNode *node;
nssArenaMark *mark = NULL;
NSSItem uid[MAX_ITEMS_FOR_UID];
nsslibc_memset(uid, 0, sizeof uid);
/* The list is traversed twice, first (here) looking to match the
* { token, handle } tuple, and if that is not found, below a search
* for unique identifier is done. Here, a match means this exact
* object instance is already in the collection, and we have nothing to
* do. Later, it means the object exists in the collection, but does
* not have this instance, so the instance needs to be added.
* for unique identifier is done. Here, a match means this exact object
* instance is already in the collection, and we have nothing to do.
*/
node = find_instance_in_collection(collection, instance);
if (node) {
/* The collection is assumed to take over the instance. Since we
* are not using it, it must be destroyed.
*/
nssCryptokiObject_Destroy(instance);
return PR_SUCCESS;
}
mark = nssArena_Mark(collection->arena);
if (!mark) {
goto loser;
}
status = (*collection->getUIDFromInstance)(instance, uid,
collection->arena);
if (status != PR_SUCCESS) {
goto loser;
}
/* search for unique identifier */
/* Search for unique identifier. A match here means the object exists
* in the collection, but does not have this instance, so the instance
* needs to be added.
*/
node = find_object_in_collection(collection, uid);
if (node) {
/* This is a object with multiple instances */
status = nssPKIObject_AddInstance(node->object, instance);
} else {
/* This is a completely new object. Create a node for it. */
node = nss_ZNEW(collection->arena, pkiObjectCollectionNode);
if (!node) {
goto loser;
}
node->object = nssPKIObject_Create(NULL, instance,
collection->td, collection->cc);
if (!node->object) {
goto loser;
}
for (i=0; i<MAX_ITEMS_FOR_UID; i++) {
node->uid[i] = uid[i];
}
@ -694,8 +753,13 @@ add_object_instance
collection->size++;
status = PR_SUCCESS;
}
nssArena_Unmark(collection->arena, mark);
return status;
loser:
if (mark) {
nssArena_Release(collection->arena, mark);
}
nssCryptokiObject_Destroy(instance);
return PR_FAILURE;
}
@ -710,16 +774,26 @@ nssPKIObjectCollection_AddInstances
PRStatus status = PR_SUCCESS;
PRUint32 i = 0;
if (instances) {
for (; *instances; instances++) {
status = add_object_instance(collection, *instances);
if (status != PR_SUCCESS ||
(numInstances > 0 && ++i == numInstances))
{
for (; *instances; instances++, i++) {
if (numInstances > 0 && i == numInstances) {
break;
}
status = add_object_instance(collection, *instances);
if (status != PR_SUCCESS) {
goto loser;
}
}
}
return status;
loser:
/* free the remaining instances */
for (; *instances; instances++, i++) {
if (numInstances > 0 && i == numInstances) {
break;
}
nssCryptokiObject_Destroy(*instances);
}
return PR_FAILURE;
}
static PRStatus
@ -795,6 +869,13 @@ static void
cert_destroyObject(nssPKIObject *o)
{
NSSCertificate *c = (NSSCertificate *)o;
#ifdef NSS_3_4_CODE
if (c->decoding) {
CERTCertificate *cc = STAN_GetCERTCertificate(c);
CERT_DestroyCertificate(cc);
return;
}
#endif
nssCertificate_Destroy(c);
}
@ -831,6 +912,17 @@ cert_createObject(nssPKIObject *o)
{
NSSCertificate *cert;
cert = nssCertificate_Create(o);
#ifdef NSS_3_4_CODE
(void)STAN_GetCERTCertificate(cert);
/* In 3.4, have to maintain uniqueness of cert pointers by caching all
* certs. Cache the cert here, before returning. If it is already
* cached, take the cached entry.
*/
{
NSSTrustDomain *td = o->trustDomain;
nssTrustDomain_AddCertsToCache(td, &cert, 1);
}
#endif
return (nssPKIObject *)cert;
}
@ -897,6 +989,7 @@ nssPKIObjectCollection_GetCertificates
return rvOpt;
}
#ifdef PURE_STAN_BUILD
/*
* PrivateKey collections
*/
@ -1102,6 +1195,7 @@ nssPKIObjectCollection_GetPublicKeys
}
return rvOpt;
}
#endif /* PURE_STAN_BUILD */
/* how bad would it be to have a static now sitting around, updated whenever
* this was called? would avoid repeated allocs...

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

@ -35,23 +35,458 @@
#define PKIM_H
#ifdef DEBUG
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.16 $ $Date: 2002/02/08 02:51:38 $ $Name: $";
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.17 $ $Date: 2002/04/15 15:22:10 $ $Name: $";
#endif /* DEBUG */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifndef PKITM_H
#include "pkitm.h"
#endif /* PKITM_H */
PR_BEGIN_EXTERN_C
NSS_EXTERN NSSToken *
STAN_GetDefaultCryptoToken
/* nssPKIObject
*
* This is the base object class, common to all PKI objects defined in
* in this module. Each object can be safely 'casted' to an nssPKIObject,
* then passed to these methods.
*
* nssPKIObject_Create
* nssPKIObject_Destroy
* nssPKIObject_AddRef
* nssPKIObject_AddInstance
* nssPKIObject_HasInstance
* nssPKIObject_GetTokens
* nssPKIObject_GetNicknameForToken
* nssPKIObject_RemoveInstanceForToken
* nssPKIObject_DeleteStoredObject
*/
/* nssPKIObject_Create
*
* A generic PKI object. It must live in a trust domain. It may be
* initialized with a token instance, or alternatively in a crypto context.
*/
NSS_EXTERN nssPKIObject *
nssPKIObject_Create
(
void
NSSArena *arenaOpt,
nssCryptokiObject *instanceOpt,
NSSTrustDomain *td,
NSSCryptoContext *ccOpt
);
/* nssPKIObject_AddRef
*/
NSS_EXTERN nssPKIObject *
nssPKIObject_AddRef
(
nssPKIObject *object
);
/* nssPKIObject_Destroy
*
* Returns true if object was destroyed. This notifies the subclass that
* all references are gone and it should delete any members it owns.
*/
NSS_EXTERN PRBool
nssPKIObject_Destroy
(
nssPKIObject *object
);
/* nssPKIObject_AddInstance
*
* Add a token instance to the object, if it does not have it already.
*/
NSS_EXTERN PRStatus
nssPKIObject_AddInstance
(
nssPKIObject *object,
nssCryptokiObject *instance
);
/* nssPKIObject_HasInstance
*
* Query the object for a token instance.
*/
NSS_EXTERN PRBool
nssPKIObject_HasInstance
(
nssPKIObject *object,
nssCryptokiObject *instance
);
/* nssPKIObject_GetTokens
*
* Get all tokens which have an instance of the object.
*/
NSS_EXTERN NSSToken **
nssPKIObject_GetTokens
(
nssPKIObject *object,
PRStatus *statusOpt
);
/* nssPKIObject_GetNicknameForToken
*
* tokenOpt == NULL means take the first available, otherwise return the
* nickname for the specified token.
*/
NSS_EXTERN NSSUTF8 *
nssPKIObject_GetNicknameForToken
(
nssPKIObject *object,
NSSToken *tokenOpt
);
/* nssPKIObject_RemoveInstanceForToken
*
* Remove the instance of the object on the specified token.
*/
NSS_EXTERN PRStatus
nssPKIObject_RemoveInstanceForToken
(
nssPKIObject *object,
NSSToken *token
);
/* nssPKIObject_DeleteStoredObject
*
* Delete all token instances of the object, as well as any crypto context
* instances (TODO). If any of the instances are read-only, or if the
* removal fails, the object will keep those instances. 'isFriendly' refers
* to the object -- can this object be removed from a friendly token without
* login? For example, certificates are friendly, private keys are not.
* Note that if the token is not friendly, authentication will be required
* regardless of the value of 'isFriendly'.
*/
NSS_EXTERN PRStatus
nssPKIObject_DeleteStoredObject
(
nssPKIObject *object,
NSSCallback *uhh,
PRBool isFriendly
);
#ifdef NSS_3_4_CODE
NSS_EXTERN nssCryptokiObject **
nssPKIObject_GetInstances
(
nssPKIObject *object
);
#endif
NSS_EXTERN NSSCertificate **
nssTrustDomain_FindCertificatesByID
(
NSSTrustDomain *td,
NSSItem *id,
NSSCertificate **rvOpt,
PRUint32 maximumOpt,
NSSArena *arenaOpt
);
/* module-private nsspki methods */
NSS_EXTERN NSSCryptoContext *
nssCryptoContext_Create
(
NSSTrustDomain *td,
NSSCallback *uhhOpt
);
/* XXX for the collection */
NSS_EXTERN NSSCertificate *
nssCertificate_Create
(
nssPKIObject *object
);
NSS_EXTERN PRStatus
nssCertificate_SetCertTrust
(
NSSCertificate *c,
NSSTrust *trust
);
NSS_EXTERN nssDecodedCert *
nssCertificate_GetDecoding
(
NSSCertificate *c
);
NSS_EXTERN nssDecodedCert *
nssDecodedCert_Create
(
NSSArena *arenaOpt,
NSSDER *encoding,
NSSCertificateType type
);
NSS_EXTERN PRStatus
nssDecodedCert_Destroy
(
nssDecodedCert *dc
);
NSS_EXTERN NSSTrust *
nssTrust_Create
(
nssPKIObject *object
);
NSS_EXTERN NSSPrivateKey *
nssPrivateKey_Create
(
nssPKIObject *o
);
NSS_EXTERN NSSPublicKey *
nssPublicKey_Create
(
nssPKIObject *object
);
/* nssCertificateArray
*
* These are being thrown around a lot, might as well group together some
* functionality.
*
* nssCertificateArray_Destroy
* nssCertificateArray_Join
* nssCertificateArray_FindBestCertificate
* nssCertificateArray_Traverse
*/
/* nssCertificateArray_Destroy
*
* Will destroy the array and the certs within it. If the array was created
* in an arena, will *not* (of course) destroy the arena. However, is safe
* to call this method on an arena-allocated array.
*/
NSS_EXTERN void
nssCertificateArray_Destroy
(
NSSCertificate **certs
);
/* nssCertificateArray_Join
*
* Join two arrays into one. The two arrays, certs1 and certs2, should
* be considered invalid after a call to this function (they may be destroyed
* as part of the join). certs1 and/or certs2 may be NULL. Safe to
* call with arrays allocated in an arena, the result will also be in the
* arena.
*/
NSS_EXTERN NSSCertificate **
nssCertificateArray_Join
(
NSSCertificate **certs1,
NSSCertificate **certs2
);
/* nssCertificateArray_FindBestCertificate
*
* Use the usual { time, usage, policies } to find the best cert in the
* array.
*/
NSS_EXTERN NSSCertificate *
nssCertificateArray_FindBestCertificate
(
NSSCertificate **certs,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt
);
/* nssCertificateArray_Traverse
*
* Do the callback for each cert, terminate the traversal if the callback
* fails.
*/
NSS_EXTERN PRStatus
nssCertificateArray_Traverse
(
NSSCertificate **certs,
PRStatus (* callback)(NSSCertificate *c, void *arg),
void *arg
);
/* nssPKIObjectCollection
*
* This is a handy way to group objects together and perform operations
* on them. It can also handle "proto-objects"-- references to
* objects instances on tokens, where the actual object hasn't
* been formed yet.
*
* nssCertificateCollection_Create
* nssPrivateKeyCollection_Create
* nssPublicKeyCollection_Create
*
* If this was a language that provided for inheritance, each type would
* inherit all of the following methods. Instead, there is only one
* type (nssPKIObjectCollection), shared among all. This may cause
* confusion; an alternative would be to define all of the methods
* for each subtype (nssCertificateCollection_Destroy, ...), but that doesn't
* seem worth the code bloat.. It is left up to the caller to remember
* what type of collection he/she is dealing with.
*
* nssPKIObjectCollection_Destroy
* nssPKIObjectCollection_Count
* nssPKIObjectCollection_AddObject
* nssPKIObjectCollection_AddInstances
* nssPKIObjectCollection_Traverse
*
* Back to type-specific methods.
*
* nssPKIObjectCollection_GetCertificates
* nssPKIObjectCollection_GetPrivateKeys
* nssPKIObjectCollection_GetPublicKeys
*/
/* nssCertificateCollection_Create
*
* Create a collection of certificates in the specified trust domain.
* Optionally provide a starting set of certs.
*/
NSS_EXTERN nssPKIObjectCollection *
nssCertificateCollection_Create
(
NSSTrustDomain *td,
NSSCertificate **certsOpt
);
/* nssPrivateKeyCollection_Create
*
* Create a collection of private keys in the specified trust domain.
* Optionally provide a starting set of keys.
*/
NSS_EXTERN nssPKIObjectCollection *
nssPrivateKeyCollection_Create
(
NSSTrustDomain *td,
NSSPrivateKey **pvkOpt
);
/* nssPublicKeyCollection_Create
*
* Create a collection of public keys in the specified trust domain.
* Optionally provide a starting set of keys.
*/
NSS_EXTERN nssPKIObjectCollection *
nssPublicKeyCollection_Create
(
NSSTrustDomain *td,
NSSPublicKey **pvkOpt
);
/* nssPKIObjectCollection_Destroy
*/
NSS_EXTERN void
nssPKIObjectCollection_Destroy
(
nssPKIObjectCollection *collection
);
/* nssPKIObjectCollection_Count
*/
NSS_EXTERN PRUint32
nssPKIObjectCollection_Count
(
nssPKIObjectCollection *collection
);
NSS_EXTERN PRStatus
nssPKIObjectCollection_AddObject
(
nssPKIObjectCollection *collection,
nssPKIObject *object
);
/* nssPKIObjectCollection_AddInstances
*
* Add a set of object instances to the collection. The instances
* will be sorted into any existing certs/proto-certs that may be in
* the collection. The instances will be absorbed by the collection,
* the array should not be used after this call (except to free it).
*
* Failure means the collection is in an invalid state.
*
* numInstances = 0 means the array is NULL-terminated
*/
NSS_EXTERN PRStatus
nssPKIObjectCollection_AddInstances
(
nssPKIObjectCollection *collection,
nssCryptokiObject **instances,
PRUint32 numInstances
);
/* nssPKIObjectCollection_Traverse
*/
NSS_EXTERN PRStatus
nssPKIObjectCollection_Traverse
(
nssPKIObjectCollection *collection,
nssPKIObjectCallback *callback
);
/* nssPKIObjectCollection_GetCertificates
*
* Get all of the certificates in the collection.
*/
NSS_EXTERN NSSCertificate **
nssPKIObjectCollection_GetCertificates
(
nssPKIObjectCollection *collection,
NSSCertificate **rvOpt,
PRUint32 maximumOpt,
NSSArena *arenaOpt
);
NSS_EXTERN NSSPrivateKey **
nssPKIObjectCollection_GetPrivateKeys
(
nssPKIObjectCollection *collection,
NSSPrivateKey **rvOpt,
PRUint32 maximumOpt,
NSSArena *arenaOpt
);
NSS_EXTERN NSSPublicKey **
nssPKIObjectCollection_GetPublicKeys
(
nssPKIObjectCollection *collection,
NSSPublicKey **rvOpt,
PRUint32 maximumOpt,
NSSArena *arenaOpt
);
NSS_EXTERN NSSTime *
NSSTime_Now
(
NSSTime *timeOpt
);
NSS_EXTERN NSSTime *
NSSTime_SetPRTime
(
NSSTime *timeOpt,
PRTime prTime
);
NSS_EXTERN PRTime
NSSTime_GetPRTime
(
NSSTime *time
);
NSS_EXTERN nssHash *
@ -61,79 +496,15 @@ nssHash_CreateCertificate
PRUint32 numBuckets
);
/* Token ordering routines */
/* 3.4 Certificate cache routines */
/*
* Given a crypto algorithm, return the preferred token for performing
* the crypto operation.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetCryptoToken
NSS_EXTERN PRStatus
nssTrustDomain_InitializeCache
(
NSSTrustDomain *td,
NSSAlgorithmAndParameters *ap
PRUint32 cacheSize
);
/* The following routines are used to obtain the preferred token on which
* to store particular objects.
*/
/*
* Find the preferred token for storing user certificates.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetUserCertToken
(
NSSTrustDomain *td
);
/*
* Find the preferred token for storing email certificates.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetEmailCertToken
(
NSSTrustDomain *td
);
/*
* Find the preferred token for storing SSL certificates.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetSSLCertToken
(
NSSTrustDomain *td
);
/*
* Find the preferred token for storing root certificates.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetRootCertToken
(
NSSTrustDomain *td
);
/*
* Find the preferred token for storing private keys.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetPrivateKeyToken
(
NSSTrustDomain *td
);
/*
* Find the preferred token for storing symmetric keys.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetSymmetricKeyToken
(
NSSTrustDomain *td
);
/* Certificate cache routines */
NSS_EXTERN PRStatus
nssTrustDomain_AddCertsToCache
(
@ -238,54 +609,11 @@ nssTrustDomain_GetCertsFromCache
nssList *certListOpt
);
NSS_EXTERN PRStatus
nssCertificate_SetCertTrust
(
NSSCertificate *c,
NSSTrust *trust
);
NSS_EXTERN nssDecodedCert *
nssCertificate_GetDecoding
(
NSSCertificate *c
);
NSS_EXTERN nssDecodedCert *
nssDecodedCert_Create
(
NSSArena *arenaOpt,
NSSDER *encoding,
NSSCertificateType type
);
NSS_EXTERN PRStatus
nssDecodedCert_Destroy
(
nssDecodedCert *dc
);
NSS_EXTERN void
nssBestCertificate_SetArgs
nssTrustDomain_DumpCacheInfo
(
nssBestCertificateCB *best,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policies
);
NSS_EXTERN PRStatus
nssBestCertificate_Callback
(
NSSCertificate *c,
void *arg
);
NSS_EXTERN PRStatus
nssCertificateList_DoCallback
(
nssList *certList,
PRStatus (* callback)(NSSCertificate *c, void *arg),
NSSTrustDomain *td,
void (* cert_dump_iter)(const void *, void *, void *),
void *arg
);
@ -295,54 +623,6 @@ nssCertificateList_AddReferences
nssList *certList
);
NSS_EXTERN PRStatus
nssPKIObject_Initialize
(
struct nssPKIObjectBaseStr *object,
NSSArena *arena,
NSSTrustDomain *td,
NSSCryptoContext *cc
);
NSS_EXTERN void
nssPKIObject_AddRef
(
struct nssPKIObjectBaseStr *object
);
NSS_EXTERN PRBool
nssPKIObject_Destroy
(
struct nssPKIObjectBaseStr *object
);
NSS_EXTERN NSSTime *
NSSTime_Now
(
NSSTime *timeOpt
);
NSS_EXTERN NSSTime *
NSSTime_SetPRTime
(
NSSTime *timeOpt,
PRTime prTime
);
NSS_EXTERN PRTime
NSSTime_GetPRTime
(
NSSTime *time
);
NSS_EXTERN void
nssTrustDomain_DumpCacheInfo
(
NSSTrustDomain *td,
void (* cert_dump_iter)(const void *, void *, void *),
void *arg
);
PR_END_EXTERN_C
#endif /* PKIM_H */

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.15 $ $Date: 2002/03/07 22:07:58 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.16 $ $Date: 2002/04/15 15:22:10 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIM_H
@ -435,7 +435,7 @@ static void match_nickname(const void *k, void *v, void *a)
nssList *subjectList = (nssList *)v;
struct nickname_template_str *nt = (struct nickname_template_str *)a;
nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
nickname = NSSCertificate_GetNickname(c, NULL);
nickname = nssCertificate_GetNickname(c, NULL);
if (nssrv == PR_SUCCESS &&
nssUTF8_Equal(nickname, nt->nickname, &nssrv))
{

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

@ -35,7 +35,7 @@
#define PKIT_H
#ifdef DEBUG
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.11 $ $Date: 2002/03/07 22:07:59 $ $Name: $";
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.12 $ $Date: 2002/04/15 15:22:10 $ $Name: $";
#endif /* DEBUG */
/*
@ -71,13 +71,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.11 $ $
PR_BEGIN_EXTERN_C
typedef struct nssDecodedCertStr nssDecodedCert;
typedef struct nssCertificateStoreStr nssCertificateStore;
/* How wide is the scope of this? */
typedef struct nssSMIMEProfileStr nssSMIMEProfile;
/*
* A note on ephemeral certs
*
@ -93,17 +86,25 @@ typedef struct nssSMIMEProfileStr nssSMIMEProfile;
* for each object.
*/
/* The common data from which all objects inherit */
struct nssPKIObjectBaseStr
/* nssPKIObject
*
* This is the base object class, common to all PKI objects defined in
* nsspkit.h
*/
struct nssPKIObjectStr
{
/* The arena for all object memory */
NSSArena *arena;
/* Thread-safe reference counting */
PZLock *lock;
/* Atomically incremented/decremented reference counting */
PRInt32 refCount;
/* List of nssCryptokiInstance's of the object */
nssList *instanceList;
nssListIterator *instances;
/* lock protects the array of nssCryptokiInstance's of the object */
PZLock *lock;
/* XXX with LRU cache, this cannot be guaranteed up-to-date. It cannot
* be compared against the update level of the trust domain, since it is
* also affected by import/export. Where is this array needed?
*/
nssCryptokiObject **instances;
PRUint32 numInstances;
/* The object must live in a trust domain */
NSSTrustDomain *trustDomain;
/* The object may live in a crypto context */
@ -112,9 +113,18 @@ struct nssPKIObjectBaseStr
NSSUTF8 *tempName;
};
typedef struct nssDecodedCertStr nssDecodedCert;
typedef struct nssCertificateStoreStr nssCertificateStore;
/* How wide is the scope of this? */
typedef struct nssSMIMEProfileStr nssSMIMEProfile;
typedef struct nssPKIObjectStr nssPKIObject;
struct NSSTrustStr
{
struct nssPKIObjectBaseStr object;
nssPKIObject object;
NSSCertificate *certificate;
nssTrustLevel serverAuth;
nssTrustLevel clientAuth;
@ -124,7 +134,7 @@ struct NSSTrustStr
struct nssSMIMEProfileStr
{
struct nssPKIObjectBaseStr object;
nssPKIObject object;
NSSCertificate *certificate;
NSSASCII7 *email;
NSSDER *subject;
@ -134,7 +144,7 @@ struct nssSMIMEProfileStr
struct NSSCertificateStr
{
struct nssPKIObjectBaseStr object;
nssPKIObject object;
NSSCertificateType type;
NSSItem id;
NSSBER encoding;
@ -156,7 +166,7 @@ typedef struct nssTDCertificateCacheStr nssTDCertificateCache;
struct NSSTrustDomainStr {
PRInt32 refCount;
NSSArena *arena;
NSSCallback defaultCallback;
NSSCallback *defaultCallback;
nssList *tokenList;
nssListIterator *tokens;
nssTDCertificateCache *cache;

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

@ -35,7 +35,7 @@
#define PKITM_H
#ifdef DEBUG
static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.7 $ $Date: 2002/02/04 22:34:22 $ $Name: $";
static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.8 $ $Date: 2002/04/15 15:22:11 $ $Name: $";
#endif /* DEBUG */
/*
@ -104,6 +104,18 @@ struct nssBestCertificateCBStr {
NSSPolicies *policies;
};
typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection;
typedef struct
{
union {
PRStatus (* cert)(NSSCertificate *c, void *arg);
PRStatus (* pvkey)(NSSPrivateKey *vk, void *arg);
PRStatus (* pbkey)(NSSPublicKey *bk, void *arg);
} func;
void *arg;
} nssPKIObjectCallback;
PR_END_EXTERN_C
#endif /* PKITM_H */

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.28 $ $Date: 2002/03/07 22:08:00 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.29 $ $Date: 2002/04/15 15:22:11 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIM_H
@ -308,7 +308,7 @@ remove_nickname_entry
)
{
PRStatus nssrv;
NSSUTF8 *nickname = NSSCertificate_GetNickname(cert, NULL);
NSSUTF8 *nickname = nssCertificate_GetNickname(cert, NULL);
if (nickname) {
nssHash_Remove(cache->nickname, nickname);
nssrv = PR_SUCCESS;
@ -562,7 +562,7 @@ add_nickname_entry
)
{
PRStatus nssrv = PR_SUCCESS;
NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL);
NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
cache_entry *ce;
ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname);
if (ce) {
@ -654,7 +654,7 @@ add_email_entry
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
static PRStatus
static NSSCertificate *
add_cert_to_cache
(
NSSTrustDomain *td,
@ -665,18 +665,24 @@ add_cert_to_cache
nssList *subjectList;
PRStatus nssrv;
PRUint32 added = 0;
cache_entry *ce;
NSSCertificate *rvCert = NULL;
PZ_Lock(td->cache->lock);
/* If it exists in the issuer/serial hash, it's already in all */
if (nssHash_Exists(td->cache->issuerAndSN, cert)) {
ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
if (ce) {
ce->hits++;
ce->lastHit = PR_Now();
rvCert = nssCertificate_AddRef(ce->entry.cert);
#ifdef DEBUG_CACHE
log_cert_ref("attempted to add cert already in cache", cert);
#endif
PZ_Unlock(td->cache->lock);
/* collision - most likely, somebody else already added the cert
/* collision - somebody else already added the cert
* to the cache before this thread got around to it.
*/
nss_SetError(NSS_ERROR_CERTIFICATE_IN_CACHE);
return PR_FAILURE;
nssCertificate_Destroy(cert);
return rvCert;
}
/* create a new cache entry for this cert within the cert's arena*/
nssrv = add_issuer_and_serial_entry(cert->object.arena, td->cache, cert);
@ -698,7 +704,7 @@ add_cert_to_cache
/* If a new subject entry was created, also need nickname and/or email */
if (subjectList != NULL) {
PRBool handle = PR_FALSE;
NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL);
NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
if (certNickname) {
nssrv = add_nickname_entry(arena, td->cache, cert, subjectList);
if (nssrv != PR_SUCCESS) {
@ -729,7 +735,7 @@ add_cert_to_cache
}
nssCertificate_AddRef(cert);
PZ_Unlock(td->cache->lock);
return nssrv;
return rvCert;
loser:
/* Remove any handles that have been created */
subjectList = NULL;
@ -753,7 +759,7 @@ loser:
nssArena_Destroy(arena);
}
PZ_Unlock(td->cache->lock);
return PR_FAILURE;
return NULL;
}
NSS_IMPLEMENT PRStatus
@ -765,31 +771,13 @@ nssTrustDomain_AddCertsToCache
)
{
PRUint32 i;
NSSError e;
NSSCertificate *c;
for (i=0; i<numCerts && certs[i]; i++) {
if (add_cert_to_cache(td, certs[i]) != PR_SUCCESS) {
if ((e = NSS_GetError()) == NSS_ERROR_CERTIFICATE_IN_CACHE) {
/* collision - delete and replace the cert here in favor
* of the already cached entry. This is safe as long as
* the cert being added here only has a single reference.
* This should be the case as this function is only called
* immediately following a traversal and before any certs
* are returned to the caller.
*/
NSSCertificate *c;
c = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
&certs[i]->issuer,
&certs[i]->serial);
if (c != certs[i]) {
NSSCertificate_Destroy(certs[i]);
certs[i] = c;
} else {
NSSCertificate_Destroy(c);
}
nss_ClearErrorStack();
continue;
}
c = add_cert_to_cache(td, certs[i]);
if (c == NULL) {
return PR_FAILURE;
} else {
certs[i] = c;
}
}
return PR_SUCCESS;

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