define decoded cert type; implement cert cache; glue code for old NSS types; define global default trust domain

This commit is contained in:
ian.mcgreer%sun.com 2001-10-11 16:34:49 +00:00
Родитель 2944f4cedb
Коммит dac43ba788
13 изменённых файлов: 2050 добавлений и 132 удалений

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

@ -0,0 +1,151 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifdef NSS_3_4_CODE
/* This is defined in nss3hack.c */
NSS_EXTERN nssDecodedCert *
nssDecodedPKIXCertificate_Create
(
NSSArena *arenaOpt,
NSSDER *encoding
);
NSS_IMPLEMENT PRStatus
nssDecodedPKIXCertificate_Destroy
(
nssDecodedCert *dc
);
#else /* NSS_4_0_CODE */
/* This is where 4.0 PKIX code will handle the decoding */
static nssDecodedCert *
nssDecodedPKIXCertificate_Create
(
NSSArena *arenaOpt,
NSSDER *encoding
)
{
return (nssDecodedCert *)NULL;
}
static PRStatus
nssDecodedPKIXCertificate_Destroy
(
nssDecodedCert *dc
)
{
return PR_FAILURE;
}
#endif /* not NSS_3_4_CODE */
NSS_IMPLEMENT nssDecodedCert *
nssDecodedCert_Create
(
NSSArena *arenaOpt,
NSSDER *encoding,
NSSCertificateType type
)
{
nssDecodedCert *rvDC = NULL;
switch(type) {
case NSSCertificateType_PKIX:
rvDC = nssDecodedPKIXCertificate_Create(arenaOpt, encoding);
break;
default:
#if 0
nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
#endif
return (nssDecodedCert *)NULL;
}
return rvDC;
}
NSS_IMPLEMENT PRStatus
nssDecodedCert_Destroy
(
nssDecodedCert *dc
)
{
switch(dc->type) {
case NSSCertificateType_PKIX:
return nssDecodedPKIXCertificate_Destroy(dc);
default:
#if 0
nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
#endif
return PR_FAILURE;
}
return PR_FAILURE;
}
/* Of course none of this belongs here */
struct NSSTimeStr {
PRTime prTime;
};
/* 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
)
{
NSSTime *rvTime;
rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime);
rvTime->prTime = PR_Now();
return rvTime;
}
NSS_IMPLEMENT PRTime
NSSTime_GetPRTime
(
NSSTime *time
)
{
return time->prTime;
}

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.4 $ $Date: 2001/09/20 20:40:03 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.5 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
@ -43,10 +43,36 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.4 $
#include "pkit.h"
#endif /* PKIT_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */
#ifndef CKT_H
#ifdef NSS_3_4_CODE
#define NSSCKT_H
#endif
#include "ckt.h"
#endif /* CKT_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
/* Hm, sadly, I'm using PK11_HashBuf... Need to get crypto context going to
* get rid of that
*/
#define NSS_3_4_CODE
#include "pk11func.h"
#include "hasht.h"
/* I assume the following accessors into cert fields will be needed.
* We need to be able to return basic cert info, however, these are
* really PKCS#11 fields, so maybe not these in particular (mcgreer)
@ -57,10 +83,7 @@ NSSCertificate_GetLabel
NSSCertificate *c
)
{
NSSUTF8 *rvStr;
rvStr = nssUTF8_Create(NULL, nssStringType_PrintableString,
c->label.data, c->label.size);
return rvStr;
return c->nickname;
}
NSS_IMPLEMENT NSSItem *
@ -72,6 +95,16 @@ NSSCertificate_GetID
return &c->id;
}
NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef
(
NSSCertificate *c
)
{
c->refCount++;
return c;
}
/* NSS needs access to this function, but does anyone else? */
static NSSCertificate *
NSSCertificate_Create
@ -105,6 +138,65 @@ loser:
return (NSSCertificate *)NULL;
}
static NSSCertificateType
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
{
CK_CERTIFICATE_TYPE ckCertType;
ckCertType = *((CK_ULONG *)attrib->pValue);
switch (ckCertType) {
case CKC_X_509:
return NSSCertificateType_PKIX;
break;
default:
return NSSCertificateType_Unknown;
}
return NSSCertificateType_Unknown;
}
static PRStatus
nssCertificate_SetCertTrust
(
NSSCertificate *c,
nssSession *session
)
{
PRStatus nssrv;
CK_TRUST saTrust, epTrust, csTrust;
CK_ULONG tobj_size, trust_size;
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_OBJECT_HANDLE tobjID;
CK_ATTRIBUTE tobj_template[] = {
{ CKA_CLASS, &tobjc, sizeof(CK_OBJECT_CLASS) },
{ CKA_CERT_SHA1_HASH, NULL, 0 }
};
CK_ATTRIBUTE trust_template[] = {
{ CKA_TRUST_SERVER_AUTH, &saTrust, sizeof(CK_TRUST) },
{ CKA_TRUST_EMAIL_PROTECTION, &epTrust, sizeof(CK_TRUST) },
{ CKA_TRUST_CODE_SIGNING, &csTrust, sizeof(CK_TRUST) }
};
unsigned char sha1_hash[SHA1_LENGTH];
tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]);
trust_size = sizeof(trust_template) / sizeof(trust_template[0]);
/* First, use the SHA-1 hash of the cert to locate the trust object */
/* XXX get rid of this PK11_ call! */
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, c->encoding.data, c->encoding.size);
tobj_template[1].pValue = (void *)sha1_hash;
tobj_template[1].ulValueLen = SHA1_LENGTH;
tobjID = nssToken_FindObjectByTemplate(c->token, session,
tobj_template, tobj_size);
if (tobjID == CK_INVALID_KEY) {
return PR_FAILURE;
}
/* Then use the trust object to find the trust settings */
nssrv = nssCKObject_GetAttributes(tobjID,
trust_template, trust_size,
NULL, session, c->slot);
c->trust.serverAuth = saTrust;
c->trust.emailProtection = epTrust;
c->trust.codeSigning = csTrust;
return PR_SUCCESS;
}
/* Create a certificate from an object handle. */
NSS_IMPLEMENT NSSCertificate *
NSSCertificate_CreateFromHandle
@ -116,13 +208,16 @@ NSSCertificate_CreateFromHandle
)
{
NSSCertificate *rvCert;
NSSArena *arena;
PRStatus nssrv;
CK_ULONG template_size;
CK_ATTRIBUTE cert_template[] = {
{ CKA_ID, NULL, 0 },
{ CKA_VALUE, NULL, 0 },
{ CKA_LABEL, 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 }
};
template_size = sizeof(cert_template) / sizeof(cert_template[0]);
rvCert = NSSCertificate_Create(arenaOpt);
@ -131,17 +226,24 @@ NSSCertificate_CreateFromHandle
}
rvCert->handle = object;
rvCert->slot = slot;
rvCert->token = slot->token;
nssrv = nssCKObject_GetAttributes(object, cert_template, template_size,
rvCert->arena, session, rvCert->slot);
rvCert->arena, session, slot);
if (nssrv) {
/* okay, but if failed because one of the attributes could not be
* found, do it gracefully (i.e., catch the error).
*/
goto loser;
}
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[0], &rvCert->id);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->der);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->label);
rvCert->type = nss_cert_type_from_ck_attrib(&cert_template[0]);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &rvCert->id);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[3], rvCert->nickname);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->issuer);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->serial);
/* get the email from an attrib */
nssCertificate_SetCertTrust(rvCert, session);
return rvCert;
loser:
NSSCertificate_Destroy(rvCert);
@ -167,8 +269,13 @@ NSSCertificate_DeleteStoredObject
NSSCallback *uhh
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
/* delete it from storage, but leave it in memory */
/* according to PKCS#11 2.11 section 13.2, the token must know how
* to handle deletion when there are multiple threads attempting to use
* the same object.
*/
/* XXX use callback to log in if neccessary */
return nssToken_DeleteStoredObject(c->token, NULL, c->handle);
}
NSS_IMPLEMENT PRStatus
@ -226,8 +333,22 @@ NSSCertificate_Encode
NSSArena *arenaOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
/* Item, DER, BER are all typedefs now... */
return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
}
static nssDecodedCert *
nssCertificate_GetDecoding
(
NSSCertificate *c
)
{
if (!c->decoding) {
c->decoding = nssDecodedCert_Create(NULL, &c->encoding, c->type);
/* Now that it's decoded, make sure it's in the cache. */
nssTrustDomain_AddCertsToCache(c->trustDomain, &c, 1);
}
return c->decoding;
}
NSS_IMPLEMENT NSSCertificate **
@ -242,8 +363,53 @@ NSSCertificate_BuildChain
NSSArena *arenaOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
PRStatus nssrv;
nssList *chain;
NSSItem *issuerID;
NSSCertificate **rvChain;
nssDecodedCert *dc;
chain = nssList_Create(NULL, PR_FALSE);
nssList_Add(chain, c);
if (rvLimit == 1) goto finish;
while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) {
dc = nssCertificate_GetDecoding(c);
issuerID = dc->getIssuerIdentifier(dc);
if (issuerID) {
c = nssTrustDomain_FindCertificateByIdentifier(c->trustDomain,
issuerID);
nss_ZFreeIf(issuerID);
if (!c) {
#if 0
nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
#endif
goto finish;
}
} else {
c = NSSTrustDomain_FindBestCertificateBySubject(c->trustDomain,
&c->issuer,
timeOpt,
usage,
policiesOpt);
if (!c) {
#if 0
nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
#endif
goto finish;
}
}
nssList_Add(chain, c);
if (nssList_Count(chain) == rvLimit) goto finish;
}
finish:
if (rvOpt) {
rvChain = rvOpt;
} else {
rvChain = nss_ZNEWARRAY(arenaOpt,
NSSCertificate *, nssList_Count(chain));
}
nssList_GetArray(chain, (void **)rvChain, rvLimit);
nssList_Destroy(chain);
return rvChain;
}
NSS_IMPLEMENT NSSTrustDomain *
@ -252,8 +418,12 @@ NSSCertificate_GetTrustDomain
NSSCertificate *c
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
#if 0
if (c->trustDomain) {
return nssTrustDomain_AddRef(c->trustDomain);
}
#endif
return (NSSTrustDomain *)NULL;
}
NSS_IMPLEMENT NSSToken *
@ -263,8 +433,10 @@ NSSCertificate_GetToken
PRStatus *statusOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
if (c->token) {
return nssToken_AddRef(c->token);
}
return (NSSToken *)NULL;
}
NSS_IMPLEMENT NSSSlot *
@ -274,8 +446,12 @@ NSSCertificate_GetSlot
PRStatus *statusOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
#if 0
if (c->token) {
return nssToken_GetSlot(c->token);
}
#endif
return (NSSSlot *)NULL;
}
NSS_IMPLEMENT NSSModule *
@ -285,8 +461,12 @@ NSSCertificate_GetModule
PRStatus *statusOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
#if 0
if (c->token) {
return nssToken_GetModule(c->token);
}
#endif
return (NSSModule *)NULL;
}
NSS_IMPLEMENT NSSItem *
@ -381,8 +561,35 @@ NSSCertificate_GetPublicKey
NSSCertificate *c
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
PRStatus nssrv;
CK_ATTRIBUTE pubktemplate[] = {
{ CKA_CLASS, g_ck_class_pubkey.data, g_ck_class_pubkey.size },
{ CKA_ID, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
if (c->id.size > 0) {
/* CKA_ID */
NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
} else {
/* failure, yes? */
return (NSSPublicKey *)NULL;
}
if (c->subject.size > 0) {
/* CKA_SUBJECT */
NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
} else {
/* failure, yes? */
return (NSSPublicKey *)NULL;
}
/* Try the cert's token first */
#if 0
if (c->token) {
nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
}
#endif
/* Try all other key tokens */
return (NSSPublicKey *)NULL;
}
NSS_IMPLEMENT NSSPrivateKey *

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

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.2 $ $Date: 2001/09/13 22:16:21 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.3 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
@ -421,6 +421,36 @@ NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID
return NULL;
}
struct token_session_str {
NSSToken *token;
nssSession *session;
};
static nssSession *
get_token_session(NSSCryptoContext *cc, NSSToken *tok)
{
#if 0
struct token_session_str *ts;
for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions);
ts != (struct token_session_str *)NULL;
ts = (struct token_session_str *)nssListIterator_Next(cc->sessions))
{
if (ts->token == tok) { /* will this need to be more general? */
break;
}
}
nssListIterator_Finish(cc->sessions);
if (!ts) {
/* need to create a session for this token. */
ts = nss_ZNEW(NULL, struct token_session_str);
ts->token = nssToken_AddRef(tok);
ts->session = nssSlot_CreateSession(tok->slot, cc->arena, PR_FALSE);
nssList_AddElement(cc->sessionList, (void *)ts);
}
return ts->session;
#endif
}
NSS_IMPLEMENT NSSItem *
NSSCryptoContext_Decrypt
(
@ -432,8 +462,58 @@ NSSCryptoContext_Decrypt
NSSArena *arenaOpt
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
#if 0
NSSToken *tok;
nssSession *session;
NSSItem *rvData;
PRUint32 dataLen;
NSSAlgorithmAndParameters *ap;
CK_RV ckrv;
ap = (apOpt) ? apOpt : cc->defaultAlgorithm;
/* Get the token for this operation */
tok = nssTrustDomain_GetCryptoToken(cc->trustDomain, ap);
if (!tok) {
return (NSSItem *)NULL;
}
/* Get the local session for this token */
session = get_token_session(cc, tok);
/* Get the key needed to decrypt */
keyHandle = get_decrypt_key(cc, ap);
/* Set up the decrypt operation */
ckrv = CKAPI(tok)->C_DecryptInit(session->handle,
&ap->mechanism, keyHandle);
if (ckrv != CKR_OK) {
/* handle PKCS#11 error */
return (NSSItem *)NULL;
}
/* Get the length of the output buffer */
ckrv = CKAPI(tok)->C_Decrypt(session->handle,
(CK_BYTE_PTR)encryptedData->data,
(CK_ULONG)encryptedData->size,
(CK_BYTE_PTR)NULL,
(CK_ULONG_PTR)&dataLen);
if (ckrv != CKR_OK) {
/* handle PKCS#11 error */
return (NSSItem *)NULL;
}
/* Alloc return value memory */
rvData = nssItem_Create(NULL, NULL, dataLen, NULL);
if (!rvItem) {
return (NSSItem *)NULL;
}
/* Do the decryption */
ckrv = CKAPI(tok)->C_Decrypt(cc->session->handle,
(CK_BYTE_PTR)encryptedData->data,
(CK_ULONG)encryptedData->size,
(CK_BYTE_PTR)rvData->data,
(CK_ULONG_PTR)&dataLen);
if (ckrv != CKR_OK) {
/* handle PKCS#11 error */
nssItem_ZFreeIf(rvData);
return (NSSItem *)NULL;
}
return rvData;
#endif
}
NSS_IMPLEMENT PRStatus

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

@ -30,7 +30,7 @@
# may use your version of this file under either the MPL or the
# GPL.
#
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.2 $ $Date: 2001/09/13 22:16:21 $ $Name: $"
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.3 $ $Date: 2001/10/11 16:34:44 $ $Name: $"
CORE_DEPTH = ../../..
@ -52,8 +52,16 @@ CSRCS = \
cryptocontext.c \
symmkey.c \
trustdomain.c \
tdcache.c \
certdecode.c \
$(NULL)
ifndef PURE_STAN_BUILD
CSRCS += nss3hack.c
PRIVATE_EXPORTS += pkinss3hack.h
DEFINES = -DNSS_3_4_CODE
endif
REQUIRES = security nspr
LIBRARY_NAME = nsspki

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

@ -0,0 +1,309 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: nss3hack.c,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
/*
* Hacks to integrate NSS 3.4 and NSS 4.0 certificates.
*/
#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifndef DEVNSS3HACK_H
#include "devnss3hack.h"
#endif /* DEVNSS3HACK_H */
#ifndef PKINSS3HACK_H
#include "pkinss3hack.h"
#endif /* PKINSS3HACK_H */
#include "secitem.h"
#include "certdb.h"
#include "certt.h"
#include "cert.h"
#include "pk11func.h"
#define NSSITEM_FROM_SECITEM(nssit, secit) \
(nssit)->data = (void *)(secit)->data; \
(nssit)->size = (secit)->len;
#define SECITEM_FROM_NSSITEM(secit, nssit) \
(secit)->data = (unsigned char *)(nssit)->data; \
(secit)->len = (nssit)->size;
NSSTrustDomain *g_default_trust_domain = NULL;
NSSTrustDomain *
STAN_GetDefaultTrustDomain()
{
return g_default_trust_domain;
}
NSS_IMPLEMENT void
STAN_LoadDefaultNSS3TrustDomain
(
void
)
{
NSSTrustDomain *td;
NSSToken *token;
PK11SlotList *list;
PK11SlotListElement *le;
td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
if (!td) {
/* um, some kind a fatal here */
return;
}
td->tokenList = nssList_Create(td->arena, PR_TRUE);
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
if (list) {
#if 0
/* XXX this doesn't work until softoken is a true PKCS#11 mod */
for (le = list->head; le; le = le->next) {
token = nssToken_CreateFromPK11SlotInfo(td, le->slot);
PK11Slot_SetNSSToken(le->slot, token);
nssList_Add(td->tokenList, token);
}
#endif
}
td->tokens = nssList_CreateIterator(td->tokenList);
g_default_trust_domain = td;
}
NSS_IMPLEMENT PRStatus
STAN_AddNewSlotToDefaultTD
(
PK11SlotInfo *sl
)
{
NSSToken *token;
token = nssToken_CreateFromPK11SlotInfo(g_default_trust_domain, sl);
PK11Slot_SetNSSToken(sl, token);
nssList_Add(g_default_trust_domain->tokenList, token);
return PR_SUCCESS;
}
/* this function should not be a hack; it will be needed in 4.0 (rename) */
NSS_IMPLEMENT NSSItem *
STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
{
NSSItem *rvKey;
SECItem secDER;
SECItem secKey = { 0 };
SECStatus secrv;
SECITEM_FROM_NSSITEM(&secDER, der);
secrv = CERT_KeyFromDERCert(NULL, &secDER, &secKey);
rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
return rvKey;
}
static NSSItem *
nss3certificate_getIdentifier(nssDecodedCert *dc)
{
NSSItem *rvID;
CERTCertificate *c = (CERTCertificate *)dc->data;
rvID = nssItem_Create(NULL, NULL, c->certKey.len, c->certKey.data);
return rvID;
}
static NSSItem *
nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
{
CERTCertificate *c = (CERTCertificate *)dc->data;
CERTAuthKeyID *cAuthKeyID;
PRArenaPool *tmpArena = NULL;
SECItem issuerCertKey;
SECItem *identifier = NULL;
NSSItem *rvID = NULL;
SECStatus secrv;
tmpArena = PORT_NewArena(512);
cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c);
if (cAuthKeyID) {
if (cAuthKeyID->keyID.data) {
identifier = &cAuthKeyID->keyID;
} else if (cAuthKeyID->authCertIssuer) {
SECItem *caName;
caName = (SECItem *)CERT_GetGeneralNameByType(
cAuthKeyID->authCertIssuer,
certDirectoryName, PR_TRUE);
if (caName) {
secrv = CERT_KeyFromIssuerAndSN(tmpArena, caName,
&cAuthKeyID->authCertSerialNumber,
&issuerCertKey);
if (secrv == SECSuccess) {
identifier = &issuerCertKey;
}
}
}
}
if (identifier) {
rvID = nssItem_Create(NULL, NULL, identifier->len, identifier->data);
}
if (tmpArena) PORT_FreeArena(tmpArena, PR_FALSE);
return rvID;
}
static NSSUsage *
nss3certificate_getUsage(nssDecodedCert *dc)
{
CERTCertificate *c = (CERTCertificate *)dc->data;
return NULL;
}
static PRBool
nss3certificate_isValidAtTime(nssDecodedCert *dc, NSSTime *time)
{
SECCertTimeValidity validity;
CERTCertificate *c = (CERTCertificate *)dc->data;
validity = CERT_CheckCertValidTimes(c, NSSTime_GetPRTime(time), PR_TRUE);
if (validity == secCertTimeValid) {
return PR_TRUE;
}
return PR_FALSE;
}
static PRBool
nss3certificate_isNewerThan(nssDecodedCert *dc, nssDecodedCert *cmpdc)
{
/* I know this isn't right, but this is glue code anyway */
if (cmpdc->type == dc->type) {
CERTCertificate *certa = (CERTCertificate *)dc->data;
CERTCertificate *certb = (CERTCertificate *)cmpdc->data;
return CERT_IsNewer(certa, certb);
}
return PR_FALSE;
}
NSS_IMPLEMENT nssDecodedCert *
nssDecodedPKIXCertificate_Create
(
NSSArena *arenaOpt,
NSSDER *encoding
)
{
nssDecodedCert *rvDC;
SECItem secDER;
rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
rvDC->type = NSSCertificateType_PKIX;
SECITEM_FROM_NSSITEM(&secDER, encoding);
rvDC->data = (void *)CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL);
rvDC->getIdentifier = nss3certificate_getIdentifier;
rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
rvDC->getUsage = nss3certificate_getUsage;
rvDC->isValidAtTime = nss3certificate_isValidAtTime;
rvDC->isNewerThan = nss3certificate_isNewerThan;
return rvDC;
}
NSS_IMPLEMENT PRStatus
nssDecodedPKIXCertificate_Destroy
(
nssDecodedCert *dc
)
{
/*CERT_DestroyCertificate((CERTCertificate *)dc->data);*/
nss_ZFreeIf(dc);
return PR_SUCCESS;
}
/* see pk11cert.c:pk11_HandleTrustObject */
static unsigned int
get_nss3trust_from_cktrust(CK_TRUST t)
{
unsigned int rt = 0;
if (t & CKT_NETSCAPE_TRUSTED) {
rt |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
}
if (t & CKT_NETSCAPE_TRUSTED_DELEGATOR) {
rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
}
if (t & CKT_NETSCAPE_VALID) {
rt |= CERTDB_VALID_PEER;
}
if (t & CKT_NETSCAPE_VALID_DELEGATOR) {
rt |= CERTDB_VALID_CA;
}
/* user */
return rt;
}
static CERTCertTrust *
NSSTrust_GetCERTCertTrust(NSSTrust *t)
{
CERTCertTrust *rvTrust = nss_ZNEW(NULL, CERTCertTrust);
rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth);
rvTrust->emailFlags = get_nss3trust_from_cktrust(t->emailProtection);
rvTrust->objectSigningFlags = get_nss3trust_from_cktrust(t->codeSigning);
return rvTrust;
}
NSS_EXTERN CERTCertificate *
STAN_GetCERTCertificate(NSSCertificate *c)
{
nssDecodedCert *dc;
CERTCertificate *cc;
if (!c->decoding) {
dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
c->decoding = dc;
/* decoded, so cache */
} else {
dc = c->decoding;
}
/* fill other fields needed by NSS3 functions using CERTCertificate */
cc = (CERTCertificate *)dc->data;
/* nickname */
cc->nickname = PL_strdup(c->nickname);
/* emailAddr ??? */
/* slot */
cc->slot = c->token->pk11slot;
/* trust */
cc->trust = NSSTrust_GetCERTCertTrust(&c->trust);
/* referenceCount addref? */
/* subjectList ? */
/* pkcs11ID */
cc->pkcs11ID = c->handle;
return cc;
}

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

@ -35,7 +35,7 @@
#define NSSPKI_H
#ifdef DEBUG
static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile: nsspki.h,v $ $Revision: 1.3 $ $Date: 2001/09/13 22:16:21 $ $Name: $";
static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile: nsspki.h,v $ $Revision: 1.4 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
/*
@ -44,9 +44,9 @@ static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile: nsspki.h,v $ $Revision: 1.3
* This file prototypes the methods of the top-level PKI objects.
*/
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
#ifndef NSSPKIT_H
#include "nsspkit.h"

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

@ -35,14 +35,24 @@
#define PKI_H
#ifdef DEBUG
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.3 $ $Date: 2001/09/20 20:40:03 $ $Name: $";
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.4 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
PR_BEGIN_EXTERN_C
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
NSS_EXTERN NSSCertificate *
nssCertificate_AddRef
(
NSSCertificate *c
);
NSS_EXTERN NSSCertificate *
NSSCertificate_CreateFromHandle
@ -65,6 +75,17 @@ NSSCertificate_GetID
NSSCertificate *c
);
/*
* Look for a specific cert in the cache.
*/
NSS_EXTERN NSSCertificate *
nssTrustDomain_GetCertForIssuerAndSNFromCache
(
NSSTrustDomain *td,
NSSDER *issuer,
NSSDER *serialNum
);
PR_END_EXTERN_C
#endif /* PKI_H */

251
security/nss/lib/pki/pkim.h Normal file
Просмотреть файл

@ -0,0 +1,251 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef PKIM_H
#define PKIM_H
#ifdef DEBUG
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
#endif /* DEBUG */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
#ifndef PKITM_H
#include "pkitm.h"
#endif /* PKITM_H */
PR_BEGIN_EXTERN_C
/* Token ordering routines */
/*
* Given a crypto algorithm, return the preferred token for performing
* the crypto operation.
*/
NSS_EXTERN NSSToken *
nssTrustDomain_GetCryptoToken
(
NSSTrustDomain *td,
NSSAlgorithmAndParameters *ap
);
/* 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
);
NSS_EXTERN NSSCertificate *
nssTrustDomain_FindCertificateByIdentifier
(
NSSTrustDomain *td,
NSSItem *identifier
);
/* Certificate cache routines */
NSS_EXTERN PRStatus
nssTrustDomain_AddCertsToCache
(
NSSTrustDomain *td,
NSSCertificate **certs,
PRUint32 numCerts
);
NSS_EXTERN PRStatus
nssTrustDomain_RemoveCertFromCache
(
NSSTrustDomain *td,
NSSCertificate *cert
);
/*
* Remove all certs for the given token from the cache. This is
* needed if the token is removed.
*/
NSS_EXTERN PRStatus
nssTrustDomain_RemoveTokenCertsFromCache
(
NSSTrustDomain *td,
NSSToken *token
);
/*
* Find all cached certs with this nickname (label).
*/
NSS_EXTERN NSSCertificate **
nssTrustDomain_GetCertsForNicknameFromCache
(
NSSTrustDomain *td,
NSSUTF8 *nickname,
nssList *certListOpt
);
/*
* Find all cached certs with this email address.
*/
NSS_EXTERN NSSCertificate **
nssTrustDomain_GetCertsForEmailAddressFromCache
(
NSSTrustDomain *td,
NSSASCII7 *email,
nssList *certListOpt
);
/*
* Find all cached certs with this subject.
*/
NSS_EXTERN NSSCertificate **
nssTrustDomain_GetCertsForSubjectFromCache
(
NSSTrustDomain *td,
NSSDER *subject,
nssList *certListOpt
);
#if 0
/*
* Look for a specific cert in the cache.
*/
NSS_EXTERN NSSCertificate *
nssTrustDomain_GetCertForIssuerAndSNFromCache
(
NSSTrustDomain *td,
NSSDER *issuer,
NSSDER *serialNum
);
#endif
/*
* Look for a specific cert in the cache.
*/
NSS_EXTERN NSSCertificate *
nssTrustDomain_GetCertForIdentifierFromCache
(
NSSTrustDomain *td,
NSSItem *id
);
/*
* Look for a specific cert in the cache.
*/
NSS_EXTERN NSSCertificate *
nssTrustDomain_GetCertByDERFromCache
(
NSSTrustDomain *td,
NSSDER *der
);
NSS_IMPLEMENT nssDecodedCert *
nssDecodedCert_Create
(
NSSArena *arenaOpt,
NSSDER *encoding,
NSSCertificateType type
);
NSS_IMPLEMENT PRStatus
nssDecodedCert_Destroy
(
nssDecodedCert *dc
);
NSS_EXTERN NSSTime *
NSSTime_Now
(
NSSTime *timeOpt
);
NSS_EXTERN PRTime
NSSTime_GetPRTime
(
NSSTime *time
);
PR_END_EXTERN_C
#endif /* PKIM_H */

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

@ -0,0 +1,69 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef PKINSS3HACK_H
#define PKINSS3HACK_H
#ifdef DEBUG
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pkinss3hack.h,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:46 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKIT_H
#include "nsspkit.h"
#endif /* NSSPKIT_H */
#include "cert.h"
PR_BEGIN_EXTERN_C
NSS_EXTERN NSSTrustDomain *
STAN_GetDefaultTrustDomain();
NSS_IMPLEMENT void
STAN_LoadDefaultNSS3TrustDomain
(
void
);
NSS_EXTERN PRStatus
STAN_AddNewSlotToDefaultTD
(
PK11SlotInfo *sl
);
NSS_EXTERN CERTCertificate *
STAN_GetCERTCertificate(NSSCertificate *c);
PR_END_EXTERN_C
#endif /* PKINSS3HACK_H */

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

@ -35,7 +35,7 @@
#define PKIT_H
#ifdef DEBUG
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.2 $ $Date: 2001/09/20 20:40:03 $ $Name: $";
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.3 $ $Date: 2001/10/11 16:34:46 $ $Name: $";
#endif /* DEBUG */
/*
@ -52,38 +52,59 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.2 $ $D
#include "baset.h"
#endif /* BASET_H */
#ifdef NSS_3_4_CODE
#include "pkcs11t.h"
#define NSSCKT_H
#include "ckt.h"
#else
#ifndef NSSCKT_H
#include "nssckt.h"
#endif /* NSSCKT_H */
#endif /* NSS_3_4_CODE */
#ifndef NSSPKIT_H
#include "nsspkit.h"
#endif /* NSSPKIT_H */
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
PR_BEGIN_EXTERN_C
#define NSSPTR_ADD_REF(p) ((p)->refCount++)
typedef enum {
NSSCertificateType_Unknown = 0,
NSSCertificateType_PKIX = 1,
} NSSCertificateType;
typedef struct nssDecodedCertStr nssDecodedCert;
struct NSSTrustStr
{
CK_TRUST serverAuth;
CK_TRUST emailProtection;
CK_TRUST codeSigning;
};
struct NSSCertificateStr
{
PRInt32 refCount;
NSSArena *arena;
NSSCertificateType type;
NSSItem id;
NSSItem der;
NSSItem label;
CK_OBJECT_HANDLE handle;
NSSBER encoding;
NSSDER issuer;
NSSDER subject;
NSSDER serial;
NSSUTF8 *nickname;
NSSASCII7 *email;
NSSSlot *slot;
NSSToken *token;
NSSTrustDomain *trustDomain;
NSSCryptoContext *cryptoContext;
NSSTrust *trust;
NSSTrust trust;
CK_OBJECT_HANDLE handle;
nssDecodedCert *decoding;
};
struct NSSPrivateKeyStr;
@ -92,13 +113,15 @@ struct NSSPublicKeyStr;
struct NSSSymmetricKeyStr;
typedef struct nssTDCertificateCacheStr nssTDCertificateCache;
struct NSSTrustDomainStr {
PRInt32 refCount;
NSSArena *arena;
NSSCallback defaultCallback;
nssList *moduleList;
nssListIterator *modules;
nssHash *certCache;
nssList *tokenList;
nssListIterator *tokens;
nssTDCertificateCache *cache;
};
struct NSSCryptoContextStr
@ -109,16 +132,12 @@ struct NSSCryptoContextStr
struct NSSTimeStr;
struct NSSTrustStr;
struct NSSUsageStr;
struct NSSPoliciesStr;
struct NSSAlgorithmAndParametersStr;
struct NSSCallbackStr;
struct NSSPKIXCertificateStr;
PR_END_EXTERN_C

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

@ -0,0 +1,82 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef PKITM_H
#define PKITM_H
#ifdef DEBUG
static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:49 $ $Name: $";
#endif /* DEBUG */
/*
* pkitm.h
*
* This file contains PKI-module specific types.
*/
#ifndef BASET_H
#include "baset.h"
#endif /* BASET_H */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
PR_BEGIN_EXTERN_C
/*
* nssDecodedCert
*
* This is an interface to allow the PKI module access to certificate
* information that can only be found by decoding. The interface is
* generic, allowing each certificate type its own way of providing
* the information
*/
struct nssDecodedCertStr {
NSSCertificateType type;
void *data;
/* returns the unique identifier for the cert (usually issuer + serial) */
NSSItem * (*getIdentifier)(nssDecodedCert *dc);
/* returns the unique identifier for this cert's issuer */
NSSItem * (*getIssuerIdentifier)(nssDecodedCert *dc);
/* returns the cert usage */
NSSUsage * (*getUsage)(nssDecodedCert *dc);
/* is time within the validity period of the cert? */
PRBool (*isValidAtTime)(nssDecodedCert *dc, NSSTime *time);
/* is the validity period of this cert newer than cmpdc? */
PRBool (*isNewerThan)(nssDecodedCert *dc, nssDecodedCert *cmpdc);
};
PR_END_EXTERN_C
#endif /* PKITM_H */

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

@ -0,0 +1,648 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:49 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
/* Certificate cache routines */
/* XXX
* Locking is not handled well at all. A single, global lock with sub-locks
* in the collection types. Cleanup needed.
*/
/* should it live in its own arena? */
struct nssTDCertificateCacheStr {
PZLock *lock;
nssHash *issuerAndSN;
nssHash *subject;
nssHash *nickname;
nssHash *email;
};
static NSSItem *
get_issuer_and_serial_key(NSSArena *arena, NSSDER *issuer, NSSDER *serial)
{
NSSItem *rvKey;
rvKey = nss_ZNEW(arena, NSSItem);
rvKey->data = nss_ZAlloc(arena, issuer->size + serial->size);
rvKey->size = issuer->size + serial->size;
nsslibc_memcpy(rvKey->data, issuer->data, issuer->size);
nsslibc_memcpy(rvKey->data + issuer->size, serial->data, serial->size);
return rvKey;
}
static PRBool cert_compare(void *v1, void *v2)
{
PRStatus rv;
NSSCertificate *c1 = (NSSCertificate *)v1;
NSSCertificate *c2 = (NSSCertificate *)v2;
return
(nssItem_Equal((NSSItem *)&c1->issuer, (NSSItem *)&c2->issuer, &rv) &&
nssItem_Equal((NSSItem *)&c1->serial, (NSSItem *)&c2->serial, &rv));
}
/* this should not be exposed in a header, but is here to keep the above
* types/functions static
*/
NSS_IMPLEMENT PRStatus
nssTrustDomain_InitializeCache
(
NSSTrustDomain *td,
PRUint32 cacheSize
)
{
if (td->cache) {
return PR_FAILURE;
}
td->cache = nss_ZNEW(td->arena, nssTDCertificateCache);
td->cache->lock = PZ_NewLock(nssILockCache);
if (!td->cache->lock) return PR_FAILURE;
PZ_Lock(td->cache->lock);
/* Create the issuer and serial DER --> certificate hash */
td->cache->issuerAndSN = nssHash_CreateItem(td->arena, cacheSize);
if (!td->cache->issuerAndSN) goto loser;
/* Create the subject DER --> subject list hash */
td->cache->subject = nssHash_CreateItem(td->arena, cacheSize);
if (!td->cache->subject) goto loser;
/* Create the nickname --> subject list hash */
td->cache->nickname = nssHash_CreateString(td->arena, cacheSize);
if (!td->cache->nickname) goto loser;
/* Create the email --> list of subject lists hash */
td->cache->email = nssHash_CreateString(td->arena, cacheSize);
if (!td->cache->email) goto loser;
PZ_Unlock(td->cache->lock);
return PR_SUCCESS;
loser:
if (td->cache->issuerAndSN)
nssHash_Destroy(td->cache->issuerAndSN);
if (td->cache->subject)
nssHash_Destroy(td->cache->subject);
if (td->cache->nickname)
nssHash_Destroy(td->cache->nickname);
PZ_Unlock(td->cache->lock);
PZ_DestroyLock(td->cache->lock);
nss_ZFreeIf(td->cache);
td->cache = NULL;
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
nssTrustDomain_DestroyCache
(
NSSTrustDomain *td
)
{
PZ_Lock(td->cache->lock);
nssHash_Destroy(td->cache->issuerAndSN);
nssHash_Destroy(td->cache->subject);
nssHash_Destroy(td->cache->nickname);
nssHash_Destroy(td->cache->email);
PZ_Unlock(td->cache->lock);
PZ_DestroyLock(td->cache->lock);
nss_ZFreeIf(td->cache);
td->cache = NULL;
return PR_SUCCESS;
}
static PRStatus
add_cert_to_cache(NSSTrustDomain *td, NSSCertificate *cert)
{
nssArenaMark *mark;
nssList *subjectList;
nssList *subjects;
NSSUTF8 *nickname = NULL;
NSSUTF8 *email = NULL;
NSSItem *ias = NULL;
PRStatus nssrv;
ias = get_issuer_and_serial_key(td->arena, &cert->issuer, &cert->serial);
PZ_Lock(td->cache->lock);
/* If it exists in the issuer/serial hash, it's already in all */
if (nssHash_Exists(td->cache->issuerAndSN, ias)) {
PZ_Unlock(td->cache->lock);
nss_ZFreeIf(ias);
return PR_SUCCESS;
}
mark = nssArena_Mark(td->arena);
if (!mark) {
PZ_Unlock(td->cache->lock);
nss_ZFreeIf(ias);
return PR_FAILURE;
}
/* Add to issuer/serial hash */
nssrv = nssHash_Add(td->cache->issuerAndSN, ias,
nssCertificate_AddRef(cert));
if (nssrv != PR_SUCCESS) goto loser;
/* Add to subject hash */
subjectList = (nssList *)nssHash_Lookup(td->cache->subject, &cert->subject);
if (subjectList) {
/* The subject is already in, add this cert to the list */
nssrv = nssList_Add(subjectList,
nssCertificate_AddRef(cert));
if (nssrv != PR_SUCCESS) goto loser;
} else {
/* Create a new subject list for the subject */
subjectList = nssList_Create(td->arena, PR_TRUE);
if (!subjectList) goto loser;
/* To allow for different cert pointers, do list comparison by
* actual cert values.
*/
nssList_SetCompareFunction(subjectList, cert_compare);
nssrv = nssList_Add(subjectList,
nssCertificate_AddRef(cert));
if (nssrv != PR_SUCCESS) goto loser;
/* Add the subject list to the cache */
nssrv = nssHash_Add(td->cache->subject, &cert->subject, subjectList);
if (nssrv != PR_SUCCESS) goto loser;
/* Since subject list was created, note the entry in the nickname
* and email hashes.
*/
/* nickname */
nickname = nssUTF8_Duplicate(cert->nickname, td->arena);
nssrv = nssHash_Add(td->cache->nickname, nickname, subjectList);
if (nssrv != PR_SUCCESS) goto loser;
/* email */
subjects = (nssList *)nssHash_Lookup(td->cache->email, cert->email);
if (subjects) {
/* The email address is already hashed, add this subject list */
nssrv = nssList_Add(subjects, subjectList);
if (nssrv != PR_SUCCESS) goto loser;
} else {
/* Create a new list of subject lists, add this subject */
subjects = nssList_Create(td->arena, PR_TRUE);
if (!subjects) goto loser;
nssrv = nssList_Add(subjects, subjectList);
if (nssrv != PR_SUCCESS) goto loser;
/* Add the list of subject lists to the hash */
email = nssUTF8_Duplicate(cert->email, td->arena);
nssrv = nssHash_Add(td->cache->email, email, subjects);
if (nssrv != PR_SUCCESS) goto loser;
}
}
nssrv = nssArena_Unmark(td->arena, mark);
PZ_Unlock(td->cache->lock);
return PR_SUCCESS;
loser:
nss_ZFreeIf(ias);
nss_ZFreeIf(nickname);
nss_ZFreeIf(email);
nssArena_Release(td->arena, mark);
PZ_Unlock(td->cache->lock);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
nssTrustDomain_AddCertsToCache
(
NSSTrustDomain *td,
NSSCertificate **certs,
PRUint32 numCerts
)
{
PRUint32 i;
for (i=0; i<numCerts && certs[i]; i++) {
if (add_cert_to_cache(td, certs[i]) != PR_SUCCESS) {
return PR_FAILURE;
}
}
return PR_SUCCESS;
}
static NSSItem *
get_static_ias(NSSItem *s_ias, NSSDER *issuer, NSSDER *serial)
{
if (issuer->size + serial->size < s_ias->size) {
nsslibc_memcpy(s_ias->data, issuer->data, issuer->size);
nsslibc_memcpy(s_ias->data + issuer->size, serial->data, serial->size);
s_ias->size = issuer->size + serial->size;
return s_ias;
}
s_ias->size = 0;
return get_issuer_and_serial_key(NULL, issuer, serial);
}
NSS_IMPLEMENT PRStatus
nssTrustDomain_RemoveCertFromCache
(
NSSTrustDomain *td,
NSSCertificate *cert
)
{
nssList *subjectList;
nssList *subjects;
NSSItem *ias;
unsigned char buf[128];
NSSItem s_ias = { (void *)buf, sizeof(buf) };
ias = get_static_ias(&s_ias, &cert->issuer, &cert->serial);
PZ_Lock(td->cache->lock);
if (nssHash_Exists(td->cache->issuerAndSN, &ias)) {
/* Whatchew talkin' bout, Willis? */
#if 0
nss_SetError(NSS_ERROR_CERTIFICATE_NOT_IN_CACHE);
#endif
if (s_ias.size == 0) {
nss_ZFreeIf(ias);
}
PZ_Unlock(td->cache->lock);
return PR_FAILURE;
}
/* Remove the cert from the issuer/serial hash */
nssHash_Remove(td->cache->issuerAndSN, ias);
/* Get the subject list for the cert's subject */
subjectList = (nssList *)nssHash_Lookup(td->cache->subject, &cert->subject);
if (subjectList) {
/* Remove the cert from the subject hash */
nssList_Remove(subjectList, cert);
if (nssList_Count(subjectList) == 0) {
/* No more certs for subject ... */
nssHash_Remove(td->cache->nickname, &cert->nickname);
/* Find the subject list in the email hash */
subjects = (nssList *)nssHash_Lookup(td->cache->email, cert->email);
if (subjects) {
/* Remove the subject list from the email hash */
nssList_Remove(subjects, subjectList);
if (nssList_Count(subjects) == 0) {
/* No more subject lists for email, delete list and
* remove hash entry
*/
nssList_Destroy(subjects);
nssHash_Remove(td->cache->email, cert->email);
}
}
/* ... so destroy the subject list and remove the hash entry */
nssList_Destroy(subjectList);
nssHash_Remove(td->cache->subject, &cert->subject);
}
}
if (s_ias.size == 0) {
nss_ZFreeIf(ias);
}
PZ_Unlock(td->cache->lock);
return PR_SUCCESS;
}
struct token_cert_destructor {
nssTDCertificateCache *cache;
NSSToken *token;
};
static void
remove_token_certs(const void *k, void *v, void *a)
{
struct NSSItem *identifier = (struct NSSItem *)k;
NSSCertificate *c = (NSSCertificate *)v;
struct token_cert_destructor *tcd = (struct token_cert_destructor *)a;
if (c->token == tcd->token) {
nssHash_Remove(tcd->cache->issuerAndSN, identifier);
/* remove from the other hashes */
}
}
/*
* Remove all certs for the given token from the cache. This is
* needed if the token is removed.
*/
NSS_IMPLEMENT PRStatus
nssTrustDomain_RemoveTokenCertsFromCache
(
NSSTrustDomain *td,
NSSToken *token
)
{
struct token_cert_destructor tcd;
tcd.cache = td->cache;
PZ_Lock(td->cache->lock);
nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&tcd);
PZ_Unlock(td->cache->lock);
return PR_SUCCESS;
}
static NSSCertificate **
collect_subject_certs
(
nssList *subjectList,
nssList *rvCertListOpt
)
{
NSSCertificate *c;
NSSCertificate **rvArray;
PRUint32 count;
if (rvCertListOpt) {
nssListIterator *iter = nssList_CreateIterator(subjectList);
for (c = (NSSCertificate *)nssListIterator_Start(iter);
c != (NSSCertificate *)NULL;
c = (NSSCertificate *)nssListIterator_Next(iter)) {
nssList_Add(rvCertListOpt, c);
}
nssListIterator_Finish(iter);
nssListIterator_Destroy(iter);
return (NSSCertificate **)NULL;
} else {
count = nssList_Count(subjectList);
rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
if (!rvArray) return (NSSCertificate **)NULL;
nssList_GetArray(subjectList, (void **)rvArray, count);
return rvArray;
}
return (NSSCertificate **)NULL;
}
/*
* Find all cached certs with this subject.
*/
NSS_IMPLEMENT NSSCertificate **
nssTrustDomain_GetCertsForSubjectFromCache
(
NSSTrustDomain *td,
NSSDER *subject,
nssList *certListOpt
)
{
NSSCertificate **rvArray = NULL;
nssList *subjectList;
PZ_Lock(td->cache->lock);
subjectList = (nssList *)nssHash_Lookup(td->cache->subject,
(void *)subject);
PZ_Unlock(td->cache->lock);
if (subjectList) {
rvArray = collect_subject_certs(subjectList, certListOpt);
}
return rvArray;
}
/*
* Find all cached certs with this label.
*/
NSS_IMPLEMENT NSSCertificate **
nssTrustDomain_GetCertsForNicknameFromCache
(
NSSTrustDomain *td,
NSSUTF8 *nickname,
nssList *certListOpt
)
{
NSSCertificate **rvArray = NULL;
nssList *subjectList;
PZ_Lock(td->cache->lock);
subjectList = (nssList *)nssHash_Lookup(td->cache->nickname,
(void *)nickname);
PZ_Unlock(td->cache->lock);
if (subjectList) {
rvArray = collect_subject_certs(subjectList, certListOpt);
}
return rvArray;
}
/*
* Find all cached certs with this email address.
*/
NSS_IMPLEMENT NSSCertificate **
nssTrustDomain_GetCertsForEmailAddressFromCache
(
NSSTrustDomain *td,
NSSASCII7 *email,
nssList *certListOpt
)
{
NSSCertificate **rvArray = NULL;
nssList *listOfSubjectLists;
nssList *collectList;
PZ_Lock(td->cache->lock);
listOfSubjectLists = (nssList *)nssHash_Lookup(td->cache->email,
(void *)email);
PZ_Unlock(td->cache->lock);
if (listOfSubjectLists) {
nssListIterator *iter;
nssList *subjectList;
if (certListOpt) {
collectList = certListOpt;
} else {
collectList = nssList_Create(NULL, PR_FALSE);
}
iter = nssList_CreateIterator(listOfSubjectLists);
for (subjectList = (nssList *)nssListIterator_Start(iter);
subjectList != (nssList *)NULL;
subjectList = (nssList *)nssListIterator_Next(iter)) {
(void)collect_subject_certs(subjectList, collectList);
}
nssListIterator_Finish(iter);
nssListIterator_Destroy(iter);
}
if (!certListOpt) {
PRUint32 count = nssList_Count(collectList);
rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
if (rvArray) {
nssList_GetArray(collectList, (void **)rvArray, count);
}
nssList_Destroy(collectList);
}
return rvArray;
}
#ifdef DEBUG
static void debug_cache(NSSTrustDomain *td);
#endif
/*
* Look for a specific cert in the cache
*/
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_GetCertForIssuerAndSNFromCache
(
NSSTrustDomain *td,
NSSDER *issuer,
NSSDER *serial
)
{
NSSCertificate *rvCert;
NSSItem *ias;
unsigned char buf[128];
NSSItem s_ias = { (void *)buf, sizeof(buf) };
ias = get_static_ias(&s_ias, issuer, serial);
#ifdef DEBUG
debug_cache(td);
#endif
PZ_Lock(td->cache->lock);
rvCert = (NSSCertificate *)nssHash_Lookup(td->cache->issuerAndSN, ias);
PZ_Unlock(td->cache->lock);
if (s_ias.size == 0) {
nss_ZFreeIf(ias);
}
return rvCert;
}
/*
* Look for a specific cert in the cache
*/
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_GetCertForIdentifierFromCache
(
NSSTrustDomain *td,
NSSItem *id
)
{
NSSCertificate *rvCert;
PZ_Lock(td->cache->lock);
rvCert = (NSSCertificate *)nssHash_Lookup(td->cache->issuerAndSN, id);
PZ_Unlock(td->cache->lock);
return rvCert;
}
NSS_EXTERN NSSItem *
STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der);
/*
* Look for a specific cert in the cache
*/
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_GetCertByDERFromCache
(
NSSTrustDomain *td,
NSSDER *der
)
{
NSSItem *identifier;
NSSCertificate *rvCert = NULL;
#ifdef NSS_3_4_CODE
identifier = STAN_GetCertIdentifierFromDER(NULL, der);
#endif
if (identifier) {
rvCert = (NSSCertificate *)nssHash_Lookup(td->cache->issuerAndSN,
identifier);
}
nss_ZFreeIf(identifier);
return rvCert;
}
#ifdef DEBUG
static int el_count = 0;
static void ias_iter(const void *k, void *v, void *a)
{
PRUint32 i;
NSSItem *ias = (NSSItem *)k;
fprintf(stderr, "[%3d]\n", el_count);
fprintf(stderr, "ISSUER AND SERIAL: ");
for (i=0; i<ias->size; i++) {
fprintf(stderr, "%02x", ((unsigned char *)ias->data)[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, "CERT: %p\n", v);
fprintf(stderr, "\n\n");
el_count++;
}
static void print_sub_list(nssList *l)
{
NSSCertificate *c;
nssListIterator *iter = nssList_CreateIterator(l);
for (c = (NSSCertificate *)nssListIterator_Start(iter);
c != NULL;
c = (NSSCertificate *)nssListIterator_Next(iter)) {
fprintf(stderr, "CERT: %p\n", c);
}
nssListIterator_Finish(iter);
nssListIterator_Destroy(iter);
}
static void sub_iter(const void *k, void *v, void *a)
{
PRUint32 i;
NSSDER *sub = (NSSDER *)k;
fprintf(stderr, "[%3d]\n", el_count);
fprintf(stderr, "SUBJECT: ");
for (i=0; i<sub->size; i++) {
fprintf(stderr, "%02x", ((unsigned char *)sub->data)[i]);
}
fprintf(stderr, "\n");
print_sub_list((nssList *)v);
fprintf(stderr, "\n\n");
}
static void nik_iter(const void *k, void *v, void *a)
{
NSSUTF8 *nick = (NSSUTF8 *)k;
fprintf(stderr, "[%3d]\n", el_count);
fprintf(stderr, "NICKNAME: %s\n", (char *)nick);
fprintf(stderr, "SUBJECT_LIST: %p\n", v);
fprintf(stderr, "\n");
}
static void print_eml_list(nssList *l)
{
nssList *s;
nssListIterator *iter = nssList_CreateIterator(l);
for (s = (nssList *)nssListIterator_Start(iter);
s != NULL;
s = (nssList *)nssListIterator_Next(iter)) {
fprintf(stderr, "LIST: %p\n", s);
}
nssListIterator_Finish(iter);
nssListIterator_Destroy(iter);
}
static void eml_iter(const void *k, void *v, void *a)
{
NSSASCII7 *email = (NSSASCII7 *)k;
fprintf(stderr, "[%3d]\n", el_count);
fprintf(stderr, "EMAIL: %s\n", (char *)email);
print_eml_list((nssList *)v);
fprintf(stderr, "\n");
}
static void debug_cache(NSSTrustDomain *td)
{
el_count = 0;
nssHash_Iterate(td->cache->issuerAndSN, ias_iter, NULL);
el_count = 0;
nssHash_Iterate(td->cache->subject, sub_iter, NULL);
el_count = 0;
nssHash_Iterate(td->cache->nickname, nik_iter, NULL);
el_count = 0;
nssHash_Iterate(td->cache->email, eml_iter, NULL);
}
#endif

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

@ -32,16 +32,20 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.5 $ $Date: 2001/09/20 20:40:03 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.6 $ $Date: 2001/10/11 16:34:49 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#ifndef DEV_H
#include "dev.h"
@ -51,6 +55,15 @@ static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.5 $
#include "ckhelper.h"
#endif /* CKHELPER_H */
#define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32
NSS_EXTERN PRStatus
nssTrustDomain_InitializeCache
(
NSSTrustDomain *td,
PRUint32 cacheSize
);
NSS_IMPLEMENT NSSTrustDomain *
NSSTrustDomain_Create
(
@ -70,16 +83,9 @@ NSSTrustDomain_Create
if (!rvTD) {
goto loser;
}
rvTD->moduleList = nssList_Create(arena, PR_TRUE);
if (!rvTD->moduleList) {
goto loser;
}
rvTD->modules = nssList_CreateIterator(rvTD->moduleList);
if (!rvTD->modules) {
goto loser;
}
rvTD->arena = arena;
rvTD->refCount = 1;
nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
return rvTD;
loser:
nssArena_Destroy(arena);
@ -92,12 +98,6 @@ token_destructor(void *tok)
(void)nssToken_Destroy((NSSToken *)tok);
}
static void
module_destructor(void *mod)
{
(void)nssModule_Destroy((NSSModule *)mod);
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_Destroy
(
@ -105,9 +105,9 @@ NSSTrustDomain_Destroy
)
{
if (--td->refCount == 0) {
/* Destroy each module in the list of modules */
if (td->moduleList) {
nssList_DestroyElements(td->moduleList, module_destructor);
/* Destroy each token in the list of tokens */
if (td->tokens) {
nssList_DestroyElements(td->tokenList, token_destructor);
}
/* Destroy the trust domain */
nssArena_Destroy(td->arena);
@ -148,19 +148,7 @@ NSSTrustDomain_LoadModule
void *reserved
)
{
NSSModule *module;
/* This is really just here for testing. I don't presume that it is
* correct. Therefore, I won't comment further.
*/
if (moduleOpt) {
module = nssModule_Create(moduleOpt, uriOpt, opaqueOpt, reserved);
nssModule_Load(module);
nssList_AddElement(td->moduleList, (void *)module);
#ifdef DEBUG
nssModule_Debug(module);
#endif
}
return PR_SUCCESS;
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
@ -348,6 +336,29 @@ NSSTrustDomain_ImportEncodedPublicKey
return NULL;
}
struct get_best_cert_arg_str {
NSSTrustDomain *td;
NSSCertificate *cert;
NSSTime *time;
NSSUsage *usage;
NSSPolicies *policies;
};
static PRStatus
get_best_cert(NSSCertificate *c, void *arg)
{
struct get_best_cert_arg_str *best = (struct get_best_cert_arg_str *)arg;
if (!best->cert) {
/* This is the first matching cert found, so it is the best so far */
best->cert = c;
return PR_SUCCESS;
}
/* usage */
/* time */
/* policies */
return PR_SUCCESS;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateByNickname
(
@ -358,11 +369,68 @@ NSSTrustDomain_FindBestCertificateByNickname
NSSPolicies *policiesOpt /* NULL for none */
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
PRStatus nssrv;
NSSToken *tok;
CK_ATTRIBUTE cert_template[] =
{
{ CKA_CLASS, g_ck_class_cert.data, g_ck_class_cert.size },
{ CKA_LABEL, NULL, 0 }
};
struct get_best_cert_arg_str best;
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0]));
cert_template[1].pValue = (CK_VOID_PTR)name;
cert_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
best.td = td;
best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage;
best.policies = policiesOpt;
/* This will really be done through the search order, probably a
* token array
*/
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
get_best_cert, &best);
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
cert_template[1].ulValueLen++;
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
get_best_cert, &best);
cert_template[1].ulValueLen--;
}
nssListIterator_Finish(td->tokens);
return best.cert;
}
struct collect_arg_str {
nssList *list;
PRUint32 maximum;
NSSArena *arena;
};
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
static PRStatus
collect_certs(NSSCertificate *c, void *arg)
{
struct collect_arg_str *ca = (struct collect_arg_str *)arg;
/* Add the cert to the return list */
nssList_Add(ca->list, (void *)c);
if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) {
/* signal the end of collection) */
nss_SetError(NSS_ERROR_MAXIMUM_FOUND);
return PR_FAILURE;
}
return PR_SUCCESS;
}
/* THIS IS A TEST IMPLEMENTATION ONLY */
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindCertificatesByNickname
(
@ -374,51 +442,48 @@ NSSTrustDomain_FindCertificatesByNickname
)
{
PRStatus nssrv;
PRUint32 i, count;
PRUint32 count;
NSSCertificate **certs;
NSSToken *tok;
NSSModule *mod;
nssList *foundCerts;
CK_ATTRIBUTE cert_template[] =
{
{ CKA_CLASS, g_ck_class_cert.data, g_ck_class_cert.size },
{ CKA_LABEL, NULL, 0 }
};
struct collect_arg_str ca;
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0]));
cert_template[1].pValue = (CK_VOID_PTR)name;
cert_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
foundCerts = nssList_Create(NULL, PR_FALSE);
ca.list = foundCerts;
ca.maximum = maximumOpt;
ca.arena = arenaOpt;
/* This will really be done through the search order, probably a
* token array
*/
for (mod = (NSSModule *)nssListIterator_Start(td->modules);
mod != (NSSModule *)NULL;
mod = (NSSModule *)nssListIterator_Next(td->modules))
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
for (i=0; i<mod->numSlots; i++) {
/* XXX not right at all */
tok = mod->slots[i]->token;
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
foundCerts, maximumOpt,
arenaOpt,
cert_template, ctsize);
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
cert_template[1].ulValueLen++;
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
foundCerts, maximumOpt,
arenaOpt,
cert_template, ctsize);
cert_template[1].ulValueLen--;
}
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
collect_certs, &ca);
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
cert_template[1].ulValueLen++;
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
collect_certs, &ca);
cert_template[1].ulValueLen--;
}
nssListIterator_Finish(td->modules);
nssListIterator_Finish(td->tokens);
count = nssList_Count(foundCerts);
if (rvOpt) {
certs = rvOpt;
} else {
count = nssList_Count(foundCerts);
certs = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
}
nssrv = nssList_GetArray(foundCerts, (void **)certs, count);
@ -426,6 +491,23 @@ NSSTrustDomain_FindCertificatesByNickname
return certs;
}
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_FindCertificateByIdentifier
(
NSSTrustDomain *td,
NSSItem *identifier
)
{
NSSCertificate *rvCert;
/* Try the cache */
rvCert = nssTrustDomain_GetCertForIdentifierFromCache(td, identifier);
if (!rvCert) {
/* uh, how to look up by id in PKCS#11? */
rvCert = NULL;
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
(
@ -647,16 +729,7 @@ NSSTrustDomain_TraverseCertificates
void *arg
)
{
NSSModule *mod;
/* Do module->slot->token, or just slotarray->tokens? */
for (mod = (NSSModule *)nssListIterator_Start(td->modules);
mod != (NSSModule *)NULL;
mod = (NSSModule *)nssListIterator_Next(td->modules))
{
nssModule_TraverseCertificates(mod, callback, arg);
}
nssListIterator_Finish(td->modules);
return PR_SUCCESS;
return NULL;
}
NSS_IMPLEMENT PRStatus