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