Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */
#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */
#include "cert.h"
#include "dev3hack.h"
#include "pki3hack.h"
#include "pk11pub.h"
#include "nssrwlk.h"
#include "pk11priv.h"
#define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32
extern const NSSError NSS_ERROR_NOT_FOUND;
typedef PRUint32 nssUpdateLevel;
NSS_IMPLEMENT NSSTrustDomain *
NSSTrustDomain_Create(
NSSUTF8 *moduleOpt,
NSSUTF8 *uriOpt,
NSSUTF8 *opaqueOpt,
void *reserved)
{
NSSArena *arena;
NSSTrustDomain *rvTD;
arena = NSSArena_Create();
if (!arena) {
return (NSSTrustDomain *)NULL;
}
rvTD = nss_ZNEW(arena, NSSTrustDomain);
if (!rvTD) {
goto loser;
}
/* protect the token list and the token iterator */
rvTD->tokensLock = NSSRWLock_New(100, "tokens");
if (!rvTD->tokensLock) {
goto loser;
}
nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
rvTD->arena = arena;
rvTD->refCount = 1;
rvTD->statusConfig = NULL;
return rvTD;
loser:
if (rvTD && rvTD->tokensLock) {
NSSRWLock_Destroy(rvTD->tokensLock);
}
nssArena_Destroy(arena);
return (NSSTrustDomain *)NULL;
}
static void
token_destructor(void *t)
{
NSSToken *tok = (NSSToken *)t;
/* Remove the token list's reference to the token */
(void)nssToken_Destroy(tok);
/* Signal that the slot should not give out any more references to the
* token. The token might still have a positive refcount after this call.
* The token has a reference to the slot, so the slot will not be destroyed
* until after the token's refcount drops to 0. */
PK11Slot_SetNSSToken(tok->pk11slot, NULL);
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_Destroy(
NSSTrustDomain *td)
{
PRStatus status = PR_SUCCESS;
if (--td->refCount == 0) {
/* Destroy each token in the list of tokens */
if (td->tokens) {
nssListIterator_Destroy(td->tokens);
td->tokens = NULL;
}
if (td->tokenList) {
nssList_Clear(td->tokenList, token_destructor);
nssList_Destroy(td->tokenList);
td->tokenList = NULL;
}
NSSRWLock_Destroy(td->tokensLock);
td->tokensLock = NULL;
status = nssTrustDomain_DestroyCache(td);
if (status == PR_FAILURE) {
return status;
}
if (td->statusConfig) {
td->statusConfig->statusDestroy(td->statusConfig);
td->statusConfig = NULL;
}
/* Destroy the trust domain */
nssArena_Destroy(td->arena);
}
return status;
}
/* XXX uses tokens until slot list is in place */
static NSSSlot **
nssTrustDomain_GetActiveSlots(
NSSTrustDomain *td,
nssUpdateLevel *updateLevel)
{
PRUint32 count;
NSSSlot **slots = NULL;
NSSToken **tp, **tokens;
*updateLevel = 1;
if (!td->tokenList) {
return NULL;
}
NSSRWLock_LockRead(td->tokensLock);
count = nssList_Count(td->tokenList);
tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
if (!tokens) {
NSSRWLock_UnlockRead(td->tokensLock);
return NULL;
}
slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
if (!slots) {
NSSRWLock_UnlockRead(td->tokensLock);
nss_ZFreeIf(tokens);
return NULL;
}
nssList_GetArray(td->tokenList, (void **)tokens, count);
count = 0;
for (tp = tokens; *tp; tp++) {
NSSSlot *slot = nssToken_GetSlot(*tp);
if (!PK11_IsDisabled(slot->pk11slot)) {
slots[count++] = slot;
} else {
nssSlot_Destroy(slot);
}
}
NSSRWLock_UnlockRead(td->tokensLock);
nss_ZFreeIf(tokens);
if (!count) {
nss_ZFreeIf(slots);
slots = NULL;
}
return slots;
}
/* XXX */
static nssSession *
nssTrustDomain_GetSessionForToken(
NSSTrustDomain *td,
NSSToken *token)
{
return nssToken_GetDefaultSession(token);
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_SetDefaultCallback(
NSSTrustDomain *td,
NSSCallback *newCallback,
NSSCallback **oldCallbackOpt)
{
if (oldCallbackOpt) {
*oldCallbackOpt = td->defaultCallback;
}
td->defaultCallback = newCallback;
return PR_SUCCESS;
}
NSS_IMPLEMENT NSSCallback *
nssTrustDomain_GetDefaultCallback(
NSSTrustDomain *td,
PRStatus *statusOpt)
{
if (statusOpt) {
*statusOpt = PR_SUCCESS;
}
return td->defaultCallback;
}
NSS_IMPLEMENT NSSCallback *
NSSTrustDomain_GetDefaultCallback(
NSSTrustDomain *td,
PRStatus *statusOpt)
{
return nssTrustDomain_GetDefaultCallback(td, statusOpt);
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_LoadModule(
NSSTrustDomain *td,
NSSUTF8 *moduleOpt,
NSSUTF8 *uriOpt,
NSSUTF8 *opaqueOpt,
void *reserved)
{
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_DisableToken(
NSSTrustDomain *td,
NSSToken *token,
NSSError why)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_EnableToken(
NSSTrustDomain *td,
NSSToken *token)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_IsTokenEnabled(
NSSTrustDomain *td,
NSSToken *token,
NSSError *whyOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT NSSSlot *
NSSTrustDomain_FindSlotByName(
NSSTrustDomain *td,
NSSUTF8 *slotName)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken **
NSSTrustDomain_FindTokensByURI(
NSSTrustDomain *td,
PK11URI *uri)
{
NSSToken *tok = NULL;
PK11SlotInfo *slotinfo;
NSSToken **tokens;
int count, i = 0;
NSSRWLock_LockRead(td->tokensLock);
count = nssList_Count(td->tokenList);
tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
if (!tokens) {
return NULL;
}
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens)) {
if (nssToken_IsPresent(tok)) {
slotinfo = tok->pk11slot;
if (pk11_MatchUriTokenInfo(slotinfo, uri))
tokens[i++] = nssToken_AddRef(tok);
}
}
tokens[i] = NULL;
nssListIterator_Finish(td->tokens);
NSSRWLock_UnlockRead(td->tokensLock);
return tokens;
}
NSS_IMPLEMENT NSSToken *
NSSTrustDomain_FindTokenByName(
NSSTrustDomain *td,
NSSUTF8 *tokenName)
{
PRStatus nssrv;
NSSUTF8 *myName;
NSSToken *tok = NULL;
NSSRWLock_LockRead(td->tokensLock);
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens)) {
if (nssToken_IsPresent(tok)) {
myName = nssToken_GetName(tok);
if (nssUTF8_Equal(tokenName, myName, &nssrv)) {
tok = nssToken_AddRef(tok);
break;
}
}
}
nssListIterator_Finish(td->tokens);
NSSRWLock_UnlockRead(td->tokensLock);
return tok;
}
NSS_IMPLEMENT NSSToken *
NSSTrustDomain_FindTokenBySlotName(
NSSTrustDomain *td,
NSSUTF8 *slotName)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
NSSTrustDomain_FindTokenForAlgorithm(
NSSTrustDomain *td,
NSSOID *algorithm)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSToken *
NSSTrustDomain_FindBestTokenForAlgorithms(
NSSTrustDomain *td,
NSSOID *algorithms[], /* may be null-terminated */
PRUint32 nAlgorithmsOpt /* limits the array if nonzero */
)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_Login(
NSSTrustDomain *td,
NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_Logout(NSSTrustDomain *td)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_ImportCertificate(
NSSTrustDomain *td,
NSSCertificate *c)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_ImportPKIXCertificate(
NSSTrustDomain *td,
/* declared as a struct until these "data types" are defined */
struct NSSPKIXCertificateStr *pc)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_ImportEncodedCertificate(
NSSTrustDomain *td,
NSSBER *ber)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_ImportEncodedCertificateChain(
NSSTrustDomain *td,
NSSBER *ber,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSPrivateKey *
NSSTrustDomain_ImportEncodedPrivateKey(
NSSTrustDomain *td,
NSSBER *ber,
NSSItem *passwordOpt, /* NULL will cause a callback */
NSSCallback *uhhOpt,
NSSToken *destination)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSPublicKey *
NSSTrustDomain_ImportEncodedPublicKey(
NSSTrustDomain *td,
NSSBER *ber)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
static NSSCertificate **
get_certs_from_list(nssList *list)
{
PRUint32 count = nssList_Count(list);
NSSCertificate **certs = NULL;
if (count > 0) {
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
if (certs) {
nssList_GetArray(list, (void **)certs, count);
}
}
return certs;
}
NSS_IMPLEMENT NSSCertificate **
nssTrustDomain_FindCertificatesByNickname(
NSSTrustDomain *td,
const NSSUTF8 *name,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt)
{
NSSToken *token = NULL;
NSSSlot **slots = NULL;
NSSSlot **slotp;
NSSCertificate **rvCerts = NULL;
nssPKIObjectCollection *collection = NULL;
nssUpdateLevel updateLevel;
nssList *nameList;
PRUint32 numRemaining = maximumOpt;
PRUint32 collectionCount = 0;
PRUint32 errors = 0;
/* First, grab from the cache */
nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) {
return NULL;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
rvCerts = get_certs_from_list(nameList);
/* initialize the collection of token certificates with the set of
* cached certs (if any).
*/
collection = nssCertificateCollection_Create(td, rvCerts);
nssCertificateArray_Destroy(rvCerts);
nssList_Destroy(nameList);
if (!collection) {
return (NSSCertificate **)NULL;
}
/* obtain the current set of active slots in the trust domain */
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
goto loser;
}
/* iterate over the slots */
for (slotp = slots; *slotp; slotp++) {
token = nssSlot_GetToken(*slotp);
if (token) {
nssSession *session;
nssCryptokiObject **instances = NULL;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
PRStatus status = PR_FAILURE;
session = nssTrustDomain_GetSessionForToken(td, token);
if (session) {
instances = nssToken_FindCertificatesByNickname(token,
session,
name,
tokenOnly,
numRemaining,
&status);
}
(void)nssToken_Destroy(token);
if (status != PR_SUCCESS) {
errors++;
continue;
}
if (instances) {
status = nssPKIObjectCollection_AddInstances(collection,
instances, 0);
nss_ZFreeIf(instances);
if (status != PR_SUCCESS) {
errors++;
continue;
}
collectionCount = nssPKIObjectCollection_Count(collection);
if (maximumOpt > 0) {
if (collectionCount >= maximumOpt)
break;
numRemaining = maximumOpt - collectionCount;
}
}
}
}
if (!collectionCount && errors)
goto loser;
/* Grab the certs collected in the search. */
rvCerts = nssPKIObjectCollection_GetCertificates(collection,
rvOpt, maximumOpt,
arenaOpt);
/* clean up */
nssPKIObjectCollection_Destroy(collection);
nssSlotArray_Destroy(slots);
return rvCerts;
loser:
if (slots) {
nssSlotArray_Destroy(slots);
}
if (collection) {
nssPKIObjectCollection_Destroy(collection);
}
return (NSSCertificate **)NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindCertificatesByNickname(
NSSTrustDomain *td,
NSSUTF8 *name,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt)
{
return nssTrustDomain_FindCertificatesByNickname(td,
name,
rvOpt,
maximumOpt,
arenaOpt);
}
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_FindBestCertificateByNickname(
NSSTrustDomain *td,
const NSSUTF8 *name,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
NSSCertificate **nicknameCerts;
NSSCertificate *rvCert = NULL;
nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name,
NULL,
0,
NULL);
if (nicknameCerts) {
rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
timeOpt,
usage,
policiesOpt);
nssCertificateArray_Destroy(nicknameCerts);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateByNickname(
NSSTrustDomain *td,
const NSSUTF8 *name,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
return nssTrustDomain_FindBestCertificateByNickname(td,
name,
timeOpt,
usage,
policiesOpt);
}
NSS_IMPLEMENT NSSCertificate **
nssTrustDomain_FindCertificatesBySubject(
NSSTrustDomain *td,
NSSDER *subject,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt)
{
NSSToken *token = NULL;
NSSSlot **slots = NULL;
NSSSlot **slotp;
NSSCertificate **rvCerts = NULL;
nssPKIObjectCollection *collection = NULL;
nssUpdateLevel updateLevel;
nssList *subjectList;
PRUint32 numRemaining = maximumOpt;
PRUint32 collectionCount = 0;
PRUint32 errors = 0;
/* look in cache */
subjectList = nssList_Create(NULL, PR_FALSE);
if (!subjectList) {
return NULL;
}
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
rvCerts = get_certs_from_list(subjectList);
collection = nssCertificateCollection_Create(td, rvCerts);
nssCertificateArray_Destroy(rvCerts);
nssList_Destroy(subjectList);
if (!collection) {
return (NSSCertificate **)NULL;
}
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
goto loser;
}
for (slotp = slots; *slotp; slotp++) {
token = nssSlot_GetToken(*slotp);
if (token) {
nssSession *session;
nssCryptokiObject **instances = NULL;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
PRStatus status = PR_FAILURE;
session = nssTrustDomain_GetSessionForToken(td, token);
if (session) {
instances = nssToken_FindCertificatesBySubject(token,
session,
subject,
tokenOnly,
numRemaining,
&status);
}
(void)nssToken_Destroy(token);
if (status != PR_SUCCESS) {
errors++;
continue;
}
if (instances) {
status = nssPKIObjectCollection_AddInstances(collection,
instances, 0);
nss_ZFreeIf(instances);
if (status != PR_SUCCESS) {
errors++;
continue;
}
collectionCount = nssPKIObjectCollection_Count(collection);
if (maximumOpt > 0) {
if (collectionCount >= maximumOpt)
break;
numRemaining = maximumOpt - collectionCount;
}
}
}
}
if (!collectionCount && errors)
goto loser;
rvCerts = nssPKIObjectCollection_GetCertificates(collection,
rvOpt, maximumOpt,
arenaOpt);
nssPKIObjectCollection_Destroy(collection);
nssSlotArray_Destroy(slots);
return rvCerts;
loser:
if (slots) {
nssSlotArray_Destroy(slots);
}
if (collection) {
nssPKIObjectCollection_Destroy(collection);
}
return (NSSCertificate **)NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindCertificatesBySubject(
NSSTrustDomain *td,
NSSDER *subject,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt,
NSSArena *arenaOpt)
{
return nssTrustDomain_FindCertificatesBySubject(td,
subject,
rvOpt,
maximumOpt,
arenaOpt);
}
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_FindBestCertificateBySubject(
NSSTrustDomain *td,
NSSDER *subject,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
NSSCertificate **subjectCerts;
NSSCertificate *rvCert = NULL;
subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject,
NULL,
0,
NULL);
if (subjectCerts) {
rvCert = nssCertificateArray_FindBestCertificate(subjectCerts,
timeOpt,
usage,
policiesOpt);
nssCertificateArray_Destroy(subjectCerts);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateBySubject(
NSSTrustDomain *td,
NSSDER *subject,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
return nssTrustDomain_FindBestCertificateBySubject(td,
subject,
timeOpt,
usage,
policiesOpt);
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateByNameComponents(
NSSTrustDomain *td,
NSSUTF8 *nameComponents,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindCertificatesByNameComponents(
NSSTrustDomain *td,
NSSUTF8 *nameComponents,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
/* This returns at most a single certificate, so it can stop the loop
* when one is found.
*/
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_FindCertificateByIssuerAndSerialNumber(
NSSTrustDomain *td,
NSSDER *issuer,
NSSDER *serial)
{
NSSSlot **slots = NULL;
NSSSlot **slotp;
NSSCertificate *rvCert = NULL;
nssPKIObjectCollection *collection = NULL;
nssUpdateLevel updateLevel;
/* see if this search is already cached */
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
issuer,
serial);
if (rvCert) {
return rvCert;
}
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (slots) {
for (slotp = slots; *slotp; slotp++) {
NSSToken *token = nssSlot_GetToken(*slotp);
nssSession *session;
nssCryptokiObject *instance;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
PRStatus status = PR_FAILURE;
if (!token)
continue;
session = nssTrustDomain_GetSessionForToken(td, token);
if (session) {
instance = nssToken_FindCertificateByIssuerAndSerialNumber(
token,
session,
issuer,
serial,
tokenOnly,
&status);
}
(void)nssToken_Destroy(token);
if (status != PR_SUCCESS) {
continue;
}
if (instance) {
if (!collection) {
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
break; /* don't keep looping if out if memory */
}
}
status = nssPKIObjectCollection_AddInstances(collection,
&instance, 1);
if (status == PR_SUCCESS) {
(void)nssPKIObjectCollection_GetCertificates(
collection, &rvCert, 1, NULL);
}
if (rvCert) {
break; /* found one cert, all done */
}
}
}
}
if (collection) {
nssPKIObjectCollection_Destroy(collection);
}
if (slots) {
nssSlotArray_Destroy(slots);
}
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindCertificateByIssuerAndSerialNumber(
NSSTrustDomain *td,
NSSDER *issuer,
NSSDER *serial)
{
return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
issuer,
serial);
}
NSS_IMPLEMENT NSSCertificate *
nssTrustDomain_FindCertificateByEncodedCertificate(
NSSTrustDomain *td,
NSSBER *ber)
{
PRStatus status;
NSSCertificate *rvCert = NULL;
NSSDER issuer = { 0 };
NSSDER serial = { 0 };
/* XXX this is not generic... will any cert crack into issuer/serial? */
status = nssPKIX509_GetIssuerAndSerialFromDER(ber, &issuer, &serial);
if (status != PR_SUCCESS) {
return NULL;
}
rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
&issuer,
&serial);
PORT_Free(issuer.data);
PORT_Free(serial.data);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindCertificateByEncodedCertificate(
NSSTrustDomain *td,
NSSBER *ber)
{
return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber);
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateByEmail(
NSSTrustDomain *td,
NSSASCII7 *email,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
return 0;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindCertificatesByEmail(
NSSTrustDomain *td,
NSSASCII7 *email,
NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindCertificateByOCSPHash(
NSSTrustDomain *td,
NSSItem *hash)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestUserCertificate(
NSSTrustDomain *td,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindUserCertificates(
NSSTrustDomain *td,
NSSTime *timeOpt,
NSSUsage *usageOpt,
NSSPolicies *policiesOpt,
NSSCertificate **rvOpt,
PRUint32 rvLimit, /* zero for no limit */
NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestUserCertificateForSSLClientAuth(
NSSTrustDomain *td,
NSSUTF8 *sslHostOpt,
NSSDER *rootCAsOpt[], /* null pointer for none */
PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
NSSAlgorithmAndParameters *apOpt,
NSSPolicies *policiesOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindUserCertificatesForSSLClientAuth(
NSSTrustDomain *td,
NSSUTF8 *sslHostOpt,
NSSDER *rootCAsOpt[], /* null pointer for none */
PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
NSSAlgorithmAndParameters *apOpt,
NSSPolicies *policiesOpt,
NSSCertificate **rvOpt,
PRUint32 rvLimit, /* zero for no limit */
NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestUserCertificateForEmailSigning(
NSSTrustDomain *td,
NSSASCII7 *signerOpt,
NSSASCII7 *recipientOpt,
/* anything more here? */
NSSAlgorithmAndParameters *apOpt,
NSSPolicies *policiesOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindUserCertificatesForEmailSigning(
NSSTrustDomain *td,
NSSASCII7 *signerOpt,
NSSASCII7 *recipientOpt,
/* anything more here? */
NSSAlgorithmAndParameters *apOpt,
NSSPolicies *policiesOpt,
NSSCertificate **rvOpt,
PRUint32 rvLimit, /* zero for no limit */
NSSArena *arenaOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
static PRStatus
collector(nssCryptokiObject *instance, void *arg)
{
nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg;
return nssPKIObjectCollection_AddInstanceAsObject(collection, instance);
}
NSS_IMPLEMENT PRStatus *
NSSTrustDomain_TraverseCertificates(
NSSTrustDomain *td,
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg)
{
NSSToken *token = NULL;
NSSSlot **slots = NULL;
NSSSlot **slotp;
nssPKIObjectCollection *collection = NULL;
nssPKIObjectCallback pkiCallback;
nssUpdateLevel updateLevel;
NSSCertificate **cached = NULL;
nssList *certList;
certList = nssList_Create(NULL, PR_FALSE);
if (!certList)
return NULL;
(void)nssTrustDomain_GetCertsFromCache(td, certList);
cached = get_certs_from_list(certList);
collection = nssCertificateCollection_Create(td, cached);
nssCertificateArray_Destroy(cached);
nssList_Destroy(certList);
if (!collection) {
return (PRStatus *)NULL;
}
/* obtain the current set of active slots in the trust domain */
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
goto loser;
}
/* iterate over the slots */
for (slotp = slots; *slotp; slotp++) {
/* get the token for the slot, if present */
token = nssSlot_GetToken(*slotp);
if (token) {
nssSession *session;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
/* get a session for the token */
session = nssTrustDomain_GetSessionForToken(td, token);
if (session) {
/* perform the traversal */
(void)nssToken_TraverseCertificates(token,
session,
tokenOnly,
collector,
collection);
}
(void)nssToken_Destroy(token);
}
}
/* Traverse the collection */
pkiCallback.func.cert = callback;
pkiCallback.arg = arg;
(void)nssPKIObjectCollection_Traverse(collection, &pkiCallback);
loser:
if (slots) {
nssSlotArray_Destroy(slots);
}
if (collection) {
nssPKIObjectCollection_Destroy(collection);
}
return NULL;
}
NSS_IMPLEMENT NSSTrust *
nssTrustDomain_FindTrustForCertificate(
NSSTrustDomain *td,
NSSCertificate *c)
{
NSSSlot **slots;
NSSSlot **slotp;
nssCryptokiObject *to = NULL;
nssPKIObject *pkio = NULL;
NSSTrust *rvt = NULL;
nssUpdateLevel updateLevel;
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
return (NSSTrust *)NULL;
}
for (slotp = slots; *slotp; slotp++) {
NSSToken *token = nssSlot_GetToken(*slotp);
if (token) {
to = nssToken_FindTrustForCertificate(token, NULL,
&c->encoding,
&c->issuer,
&c->serial,
nssTokenSearchType_TokenOnly);
if (to) {
PRStatus status;
if (!pkio) {
pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock);
status = pkio ? PR_SUCCESS : PR_FAILURE;
} else {
status = nssPKIObject_AddInstance(pkio, to);
}
if (status != PR_SUCCESS) {
nssCryptokiObject_Destroy(to);
}
}
(void)nssToken_Destroy(token);
}
}
if (pkio) {
rvt = nssTrust_Create(pkio, &c->encoding);
if (rvt) {
pkio = NULL; /* rvt object now owns the pkio reference */
}
}
nssSlotArray_Destroy(slots);
if (pkio) {
nssPKIObject_Destroy(pkio);
}
return rvt;
}
NSS_IMPLEMENT NSSCRL **
nssTrustDomain_FindCRLsBySubject(
NSSTrustDomain *td,
NSSDER *subject)
{
NSSSlot **slots;
NSSSlot **slotp;
NSSToken *token;
nssUpdateLevel updateLevel;
nssPKIObjectCollection *collection;
NSSCRL **rvCRLs = NULL;
collection = nssCRLCollection_Create(td, NULL);
if (!collection) {
return (NSSCRL **)NULL;
}
slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
if (!slots) {
goto loser;
}
for (slotp = slots; *slotp; slotp++) {
token = nssSlot_GetToken(*slotp);
if (token) {
PRStatus status = PR_FAILURE;
nssSession *session;
nssCryptokiObject **instances = NULL;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
/* get a session for the token */
session = nssTrustDomain_GetSessionForToken(td, token);
if (session) {
/* perform the traversal */
instances = nssToken_FindCRLsBySubject(token, session, subject,
tokenOnly, 0, &status);
}
(void)nssToken_Destroy(token);
if (status == PR_SUCCESS) {
/* add the found CRL's to the collection */
status = nssPKIObjectCollection_AddInstances(collection,
instances, 0);
}
nss_ZFreeIf(instances);
}
}
rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
loser:
nssPKIObjectCollection_Destroy(collection);
nssSlotArray_Destroy(slots);
return rvCRLs;
}
NSS_IMPLEMENT PRStatus
NSSTrustDomain_GenerateKeyPair(
NSSTrustDomain *td,
NSSAlgorithmAndParameters *ap,
NSSPrivateKey **pvkOpt,
NSSPublicKey **pbkOpt,
PRBool privateKeyIsSensitive,
NSSToken *destination,
NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return PR_FAILURE;
}
NSS_IMPLEMENT NSSSymmetricKey *
NSSTrustDomain_GenerateSymmetricKey(
NSSTrustDomain *td,
NSSAlgorithmAndParameters *ap,
PRUint32 keysize,
NSSToken *destination,
NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSSymmetricKey *
NSSTrustDomain_GenerateSymmetricKeyFromPassword(
NSSTrustDomain *td,
NSSAlgorithmAndParameters *ap,
NSSUTF8 *passwordOpt, /* if null, prompt */
NSSToken *destinationOpt,
NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSSymmetricKey *
NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID(
NSSTrustDomain *td,
NSSOID *algorithm,
NSSItem *keyID,
NSSCallback *uhhOpt)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCryptoContext *
nssTrustDomain_CreateCryptoContext(
NSSTrustDomain *td,
NSSCallback *uhhOpt)
{
return nssCryptoContext_Create(td, uhhOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
NSSTrustDomain_CreateCryptoContext(
NSSTrustDomain *td,
NSSCallback *uhhOpt)
{
return nssTrustDomain_CreateCryptoContext(td, uhhOpt);
}
NSS_IMPLEMENT NSSCryptoContext *
NSSTrustDomain_CreateCryptoContextForAlgorithm(
NSSTrustDomain *td,
NSSOID *algorithm)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}
NSS_IMPLEMENT NSSCryptoContext *
NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters(
NSSTrustDomain *td,
NSSAlgorithmAndParameters *ap)
{
nss_SetError(NSS_ERROR_NOT_FOUND);
return NULL;
}