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