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

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef NSSCKEPV_H #ifndef NSSCKEPV_H
@ -287,7 +287,6 @@ nssCKObject_IsTokenObjectTemplate
return PR_FALSE; return PR_FALSE;
} }
#ifdef PURE_STAN_BUILD
static NSSCertificateType static NSSCertificateType
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{ {
@ -358,10 +357,14 @@ nssCryptokiCertificate_GetAttributes
return PR_SUCCESS; return PR_SUCCESS;
} }
#ifdef PURE_STAN_BUILD
status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt, status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
certObject, CKO_CERTIFICATE, certObject, CKO_CERTIFICATE,
cert_template, template_size); cert_template, template_size);
if (status != PR_SUCCESS) { if (status != PR_SUCCESS) {
#else
if (PR_TRUE) {
#endif
session = sessionOpt ? session = sessionOpt ?
sessionOpt : sessionOpt :
@ -402,6 +405,7 @@ nssCryptokiCertificate_GetAttributes
return PR_SUCCESS; return PR_SUCCESS;
} }
#ifdef PURE_STAN_BUILD
static NSSKeyPairType static NSSKeyPairType
nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{ {
@ -523,6 +527,7 @@ nssCryptokiPublicKey_GetAttributes
} }
return PR_SUCCESS; return PR_SUCCESS;
} }
#endif /* PURE_STAN_BUILD */
static nssTrustLevel static nssTrustLevel
get_nss_trust get_nss_trust
@ -572,11 +577,15 @@ nssCryptokiTrust_GetAttributes
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust);
NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
#ifdef PURE_STAN_BUILD
status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL, status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
trustObject, trustObject,
CKO_NETSCAPE_TRUST, CKO_NETSCAPE_TRUST,
trust_template, trust_size); trust_template, trust_size);
if (status != PR_SUCCESS) { if (status != PR_SUCCESS) {
#else
if (PR_TRUE) {
#endif
session = sessionOpt ? session = sessionOpt ?
sessionOpt : sessionOpt :
nssToken_GetDefaultSession(trustObject->token); nssToken_GetDefaultSession(trustObject->token);
@ -598,6 +607,7 @@ nssCryptokiTrust_GetAttributes
return PR_SUCCESS; return PR_SUCCESS;
} }
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssCryptokiCRL_GetAttributes nssCryptokiCRL_GetAttributes
( (

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

@ -41,7 +41,7 @@
#define CKHELPER_H #define CKHELPER_H
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef NSSCKT_H #ifndef NSSCKT_H
@ -86,6 +86,12 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
(pattr)->ulValueLen = (CK_ULONG)sizeof(var); \ (pattr)->ulValueLen = (CK_ULONG)sizeof(var); \
(pattr)++; (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) \ #define NSS_CK_TEMPLATE_FINISH(_template, attr, size) \
size = (attr) - (_template); \ size = (attr) - (_template); \
PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0])); PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0]));

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

@ -41,7 +41,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef NSSCKT_H #ifndef NSSCKT_H
@ -421,7 +421,6 @@ nssToken_NeedsPINInitialization
NSSToken *token NSSToken *token
); );
#ifdef PURE_STAN_BUILD
NSS_EXTERN nssCryptokiObject * NSS_EXTERN nssCryptokiObject *
nssToken_ImportCertificate nssToken_ImportCertificate
( (
@ -603,8 +602,6 @@ nssToken_FindPublicKeyByID
NSSItem *keyID NSSItem *keyID
); );
#endif /* PURE_STAN_BUILD */
NSS_EXTERN NSSItem * NSS_EXTERN NSSItem *
nssToken_Digest nssToken_Digest
( (
@ -903,26 +900,18 @@ nssSlotList_GetBestSlotForAlgorithmsAndParameters
NSSAlgorithmAndParameters **ap NSSAlgorithmAndParameters **ap
); );
#ifndef PURE_STAN_BUILD #ifdef NSS_3_4_CODE
/* XXX the following remain while merging new work */
NSS_EXTERN PRStatus NSS_EXTERN PRBool
nssToken_ImportCertificate nssToken_IsPresent
( (
NSSToken *tok, NSSToken *token
nssSession *sessionOpt,
NSSCertificate *cert,
NSSUTF8 *nickname,
PRBool asTokenObject
); );
NSS_EXTERN PRStatus NSS_EXTERN nssSession *
nssToken_ImportTrust nssToken_GetDefaultSession
( (
NSSToken *tok, NSSToken *token
nssSession *sessionOpt,
NSSTrust *trust,
PRBool asTokenObject
); );
NSS_EXTERN PRStatus NSS_EXTERN PRStatus
@ -949,96 +938,13 @@ nssToken_SetHasCrls
NSSToken *tok NSSToken *tok
); );
/* Permanently remove an object from the token. */
NSS_EXTERN PRStatus NSS_EXTERN PRStatus
nssToken_DeleteStoredObject nssToken_GetTrustOrder
( (
nssCryptokiInstance *instance NSSToken *tok
); );
NSS_EXTERN NSSTrust * #endif
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 */
PR_END_EXTERN_C PR_END_EXTERN_C

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

@ -35,7 +35,7 @@
#define DEVT_H #define DEVT_H
#ifdef DEBUG #ifdef DEBUG
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.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 */ #endif /* DEBUG */
/* /*
@ -144,7 +144,7 @@ typedef enum {
NSSCertificateType_PKIX = 1 NSSCertificateType_PKIX = 1
} NSSCertificateType; } NSSCertificateType;
#ifdef NSS_3_4_CODE #ifdef nodef
/* the current definition of NSSTrust depends on this value being CK_ULONG */ /* the current definition of NSSTrust depends on this value being CK_ULONG */
typedef CK_ULONG nssTrustLevel; typedef CK_ULONG nssTrustLevel;
#else #else
@ -175,7 +175,8 @@ typedef struct nssTokenCertSearchStr nssTokenCertSearch;
typedef enum { typedef enum {
nssTokenSearchType_AllObjects = 0, nssTokenSearchType_AllObjects = 0,
nssTokenSearchType_SessionOnly = 1, nssTokenSearchType_SessionOnly = 1,
nssTokenSearchType_TokenOnly = 2 nssTokenSearchType_TokenOnly = 2,
nssTokenSearchType_TokenForced = 3
} nssTokenSearchType; } nssTokenSearchType;
struct nssTokenCertSearchStr struct nssTokenCertSearchStr

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef NSSCKEPV_H #ifndef NSSCKEPV_H
@ -48,6 +48,8 @@ static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.11 $ $D
#endif /* CKHELPER_H */ #endif /* CKHELPER_H */
#ifdef NSS_3_4_CODE #ifdef NSS_3_4_CODE
#include "pk11func.h"
#include "dev3hack.h"
#endif #endif
/* The number of object handles to grab during each call to C_FindObjects */ /* 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)); return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED));
} }
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssToken_DeleteStoredObject nssToken_DeleteStoredObject
( (
@ -267,9 +268,11 @@ nssToken_DeleteStoredObject
NSSToken *token = instance->token; NSSToken *token = instance->token;
nssSession *session = NULL; nssSession *session = NULL;
void *epv = nssToken_GetCryptokiEPV(instance->token); void *epv = nssToken_GetCryptokiEPV(instance->token);
#ifdef PURE_STAN_BUILD
if (token->cache) { if (token->cache) {
status = nssTokenObjectCache_RemoveObject(token->cache, instance); status = nssTokenObjectCache_RemoveObject(token->cache, instance);
} }
#endif
if (instance->isTokenObject) { if (instance->isTokenObject) {
if (nssSession_IsReadWrite(token->defaultSession)) { if (nssSession_IsReadWrite(token->defaultSession)) {
session = token->defaultSession; session = token->defaultSession;
@ -304,6 +307,7 @@ import_object
{ {
nssSession *session = NULL; nssSession *session = NULL;
PRBool createdSession = PR_FALSE; PRBool createdSession = PR_FALSE;
nssCryptokiObject *object = NULL;
CK_OBJECT_HANDLE handle; CK_OBJECT_HANDLE handle;
CK_RV ckrv; CK_RV ckrv;
void *epv = nssToken_GetCryptokiEPV(tok); void *epv = nssToken_GetCryptokiEPV(tok);
@ -331,13 +335,13 @@ import_object
objectTemplate, otsize, objectTemplate, otsize,
&handle); &handle);
nssSession_ExitMonitor(session); nssSession_ExitMonitor(session);
if (ckrv == CKR_OK) {
object = nssCryptokiObject_Create(tok, session, handle);
}
if (createdSession) { if (createdSession) {
nssSession_Destroy(session); nssSession_Destroy(session);
} }
if (ckrv != CKR_OK) { return object;
return CK_INVALID_HANDLE;
}
return nssCryptokiObject_Create(tok, session, handle);
} }
static nssCryptokiObject ** static nssCryptokiObject **
@ -421,8 +425,11 @@ find_objects
} }
/* bump the number of found objects */ /* bump the number of found objects */
numHandles += count; numHandles += count;
if (maximumOpt == 0 || numHandles < arraySize) { if (maximumOpt > 0 || numHandles < arraySize) {
/* either reached maximum, or no more objects to get */ /* 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; break;
} }
/* the array is filled, double it and continue */ /* the array is filled, double it and continue */
@ -469,6 +476,7 @@ find_objects_by_template
CK_OBJECT_CLASS objclass; CK_OBJECT_CLASS objclass;
nssCryptokiObject **objects = NULL; nssCryptokiObject **objects = NULL;
PRUint32 i; PRUint32 i;
#ifdef PURE_STAN_BUILD
for (i=0; i<otsize; i++) { for (i=0; i<otsize; i++) {
if (obj_template[i].type == CKA_CLASS) { if (obj_template[i].type == CKA_CLASS) {
objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
@ -487,6 +495,7 @@ find_objects_by_template
maximumOpt); maximumOpt);
if (statusOpt) *statusOpt = PR_SUCCESS; if (statusOpt) *statusOpt = PR_SUCCESS;
} }
#endif /* PURE_STAN_BUILD */
/* Either they are not cached, or cache failed; look on token. */ /* Either they are not cached, or cache failed; look on token. */
if (!objects) { if (!objects) {
objects = find_objects(token, sessionOpt, objects = find_objects(token, sessionOpt,
@ -538,11 +547,13 @@ nssToken_ImportCertificate
NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
/* Import the certificate onto the token */ /* Import the certificate onto the token */
rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize); rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);
#ifdef PURE_STAN_BUILD
if (rvObject && tok->cache) { if (rvObject && tok->cache) {
nssTokenObjectCache_ImportObject(tok->cache, rvObject, nssTokenObjectCache_ImportObject(tok->cache, rvObject,
CKO_CERTIFICATE, CKO_CERTIFICATE,
cert_tmpl, ctsize); cert_tmpl, ctsize);
} }
#endif
return rvObject; return rvObject;
} }
@ -909,7 +920,12 @@ static void
sha1_hash(NSSItem *input, NSSItem *output) sha1_hash(NSSItem *input, NSSItem *output)
{ {
NSSAlgorithmAndParameters *ap; NSSAlgorithmAndParameters *ap;
#ifdef NSS_3_4_CODE
PK11SlotInfo *internal = PK11_GetInternalSlot();
NSSToken *token = PK11Slot_GetNSSToken(internal);
#else
NSSToken *token = nss_GetDefaultCryptoToken(); NSSToken *token = nss_GetDefaultCryptoToken();
#endif
ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
(void)nssToken_Digest(token, NULL, ap, input, output, NULL); (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
#ifdef NSS_3_4_CODE #ifdef NSS_3_4_CODE
@ -922,7 +938,12 @@ static void
md5_hash(NSSItem *input, NSSItem *output) md5_hash(NSSItem *input, NSSItem *output)
{ {
NSSAlgorithmAndParameters *ap; NSSAlgorithmAndParameters *ap;
#ifdef NSS_3_4_CODE
PK11SlotInfo *internal = PK11_GetInternalSlot();
NSSToken *token = PK11Slot_GetNSSToken(internal);
#else
NSSToken *token = nss_GetDefaultCryptoToken(); NSSToken *token = nss_GetDefaultCryptoToken();
#endif
ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
(void)nssToken_Digest(token, NULL, ap, input, output, NULL); (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
#ifdef NSS_3_4_CODE #ifdef NSS_3_4_CODE
@ -1001,16 +1022,13 @@ nssToken_ImportTrust
NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize);
/* import the trust object onto the token */ /* import the trust object onto the token */
object = import_object(tok, sessionOpt, trust_tmpl, tsize); object = import_object(tok, sessionOpt, trust_tmpl, tsize);
#ifdef PURE_STAN_BUILD
if (object && tok->cache) { if (object && tok->cache) {
nssTokenObjectCache_ImportObject(tok->cache, object, nssTokenObjectCache_ImportObject(tok->cache, object,
CKO_CERTIFICATE, CKO_CERTIFICATE,
trust_tmpl, tsize); trust_tmpl, tsize);
} }
/* XXX #endif
if (object) {
tok->hasNoTrust = PR_FALSE;
}
*/
return object; return object;
} }
@ -1144,11 +1162,13 @@ nssToken_ImportCRL
/* import the crl object onto the token */ /* import the crl object onto the token */
object = import_object(token, sessionOpt, crl_tmpl, crlsize); object = import_object(token, sessionOpt, crl_tmpl, crlsize);
#ifdef PURE_STAN_BUILD
if (object && token->cache) { if (object && token->cache) {
nssTokenObjectCache_ImportObject(token->cache, object, nssTokenObjectCache_ImportObject(token->cache, object,
CKO_CERTIFICATE, CKO_CERTIFICATE,
crl_tmpl, crlsize); crl_tmpl, crlsize);
} }
#endif
return object; return object;
} }
@ -1191,6 +1211,7 @@ nssToken_FindCRLs
return objects; return objects;
} }
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssToken_GetCachedObjectAttributes nssToken_GetCachedObjectAttributes
( (
@ -1209,7 +1230,7 @@ nssToken_GetCachedObjectAttributes
object, objclass, object, objclass,
atemplate, atlen); atemplate, atlen);
} }
#endif /* PURE_STAN_BUILD */ #endif
NSS_IMPLEMENT NSSItem * NSS_IMPLEMENT NSSItem *
nssToken_Digest nssToken_Digest
@ -1370,3 +1391,92 @@ nssToken_FinishDigest
return rvItem; 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 #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 */ #endif /* DEBUG */
#ifndef DEVM_H #ifndef DEVM_H
@ -43,7 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.2 $ $Dat
#include "ckhelper.h" #include "ckhelper.h"
#endif /* CKHELPER_H */ #endif /* CKHELPER_H */
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT nssCryptokiObject * NSS_IMPLEMENT nssCryptokiObject *
nssCryptokiObject_Create nssCryptokiObject_Create
( (
@ -161,6 +160,7 @@ nssSlotArray_Clone
return rvSlots; return rvSlots;
} }
#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT void NSS_IMPLEMENT void
nssModuleArray_Destroy nssModuleArray_Destroy
( (
@ -175,6 +175,7 @@ nssModuleArray_Destroy
nss_ZFreeIf(modules); nss_ZFreeIf(modules);
} }
} }
#endif
NSS_IMPLEMENT void NSS_IMPLEMENT void
nssSlotArray_Destroy nssSlotArray_Destroy
@ -239,6 +240,7 @@ nssCryptokiObjectArray_Destroy
} }
} }
#ifdef PURE_STAN_BUILD
/* /*
* Slot lists * Slot lists
*/ */

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

@ -30,7 +30,7 @@
# may use your version of this file under either the MPL or the # may use your version of this file under either the MPL or the
# GPL. # GPL.
# #
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.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 = ../../.. CORE_DEPTH = ../../..
@ -50,7 +50,6 @@ MODULE = security
CSRCS = \ CSRCS = \
devmod.c \ devmod.c \
devslot.c \ devslot.c \
devobject.c \
devtoken.c \ devtoken.c \
devutil.c \ devutil.c \
ckhelper.c \ ckhelper.c \

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef NSS_3_4_CODE #ifndef NSS_3_4_CODE
@ -173,6 +173,15 @@ nssSlot_IsPermanent
return slot->pk11slot->isPerm; return slot->pk11slot->isPerm;
} }
NSS_IMPLEMENT PRBool
nssSlot_IsFriendly
(
NSSSlot *slot
)
{
return PK11_IsFriendly(slot->pk11slot);
}
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssToken_Refresh(NSSToken *token) nssToken_Refresh(NSSToken *token)
{ {
@ -203,6 +212,19 @@ nssSlot_Refresh
return nssToken_Refresh(slot->token); 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 * NSSTrustDomain *

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

@ -89,50 +89,6 @@ static PRStatus convert_cert(NSSCertificate *c, void *arg)
return (secrv) ? PR_FAILURE : PR_SUCCESS; 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 void
PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst) PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
{ {
@ -1215,58 +1171,6 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
return objID; return objID;
} }
static PRStatus
get_newest_cert(NSSCertificate *c, void *arg)
{
nssDecodedCert *dc, *founddc;
NSSCertificate **cfound = (NSSCertificate **)arg;
if (!*cfound) {
*cfound = 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 */ /* match all token certs with a nickname */
static nssList * static nssList *
filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname) 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 *)NULL;
cert = (NSSCertificate *)nssListIterator_Next(certs)) cert = (NSSCertificate *)nssListIterator_Next(certs))
{ {
NSSUTF8 *tokenNick = NSSCertificate_GetNickname(cert, token); NSSUTF8 *tokenNick = nssCertificate_GetNickname(cert, token);
if (!tokenNick) continue; if (!tokenNick) continue;
if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) { if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) {
nssList_Add(rvList, nssCertificate_AddRef(cert)); nssList_Add(rvList, nssCertificate_AddRef(cert));
@ -1334,6 +1238,38 @@ filter_token_certs_email(NSSToken *token, NSSASCII7 *email)
return rvList; 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 * CERTCertificate *
PK11_FindCertFromNickname(char *nickname, void *wincx) { PK11_FindCertFromNickname(char *nickname, void *wincx) {
#ifdef NSS_CLASSIC #ifdef NSS_CLASSIC
@ -1349,8 +1285,10 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
PORT_Free(certID); PORT_Free(certID);
return cert; return cert;
#else #else
PRStatus status;
CERTCertificate *rvCert = NULL; CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL; NSSCertificate *cert = NULL;
NSSCertificate **certs = NULL;
NSSUsage usage; NSSUsage usage;
NSSToken *token; NSSToken *token;
PK11SlotInfo *slot = NULL; PK11SlotInfo *slot = NULL;
@ -1375,111 +1313,89 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot); token = PK11Slot_GetNSSToken(slot);
} }
if (token) { if (token) {
nssTokenCertSearch search;
struct token_cbstr token_cb;
nssList *certList; nssList *certList;
nssCryptokiObject **instances;
nssPKIObjectCollection *collection;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
if (!PK11_IsPresent(slot)) { if (!PK11_IsPresent(slot)) {
return NULL; goto loser;
} }
if (!PK11_IsFriendly(slot)) { if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
PK11_FreeSlot(slot); goto loser;
return NULL;
} }
} }
/* find best cert on token */ collection = nssCertificateCollection_Create(defaultTD, NULL);
if (!collection) {
goto loser;
}
if (!nssToken_SearchCerts(token, NULL)) { 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); certList = filter_token_certs_nickname(token, nickname);
if (certList) { transfer_token_certs_to_collection(certList, token, collection);
nssCertificateList_DoCallback(certList, nssList_Destroy(certList);
get_newest_cert,
(void *)&cert);
}
} else { } else {
/* find matching certs on the token */
certList = nssList_Create(NULL, PR_FALSE); certList = nssList_Create(NULL, PR_FALSE);
if (!certList) return NULL; if (!certList) {
/* first, get all matching certs from the cache */ nssPKIObjectCollection_Destroy(collection);
goto loser;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname, nickname,
certList); certList);
/* set the search criteria */ transfer_token_certs_to_collection(certList, token, collection);
token_cb.callback = get_newest_cert; instances = nssToken_FindCertificatesByNickname(token,
token_cb.cbarg = (void *)&cert; NULL,
token_cb.token = token; nickname,
search.callback = token_callback; tokenOnly,
search.cbarg = &token_cb; 0,
search.cached = certList; &status);
search.searchType = nssTokenSearchType_TokenOnly; nssPKIObjectCollection_AddInstances(collection, instances, 0);
/* now search the token */ nss_ZFreeIf(instances);
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);
} }
/* if it wasn't found, repeat the process for email address */ /* if it wasn't found, repeat the process for email address */
if (!cert) { if (nssPKIObjectCollection_Count(collection) == 0) {
if (!nssToken_SearchCerts(token, NULL)) { if (!nssToken_SearchCerts(token, NULL)) {
certList = filter_token_certs_email(token, nickname); certList = filter_token_certs_email(token, nickname);
if (certList) { transfer_token_certs_to_collection(certList, token, collection);
nssCertificateList_DoCallback(certList, nssList_Destroy(certList);
get_newest_cert,
(void *)&cert);
}
} else { } else {
certList = nssList_Create(NULL, PR_FALSE); (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
if (!certList) return NULL;
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(
defaultTD,
nickname, nickname,
certList); certList);
search.cached = certList; transfer_token_certs_to_collection(certList, token, collection);
nssToken_TraverseCertificatesByEmail(token, NULL, instances = nssToken_FindCertificatesByEmail(token,
(NSSASCII7 *)nickname, NULL,
&search); nickname,
nssCertificateList_DoCallback(certList, tokenOnly,
token_callback, 0,
&token_cb); &status);
} nssPKIObjectCollection_AddInstances(collection, instances, 0);
if (certList) { nss_ZFreeIf(instances);
nssList_Clear(certList, cert_destructor);
nssList_Destroy(certList);
} }
} }
if (cert) { certs = nssPKIObjectCollection_GetCertificates(collection,
(void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1); NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
if (certs) {
cert = nssCertificateArray_FindBestCertificate(certs, NULL,
&usage, NULL);
rvCert = STAN_GetCERTCertificate(cert); rvCert = STAN_GetCERTCertificate(cert);
nssCertificateArray_Destroy(certs);
} }
nssList_Destroy(certList);
} }
if (slot) { if (slot) {
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
} }
if (nickCopy) PORT_Free(nickCopy); if (nickCopy) PORT_Free(nickCopy);
return rvCert; return rvCert;
#endif loser:
} if (slot) {
PK11_FreeSlot(slot);
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);
} }
return PR_SUCCESS; if (nickCopy) PORT_Free(nickCopy);
return NULL;
#endif
} }
CERTCertList * CERTCertList *
@ -1509,12 +1425,12 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
PORT_Free(certID); PORT_Free(certID);
return certList; return certList;
#else #else
PRStatus nssrv;
char *nickCopy; char *nickCopy;
char *delimit = NULL; char *delimit = NULL;
char *tokenName; char *tokenName;
int i; int i;
CERTCertList *certList = NULL; CERTCertList *certList = NULL;
nssPKIObjectCollection *collection = NULL;
NSSCertificate **foundCerts = NULL; NSSCertificate **foundCerts = NULL;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
NSSCertificate *c; NSSCertificate *c;
@ -1538,8 +1454,6 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot); token = PK11Slot_GetNSSToken(slot);
} }
if (token) { if (token) {
nssTokenCertSearch search;
PRUint32 count;
nssList *nameList; nssList *nameList;
if (!PK11_IsFriendly(slot)) { if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
@ -1547,28 +1461,40 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
return NULL; return NULL;
} }
} }
collection = nssCertificateCollection_Create(defaultTD, NULL);
if (!collection) {
PK11_FreeSlot(slot);
return NULL;
}
if (!nssToken_SearchCerts(token, NULL)) { if (!nssToken_SearchCerts(token, NULL)) {
nameList = filter_token_certs_nickname(token, nickname); nameList = filter_token_certs_nickname(token, nickname);
transfer_token_certs_to_collection(nameList, token, collection);
} else { } else {
PRStatus status;
nssCryptokiObject **instances;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
nameList = nssList_Create(NULL, PR_FALSE); nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) return NULL; if (!nameList) {
PK11_FreeSlot(slot);
return NULL;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname, nickname,
nameList); nameList);
/* set the search criteria */ transfer_token_certs_to_collection(nameList, token, collection);
search.callback = collect_certs; instances = nssToken_FindCertificatesByNickname(token,
search.cbarg = nameList; NULL,
search.cached = nameList; nickname,
search.searchType = nssTokenSearchType_TokenOnly; tokenOnly,
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, 0,
nickname, &search); &status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
} }
if (nameList) {
count = nssList_Count(nameList);
foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
nssList_GetArray(nameList, (void **)foundCerts, count);
nssList_Destroy(nameList); nssList_Destroy(nameList);
} foundCerts = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
} }
if (slot) { if (slot) {
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
@ -1815,10 +1741,7 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
instance->token = slot->nssToken; instance->token = slot->nssToken;
instance->handle = cert->pkcs11ID; instance->handle = cert->pkcs11ID;
instance->isTokenObject = PR_TRUE; instance->isTokenObject = PR_TRUE;
nssList_Add(c->object.instanceList, instance); nssPKIObject_AddInstance(&c->object, instance);
/* XXX Fix this! */
nssListIterator_Destroy(c->object.instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
} else { } else {
cert->nssCertificate = STAN_GetNSSCertificate(cert); cert->nssCertificate = STAN_GetNSSCertificate(cert);
} }
@ -2629,40 +2552,6 @@ filter_token_certs_subject(NSSToken *token, NSSDER *subject)
return rvList; 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 SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg) SECStatus(* callback)(CERTCertificate*, void *), void *arg)
@ -2695,48 +2584,51 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg); return PK11_TraverseSlot(slot, &callarg);
#else #else
struct nss3_cert_cbstr pk11cb;
PRStatus nssrv = PR_SUCCESS; PRStatus nssrv = PR_SUCCESS;
NSSToken *token; NSSToken *token;
NSSDER subject; NSSDER subject;
NSSTrustDomain *td; NSSTrustDomain *td;
nssList *subjectList; nssList *subjectList;
nssTokenCertSearch search; nssPKIObjectCollection *collection;
pk11cb.callback = callback; nssCryptokiObject **instances;
pk11cb.arg = arg; NSSCertificate **certs;
td = STAN_GetDefaultTrustDomain(); td = STAN_GetDefaultTrustDomain();
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
token = PK11Slot_GetNSSToken(slot); token = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!nssToken_SearchCerts(token, NULL)) { if (!nssToken_SearchCerts(token, NULL)) {
subjectList = filter_token_certs_subject(token, &subject); subjectList = filter_token_certs_subject(token, &subject);
if (subjectList) { transfer_token_certs_to_collection(subjectList, token, collection);
nssrv = nssCertificateList_DoCallback(subjectList,
convert_cert, &pk11cb);
}
} else { } else {
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
subjectList = nssList_Create(NULL, PR_FALSE); subjectList = nssList_Create(NULL, PR_FALSE);
if (!subjectList) { if (!subjectList) {
return SECFailure; return SECFailure;
} }
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
subjectList); subjectList);
/* set the search criteria */ transfer_token_certs_to_collection(subjectList, token, collection);
search.callback = convert_and_cache_cert; instances = nssToken_FindCertificatesBySubject(token, NULL,
search.cbarg = &pk11cb; &subject,
search.cached = subjectList; tokenOnly, 0, &nssrv);
search.searchType = nssTokenSearchType_TokenOnly; nssPKIObjectCollection_AddInstances(collection, instances, 0);
pk11cb.cached = subjectList; nss_ZFreeIf(instances);
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);
} }
}
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; return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif #endif
@ -2785,7 +2677,9 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
NSSTrustDomain *td; NSSTrustDomain *td;
NSSUTF8 *nick; NSSUTF8 *nick;
PRBool created = PR_FALSE; PRBool created = PR_FALSE;
nssTokenCertSearch search; nssCryptokiObject **instances;
nssPKIObjectCollection *collection;
NSSCertificate **certs;
nssList *nameList; nssList *nameList;
pk11cb.callback = callback; pk11cb.callback = callback;
pk11cb.arg = arg; pk11cb.arg = arg;
@ -2798,32 +2692,39 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
} }
td = STAN_GetDefaultTrustDomain(); td = STAN_GetDefaultTrustDomain();
token = PK11Slot_GetNSSToken(slot); token = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!nssToken_SearchCerts(token, NULL)) { if (!nssToken_SearchCerts(token, NULL)) {
nameList = filter_token_certs_nickname(token, nick); nameList = filter_token_certs_nickname(token, nick);
if (nameList) { transfer_token_certs_to_collection(nameList, token, collection);
nssrv = nssCertificateList_DoCallback(nameList,
convert_cert, &pk11cb);
}
} else { } else {
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
nameList = nssList_Create(NULL, PR_FALSE); nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) {
return SECFailure;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList); (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
/* set the search criteria */ transfer_token_certs_to_collection(nameList, token, collection);
search.callback = convert_and_cache_cert; instances = nssToken_FindCertificatesByNickname(token, NULL,
search.cbarg = &pk11cb; nick,
search.cached = nameList; tokenOnly, 0, &nssrv);
search.searchType = nssTokenSearchType_TokenOnly; nssPKIObjectCollection_AddInstances(collection, instances, 0);
pk11cb.cached = nameList; nss_ZFreeIf(instances);
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) {
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); if (created) nss_ZFreeIf(nick);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
@ -2862,36 +2763,47 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
#else #else
PRStatus nssrv; PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
struct nss3_cert_cbstr pk11cb;
NSSToken *tok; NSSToken *tok;
nssList *certList = NULL; nssList *certList = NULL;
nssTokenCertSearch search; nssCryptokiObject **instances;
pk11cb.callback = callback; nssPKIObjectCollection *collection;
pk11cb.arg = arg; NSSCertificate **certs;
tok = PK11Slot_GetNSSToken(slot); tok = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
return SECFailure;
}
if (!nssToken_SearchCerts(tok, NULL)) { if (!nssToken_SearchCerts(tok, NULL)) {
certList = tok->certList; certList = nssList_Clone(tok->certList);
nssrv = nssCertificateList_DoCallback(certList, convert_cert, &pk11cb); transfer_token_certs_to_collection(certList, tok, collection);
} else { } else {
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
certList = nssList_Create(NULL, PR_FALSE); certList = nssList_Create(NULL, PR_FALSE);
if (!certList) { if (!certList) {
return SECFailure; return SECFailure;
} }
(void *)nssTrustDomain_GetCertsFromCache(td, certList); (void *)nssTrustDomain_GetCertsFromCache(td, certList);
/* set the search criteria */ transfer_token_certs_to_collection(certList, tok, collection);
search.callback = convert_and_cache_cert; instances = nssToken_FindCertificates(tok, NULL,
search.cbarg = &pk11cb; tokenOnly, 0, &nssrv);
search.cached = certList; nssPKIObjectCollection_AddInstances(collection, instances, 0);
search.searchType = nssTokenSearchType_TokenOnly; nss_ZFreeIf(instances);
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);
} }
nssList_Clear(certList, cert_destructor);
nssList_Destroy(certList); 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;
}
}
nssCertificateArray_Destroy(certs);
} }
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif #endif
@ -2973,11 +2885,24 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
if (!nssToken_SearchCerts(tok, NULL)) { if (!nssToken_SearchCerts(tok, NULL)) {
c = filter_token_certs_DER(tok, &derCert); c = filter_token_certs_DER(tok, &derCert);
} else { } else {
c = nssTrustDomain_GetCertByDERFromCache(td, &derCert); c = NSSTrustDomain_FindCertificateByEncodedCertificate(td, &derCert);
if (!c) { if (c) {
c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, PRBool isToken = PR_FALSE;
&derCert, NSSToken **tp;
nssTokenSearchType_TokenOnly); 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) { if (c) {

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef PKIT_H #ifndef PKIT_H
@ -43,78 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.11 $
#include "pkim.h" #include "pkim.h"
#endif /* 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 #ifdef NSS_3_4_CODE
/* This is defined in nss3hack.c */ /* This is defined in nss3hack.c */
NSS_EXTERN nssDecodedCert * NSS_EXTERN nssDecodedCert *
@ -194,39 +122,3 @@ nssDecodedCert_Destroy
return PR_FAILURE; 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 #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 */ #endif /* DEBUG */
#ifndef NSSPKI_H #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; 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 * NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef nssCertificate_AddRef
( (
@ -74,7 +108,7 @@ nssCertificate_AddRef
} }
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
NSSCertificate_Destroy nssCertificate_Destroy
( (
NSSCertificate *c NSSCertificate *c
) )
@ -92,37 +126,84 @@ NSSCertificate_Destroy
return PR_SUCCESS; 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 * NSS_IMPLEMENT NSSUTF8 *
NSSCertificate_GetNickname nssCertificate_GetNickname
( (
NSSCertificate *c, NSSCertificate *c,
NSSToken *tokenOpt NSSToken *tokenOpt
) )
{ {
NSSUTF8 *rvNick = NULL; return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
nssCryptokiInstance *instance; }
nssListIterator *instances = c->object.instances;
if (c->object.cryptoContext) { NSS_IMPLEMENT NSSASCII7 *
return c->object.tempName; nssCertificate_GetEmailAddress
} (
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); NSSCertificate *c
instance != (nssCryptokiInstance *)NULL; )
instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) {
{ return c->email;
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;
} }
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
@ -132,39 +213,7 @@ NSSCertificate_DeleteStoredObject
NSSCallback *uhh NSSCallback *uhh
) )
{ {
/* this needs more thought on what will happen when there are multiple return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
* 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;
} }
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
@ -238,85 +287,171 @@ nssCertificate_GetDecoding
return c->decoding; 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 * static NSSCertificate *
filter_subject_certs_for_id(NSSCertificate **subjectCerts, NSSItem *id) filter_subject_certs_for_id
(
NSSCertificate **subjectCerts,
NSSItem *id
)
{ {
NSSCertificate **si; NSSCertificate **si;
NSSCertificate *rvCert = NULL; NSSCertificate *rvCert = NULL;
nssDecodedCert *dcp; nssDecodedCert *dcp;
/* walk the subject certs */ /* walk the subject certs */
si = subjectCerts; for (si = subjectCerts; *si; si++) {
while (*si) {
dcp = nssCertificate_GetDecoding(*si); dcp = nssCertificate_GetDecoding(*si);
if (dcp->matchIdentifier(dcp, id)) { if (dcp->matchIdentifier(dcp, id)) {
/* this cert has the correct identifier */ /* this cert has the correct identifier */
rvCert = nssCertificate_AddRef(*si); rvCert = nssCertificate_AddRef(*si);
break; break;
} }
si++;
} }
return rvCert; return rvCert;
} }
static NSSCertificate * 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; NSSArena *arena;
NSSCertificate **subjectCerts = NULL; NSSCertificate **certs = NULL;
NSSCertificate **ccIssuers = NULL;
NSSCertificate **tdIssuers = NULL;
NSSCertificate *issuer = NULL;
NSSTrustDomain *td; NSSTrustDomain *td;
NSSCryptoContext *cc; NSSCryptoContext *cc;
/* Find all certs with this cert's issuer as the subject */
cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */ cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */
if (cc) {
subjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc,
&c->issuer,
NULL,
0,
NULL);
if (subjectCerts) {
rvCert = filter_subject_certs_for_id(subjectCerts, id);
nssCertificateArray_Destroy(subjectCerts);
}
}
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); td = NSSCertificate_GetTrustDomain(c);
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, #ifdef NSS_3_4_CODE
if (!td) {
td = STAN_GetDefaultTrustDomain();
}
#endif
arena = nssArena_Create();
if (!arena) {
return (NSSCertificate *)NULL;
}
if (cc) {
ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
&c->issuer, &c->issuer,
NULL, NULL,
0, 0,
NULL); arena);
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);
} }
return rvCert; if (issuerID) {
issuer = filter_subject_certs_for_id(certs, issuerID);
nssItem_Destroy(issuerID);
} else {
issuer = nssCertificateArray_FindBestCertificate(certs,
timeOpt,
usage,
policiesOpt);
}
nssCertificateArray_Destroy(certs);
}
nssArena_Destroy(arena);
return issuer;
} }
/* XXX review based on CERT_FindCertIssuer /* XXX review based on CERT_FindCertIssuer
* this function is not using the authCertIssuer field as a fallback * this function is not using the authCertIssuer field as a fallback
* if authority key id does not exist * 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 ** NSS_IMPLEMENT NSSCertificate **
NSSCertificate_BuildChain NSSCertificate_BuildChain
( (
@ -330,129 +465,26 @@ NSSCertificate_BuildChain
PRStatus *statusOpt PRStatus *statusOpt
) )
{ {
PRStatus nssrv; return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
nssList *chain; rvOpt, rvLimit, arenaOpt, statusOpt);
NSSItem *issuerID; }
NSSCertificate **rvChain;
NSSTrustDomain *td; NSS_IMPLEMENT NSSCryptoContext *
NSSCryptoContext *cc; nssCertificate_GetCryptoContext
nssDecodedCert *dc; (
NSSCertificate *ct, *cp; NSSCertificate *c
cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */ )
td = NSSCertificate_GetTrustDomain(c); {
#ifdef NSS_3_4_CODE return c->object.cryptoContext;
if (!td) { }
td = STAN_GetDefaultTrustDomain();
} NSS_IMPLEMENT NSSTrustDomain *
#endif nssCertificate_GetTrustDomain
chain = nssList_Create(NULL, PR_FALSE); (
nssList_Add(chain, nssCertificate_AddRef(c)); NSSCertificate *c
if (statusOpt) *statusOpt = PR_SUCCESS; )
if (rvLimit == 1) goto finish; {
while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) { return c->object.trustDomain;
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;
} }
NSS_IMPLEMENT NSSTrustDomain * NSS_IMPLEMENT NSSTrustDomain *
@ -461,7 +493,7 @@ NSSCertificate_GetTrustDomain
NSSCertificate *c NSSCertificate *c
) )
{ {
return c->object.trustDomain; return nssCertificate_GetTrustDomain(c);
} }
NSS_IMPLEMENT NSSToken * NSS_IMPLEMENT NSSToken *
@ -825,22 +857,24 @@ nssSMIMEProfile_Create
NSSItem *profileData NSSItem *profileData
) )
{ {
PRStatus nssrv;
NSSArena *arena; NSSArena *arena;
nssSMIMEProfile *rvProfile; nssSMIMEProfile *rvProfile;
nssPKIObject *object;
NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
arena = nssArena_Create(); arena = nssArena_Create();
if (!arena) { if (!arena) {
return NULL; return NULL;
} }
rvProfile = nss_ZNEW(arena, nssSMIMEProfile); object = nssPKIObject_Create(arena, NULL, td, cc);
if (!rvProfile) { if (!object) {
nssArena_Destroy(arena);
return NULL;
}
nssrv = nssPKIObject_Initialize(&rvProfile->object, arena, NULL, NULL);
if (nssrv != PR_SUCCESS) {
goto loser; goto loser;
} }
rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
if (!rvProfile) {
goto loser;
}
rvProfile->object = *object;
rvProfile->certificate = cert; rvProfile->certificate = cert;
rvProfile->email = nssUTF8_Duplicate(cert->email, arena); rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL); rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
@ -852,8 +886,8 @@ nssSMIMEProfile_Create
} }
return rvProfile; return rvProfile;
loser: loser:
nssPKIObject_Destroy(&rvProfile->object); nssPKIObject_Destroy(object);
return NULL; return (nssSMIMEProfile *)NULL;
} }
/* execute a callback function on all members of a cert list */ /* 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); (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 * NSS_IMPLEMENT NSSTrust *
nssTrust_AddRef nssTrust_AddRef
( (

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

@ -32,36 +32,59 @@
*/ */
#ifdef DEBUG #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 */ #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 #ifndef DEV_H
#include "dev.h" #include "dev.h"
#endif /* DEV_H */ #endif /* DEV_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifndef PKISTORE_H #ifndef PKISTORE_H
#include "pkistore.h" #include "pkistore.h"
#endif /* PKISTORE_H */ #endif /* PKISTORE_H */
#ifdef NSS_3_4_CODE #include "pki1t.h"
#include "pk11func.h"
#include "dev3hack.h" #ifdef PURE_STAN_BUILD
struct NSSCryptoContextStr
{
PRInt32 refCount;
NSSArena *arena;
NSSTrustDomain *td;
NSSToken *token;
nssSession *session;
nssCertificateStore *certStore;
};
#endif #endif
extern const NSSError NSS_ERROR_NOT_FOUND; 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 NSS_IMPLEMENT PRStatus
NSSCryptoContext_Destroy NSSCryptoContext_Destroy
( (
@ -177,9 +200,11 @@ nssCryptoContext_ImportTrust
} }
} }
nssrv = nssCertificateStore_AddTrust(cc->certStore, trust); nssrv = nssCertificateStore_AddTrust(cc->certStore, trust);
#if 0
if (nssrv == PR_SUCCESS) { if (nssrv == PR_SUCCESS) {
trust->object.cryptoContext = cc; trust->object.cryptoContext = cc;
} }
#endif
return nssrv; return nssrv;
} }
@ -198,9 +223,11 @@ nssCryptoContext_ImportSMIMEProfile
} }
} }
nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile); nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile);
#if 0
if (nssrv == PR_SUCCESS) { if (nssrv == PR_SUCCESS) {
profile->object.cryptoContext = cc; profile->object.cryptoContext = cc;
} }
#endif
return nssrv; return nssrv;
} }
@ -214,36 +241,22 @@ NSSCryptoContext_FindBestCertificateByNickname
NSSPolicies *policiesOpt /* NULL for none */ NSSPolicies *policiesOpt /* NULL for none */
) )
{ {
PRIntn i; NSSCertificate **certs;
NSSCertificate *c; NSSCertificate *rvCert = NULL;
NSSCertificate **nickCerts;
nssBestCertificateCB best;
if (!cc->certStore) { if (!cc->certStore) {
return NULL; return NULL;
} }
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
/* This could be improved by querying the store with a callback */
nickCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
name, name,
NULL, NULL, 0, NULL);
0, if (certs) {
NULL); rvCert = nssCertificateArray_FindBestCertificate(certs,
if (nickCerts) { timeOpt,
PRStatus nssrv; usage,
for (i=0, c = *nickCerts; c != NULL; c = nickCerts[++i]) { policiesOpt);
nssrv = nssBestCertificate_Callback(c, &best); nssCertificateArray_Destroy(certs);
NSSCertificate_Destroy(c);
if (nssrv != PR_SUCCESS) {
if (best.cert) {
NSSCertificate_Destroy(best.cert);
best.cert = NULL;
} }
break; return rvCert;
}
}
nss_ZFreeIf(nickCerts);
}
return best.cert;
} }
NSS_IMPLEMENT NSSCertificate ** NSS_IMPLEMENT NSSCertificate **
@ -295,39 +308,26 @@ NSSCryptoContext_FindBestCertificateBySubject
NSSPolicies *policiesOpt NSSPolicies *policiesOpt
) )
{ {
PRIntn i; NSSCertificate **certs;
NSSCertificate *c; NSSCertificate *rvCert = NULL;
NSSCertificate **subjectCerts;
nssBestCertificateCB best;
if (!cc->certStore) { if (!cc->certStore) {
return NULL; return NULL;
} }
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
subjectCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
subject, subject,
NULL, NULL, 0, NULL);
0, if (certs) {
NULL); rvCert = nssCertificateArray_FindBestCertificate(certs,
if (subjectCerts) { timeOpt,
PRStatus nssrv; usage,
for (i=0, c = *subjectCerts; c != NULL; c = subjectCerts[++i]) { policiesOpt);
nssrv = nssBestCertificate_Callback(c, &best); nssCertificateArray_Destroy(certs);
NSSCertificate_Destroy(c);
if (nssrv != PR_SUCCESS) {
if (best.cert) {
NSSCertificate_Destroy(best.cert);
best.cert = NULL;
} }
break; return rvCert;
}
}
nss_ZFreeIf(subjectCerts);
}
return best.cert;
} }
NSS_IMPLEMENT NSSCertificate ** NSS_IMPLEMENT NSSCertificate **
NSSCryptoContext_FindCertificatesBySubject nssCryptoContext_FindCertificatesBySubject
( (
NSSCryptoContext *cc, NSSCryptoContext *cc,
NSSDER *subject, NSSDER *subject,
@ -348,6 +348,21 @@ NSSCryptoContext_FindCertificatesBySubject
return rvCerts; 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 * NSS_IMPLEMENT NSSCertificate *
NSSCryptoContext_FindBestCertificateByNameComponents NSSCryptoContext_FindBestCertificateByNameComponents
( (
@ -401,35 +416,22 @@ NSSCryptoContext_FindBestCertificateByEmail
NSSPolicies *policiesOpt NSSPolicies *policiesOpt
) )
{ {
PRIntn i; NSSCertificate **certs;
NSSCertificate *c; NSSCertificate *rvCert = NULL;
NSSCertificate **emailCerts;
nssBestCertificateCB best;
if (!cc->certStore) { if (!cc->certStore) {
return NULL; return NULL;
} }
nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
emailCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
email, email,
NULL, NULL, 0, NULL);
0, if (certs) {
NULL); rvCert = nssCertificateArray_FindBestCertificate(certs,
if (emailCerts) { timeOpt,
PRStatus nssrv; usage,
for (i=0, c = *emailCerts; c != NULL; c = emailCerts[++i]) { policiesOpt);
nssrv = nssBestCertificate_Callback(c, &best); nssCertificateArray_Destroy(certs);
NSSCertificate_Destroy(c);
if (nssrv != PR_SUCCESS) {
if (best.cert) {
NSSCertificate_Destroy(best.cert);
best.cert = NULL;
} }
break; return rvCert;
}
}
nss_ZFreeIf(emailCerts);
}
return best.cert;
} }
NSS_IMPLEMENT NSSCertificate ** NSS_IMPLEMENT NSSCertificate **
@ -649,31 +651,6 @@ struct token_session_str {
nssSession *session; 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 * NSS_IMPLEMENT NSSItem *
NSSCryptoContext_Decrypt NSSCryptoContext_Decrypt
( (
@ -685,58 +662,7 @@ NSSCryptoContext_Decrypt
NSSArena *arenaOpt NSSArena *arenaOpt
) )
{ {
#if 0 nss_SetError(NSS_ERROR_NOT_FOUND);
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
return NULL; return NULL;
} }

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

@ -30,7 +30,7 @@
# may use your version of this file under either the MPL or the # may use your version of this file under either the MPL or the
# GPL. # GPL.
# #
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.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 = ../../.. CORE_DEPTH = ../../..
@ -55,6 +55,7 @@ CSRCS = \
tdcache.c \ tdcache.c \
certdecode.c \ certdecode.c \
pkistore.c \ pkistore.c \
pkibase.c \
$(NULL) $(NULL)
ifndef PURE_STAN_BUILD ifndef PURE_STAN_BUILD

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

@ -35,32 +35,150 @@
#define PKI_H #define PKI_H
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef NSSDEVT_H #ifndef NSSDEVT_H
#include "nssdevt.h" #include "nssdevt.h"
#endif /* 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 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 * NSS_EXTERN NSSCertificate *
nssCertificate_AddRef nssCertificate_AddRef
( (
NSSCertificate *c 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 * NSS_EXTERN NSSUTF8 *
NSSCertificate_GetNickname nssCertificate_GetNickname
( (
NSSCertificate *c, NSSCertificate *c,
NSSToken *tokenOpt 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 */ /* putting here for now, needs more thought */
NSS_EXTERN PRStatus NSS_EXTERN PRStatus
nssCryptoContext_ImportTrust nssCryptoContext_ImportTrust

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #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 /* The cert was already in the cache, from another token. Add this
* token's instance to the cert. * token's instance to the cert.
*/ */
nssCryptokiInstance *tokenInstance, *instance; nssCryptokiObject **instance;
nssList_GetArray(cp->object.instanceList, (void **)&tokenInstance, 1); instance = nssPKIObject_GetInstances(&cp->object);
instance = nssCryptokiInstance_Create(c->object.arena, token, nssPKIObject_AddInstance(&c->object, *instance);
tokenInstance->handle, PR_TRUE); nss_ZFreeIf(instance);
nssList_Add(c->object.instanceList, instance);
nssListIterator_Destroy(c->object.instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
} }
/* This list reference persists with the token */ /* This list reference persists with the token */
nssList_Add(token->certList, nssCertificate_AddRef(c)); nssList_Add(token->certList, nssCertificate_AddRef(c));
@ -142,32 +139,11 @@ cache_token_cert(NSSCertificate *c, void *arg)
return PR_SUCCESS; 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) static PRBool instance_destructor(NSSCertificate *c, NSSToken *token)
{ {
remove_token_instance(c, token); nssPKIObject_RemoveInstanceForToken(&c->object, token);
if (nssList_Count(c->object.instanceList) == 0) { /* XXX cheating, this code to be replaced anyway */
if (c->object.numInstances == 0) {
return PR_TRUE; return PR_TRUE;
} }
return PR_FALSE; return PR_FALSE;
@ -238,6 +214,26 @@ nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances)
/* leave the list non-null to prevent it from being searched */ /* 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 */ /* create a list of local cert references for certain tokens */
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
nssToken_LoadCerts(NSSToken *token) nssToken_LoadCerts(NSSToken *token)
@ -263,7 +259,7 @@ nssToken_LoadCerts(NSSToken *token)
return PR_SUCCESS; return PR_SUCCESS;
} }
/* ignore the rv, just work without the list */ /* 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_SetTrustCache(token);
(void)nssToken_SetCrlCache(token); (void)nssToken_SetCrlCache(token);
@ -338,8 +334,6 @@ STAN_LoadDefaultNSS3TrustDomain
{ {
NSSTrustDomain *td; NSSTrustDomain *td;
NSSToken *token; NSSToken *token;
PK11SlotList *list;
PK11SlotListElement *le;
SECMODModuleList *mlp; SECMODModuleList *mlp;
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
int i; int i;
@ -461,6 +455,31 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
return rvKey; 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 * static NSSItem *
nss3certificate_getIdentifier(nssDecodedCert *dc) nss3certificate_getIdentifier(nssDecodedCert *dc)
{ {
@ -476,9 +495,7 @@ nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
CERTCertificate *c = (CERTCertificate *)dc->data; CERTCertificate *c = (CERTCertificate *)dc->data;
CERTAuthKeyID *cAuthKeyID; CERTAuthKeyID *cAuthKeyID;
PRArenaPool *tmpArena = NULL; PRArenaPool *tmpArena = NULL;
SECItem issuerCertKey;
NSSItem *rvID = NULL; NSSItem *rvID = NULL;
SECStatus secrv;
tmpArena = PORT_NewArena(512); tmpArena = PORT_NewArena(512);
cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c); cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c);
if (cAuthKeyID == NULL) { if (cAuthKeyID == NULL) {
@ -690,22 +707,21 @@ PK11_IsUserCert(PK11SlotInfo *, CERTCertificate *, CK_OBJECT_HANDLE);
/* see pk11cert.c:pk11_HandleTrustObject */ /* see pk11cert.c:pk11_HandleTrustObject */
static unsigned int static unsigned int
get_nss3trust_from_cktrust(CK_TRUST t) get_nss3trust_from_nss4trust(CK_TRUST t)
{ {
unsigned int rt = 0; unsigned int rt = 0;
if (t == CKT_NETSCAPE_TRUSTED) { if (t == nssTrustLevel_Trusted) {
rt |= CERTDB_VALID_PEER | CERTDB_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*/; rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA /*| CERTDB_NS_TRUSTED_CA*/;
} }
if (t == CKT_NETSCAPE_VALID) { if (t == nssTrustLevel_Valid) {
rt |= CERTDB_VALID_PEER; rt |= CERTDB_VALID_PEER;
} }
if (t == CKT_NETSCAPE_VALID_DELEGATOR) { if (t == nssTrustLevel_ValidDelegator) {
rt |= CERTDB_VALID_CA; rt |= CERTDB_VALID_CA;
} }
/* user */
return rt; return rt;
} }
@ -719,95 +735,57 @@ cert_trust_from_stan_trust(NSSTrust *t, PRArenaPool *arena)
} }
rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust)); rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust));
if (!rvTrust) return NULL; if (!rvTrust) return NULL;
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth); rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth);
client = get_nss3trust_from_cktrust(t->clientAuth); client = get_nss3trust_from_nss4trust(t->clientAuth);
if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) { if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA); client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA);
rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA; rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
} }
rvTrust->sslFlags |= client; rvTrust->sslFlags |= client;
rvTrust->emailFlags = get_nss3trust_from_cktrust(t->emailProtection); rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection);
rvTrust->objectSigningFlags = get_nss3trust_from_cktrust(t->codeSigning); rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning);
return rvTrust; 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 */ /* check all cert instances for private key */
static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc) static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc)
{ {
PRBool isUser = PR_FALSE; PRBool isUser = PR_FALSE;
nssCryptokiInstance *instance; nssCryptokiObject **ip;
nssListIterator *instances = c->object.instances; nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); for (ip = instances; *ip; ip++) {
instance != (nssCryptokiInstance *)NULL; nssCryptokiObject *instance = *ip;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) { if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) {
isUser = PR_TRUE; isUser = PR_TRUE;
} }
} }
nssListIterator_Finish(instances); nssCryptokiObjectArray_Destroy(instances);
return isUser; return isUser;
} }
CERTCertTrust * CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{ {
CERTCertTrust *rvTrust; CERTCertTrust *rvTrust = NULL;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
NSSToken *tok; NSSTrust *t;
NSSTrust *tokenTrust; t = nssTrustDomain_FindTrustForCertificate(td, c);
NSSTrust t; if (t) {
nssListIterator *tokens; rvTrust = cert_trust_from_stan_trust(t, cc->arena);
int lastTrustOrder, myTrustOrder; if (!rvTrust) {
tokens = nssList_CreateIterator(td->tokenList); nssTrust_Destroy(t);
if (!tokens) return NULL; 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 || nssTrust_Destroy(t);
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;
}
}
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 (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->sslFlags |= CERTDB_USER;
rvTrust->emailFlags |= CERTDB_USER; rvTrust->emailFlags |= CERTDB_USER;
rvTrust->objectSigningFlags |= CERTDB_USER; rvTrust->objectSigningFlags |= CERTDB_USER;
@ -818,15 +796,15 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
static nssCryptokiInstance * static nssCryptokiInstance *
get_cert_instance(NSSCertificate *c) get_cert_instance(NSSCertificate *c)
{ {
nssCryptokiInstance *instance, *ci; nssCryptokiObject *instance, **ci;
nssListIterator *instances = c->object.instances; nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
if (!instances) {
return NULL;
}
instance = NULL; instance = NULL;
for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances); for (ci = instances; *ci; ci++) {
ci != (nssCryptokiInstance *)NULL;
ci = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
if (!instance) { if (!instance) {
instance = ci; instance = nssCryptokiObject_Clone(*ci);
} else { } else {
/* This only really works for two instances... But 3.4 can't /* This only really works for two instances... But 3.4 can't
* handle more anyway. The logic is, if there are multiple * handle more anyway. The logic is, if there are multiple
@ -834,11 +812,12 @@ get_cert_instance(NSSCertificate *c)
* a hardware device. * a hardware device.
*/ */
if (PK11_IsInternal(instance->token->pk11slot)) { if (PK11_IsInternal(instance->token->pk11slot)) {
instance = ci; nssCryptokiObject_Destroy(instance);
instance = nssCryptokiObject_Clone(*ci);
} }
} }
} }
nssListIterator_Finish(instances); nssCryptokiObjectArray_Destroy(instances);
return instance; return instance;
} }
@ -888,15 +867,18 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
} }
} else if (instance) { } else if (instance) {
/* slot */ /* slot */
if (cc->slot != instance->token->pk11slot) {
if (cc->slot) { if (cc->slot) {
PK11_FreeSlot(cc->slot); PK11_FreeSlot(cc->slot);
} }
cc->slot = PK11_ReferenceSlot(instance->token->pk11slot); cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
}
cc->ownSlot = PR_TRUE; cc->ownSlot = PR_TRUE;
/* pkcs11ID */ /* pkcs11ID */
cc->pkcs11ID = instance->handle; cc->pkcs11ID = instance->handle;
/* trust */ /* trust */
cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc);
nssCryptokiObject_Destroy(instance);
} }
/* database handle is now the trust domain */ /* database handle is now the trust domain */
cc->dbhandle = c->object.trustDomain; cc->dbhandle = c->object.trustDomain;
@ -947,28 +929,28 @@ STAN_GetCERTCertificate(NSSCertificate *c)
return stan_GetCERTCertificate(c, PR_FALSE); return stan_GetCERTCertificate(c, PR_FALSE);
} }
static CK_TRUST static nssTrustLevel
get_stan_trust(unsigned int t, PRBool isClientAuth) get_stan_trust(unsigned int t, PRBool isClientAuth)
{ {
if (isClientAuth) { if (isClientAuth) {
if (t & CERTDB_TRUSTED_CLIENT_CA) { if (t & CERTDB_TRUSTED_CLIENT_CA) {
return CKT_NETSCAPE_TRUSTED_DELEGATOR; return nssTrustLevel_TrustedDelegator;
} }
} else { } else {
if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) { if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) {
return CKT_NETSCAPE_TRUSTED_DELEGATOR; return nssTrustLevel_TrustedDelegator;
} }
} }
if (t & CERTDB_TRUSTED) { if (t & CERTDB_TRUSTED) {
return CKT_NETSCAPE_TRUSTED; return nssTrustLevel_Trusted;
} }
if (t & CERTDB_VALID_CA) { if (t & CERTDB_VALID_CA) {
return CKT_NETSCAPE_VALID_DELEGATOR; return nssTrustLevel_ValidDelegator;
} }
if (t & CERTDB_VALID_PEER) { if (t & CERTDB_VALID_PEER) {
return CKT_NETSCAPE_VALID; return nssTrustLevel_Valid;
} }
return CKT_NETSCAPE_UNTRUSTED; return nssTrustLevel_NotTrusted;
} }
NSS_EXTERN NSSCertificate * NSS_EXTERN NSSCertificate *
@ -976,8 +958,8 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
{ {
NSSCertificate *c; NSSCertificate *c;
nssCryptokiInstance *instance; nssCryptokiInstance *instance;
nssPKIObject *pkiob;
NSSArena *arena; NSSArena *arena;
PRStatus nssrv;
c = cc->nssCertificate; c = cc->nssCertificate;
if (c) { if (c) {
return c; return c;
@ -996,10 +978,12 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
} }
NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
c->type = NSSCertificateType_PKIX; c->type = NSSCertificateType_PKIX;
nssrv = nssPKIObject_Initialize(&c->object, arena, cc->dbhandle, NULL); pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL);
if (nssrv != PR_SUCCESS) { if (!pkiob) {
nssPKIObject_Destroy(&c->object); nssArena_Destroy(arena);
return NULL;
} }
c->object = *pkiob;
nssItem_Create(arena, nssItem_Create(arena,
&c->issuer, cc->derIssuer.len, cc->derIssuer.data); &c->issuer, cc->derIssuer.len, cc->derIssuer.data);
nssItem_Create(arena, nssItem_Create(arena,
@ -1021,7 +1005,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
} }
if (cc->slot) { if (cc->slot) {
instance = nss_ZNEW(arena, nssCryptokiInstance); instance = nss_ZNEW(arena, nssCryptokiInstance);
instance->token = PK11Slot_GetNSSToken(cc->slot); instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
instance->handle = cc->pkcs11ID; instance->handle = cc->pkcs11ID;
instance->isTokenObject = PR_TRUE; instance->isTokenObject = PR_TRUE;
if (cc->nickname) { if (cc->nickname) {
@ -1030,10 +1014,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc)
(NSSUTF8 *)cc->nickname, (NSSUTF8 *)cc->nickname,
PORT_Strlen(cc->nickname)); PORT_Strlen(cc->nickname));
} }
nssList_Add(c->object.instanceList, instance); nssPKIObject_AddInstance(&c->object, instance);
/* XXX Fix this! */
nssListIterator_Destroy(c->object.instances);
c->object.instances = nssList_CreateIterator(c->object.instanceList);
} }
c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc); c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc);
cc->nssCertificate = c; cc->nssCertificate = c;
@ -1052,6 +1033,8 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
CERTCertTrust *oldTrust; CERTCertTrust *oldTrust;
nssListIterator *tokens; nssListIterator *tokens;
PRBool moving_object; PRBool moving_object;
nssCryptokiObject *newInstance;
nssPKIObject *pkiob;
oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc); oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc);
if (oldTrust) { if (oldTrust) {
if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) { if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) {
@ -1069,11 +1052,12 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
arena = nssArena_Create(); arena = nssArena_Create();
if (!arena) return PR_FAILURE; if (!arena) return PR_FAILURE;
nssTrust = nss_ZNEW(arena, NSSTrust); nssTrust = nss_ZNEW(arena, NSSTrust);
nssrv = nssPKIObject_Initialize(&nssTrust->object, arena, NULL, NULL); pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL);
if (nssrv != PR_SUCCESS) { if (!pkiob) {
nssPKIObject_Destroy(&nssTrust->object); nssArena_Destroy(arena);
return PR_FAILURE; return PR_FAILURE;
} }
nssTrust->object = *pkiob;
nssTrust->certificate = c; nssTrust->certificate = c;
nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE); nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE); nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
@ -1087,7 +1071,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
nssTrust_Destroy(nssTrust); nssTrust_Destroy(nssTrust);
return nssrv; return nssrv;
} }
if (nssList_Count(c->object.instanceList) == 0) { if (c->object.numInstances == 0) {
/* The context is the only instance, finished */ /* The context is the only instance, finished */
return nssrv; return nssrv;
} }
@ -1115,11 +1099,33 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
/* this is kind of hacky. the softoken needs the cert /* this is kind of hacky. the softoken needs the cert
* object in order to store trust. forcing it to be perm * object in order to store trust. forcing it to be perm
*/ */
NSSUTF8 *nickname = NSSCertificate_GetNickname(c, NULL); NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
nssrv = nssToken_ImportCertificate(tok, NULL, c, nickname, PR_TRUE); newInstance = nssToken_ImportCertificate(tok, NULL,
if (nssrv != PR_SUCCESS) return nssrv; 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 { } else {
nssrv = PR_FAILURE; nssrv = PR_FAILURE;
} }
@ -1183,103 +1189,6 @@ nssTrustDomain_TraverseCertificatesByNickname
return nssrv; 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) static void cert_dump_iter(const void *k, void *v, void *a)
{ {
NSSCertificate *c = (NSSCertificate *)k; NSSCertificate *c = (NSSCertificate *)k;

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

@ -35,7 +35,7 @@
#define PKINSS3HACK_H #define PKINSS3HACK_H
#ifdef DEBUG #ifdef DEBUG
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.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 */ #endif /* DEBUG */
#ifndef NSSDEVT_H #ifndef NSSDEVT_H
@ -125,6 +125,10 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc);
NSS_EXTERN PRStatus NSS_EXTERN PRStatus
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust); STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
NSS_EXTERN PRStatus
nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
NSSDER *issuer, NSSDER *serial);
/* exposing this */ /* exposing this */
NSS_EXTERN NSSCertificate * NSS_EXTERN NSSCertificate *
NSSCertificate_Create NSSCertificate_Create

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

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

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

@ -35,23 +35,458 @@
#define PKIM_H #define PKIM_H
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef BASE_H #ifndef BASE_H
#include "base.h" #include "base.h"
#endif /* BASE_H */ #endif /* BASE_H */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifndef PKITM_H #ifndef PKITM_H
#include "pkitm.h" #include "pkitm.h"
#endif /* PKITM_H */ #endif /* PKITM_H */
PR_BEGIN_EXTERN_C PR_BEGIN_EXTERN_C
NSS_EXTERN NSSToken * /* nssPKIObject
STAN_GetDefaultCryptoToken *
* 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 * NSS_EXTERN nssHash *
@ -61,79 +496,15 @@ nssHash_CreateCertificate
PRUint32 numBuckets PRUint32 numBuckets
); );
/* Token ordering routines */ /* 3.4 Certificate cache routines */
/* NSS_EXTERN PRStatus
* Given a crypto algorithm, return the preferred token for performing nssTrustDomain_InitializeCache
* the crypto operation.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetCryptoToken
( (
NSSTrustDomain *td, 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 NSS_EXTERN PRStatus
nssTrustDomain_AddCertsToCache nssTrustDomain_AddCertsToCache
( (
@ -238,54 +609,11 @@ nssTrustDomain_GetCertsFromCache
nssList *certListOpt 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 NSS_EXTERN void
nssBestCertificate_SetArgs nssTrustDomain_DumpCacheInfo
( (
nssBestCertificateCB *best, NSSTrustDomain *td,
NSSTime *timeOpt, void (* cert_dump_iter)(const void *, void *, void *),
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),
void *arg void *arg
); );
@ -295,54 +623,6 @@ nssCertificateList_AddReferences
nssList *certList 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 PR_END_EXTERN_C
#endif /* PKIM_H */ #endif /* PKIM_H */

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef PKIM_H #ifndef PKIM_H
@ -435,7 +435,7 @@ static void match_nickname(const void *k, void *v, void *a)
nssList *subjectList = (nssList *)v; nssList *subjectList = (nssList *)v;
struct nickname_template_str *nt = (struct nickname_template_str *)a; struct nickname_template_str *nt = (struct nickname_template_str *)a;
nssrv = nssList_GetArray(subjectList, (void **)&c, 1); nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
nickname = NSSCertificate_GetNickname(c, NULL); nickname = nssCertificate_GetNickname(c, NULL);
if (nssrv == PR_SUCCESS && if (nssrv == PR_SUCCESS &&
nssUTF8_Equal(nickname, nt->nickname, &nssrv)) nssUTF8_Equal(nickname, nt->nickname, &nssrv))
{ {

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

@ -35,7 +35,7 @@
#define PKIT_H #define PKIT_H
#ifdef DEBUG #ifdef DEBUG
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.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 */ #endif /* DEBUG */
/* /*
@ -71,13 +71,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.11 $ $
PR_BEGIN_EXTERN_C 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 * A note on ephemeral certs
* *
@ -93,17 +86,25 @@ typedef struct nssSMIMEProfileStr nssSMIMEProfile;
* for each object. * for each object.
*/ */
/* The common data from which all objects inherit */ /* nssPKIObject
struct nssPKIObjectBaseStr *
* This is the base object class, common to all PKI objects defined in
* nsspkit.h
*/
struct nssPKIObjectStr
{ {
/* The arena for all object memory */ /* The arena for all object memory */
NSSArena *arena; NSSArena *arena;
/* Thread-safe reference counting */ /* Atomically incremented/decremented reference counting */
PZLock *lock;
PRInt32 refCount; PRInt32 refCount;
/* List of nssCryptokiInstance's of the object */ /* lock protects the array of nssCryptokiInstance's of the object */
nssList *instanceList; PZLock *lock;
nssListIterator *instances; /* 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 */ /* The object must live in a trust domain */
NSSTrustDomain *trustDomain; NSSTrustDomain *trustDomain;
/* The object may live in a crypto context */ /* The object may live in a crypto context */
@ -112,9 +113,18 @@ struct nssPKIObjectBaseStr
NSSUTF8 *tempName; 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 NSSTrustStr
{ {
struct nssPKIObjectBaseStr object; nssPKIObject object;
NSSCertificate *certificate; NSSCertificate *certificate;
nssTrustLevel serverAuth; nssTrustLevel serverAuth;
nssTrustLevel clientAuth; nssTrustLevel clientAuth;
@ -124,7 +134,7 @@ struct NSSTrustStr
struct nssSMIMEProfileStr struct nssSMIMEProfileStr
{ {
struct nssPKIObjectBaseStr object; nssPKIObject object;
NSSCertificate *certificate; NSSCertificate *certificate;
NSSASCII7 *email; NSSASCII7 *email;
NSSDER *subject; NSSDER *subject;
@ -134,7 +144,7 @@ struct nssSMIMEProfileStr
struct NSSCertificateStr struct NSSCertificateStr
{ {
struct nssPKIObjectBaseStr object; nssPKIObject object;
NSSCertificateType type; NSSCertificateType type;
NSSItem id; NSSItem id;
NSSBER encoding; NSSBER encoding;
@ -156,7 +166,7 @@ typedef struct nssTDCertificateCacheStr nssTDCertificateCache;
struct NSSTrustDomainStr { struct NSSTrustDomainStr {
PRInt32 refCount; PRInt32 refCount;
NSSArena *arena; NSSArena *arena;
NSSCallback defaultCallback; NSSCallback *defaultCallback;
nssList *tokenList; nssList *tokenList;
nssListIterator *tokens; nssListIterator *tokens;
nssTDCertificateCache *cache; nssTDCertificateCache *cache;

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

@ -35,7 +35,7 @@
#define PKITM_H #define PKITM_H
#ifdef DEBUG #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 */ #endif /* DEBUG */
/* /*
@ -104,6 +104,18 @@ struct nssBestCertificateCBStr {
NSSPolicies *policies; 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 PR_END_EXTERN_C
#endif /* PKITM_H */ #endif /* PKITM_H */

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #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 */ #endif /* DEBUG */
#ifndef PKIM_H #ifndef PKIM_H
@ -308,7 +308,7 @@ remove_nickname_entry
) )
{ {
PRStatus nssrv; PRStatus nssrv;
NSSUTF8 *nickname = NSSCertificate_GetNickname(cert, NULL); NSSUTF8 *nickname = nssCertificate_GetNickname(cert, NULL);
if (nickname) { if (nickname) {
nssHash_Remove(cache->nickname, nickname); nssHash_Remove(cache->nickname, nickname);
nssrv = PR_SUCCESS; nssrv = PR_SUCCESS;
@ -562,7 +562,7 @@ add_nickname_entry
) )
{ {
PRStatus nssrv = PR_SUCCESS; PRStatus nssrv = PR_SUCCESS;
NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
cache_entry *ce; cache_entry *ce;
ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname); ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname);
if (ce) { if (ce) {
@ -654,7 +654,7 @@ add_email_entry
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE; extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
static PRStatus static NSSCertificate *
add_cert_to_cache add_cert_to_cache
( (
NSSTrustDomain *td, NSSTrustDomain *td,
@ -665,18 +665,24 @@ add_cert_to_cache
nssList *subjectList; nssList *subjectList;
PRStatus nssrv; PRStatus nssrv;
PRUint32 added = 0; PRUint32 added = 0;
cache_entry *ce;
NSSCertificate *rvCert = NULL;
PZ_Lock(td->cache->lock); PZ_Lock(td->cache->lock);
/* If it exists in the issuer/serial hash, it's already in all */ /* 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 #ifdef DEBUG_CACHE
log_cert_ref("attempted to add cert already in cache", cert); log_cert_ref("attempted to add cert already in cache", cert);
#endif #endif
PZ_Unlock(td->cache->lock); 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. * to the cache before this thread got around to it.
*/ */
nss_SetError(NSS_ERROR_CERTIFICATE_IN_CACHE); nssCertificate_Destroy(cert);
return PR_FAILURE; return rvCert;
} }
/* create a new cache entry for this cert within the cert's arena*/ /* 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); 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 a new subject entry was created, also need nickname and/or email */
if (subjectList != NULL) { if (subjectList != NULL) {
PRBool handle = PR_FALSE; PRBool handle = PR_FALSE;
NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
if (certNickname) { if (certNickname) {
nssrv = add_nickname_entry(arena, td->cache, cert, subjectList); nssrv = add_nickname_entry(arena, td->cache, cert, subjectList);
if (nssrv != PR_SUCCESS) { if (nssrv != PR_SUCCESS) {
@ -729,7 +735,7 @@ add_cert_to_cache
} }
nssCertificate_AddRef(cert); nssCertificate_AddRef(cert);
PZ_Unlock(td->cache->lock); PZ_Unlock(td->cache->lock);
return nssrv; return rvCert;
loser: loser:
/* Remove any handles that have been created */ /* Remove any handles that have been created */
subjectList = NULL; subjectList = NULL;
@ -753,7 +759,7 @@ loser:
nssArena_Destroy(arena); nssArena_Destroy(arena);
} }
PZ_Unlock(td->cache->lock); PZ_Unlock(td->cache->lock);
return PR_FAILURE; return NULL;
} }
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
@ -765,31 +771,13 @@ nssTrustDomain_AddCertsToCache
) )
{ {
PRUint32 i; PRUint32 i;
NSSError e;
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; NSSCertificate *c;
c = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, for (i=0; i<numCerts && certs[i]; i++) {
&certs[i]->issuer, c = add_cert_to_cache(td, certs[i]);
&certs[i]->serial); if (c == NULL) {
if (c != certs[i]) {
NSSCertificate_Destroy(certs[i]);
certs[i] = c;
} else {
NSSCertificate_Destroy(c);
}
nss_ClearErrorStack();
continue;
}
return PR_FAILURE; return PR_FAILURE;
} else {
certs[i] = c;
} }
} }
return PR_SUCCESS; return PR_SUCCESS;

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