зеркало из https://github.com/mozilla/gecko-dev.git
some more cert lookup methods; find cert issuer/chain; mimic nickname as "token name:nickname"
This commit is contained in:
Родитель
3ab8e6fcaa
Коммит
a70ca44727
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.8 $ $Date: 2001/10/15 18:19:03 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.9 $ $Date: 2001/10/17 14:40:20 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -204,9 +204,36 @@ nssCertificate_SetCertTrust
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef NSS_3_4_CODE
|
||||
static void make_nss3_nickname(NSSCertificate *c)
|
||||
{
|
||||
/* In NSS 3.4, the semantic is that nickname = token name + label */
|
||||
PRStatus utf8rv;
|
||||
NSSUTF8 *tokenName;
|
||||
NSSUTF8 *label;
|
||||
char *fullname;
|
||||
PRUint32 len, tlen;
|
||||
tokenName = nssToken_GetName(c->token);
|
||||
label = c->nickname;
|
||||
tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */
|
||||
tlen += 1; /* : */
|
||||
len = nssUTF8_Length(label, &utf8rv); /* label */
|
||||
len += 1; /* \0 */
|
||||
len += tlen;
|
||||
fullname = nss_ZAlloc(c->arena, len);
|
||||
utf8rv = nssUTF8_CopyIntoFixedBuffer(tokenName, fullname, tlen, ':');
|
||||
utf8rv = nssUTF8_CopyIntoFixedBuffer(label, fullname + tlen,
|
||||
len - tlen, '\0');
|
||||
nss_ZFreeIf(c->nickname);
|
||||
c->nickname = nssUTF8_Create(c->arena,
|
||||
nssStringType_UTF8String,
|
||||
fullname, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a certificate from an object handle. */
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
NSSCertificate_CreateFromHandle
|
||||
nssCertificate_CreateFromHandle
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_OBJECT_HANDLE object,
|
||||
|
@ -232,8 +259,10 @@ NSSCertificate_CreateFromHandle
|
|||
return (NSSCertificate *)NULL;
|
||||
}
|
||||
rvCert->handle = object;
|
||||
/* clean this up */
|
||||
rvCert->slot = slot;
|
||||
rvCert->token = slot->token;
|
||||
rvCert->trustDomain = slot->token->trustDomain;
|
||||
nssrv = nssCKObject_GetAttributes(object, cert_template, template_size,
|
||||
rvCert->arena, session, slot);
|
||||
if (nssrv) {
|
||||
|
@ -250,6 +279,9 @@ NSSCertificate_CreateFromHandle
|
|||
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 */
|
||||
#ifdef NSS_3_4_CODE
|
||||
make_nss3_nickname(rvCert);
|
||||
#endif
|
||||
nssCertificate_SetCertTrust(rvCert, session);
|
||||
return rvCert;
|
||||
loser:
|
||||
|
@ -352,12 +384,47 @@ nssCertificate_GetDecoding
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static NSSCertificate *
|
||||
find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
NSSCertificate **subjectCerts;
|
||||
/* Find all certs with this cert's issuer as the subject */
|
||||
subjectCerts = NSSTrustDomain_FindCertificatesBySubject(c->trustDomain,
|
||||
&c->issuer,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (subjectCerts) {
|
||||
NSSCertificate *p;
|
||||
nssDecodedCert *dcp;
|
||||
int i = 0;
|
||||
/* walk the subject certs */
|
||||
while ((p = subjectCerts[i++])) {
|
||||
dcp = nssCertificate_GetDecoding(p);
|
||||
if (dcp->hasThisIdentifier(dcp, id)) {
|
||||
/* this cert has the correct identifier */
|
||||
rvCert = p;
|
||||
/* now free all the remaining subject certs */
|
||||
while ((p = subjectCerts[++i])) {
|
||||
NSSCertificate_Destroy(p);
|
||||
}
|
||||
/* and exit */
|
||||
break;
|
||||
} else {
|
||||
/* cert didn't have the correct identifier, so free it */
|
||||
NSSCertificate_Destroy(p);
|
||||
}
|
||||
}
|
||||
nss_ZFreeIf(subjectCerts);
|
||||
}
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
NSSCertificate_BuildChain
|
||||
(
|
||||
|
@ -382,8 +449,7 @@ NSSCertificate_BuildChain
|
|||
dc = nssCertificate_GetDecoding(c);
|
||||
issuerID = dc->getIssuerIdentifier(dc);
|
||||
if (issuerID) {
|
||||
c = nssTrustDomain_FindCertificateByIdentifier(c->trustDomain,
|
||||
issuerID);
|
||||
c = find_issuer_cert_for_identifier(c, issuerID);
|
||||
nss_ZFreeIf(issuerID);
|
||||
if (!c) {
|
||||
#if 0
|
||||
|
@ -412,10 +478,11 @@ finish:
|
|||
rvChain = rvOpt;
|
||||
} else {
|
||||
rvChain = nss_ZNEWARRAY(arenaOpt,
|
||||
NSSCertificate *, nssList_Count(chain));
|
||||
NSSCertificate *, nssList_Count(chain) + 1);
|
||||
}
|
||||
nssList_GetArray(chain, (void **)rvChain, rvLimit);
|
||||
nssList_Destroy(chain);
|
||||
/* XXX now, the question is, cache all certs in the chain? */
|
||||
return rvChain;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: nss3hack.c,v $ $Revision: 1.1 $ $Date: 2001/10/11 16:34:44 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: nss3hack.c,v $ $Revision: 1.2 $ $Date: 2001/10/17 14:40:20 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -99,7 +99,7 @@ STAN_LoadDefaultNSS3TrustDomain
|
|||
td->tokenList = nssList_Create(td->arena, PR_TRUE);
|
||||
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
|
||||
if (list) {
|
||||
#if 0
|
||||
#ifndef NSS_SOFTOKEN_MODULE_FOO
|
||||
/* 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);
|
||||
|
@ -185,6 +185,19 @@ nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
|
|||
return rvID;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
nss3certificate_hasThisIdentifier(nssDecodedCert *dc, NSSItem *id)
|
||||
{
|
||||
CERTCertificate *c = (CERTCertificate *)dc->data;
|
||||
SECItem *subjectKeyID, authKeyID;
|
||||
subjectKeyID = &c->subjectKeyID;
|
||||
SECITEM_FROM_NSSITEM(&authKeyID, id);
|
||||
if (SECITEM_CompareItem(subjectKeyID, &authKeyID) == SECEqual) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static NSSUsage *
|
||||
nss3certificate_getUsage(nssDecodedCert *dc)
|
||||
{
|
||||
|
@ -231,6 +244,7 @@ nssDecodedPKIXCertificate_Create
|
|||
rvDC->data = (void *)CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL);
|
||||
rvDC->getIdentifier = nss3certificate_getIdentifier;
|
||||
rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
|
||||
rvDC->hasThisIdentifier = nss3certificate_hasThisIdentifier;
|
||||
rvDC->getUsage = nss3certificate_getUsage;
|
||||
rvDC->isValidAtTime = nss3certificate_isValidAtTime;
|
||||
rvDC->isNewerThan = nss3certificate_isNewerThan;
|
||||
|
@ -269,13 +283,22 @@ get_nss3trust_from_cktrust(CK_TRUST t)
|
|||
return rt;
|
||||
}
|
||||
|
||||
/* From pk11cert.c */
|
||||
extern PRBool
|
||||
PK11_IsUserCert(PK11SlotInfo *, CERTCertificate *, CK_OBJECT_HANDLE);
|
||||
|
||||
static CERTCertTrust *
|
||||
NSSTrust_GetCERTCertTrust(NSSTrust *t)
|
||||
nssTrust_GetCERTCertTrust(NSSTrust *t, CERTCertificate *cc)
|
||||
{
|
||||
CERTCertTrust *rvTrust = nss_ZNEW(NULL, CERTCertTrust);
|
||||
CERTCertTrust *rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(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);
|
||||
if (PK11_IsUserCert(cc->slot, cc, cc->pkcs11ID)) {
|
||||
rvTrust->sslFlags |= CERTDB_USER;
|
||||
rvTrust->emailFlags |= CERTDB_USER;
|
||||
rvTrust->objectSigningFlags |= CERTDB_USER;
|
||||
}
|
||||
return rvTrust;
|
||||
}
|
||||
|
||||
|
@ -287,23 +310,41 @@ STAN_GetCERTCertificate(NSSCertificate *c)
|
|||
if (!c->decoding) {
|
||||
dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
|
||||
c->decoding = dc;
|
||||
/* decoded, so cache */
|
||||
cc = (CERTCertificate *)dc->data;
|
||||
/* fill other fields needed by NSS3 functions using CERTCertificate */
|
||||
/* handle */
|
||||
cc->pkcs11ID = c->handle;
|
||||
/* nickname */
|
||||
cc->nickname = PL_strdup(c->nickname);
|
||||
/* emailAddr ??? */
|
||||
/* slot (ownSlot ?) (addref ?) */
|
||||
cc->slot = c->token->pk11slot;
|
||||
/* trust */
|
||||
cc->trust = nssTrust_GetCERTCertTrust(&c->trust, cc);
|
||||
/* referenceCount addref? */
|
||||
/* subjectList ? */
|
||||
/* pkcs11ID */
|
||||
cc->pkcs11ID = c->handle;
|
||||
/* pointer back */
|
||||
cc->nssCertificate = c;
|
||||
} else {
|
||||
dc = c->decoding;
|
||||
cc = (CERTCertificate *)dc->data;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
STAN_GetNSSCertificate(CERTCertificate *cc)
|
||||
{
|
||||
NSSCertificate *c;
|
||||
c = cc->nssCertificate;
|
||||
if (!c) {
|
||||
/* i don't think this should happen. but if it can, need to create
|
||||
* NSSCertificate from CERTCertificate values here.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKI_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.5 $ $Date: 2001/10/12 17:54:50 $ $Name: $";
|
||||
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.6 $ $Date: 2001/10/17 14:40:22 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef PKIT_H
|
||||
|
@ -55,7 +55,7 @@ nssCertificate_AddRef
|
|||
);
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
NSSCertificate_CreateFromHandle
|
||||
nssCertificate_CreateFromHandle
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
CK_OBJECT_HANDLE object,
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKIM_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.3 $ $Date: 2001/10/15 18:19:03 $ $Name: $";
|
||||
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.4 $ $Date: 2001/10/17 14:40:22 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef BASE_H
|
||||
|
@ -119,13 +119,6 @@ nssTrustDomain_GetSymmetricKeyToken
|
|||
NSSTrustDomain *td
|
||||
);
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
nssTrustDomain_FindCertificateByIdentifier
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSItem *identifier
|
||||
);
|
||||
|
||||
/* Certificate cache routines */
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#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: $";
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pkinss3hack.h,v $ $Revision: 1.2 $ $Date: 2001/10/17 14:40:22 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKIT_H
|
||||
|
@ -64,6 +64,37 @@ STAN_AddNewSlotToDefaultTD
|
|||
NSS_EXTERN CERTCertificate *
|
||||
STAN_GetCERTCertificate(NSSCertificate *c);
|
||||
|
||||
NSS_EXTERN NSSCertificate *
|
||||
STAN_GetNSSCertificate(CERTCertificate *c);
|
||||
|
||||
/* This function is being put here because it is a hack for
|
||||
* PK11_FindCertFromNickname.
|
||||
*/
|
||||
NSS_EXTERN NSSCertificate *
|
||||
nssTrustDomain_FindBestCertificateByNicknameForToken
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
NSSUTF8 *name,
|
||||
NSSTime *timeOpt, /* NULL for "now" */
|
||||
NSSUsage *usage,
|
||||
NSSPolicies *policiesOpt /* NULL for none */
|
||||
);
|
||||
|
||||
/* This function is being put here because it is a hack for
|
||||
* PK11_FindCertsFromNickname.
|
||||
*/
|
||||
NSS_EXTERN NSSCertificate **
|
||||
nssTrustDomain_FindCertificatesByNicknameForToken
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
NSSUTF8 *name,
|
||||
NSSCertificate *rvOpt[],
|
||||
PRUint32 maximumOpt, /* 0 for no max */
|
||||
NSSArena *arenaOpt
|
||||
);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* PKINSS3HACK_H */
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#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: $";
|
||||
static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.2 $ $Date: 2001/10/17 14:40:22 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -65,10 +65,12 @@ PR_BEGIN_EXTERN_C
|
|||
struct nssDecodedCertStr {
|
||||
NSSCertificateType type;
|
||||
void *data;
|
||||
/* returns the unique identifier for the cert (usually issuer + serial) */
|
||||
/* returns the unique identifier for the cert */
|
||||
NSSItem * (*getIdentifier)(nssDecodedCert *dc);
|
||||
/* returns the unique identifier for this cert's issuer */
|
||||
NSSItem * (*getIssuerIdentifier)(nssDecodedCert *dc);
|
||||
/* is id the identifier for this cert? */
|
||||
PRBool (*hasThisIdentifier)(nssDecodedCert *dc, NSSItem *id);
|
||||
/* returns the cert usage */
|
||||
NSSUsage * (*getUsage)(nssDecodedCert *dc);
|
||||
/* is time within the validity period of the cert? */
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.4 $ $Date: 2001/10/15 17:18:06 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.5 $ $Date: 2001/10/17 14:40:23 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef PKIM_H
|
||||
|
@ -227,21 +227,23 @@ add_cert_to_cache(NSSTrustDomain *td, NSSCertificate *cert)
|
|||
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;
|
||||
if (cert->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);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.9 $ $Date: 2001/10/12 17:54:50 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.10 $ $Date: 2001/10/17 14:40:27 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -211,8 +211,18 @@ NSSTrustDomain_FindTokenByName
|
|||
NSSUTF8 *tokenName
|
||||
)
|
||||
{
|
||||
nss_SetError(NSS_ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
PRStatus nssrv;
|
||||
NSSUTF8 *myName;
|
||||
NSSToken *tok = NULL;
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
myName = nssToken_GetName(tok);
|
||||
if (nssUTF8_Equal(tokenName, myName, &nssrv)) break;
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
return tok;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSToken *
|
||||
|
@ -356,13 +366,39 @@ static PRStatus
|
|||
get_best_cert(NSSCertificate *c, void *arg)
|
||||
{
|
||||
struct get_best_cert_arg_str *best = (struct get_best_cert_arg_str *)arg;
|
||||
nssDecodedCert *dc, *bestdc;
|
||||
if (!best->cert) {
|
||||
/* This is the first matching cert found, so it is the best so far */
|
||||
best->cert = c;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
dc = nssCertificate_GetDecoding(c);
|
||||
bestdc = nssCertificate_GetDecoding(best->cert);
|
||||
/* usage */
|
||||
/* XXX something like NSSUsage_MatchUsage() maybe? */
|
||||
/* time */
|
||||
if (bestdc->isValidAtTime(bestdc, best->time)) {
|
||||
/* The current best cert is valid at time */
|
||||
if (!dc->isValidAtTime(dc, best->time)) {
|
||||
/* If the new cert isn't valid at time, it's not better */
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
/* The current best cert is not valid at time */
|
||||
if (dc->isValidAtTime(dc, best->time)) {
|
||||
/* If the new cert is valid at time, it's better */
|
||||
best->cert = c;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
/* either they are both valid at time, or neither valid; take the newer */
|
||||
/* XXX later -- defer to policies */
|
||||
if (bestdc->isNewerThan(bestdc, dc)) {
|
||||
return PR_SUCCESS;
|
||||
} else {
|
||||
best->cert = c;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
/* policies */
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
@ -371,6 +407,7 @@ static NSSCertificate *
|
|||
find_best_cert_for_template
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
struct get_best_cert_arg_str *best,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
|
@ -378,15 +415,23 @@ find_best_cert_for_template
|
|||
{
|
||||
PRStatus nssrv;
|
||||
NSSToken *tok;
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, best->cached,
|
||||
if (token) {
|
||||
nssrv = nssToken_FindCertificatesByTemplate(token, NULL, best->cached,
|
||||
cktemplate, ctsize,
|
||||
get_best_cert, &best);
|
||||
get_best_cert, best);
|
||||
} else {
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, best->cached,
|
||||
cktemplate, ctsize,
|
||||
get_best_cert, best);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
/* Cache the cert before returning */
|
||||
nssTrustDomain_AddCertsToCache(td, &best->cert, 1);
|
||||
return best->cert;
|
||||
}
|
||||
|
||||
|
@ -417,6 +462,7 @@ static NSSCertificate **
|
|||
find_all_certs_for_template
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
struct collect_arg_str *ca,
|
||||
CK_ATTRIBUTE_PTR cktemplate,
|
||||
CK_ULONG ctsize
|
||||
|
@ -426,15 +472,21 @@ find_all_certs_for_template
|
|||
PRStatus nssrv;
|
||||
PRUint32 count;
|
||||
NSSToken *tok;
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, ca->list,
|
||||
if (token) {
|
||||
nssrv = nssToken_FindCertificatesByTemplate(token, NULL, ca->list,
|
||||
cktemplate, ctsize,
|
||||
collect_certs, ca);
|
||||
} else {
|
||||
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
|
||||
tok != (NSSToken *)NULL;
|
||||
tok = (NSSToken *)nssListIterator_Next(td->tokens))
|
||||
{
|
||||
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, ca->list,
|
||||
cktemplate, ctsize,
|
||||
collect_certs, ca);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
}
|
||||
nssListIterator_Finish(td->tokens);
|
||||
count = nssList_Count(ca->list);
|
||||
if (ca->rvOpt) {
|
||||
certs = ca->rvOpt;
|
||||
|
@ -442,9 +494,67 @@ find_all_certs_for_template
|
|||
certs = nss_ZNEWARRAY(ca->arena, NSSCertificate *, count + 1);
|
||||
}
|
||||
nssrv = nssList_GetArray(ca->list, (void **)certs, count);
|
||||
/* Cache the certs before returning */
|
||||
nssTrustDomain_AddCertsToCache(td, certs, count);
|
||||
return certs;
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* This is really a hack for PK11_ calls that want to specify the token to
|
||||
* do lookups on (see PK11_FindCertFromNickname). I don't think this
|
||||
* is something we want to keep.
|
||||
*/
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
nssTrustDomain_FindBestCertificateByNicknameForToken
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
NSSUTF8 *name,
|
||||
NSSTime *timeOpt, /* NULL for "now" */
|
||||
NSSUsage *usage,
|
||||
NSSPolicies *policiesOpt /* NULL for none */
|
||||
)
|
||||
{
|
||||
NSSCertificate *rvCert = NULL;
|
||||
PRStatus nssrv;
|
||||
struct get_best_cert_arg_str best;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
CK_ULONG ctsize;
|
||||
nssList *nameList;
|
||||
/* set up the search template */
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
/* set the criteria for determining the best cert */
|
||||
best.td = td;
|
||||
best.cert = NULL;
|
||||
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
|
||||
best.usage = usage;
|
||||
best.policies = policiesOpt;
|
||||
/* find all matching certs in the cache */
|
||||
nameList = nssList_Create(NULL, PR_FALSE);
|
||||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||
best.cached = nameList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, token,
|
||||
&best, nick_template, ctsize);
|
||||
if (!rvCert) {
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
*/
|
||||
nick_template[1].ulValueLen++;
|
||||
rvCert = find_best_cert_for_template(td, token,
|
||||
&best, nick_template, ctsize);
|
||||
}
|
||||
nssList_Destroy(nameList);
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate *
|
||||
NSSTrustDomain_FindBestCertificateByNickname
|
||||
(
|
||||
|
@ -481,18 +591,61 @@ NSSTrustDomain_FindBestCertificateByNickname
|
|||
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
|
||||
best.cached = nameList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, &best, nick_template, ctsize);
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, nick_template, ctsize);
|
||||
if (!rvCert) {
|
||||
/* This is to workaround the fact that PKCS#11 doesn't specify
|
||||
* whether the '\0' should be included. XXX Is that still true?
|
||||
*/
|
||||
nick_template[1].ulValueLen++;
|
||||
rvCert = find_best_cert_for_template(td, &best, nick_template, ctsize);
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, nick_template, ctsize);
|
||||
}
|
||||
nssList_Destroy(nameList);
|
||||
return rvCert;
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* This is really a hack for PK11_ calls that want to specify the token to
|
||||
* do lookups on (see PK11_FindCertsFromNickname). I don't think this
|
||||
* is something we want to keep.
|
||||
*/
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
nssTrustDomain_FindCertificatesByNicknameForToken
|
||||
(
|
||||
NSSTrustDomain *td,
|
||||
NSSToken *token,
|
||||
NSSUTF8 *name,
|
||||
NSSCertificate *rvOpt[],
|
||||
PRUint32 maximumOpt, /* 0 for no max */
|
||||
NSSArena *arenaOpt
|
||||
)
|
||||
{
|
||||
NSSCertificate **rvCerts = NULL;
|
||||
PRStatus nssrv;
|
||||
CK_ATTRIBUTE nick_template[] =
|
||||
{
|
||||
{ CKA_CLASS, NULL, 0 },
|
||||
{ CKA_LABEL, NULL, 0 }
|
||||
};
|
||||
nssList *nickCerts;
|
||||
struct collect_arg_str ca;
|
||||
CK_ULONG ctsize;
|
||||
ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
|
||||
NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
|
||||
nick_template[1].pValue = (CK_VOID_PTR)name;
|
||||
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
|
||||
nickCerts = nssList_Create(NULL, PR_FALSE);
|
||||
ca.list = nickCerts;
|
||||
ca.maximum = maximumOpt;
|
||||
ca.arena = arenaOpt;
|
||||
ca.rvOpt = rvOpt;
|
||||
rvCerts = find_all_certs_for_template(td, token,
|
||||
&ca, nick_template, ctsize);
|
||||
nssList_Destroy(nickCerts);
|
||||
return rvCerts;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCertificate **
|
||||
NSSTrustDomain_FindCertificatesByNickname
|
||||
(
|
||||
|
@ -522,28 +675,12 @@ NSSTrustDomain_FindCertificatesByNickname
|
|||
ca.maximum = maximumOpt;
|
||||
ca.arena = arenaOpt;
|
||||
ca.rvOpt = rvOpt;
|
||||
rvCerts = find_all_certs_for_template(td, &ca, nick_template, ctsize);
|
||||
rvCerts = find_all_certs_for_template(td, NULL,
|
||||
&ca, nick_template, ctsize);
|
||||
nssList_Destroy(nickCerts);
|
||||
return rvCerts;
|
||||
}
|
||||
|
||||
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
|
||||
(
|
||||
|
@ -580,7 +717,7 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
|
|||
cert_template, ctsize);
|
||||
if (object != CK_INVALID_KEY) {
|
||||
/* Could not find cert, so create it */
|
||||
rvCert = NSSCertificate_CreateFromHandle(NULL, object,
|
||||
rvCert = nssCertificate_CreateFromHandle(NULL, object,
|
||||
NULL, tok->slot);
|
||||
if (rvCert) {
|
||||
/* cache it */
|
||||
|
@ -625,7 +762,8 @@ NSSTrustDomain_FindBestCertificateBySubject
|
|||
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
|
||||
best.cached = subjectList;
|
||||
/* now find the best cert on tokens */
|
||||
rvCert = find_best_cert_for_template(td, &best, subj_template, ctsize);
|
||||
rvCert = find_best_cert_for_template(td, NULL,
|
||||
&best, subj_template, ctsize);
|
||||
nssList_Destroy(subjectList);
|
||||
return rvCert;
|
||||
}
|
||||
|
@ -658,7 +796,8 @@ NSSTrustDomain_FindCertificatesBySubject
|
|||
ca.maximum = maximumOpt;
|
||||
ca.arena = arenaOpt;
|
||||
ca.rvOpt = rvOpt;
|
||||
rvCerts = find_all_certs_for_template(td, &ca, subj_template, ctsize);
|
||||
rvCerts = find_all_certs_for_template(td, NULL,
|
||||
&ca, subj_template, ctsize);
|
||||
nssList_Destroy(subjectList);
|
||||
return rvCerts;
|
||||
}
|
||||
|
@ -721,7 +860,7 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
|
|||
cert_template, ctsize);
|
||||
if (object != CK_INVALID_KEY) {
|
||||
/* Could not find cert, so create it */
|
||||
rvCert = NSSCertificate_CreateFromHandle(NULL, object,
|
||||
rvCert = nssCertificate_CreateFromHandle(NULL, object,
|
||||
NULL, tok->slot);
|
||||
if (rvCert) {
|
||||
/* cache it */
|
||||
|
|
Загрузка…
Ссылка в новой задаче