| /* 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 "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; |
| /* The token holds the first/last reference to the slot. |
| * When the token is actually destroyed (ref count == 0), |
| * the slot will also be destroyed. |
| */ |
| nssToken_Destroy(tok); |
| } |
| |
| 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); |
| NSSRWLock_UnlockRead(td->tokensLock); |
| count = 0; |
| for (tp = tokens; *tp; tp++) { |
| NSSSlot *slot = nssToken_GetSlot(*tp); |
| if (!PK11_IsDisabled(slot->pk11slot)) { |
| slots[count++] = slot; |
| } else { |
| nssSlot_Destroy(slot); |
| } |
| } |
| 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); |
| } |
| 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); |
| } |
| 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); |
| } |
| 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); |
| } |
| 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); |
| } |
| } |
| 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); |
| } |
| 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; |
| } |