| /* ***** BEGIN LICENSE BLOCK ***** |
| * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| * |
| * The contents of this file are subject to the Mozilla Public License Version |
| * 1.1 (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * http://www.mozilla.org/MPL/ |
| * |
| * Software distributed under the License is distributed on an "AS IS" basis, |
| * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| * for the specific language governing rights and limitations under the |
| * License. |
| * |
| * The Original Code is the Netscape security libraries. |
| * |
| * The Initial Developer of the Original Code is |
| * Netscape Communications Corporation. |
| * Portions created by the Initial Developer are Copyright (C) 1994-2000 |
| * the Initial Developer. All Rights Reserved. |
| * |
| * Contributor(s): |
| * |
| * Alternatively, the contents of this file may be used under the terms of |
| * either the GNU General Public License Version 2 or later (the "GPL"), or |
| * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
| * in which case the provisions of the GPL or the LGPL are applicable instead |
| * of those above. If you wish to allow use of your version of this file only |
| * under the terms of either the GPL or the LGPL, and not to allow others to |
| * use your version of this file under the terms of the MPL, indicate your |
| * decision by deleting the provisions above and replace them with the notice |
| * and other provisions required by the GPL or the LGPL. If you do not delete |
| * the provisions above, a recipient may use your version of this file under |
| * the terms of any one of the MPL, the GPL or the LGPL. |
| * |
| * ***** END LICENSE BLOCK ***** */ |
| |
| #ifdef DEBUG |
| static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.61 $ $Date: 2010/02/10 02:04:32 $"; |
| #endif /* DEBUG */ |
| |
| #ifndef DEV_H |
| #include "dev.h" |
| #endif /* DEV_H */ |
| |
| #ifndef PKIM_H |
| #include "pkim.h" |
| #endif /* PKIM_H */ |
| |
| #ifndef PKI1T_H |
| #include "pki1t.h" |
| #endif /* PKI1T_H */ |
| |
| #include "cert.h" |
| #include "pki3hack.h" |
| #include "pk11pub.h" |
| #include "nssrwlk.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; |
| 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_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)) 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 }; |
| NSSArena *arena = nssArena_Create(); |
| if (!arena) { |
| return (NSSCertificate *)NULL; |
| } |
| /* XXX this is not generic... will any cert crack into issuer/serial? */ |
| status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial); |
| if (status != PR_SUCCESS) { |
| goto finish; |
| } |
| rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, |
| &issuer, |
| &serial); |
| finish: |
| nssArena_Destroy(arena); |
| 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 |
| ) |
| { |
| PRStatus status = PR_FAILURE; |
| 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 */ |
| status = nssToken_TraverseCertificates(token, |
| session, |
| tokenOnly, |
| collector, |
| collection); |
| } |
| nssToken_Destroy(token); |
| } |
| } |
| |
| /* Traverse the collection */ |
| pkiCallback.func.cert = callback; |
| pkiCallback.arg = arg; |
| status = 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; |
| } |
| |