security/nss/lib/pki/trustdomain.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef DEV_H
     6 #include "dev.h"
     7 #endif /* DEV_H */
     9 #ifndef PKIM_H
    10 #include "pkim.h"
    11 #endif /* PKIM_H */
    13 #include "cert.h"
    14 #include "pki3hack.h"
    15 #include "pk11pub.h"
    16 #include "nssrwlk.h"
    18 #define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32
    20 extern const NSSError NSS_ERROR_NOT_FOUND;
    22 typedef PRUint32 nssUpdateLevel;
    24 NSS_IMPLEMENT NSSTrustDomain *
    25 NSSTrustDomain_Create (
    26   NSSUTF8 *moduleOpt,
    27   NSSUTF8 *uriOpt,
    28   NSSUTF8 *opaqueOpt,
    29   void *reserved
    30 )
    31 {
    32     NSSArena *arena;
    33     NSSTrustDomain *rvTD;
    34     arena = NSSArena_Create();
    35     if(!arena) {
    36 	return (NSSTrustDomain *)NULL;
    37     }
    38     rvTD = nss_ZNEW(arena, NSSTrustDomain);
    39     if (!rvTD) {
    40 	goto loser;
    41     }
    42     /* protect the token list and the token iterator */
    43     rvTD->tokensLock = NSSRWLock_New(100, "tokens");
    44     if (!rvTD->tokensLock) {
    45 	goto loser;
    46     }
    47     nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
    48     rvTD->arena = arena;
    49     rvTD->refCount = 1;
    50     rvTD->statusConfig = NULL;
    51     return rvTD;
    52 loser:
    53     if (rvTD && rvTD->tokensLock) {
    54 	NSSRWLock_Destroy(rvTD->tokensLock);
    55     }
    56     nssArena_Destroy(arena);
    57     return (NSSTrustDomain *)NULL;
    58 }
    60 static void
    61 token_destructor(void *t)
    62 {
    63     NSSToken *tok = (NSSToken *)t;
    64     /* The token holds the first/last reference to the slot.
    65      * When the token is actually destroyed (ref count == 0), 
    66      * the slot will also be destroyed.
    67      */
    68     nssToken_Destroy(tok);
    69 }
    71 NSS_IMPLEMENT PRStatus
    72 NSSTrustDomain_Destroy (
    73   NSSTrustDomain *td
    74 )
    75 {
    76     PRStatus status = PR_SUCCESS;
    77     if (--td->refCount == 0) {
    78 	/* Destroy each token in the list of tokens */
    79 	if (td->tokens) {
    80 	    nssListIterator_Destroy(td->tokens);
    81 	    td->tokens = NULL;
    82 	}
    83 	if (td->tokenList) {
    84 	    nssList_Clear(td->tokenList, token_destructor);
    85 	    nssList_Destroy(td->tokenList);
    86 	    td->tokenList = NULL;
    87 	}
    88 	NSSRWLock_Destroy(td->tokensLock);
    89 	td->tokensLock = NULL;
    90 	status = nssTrustDomain_DestroyCache(td);
    91 	if (status == PR_FAILURE) {
    92 	    return status;
    93 	}
    94 	if (td->statusConfig) {
    95 	    td->statusConfig->statusDestroy(td->statusConfig);
    96 	    td->statusConfig = NULL;
    97 	}
    98 	/* Destroy the trust domain */
    99 	nssArena_Destroy(td->arena);
   100     }
   101     return status;
   102 }
   104 /* XXX uses tokens until slot list is in place */
   105 static NSSSlot **
   106 nssTrustDomain_GetActiveSlots (
   107   NSSTrustDomain *td,
   108   nssUpdateLevel *updateLevel
   109 )
   110 {
   111     PRUint32 count;
   112     NSSSlot **slots = NULL;
   113     NSSToken **tp, **tokens;
   114     *updateLevel = 1;
   115     NSSRWLock_LockRead(td->tokensLock);
   116     count = nssList_Count(td->tokenList);
   117     tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
   118     if (!tokens) {
   119 	NSSRWLock_UnlockRead(td->tokensLock);
   120 	return NULL;
   121     }
   122     slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
   123     if (!slots) {
   124 	NSSRWLock_UnlockRead(td->tokensLock);
   125 	nss_ZFreeIf(tokens);
   126 	return NULL;
   127     }
   128     nssList_GetArray(td->tokenList, (void **)tokens, count);
   129     NSSRWLock_UnlockRead(td->tokensLock);
   130     count = 0;
   131     for (tp = tokens; *tp; tp++) {
   132         NSSSlot * slot = nssToken_GetSlot(*tp);
   133         if (!PK11_IsDisabled(slot->pk11slot)) {
   134             slots[count++] = slot;
   135         } else {
   136 	    nssSlot_Destroy(slot);
   137 	}
   138     }
   139     nss_ZFreeIf(tokens);
   140     if (!count) {
   141 	nss_ZFreeIf(slots);
   142     	slots = NULL;
   143     }
   144     return slots;
   145 }
   147 /* XXX */
   148 static nssSession *
   149 nssTrustDomain_GetSessionForToken (
   150   NSSTrustDomain *td,
   151   NSSToken *token
   152 )
   153 {
   154     return nssToken_GetDefaultSession(token);
   155 }
   157 NSS_IMPLEMENT PRStatus
   158 NSSTrustDomain_SetDefaultCallback (
   159   NSSTrustDomain *td,
   160   NSSCallback *newCallback,
   161   NSSCallback **oldCallbackOpt
   162 )
   163 {
   164     if (oldCallbackOpt) {
   165 	*oldCallbackOpt = td->defaultCallback;
   166     }
   167     td->defaultCallback = newCallback;
   168     return PR_SUCCESS;
   169 }
   171 NSS_IMPLEMENT NSSCallback *
   172 nssTrustDomain_GetDefaultCallback (
   173   NSSTrustDomain *td,
   174   PRStatus *statusOpt
   175 )
   176 {
   177     if (statusOpt) {
   178 	*statusOpt = PR_SUCCESS;
   179     }
   180     return td->defaultCallback;
   181 }
   183 NSS_IMPLEMENT NSSCallback *
   184 NSSTrustDomain_GetDefaultCallback (
   185   NSSTrustDomain *td,
   186   PRStatus *statusOpt
   187 )
   188 {
   189     return nssTrustDomain_GetDefaultCallback(td, statusOpt);
   190 }
   192 NSS_IMPLEMENT PRStatus
   193 NSSTrustDomain_LoadModule (
   194   NSSTrustDomain *td,
   195   NSSUTF8 *moduleOpt,
   196   NSSUTF8 *uriOpt,
   197   NSSUTF8 *opaqueOpt,
   198   void *reserved
   199 )
   200 {
   201     return PR_FAILURE;
   202 }
   204 NSS_IMPLEMENT PRStatus
   205 NSSTrustDomain_DisableToken (
   206   NSSTrustDomain *td,
   207   NSSToken *token,
   208   NSSError why
   209 )
   210 {
   211     nss_SetError(NSS_ERROR_NOT_FOUND);
   212     return PR_FAILURE;
   213 }
   215 NSS_IMPLEMENT PRStatus
   216 NSSTrustDomain_EnableToken (
   217   NSSTrustDomain *td,
   218   NSSToken *token
   219 )
   220 {
   221     nss_SetError(NSS_ERROR_NOT_FOUND);
   222     return PR_FAILURE;
   223 }
   225 NSS_IMPLEMENT PRStatus
   226 NSSTrustDomain_IsTokenEnabled (
   227   NSSTrustDomain *td,
   228   NSSToken *token,
   229   NSSError *whyOpt
   230 )
   231 {
   232     nss_SetError(NSS_ERROR_NOT_FOUND);
   233     return PR_FAILURE;
   234 }
   236 NSS_IMPLEMENT NSSSlot *
   237 NSSTrustDomain_FindSlotByName (
   238   NSSTrustDomain *td,
   239   NSSUTF8 *slotName
   240 )
   241 {
   242     nss_SetError(NSS_ERROR_NOT_FOUND);
   243     return NULL;
   244 }
   246 NSS_IMPLEMENT NSSToken *
   247 NSSTrustDomain_FindTokenByName (
   248   NSSTrustDomain *td,
   249   NSSUTF8 *tokenName
   250 )
   251 {
   252     PRStatus nssrv;
   253     NSSUTF8 *myName;
   254     NSSToken *tok = NULL;
   255     NSSRWLock_LockRead(td->tokensLock);
   256     for (tok  = (NSSToken *)nssListIterator_Start(td->tokens);
   257          tok != (NSSToken *)NULL;
   258          tok  = (NSSToken *)nssListIterator_Next(td->tokens))
   259     {
   260 	if (nssToken_IsPresent(tok)) {
   261 	    myName = nssToken_GetName(tok);
   262 	    if (nssUTF8_Equal(tokenName, myName, &nssrv)) break;
   263 	}
   264     }
   265     nssListIterator_Finish(td->tokens);
   266     NSSRWLock_UnlockRead(td->tokensLock);
   267     return tok;
   268 }
   270 NSS_IMPLEMENT NSSToken *
   271 NSSTrustDomain_FindTokenBySlotName (
   272   NSSTrustDomain *td,
   273   NSSUTF8 *slotName
   274 )
   275 {
   276     nss_SetError(NSS_ERROR_NOT_FOUND);
   277     return NULL;
   278 }
   280 NSS_IMPLEMENT NSSToken *
   281 NSSTrustDomain_FindTokenForAlgorithm (
   282   NSSTrustDomain *td,
   283   NSSOID *algorithm
   284 )
   285 {
   286     nss_SetError(NSS_ERROR_NOT_FOUND);
   287     return NULL;
   288 }
   290 NSS_IMPLEMENT NSSToken *
   291 NSSTrustDomain_FindBestTokenForAlgorithms (
   292   NSSTrustDomain *td,
   293   NSSOID *algorithms[], /* may be null-terminated */
   294   PRUint32 nAlgorithmsOpt /* limits the array if nonzero */
   295 )
   296 {
   297     nss_SetError(NSS_ERROR_NOT_FOUND);
   298     return NULL;
   299 }
   301 NSS_IMPLEMENT PRStatus
   302 NSSTrustDomain_Login (
   303   NSSTrustDomain *td,
   304   NSSCallback *uhhOpt
   305 )
   306 {
   307     nss_SetError(NSS_ERROR_NOT_FOUND);
   308     return PR_FAILURE;
   309 }
   311 NSS_IMPLEMENT PRStatus
   312 NSSTrustDomain_Logout (
   313   NSSTrustDomain *td
   314 )
   315 {
   316     nss_SetError(NSS_ERROR_NOT_FOUND);
   317     return PR_FAILURE;
   318 }
   320 NSS_IMPLEMENT NSSCertificate *
   321 NSSTrustDomain_ImportCertificate (
   322   NSSTrustDomain *td,
   323   NSSCertificate *c
   324 )
   325 {
   326     nss_SetError(NSS_ERROR_NOT_FOUND);
   327     return NULL;
   328 }
   330 NSS_IMPLEMENT NSSCertificate *
   331 NSSTrustDomain_ImportPKIXCertificate (
   332   NSSTrustDomain *td,
   333   /* declared as a struct until these "data types" are defined */
   334   struct NSSPKIXCertificateStr *pc
   335 )
   336 {
   337     nss_SetError(NSS_ERROR_NOT_FOUND);
   338     return NULL;
   339 }
   341 NSS_IMPLEMENT NSSCertificate *
   342 NSSTrustDomain_ImportEncodedCertificate (
   343   NSSTrustDomain *td,
   344   NSSBER *ber
   345 )
   346 {
   347     nss_SetError(NSS_ERROR_NOT_FOUND);
   348     return NULL;
   349 }
   351 NSS_IMPLEMENT NSSCertificate **
   352 NSSTrustDomain_ImportEncodedCertificateChain (
   353   NSSTrustDomain *td,
   354   NSSBER *ber,
   355   NSSCertificate *rvOpt[],
   356   PRUint32 maximumOpt, /* 0 for no max */
   357   NSSArena *arenaOpt
   358 )
   359 {
   360     nss_SetError(NSS_ERROR_NOT_FOUND);
   361     return NULL;
   362 }
   364 NSS_IMPLEMENT NSSPrivateKey *
   365 NSSTrustDomain_ImportEncodedPrivateKey (
   366   NSSTrustDomain *td,
   367   NSSBER *ber,
   368   NSSItem *passwordOpt, /* NULL will cause a callback */
   369   NSSCallback *uhhOpt,
   370   NSSToken *destination
   371 )
   372 {
   373     nss_SetError(NSS_ERROR_NOT_FOUND);
   374     return NULL;
   375 }
   377 NSS_IMPLEMENT NSSPublicKey *
   378 NSSTrustDomain_ImportEncodedPublicKey (
   379   NSSTrustDomain *td,
   380   NSSBER *ber
   381 )
   382 {
   383     nss_SetError(NSS_ERROR_NOT_FOUND);
   384     return NULL;
   385 }
   387 static NSSCertificate **
   388 get_certs_from_list(nssList *list)
   389 {
   390     PRUint32 count = nssList_Count(list);
   391     NSSCertificate **certs = NULL;
   392     if (count > 0) {
   393 	certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
   394 	if (certs) {
   395 	    nssList_GetArray(list, (void **)certs, count);
   396 	}
   397     }
   398     return certs;
   399 }
   401 NSS_IMPLEMENT NSSCertificate **
   402 nssTrustDomain_FindCertificatesByNickname (
   403   NSSTrustDomain *td,
   404   const NSSUTF8 *name,
   405   NSSCertificate *rvOpt[],
   406   PRUint32 maximumOpt, /* 0 for no max */
   407   NSSArena *arenaOpt
   408 )
   409 {
   410     NSSToken *token = NULL;
   411     NSSSlot **slots = NULL;
   412     NSSSlot **slotp;
   413     NSSCertificate **rvCerts = NULL;
   414     nssPKIObjectCollection *collection = NULL;
   415     nssUpdateLevel updateLevel;
   416     nssList *nameList;
   417     PRUint32 numRemaining = maximumOpt;
   418     PRUint32 collectionCount = 0;
   419     PRUint32 errors = 0;
   421     /* First, grab from the cache */
   422     nameList = nssList_Create(NULL, PR_FALSE);
   423     if (!nameList) {
   424 	return NULL;
   425     }
   426     (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
   427     rvCerts = get_certs_from_list(nameList);
   428     /* initialize the collection of token certificates with the set of
   429      * cached certs (if any).
   430      */
   431     collection = nssCertificateCollection_Create(td, rvCerts);
   432     nssCertificateArray_Destroy(rvCerts);
   433     nssList_Destroy(nameList);
   434     if (!collection) {
   435 	return (NSSCertificate **)NULL;
   436     }
   437     /* obtain the current set of active slots in the trust domain */
   438     slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
   439     if (!slots) {
   440 	goto loser;
   441     }
   442     /* iterate over the slots */
   443     for (slotp = slots; *slotp; slotp++) {
   444 	token = nssSlot_GetToken(*slotp);
   445 	if (token) {
   446 	    nssSession *session;
   447 	    nssCryptokiObject **instances = NULL;
   448 	    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
   449 	    PRStatus status = PR_FAILURE;
   451 	    session = nssTrustDomain_GetSessionForToken(td, token);
   452 	    if (session) {
   453 		instances = nssToken_FindCertificatesByNickname(token,
   454 								session,
   455 								name,
   456 								tokenOnly,
   457 								numRemaining,
   458 								&status);
   459 	    }
   460 	    nssToken_Destroy(token);
   461 	    if (status != PR_SUCCESS) {
   462 		errors++;
   463 		continue;
   464 	    }
   465 	    if (instances) {
   466 		status = nssPKIObjectCollection_AddInstances(collection, 
   467 		                                             instances, 0);
   468 		nss_ZFreeIf(instances);
   469 		if (status != PR_SUCCESS) {
   470 		    errors++;
   471 		    continue;
   472 		}
   473 		collectionCount = nssPKIObjectCollection_Count(collection);
   474 		if (maximumOpt > 0) {
   475 		    if (collectionCount >= maximumOpt)
   476 		    	break;
   477 		    numRemaining = maximumOpt - collectionCount;
   478 		}
   479 	    }
   480 	}
   481     }
   482     if (!collectionCount && errors)
   483     	goto loser;
   484     /* Grab the certs collected in the search. */
   485     rvCerts = nssPKIObjectCollection_GetCertificates(collection,
   486                                                      rvOpt, maximumOpt,
   487                                                      arenaOpt);
   488     /* clean up */
   489     nssPKIObjectCollection_Destroy(collection);
   490     nssSlotArray_Destroy(slots);
   491     return rvCerts;
   492 loser:
   493     if (slots) {
   494 	nssSlotArray_Destroy(slots);
   495     }
   496     if (collection) {
   497 	nssPKIObjectCollection_Destroy(collection);
   498     }
   499     return (NSSCertificate **)NULL;
   500 }
   502 NSS_IMPLEMENT NSSCertificate **
   503 NSSTrustDomain_FindCertificatesByNickname (
   504   NSSTrustDomain *td,
   505   NSSUTF8 *name,
   506   NSSCertificate *rvOpt[],
   507   PRUint32 maximumOpt, /* 0 for no max */
   508   NSSArena *arenaOpt
   509 )
   510 {
   511     return nssTrustDomain_FindCertificatesByNickname(td,
   512                                                      name,
   513                                                      rvOpt,
   514                                                      maximumOpt,
   515                                                      arenaOpt);
   516 }
   518 NSS_IMPLEMENT NSSCertificate *
   519 nssTrustDomain_FindBestCertificateByNickname (
   520   NSSTrustDomain *td,
   521   const NSSUTF8 *name,
   522   NSSTime *timeOpt,
   523   NSSUsage *usage,
   524   NSSPolicies *policiesOpt
   525 )
   526 {
   527     NSSCertificate **nicknameCerts;
   528     NSSCertificate *rvCert = NULL;
   529     nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name,
   530                                                               NULL,
   531                                                               0,
   532                                                               NULL);
   533     if (nicknameCerts) {
   534 	rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
   535                                                          timeOpt,
   536                                                          usage,
   537                                                          policiesOpt);
   538 	nssCertificateArray_Destroy(nicknameCerts);
   539     }
   540     return rvCert;
   541 }
   543 NSS_IMPLEMENT NSSCertificate *
   544 NSSTrustDomain_FindBestCertificateByNickname (
   545   NSSTrustDomain *td,
   546   const NSSUTF8 *name,
   547   NSSTime *timeOpt,
   548   NSSUsage *usage,
   549   NSSPolicies *policiesOpt
   550 )
   551 {
   552     return nssTrustDomain_FindBestCertificateByNickname(td,
   553                                                         name,
   554                                                         timeOpt,
   555                                                         usage,
   556                                                         policiesOpt);
   557 }
   559 NSS_IMPLEMENT NSSCertificate **
   560 nssTrustDomain_FindCertificatesBySubject (
   561   NSSTrustDomain *td,
   562   NSSDER *subject,
   563   NSSCertificate *rvOpt[],
   564   PRUint32 maximumOpt, /* 0 for no max */
   565   NSSArena *arenaOpt
   566 )
   567 {
   568     NSSToken *token = NULL;
   569     NSSSlot **slots = NULL;
   570     NSSSlot **slotp;
   571     NSSCertificate **rvCerts = NULL;
   572     nssPKIObjectCollection *collection = NULL;
   573     nssUpdateLevel updateLevel;
   574     nssList *subjectList;
   575     PRUint32 numRemaining = maximumOpt;
   576     PRUint32 collectionCount = 0;
   577     PRUint32 errors = 0;
   579     /* look in cache */
   580     subjectList = nssList_Create(NULL, PR_FALSE);
   581     if (!subjectList) {
   582 	return NULL;
   583     }
   584     (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
   585     rvCerts = get_certs_from_list(subjectList);
   586     collection = nssCertificateCollection_Create(td, rvCerts);
   587     nssCertificateArray_Destroy(rvCerts);
   588     nssList_Destroy(subjectList);
   589     if (!collection) {
   590 	return (NSSCertificate **)NULL;
   591     }
   592     slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
   593     if (!slots) {
   594 	goto loser;
   595     }
   596     for (slotp = slots; *slotp; slotp++) {
   597 	token = nssSlot_GetToken(*slotp);
   598 	if (token) {
   599 	    nssSession *session;
   600 	    nssCryptokiObject **instances = NULL;
   601 	    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
   602 	    PRStatus status = PR_FAILURE;
   604 	    session = nssTrustDomain_GetSessionForToken(td, token);
   605 	    if (session) {
   606 		instances = nssToken_FindCertificatesBySubject(token,
   607 							       session,
   608 							       subject,
   609 							       tokenOnly,
   610 							       numRemaining,
   611 							       &status);
   612 	    }
   613 	    nssToken_Destroy(token);
   614 	    if (status != PR_SUCCESS) {
   615 		errors++;
   616 		continue;
   617 	    }
   618 	    if (instances) {
   619 		status = nssPKIObjectCollection_AddInstances(collection, 
   620 		                                             instances, 0);
   621 		nss_ZFreeIf(instances);
   622 		if (status != PR_SUCCESS) {
   623 		    errors++;
   624 		    continue;
   625 		}
   626 		collectionCount = nssPKIObjectCollection_Count(collection);
   627 		if (maximumOpt > 0) {
   628 		    if (collectionCount >= maximumOpt)
   629 		    	break;
   630 		    numRemaining = maximumOpt - collectionCount;
   631 		}
   632 	    }
   633 	}
   634     }
   635     if (!collectionCount && errors)
   636     	goto loser;
   637     rvCerts = nssPKIObjectCollection_GetCertificates(collection,
   638                                                      rvOpt, maximumOpt,
   639                                                      arenaOpt);
   640     nssPKIObjectCollection_Destroy(collection);
   641     nssSlotArray_Destroy(slots);
   642     return rvCerts;
   643 loser:
   644     if (slots) {
   645 	nssSlotArray_Destroy(slots);
   646     }
   647     if (collection) {
   648 	nssPKIObjectCollection_Destroy(collection);
   649     }
   650     return (NSSCertificate **)NULL;
   651 }
   653 NSS_IMPLEMENT NSSCertificate **
   654 NSSTrustDomain_FindCertificatesBySubject (
   655   NSSTrustDomain *td,
   656   NSSDER *subject,
   657   NSSCertificate *rvOpt[],
   658   PRUint32 maximumOpt,
   659   NSSArena *arenaOpt
   660 )
   661 {
   662     return nssTrustDomain_FindCertificatesBySubject(td, 
   663                                                     subject,
   664                                                     rvOpt,
   665                                                     maximumOpt,
   666                                                     arenaOpt);
   667 }
   669 NSS_IMPLEMENT NSSCertificate *
   670 nssTrustDomain_FindBestCertificateBySubject (
   671   NSSTrustDomain *td,
   672   NSSDER *subject,
   673   NSSTime *timeOpt,
   674   NSSUsage *usage,
   675   NSSPolicies *policiesOpt
   676 )
   677 {
   678     NSSCertificate **subjectCerts;
   679     NSSCertificate *rvCert = NULL;
   680     subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject,
   681                                                             NULL,
   682                                                             0,
   683                                                             NULL);
   684     if (subjectCerts) {
   685 	rvCert = nssCertificateArray_FindBestCertificate(subjectCerts,
   686                                                          timeOpt,
   687                                                          usage,
   688                                                          policiesOpt);
   689 	nssCertificateArray_Destroy(subjectCerts);
   690     }
   691     return rvCert;
   692 }
   694 NSS_IMPLEMENT NSSCertificate *
   695 NSSTrustDomain_FindBestCertificateBySubject (
   696   NSSTrustDomain *td,
   697   NSSDER *subject,
   698   NSSTime *timeOpt,
   699   NSSUsage *usage,
   700   NSSPolicies *policiesOpt
   701 )
   702 {
   703     return nssTrustDomain_FindBestCertificateBySubject(td,
   704                                                        subject,
   705                                                        timeOpt,
   706                                                        usage,
   707                                                        policiesOpt);
   708 }
   710 NSS_IMPLEMENT NSSCertificate *
   711 NSSTrustDomain_FindBestCertificateByNameComponents (
   712   NSSTrustDomain *td,
   713   NSSUTF8 *nameComponents,
   714   NSSTime *timeOpt,
   715   NSSUsage *usage,
   716   NSSPolicies *policiesOpt
   717 )
   718 {
   719     nss_SetError(NSS_ERROR_NOT_FOUND);
   720     return NULL;
   721 }
   723 NSS_IMPLEMENT NSSCertificate **
   724 NSSTrustDomain_FindCertificatesByNameComponents (
   725   NSSTrustDomain *td,
   726   NSSUTF8 *nameComponents,
   727   NSSCertificate *rvOpt[],
   728   PRUint32 maximumOpt, /* 0 for no max */
   729   NSSArena *arenaOpt
   730 )
   731 {
   732     nss_SetError(NSS_ERROR_NOT_FOUND);
   733     return NULL;
   734 }
   736 /* This returns at most a single certificate, so it can stop the loop
   737  * when one is found.
   738  */
   739 NSS_IMPLEMENT NSSCertificate *
   740 nssTrustDomain_FindCertificateByIssuerAndSerialNumber (
   741   NSSTrustDomain *td,
   742   NSSDER *issuer,
   743   NSSDER *serial
   744 )
   745 {
   746     NSSSlot **slots = NULL;
   747     NSSSlot **slotp;
   748     NSSCertificate *rvCert = NULL;
   749     nssPKIObjectCollection *collection = NULL;
   750     nssUpdateLevel updateLevel;
   752     /* see if this search is already cached */
   753     rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
   754                                                            issuer, 
   755                                                            serial);
   756     if (rvCert) {
   757 	return rvCert;
   758     }
   759     slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
   760     if (slots) {
   761 	for (slotp = slots; *slotp; slotp++) {
   762 	    NSSToken *token = nssSlot_GetToken(*slotp);
   763 	    nssSession *session;
   764 	    nssCryptokiObject *instance;
   765 	    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
   766 	    PRStatus status = PR_FAILURE;
   768 	    if (!token) 
   769 		continue;
   770 	    session = nssTrustDomain_GetSessionForToken(td, token);
   771 	    if (session) {
   772 		instance = nssToken_FindCertificateByIssuerAndSerialNumber(
   773 								    token,
   774 								    session,
   775 								    issuer,
   776 								    serial,
   777 								    tokenOnly,
   778 								    &status);
   779 	    }
   780 	    nssToken_Destroy(token);
   781 	    if (status != PR_SUCCESS) {
   782 		continue;
   783 	    }
   784 	    if (instance) {
   785 		if (!collection) {
   786 		    collection = nssCertificateCollection_Create(td, NULL);
   787 		    if (!collection) {
   788 			break;  /* don't keep looping if out if memory */
   789 		    }
   790 		}
   791 		status = nssPKIObjectCollection_AddInstances(collection, 
   792 							     &instance, 1);
   793 		if (status == PR_SUCCESS) {
   794 		    (void)nssPKIObjectCollection_GetCertificates(
   795 					     collection, &rvCert, 1, NULL);
   796 		}
   797 		if (rvCert) {
   798 		    break; /* found one cert, all done */
   799 		}
   800 	    }
   801 	}
   802     }
   803     if (collection) {
   804 	nssPKIObjectCollection_Destroy(collection);
   805     }
   806     if (slots) {
   807 	nssSlotArray_Destroy(slots);
   808     }
   809     return rvCert;
   810 }
   812 NSS_IMPLEMENT NSSCertificate *
   813 NSSTrustDomain_FindCertificateByIssuerAndSerialNumber (
   814   NSSTrustDomain *td,
   815   NSSDER *issuer,
   816   NSSDER *serial
   817 )
   818 {
   819     return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
   820                                                                  issuer,
   821                                                                  serial);
   822 }
   824 NSS_IMPLEMENT NSSCertificate *
   825 nssTrustDomain_FindCertificateByEncodedCertificate (
   826   NSSTrustDomain *td,
   827   NSSBER *ber
   828 )
   829 {
   830     PRStatus status;
   831     NSSCertificate *rvCert = NULL;
   832     NSSDER issuer = { 0 };
   833     NSSDER serial = { 0 };
   834     NSSArena *arena = nssArena_Create();
   835     if (!arena) {
   836 	return (NSSCertificate *)NULL;
   837     }
   838     /* XXX this is not generic...  will any cert crack into issuer/serial? */
   839     status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial);
   840     if (status != PR_SUCCESS) {
   841 	goto finish;
   842     }
   843     rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
   844                                                                    &issuer,
   845                                                                    &serial);
   846 finish:
   847     nssArena_Destroy(arena);
   848     return rvCert;
   849 }
   851 NSS_IMPLEMENT NSSCertificate *
   852 NSSTrustDomain_FindCertificateByEncodedCertificate (
   853   NSSTrustDomain *td,
   854   NSSBER *ber
   855 )
   856 {
   857     return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber);
   858 }
   860 NSS_IMPLEMENT NSSCertificate *
   861 NSSTrustDomain_FindBestCertificateByEmail (
   862   NSSTrustDomain *td,
   863   NSSASCII7 *email,
   864   NSSTime *timeOpt,
   865   NSSUsage *usage,
   866   NSSPolicies *policiesOpt
   867 )
   868 {
   869     return 0;
   870 }
   872 NSS_IMPLEMENT NSSCertificate **
   873 NSSTrustDomain_FindCertificatesByEmail (
   874   NSSTrustDomain *td,
   875   NSSASCII7 *email,
   876   NSSCertificate *rvOpt[],
   877   PRUint32 maximumOpt, /* 0 for no max */
   878   NSSArena *arenaOpt
   879 )
   880 {
   881     nss_SetError(NSS_ERROR_NOT_FOUND);
   882     return NULL;
   883 }
   885 NSS_IMPLEMENT NSSCertificate *
   886 NSSTrustDomain_FindCertificateByOCSPHash (
   887   NSSTrustDomain *td,
   888   NSSItem *hash
   889 )
   890 {
   891     nss_SetError(NSS_ERROR_NOT_FOUND);
   892     return NULL;
   893 }
   895 NSS_IMPLEMENT NSSCertificate *
   896 NSSTrustDomain_FindBestUserCertificate (
   897   NSSTrustDomain *td,
   898   NSSTime *timeOpt,
   899   NSSUsage *usage,
   900   NSSPolicies *policiesOpt
   901 )
   902 {
   903     nss_SetError(NSS_ERROR_NOT_FOUND);
   904     return NULL;
   905 }
   907 NSS_IMPLEMENT NSSCertificate **
   908 NSSTrustDomain_FindUserCertificates (
   909   NSSTrustDomain *td,
   910   NSSTime *timeOpt,
   911   NSSUsage *usageOpt,
   912   NSSPolicies *policiesOpt,
   913   NSSCertificate **rvOpt,
   914   PRUint32 rvLimit, /* zero for no limit */
   915   NSSArena *arenaOpt
   916 )
   917 {
   918     nss_SetError(NSS_ERROR_NOT_FOUND);
   919     return NULL;
   920 }
   922 NSS_IMPLEMENT NSSCertificate *
   923 NSSTrustDomain_FindBestUserCertificateForSSLClientAuth (
   924   NSSTrustDomain *td,
   925   NSSUTF8 *sslHostOpt,
   926   NSSDER *rootCAsOpt[], /* null pointer for none */
   927   PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
   928   NSSAlgorithmAndParameters *apOpt,
   929   NSSPolicies *policiesOpt
   930 )
   931 {
   932     nss_SetError(NSS_ERROR_NOT_FOUND);
   933     return NULL;
   934 }
   936 NSS_IMPLEMENT NSSCertificate **
   937 NSSTrustDomain_FindUserCertificatesForSSLClientAuth (
   938   NSSTrustDomain *td,
   939   NSSUTF8 *sslHostOpt,
   940   NSSDER *rootCAsOpt[], /* null pointer for none */
   941   PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
   942   NSSAlgorithmAndParameters *apOpt,
   943   NSSPolicies *policiesOpt,
   944   NSSCertificate **rvOpt,
   945   PRUint32 rvLimit, /* zero for no limit */
   946   NSSArena *arenaOpt
   947 )
   948 {
   949     nss_SetError(NSS_ERROR_NOT_FOUND);
   950     return NULL;
   951 }
   953 NSS_IMPLEMENT NSSCertificate *
   954 NSSTrustDomain_FindBestUserCertificateForEmailSigning (
   955   NSSTrustDomain *td,
   956   NSSASCII7 *signerOpt,
   957   NSSASCII7 *recipientOpt,
   958   /* anything more here? */
   959   NSSAlgorithmAndParameters *apOpt,
   960   NSSPolicies *policiesOpt
   961 )
   962 {
   963     nss_SetError(NSS_ERROR_NOT_FOUND);
   964     return NULL;
   965 }
   967 NSS_IMPLEMENT NSSCertificate **
   968 NSSTrustDomain_FindUserCertificatesForEmailSigning (
   969   NSSTrustDomain *td,
   970   NSSASCII7 *signerOpt,
   971   NSSASCII7 *recipientOpt,
   972   /* anything more here? */
   973   NSSAlgorithmAndParameters *apOpt,
   974   NSSPolicies *policiesOpt,
   975   NSSCertificate **rvOpt,
   976   PRUint32 rvLimit, /* zero for no limit */
   977   NSSArena *arenaOpt
   978 )
   979 {
   980     nss_SetError(NSS_ERROR_NOT_FOUND);
   981     return NULL;
   982 }
   984 static PRStatus
   985 collector(nssCryptokiObject *instance, void *arg)
   986 {
   987     nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg;
   988     return nssPKIObjectCollection_AddInstanceAsObject(collection, instance);
   989 }
   991 NSS_IMPLEMENT PRStatus *
   992 NSSTrustDomain_TraverseCertificates (
   993   NSSTrustDomain *td,
   994   PRStatus (*callback)(NSSCertificate *c, void *arg),
   995   void *arg
   996 )
   997 {
   998     PRStatus status = PR_FAILURE;
   999     NSSToken *token = NULL;
  1000     NSSSlot **slots = NULL;
  1001     NSSSlot **slotp;
  1002     nssPKIObjectCollection *collection = NULL;
  1003     nssPKIObjectCallback pkiCallback;
  1004     nssUpdateLevel updateLevel;
  1005     NSSCertificate **cached = NULL;
  1006     nssList *certList;
  1008     certList = nssList_Create(NULL, PR_FALSE);
  1009     if (!certList) 
  1010     	return NULL;
  1011     (void)nssTrustDomain_GetCertsFromCache(td, certList);
  1012     cached = get_certs_from_list(certList);
  1013     collection = nssCertificateCollection_Create(td, cached);
  1014     nssCertificateArray_Destroy(cached);
  1015     nssList_Destroy(certList);
  1016     if (!collection) {
  1017 	return (PRStatus *)NULL;
  1019     /* obtain the current set of active slots in the trust domain */
  1020     slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
  1021     if (!slots) {
  1022 	goto loser;
  1024     /* iterate over the slots */
  1025     for (slotp = slots; *slotp; slotp++) {
  1026 	/* get the token for the slot, if present */
  1027 	token = nssSlot_GetToken(*slotp);
  1028 	if (token) {
  1029 	    nssSession *session;
  1030 	    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
  1031 	    /* get a session for the token */
  1032 	    session = nssTrustDomain_GetSessionForToken(td, token);
  1033 	    if (session) {
  1034 		/* perform the traversal */
  1035 		status = nssToken_TraverseCertificates(token,
  1036 						       session,
  1037 						       tokenOnly,
  1038 						       collector,
  1039 						       collection);
  1041 	    nssToken_Destroy(token);
  1045     /* Traverse the collection */
  1046     pkiCallback.func.cert = callback;
  1047     pkiCallback.arg = arg;
  1048     status = nssPKIObjectCollection_Traverse(collection, &pkiCallback);
  1049 loser:
  1050     if (slots) {
  1051 	nssSlotArray_Destroy(slots);
  1053     if (collection) {
  1054 	nssPKIObjectCollection_Destroy(collection);
  1056     return NULL;
  1060 NSS_IMPLEMENT NSSTrust *
  1061 nssTrustDomain_FindTrustForCertificate (
  1062   NSSTrustDomain *td,
  1063   NSSCertificate *c
  1066     NSSSlot **slots;
  1067     NSSSlot **slotp;
  1068     nssCryptokiObject *to = NULL;
  1069     nssPKIObject *pkio = NULL;
  1070     NSSTrust *rvt = NULL;
  1071     nssUpdateLevel updateLevel;
  1072     slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
  1073     if (!slots) {
  1074 	return (NSSTrust *)NULL;
  1076     for (slotp = slots; *slotp; slotp++) {
  1077 	NSSToken *token = nssSlot_GetToken(*slotp);
  1079 	if (token) {
  1080 	    to = nssToken_FindTrustForCertificate(token, NULL, 
  1081 	                                          &c->encoding,
  1082 	                                          &c->issuer,
  1083 	                                          &c->serial,
  1084 	                                      nssTokenSearchType_TokenOnly);
  1085 	    if (to) {
  1086 		PRStatus status;
  1087 		if (!pkio) {
  1088 		    pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock);
  1089 		    status = pkio ? PR_SUCCESS : PR_FAILURE;
  1090 		} else {
  1091 		    status = nssPKIObject_AddInstance(pkio, to);
  1093 		if (status != PR_SUCCESS) {
  1094 		    nssCryptokiObject_Destroy(to);
  1097 	    nssToken_Destroy(token);
  1100     if (pkio) {
  1101 	rvt = nssTrust_Create(pkio, &c->encoding);
  1102 	if (rvt) {
  1103 	    pkio = NULL;  /* rvt object now owns the pkio reference */
  1106     nssSlotArray_Destroy(slots);
  1107     if (pkio) {
  1108 	nssPKIObject_Destroy(pkio);
  1110     return rvt;
  1113 NSS_IMPLEMENT NSSCRL **
  1114 nssTrustDomain_FindCRLsBySubject (
  1115   NSSTrustDomain *td,
  1116   NSSDER *subject
  1119     NSSSlot **slots;
  1120     NSSSlot **slotp;
  1121     NSSToken *token;
  1122     nssUpdateLevel updateLevel;
  1123     nssPKIObjectCollection *collection;
  1124     NSSCRL **rvCRLs = NULL;
  1125     collection = nssCRLCollection_Create(td, NULL);
  1126     if (!collection) {
  1127 	return (NSSCRL **)NULL;
  1129     slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
  1130     if (!slots) {
  1131 	goto loser;
  1133     for (slotp = slots; *slotp; slotp++) {
  1134 	token = nssSlot_GetToken(*slotp);
  1135 	if (token) {
  1136 	    PRStatus status = PR_FAILURE;
  1137 	    nssSession *session;
  1138 	    nssCryptokiObject **instances = NULL;
  1139 	    nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
  1141 	    /* get a session for the token */
  1142 	    session = nssTrustDomain_GetSessionForToken(td, token);
  1143 	    if (session) {
  1144 		/* perform the traversal */
  1145 		instances = nssToken_FindCRLsBySubject(token, session, subject,
  1146 	                                               tokenOnly, 0, &status);
  1148 	    nssToken_Destroy(token);
  1149 	    if (status == PR_SUCCESS) {
  1150 		/* add the found CRL's to the collection */
  1151 		status = nssPKIObjectCollection_AddInstances(collection, 
  1152 							     instances, 0);
  1154 	    nss_ZFreeIf(instances);
  1157     rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
  1158 loser:
  1159     nssPKIObjectCollection_Destroy(collection);
  1160     nssSlotArray_Destroy(slots);
  1161     return rvCRLs;
  1164 NSS_IMPLEMENT PRStatus
  1165 NSSTrustDomain_GenerateKeyPair (
  1166   NSSTrustDomain *td,
  1167   NSSAlgorithmAndParameters *ap,
  1168   NSSPrivateKey **pvkOpt,
  1169   NSSPublicKey **pbkOpt,
  1170   PRBool privateKeyIsSensitive,
  1171   NSSToken *destination,
  1172   NSSCallback *uhhOpt
  1175     nss_SetError(NSS_ERROR_NOT_FOUND);
  1176     return PR_FAILURE;
  1179 NSS_IMPLEMENT NSSSymmetricKey *
  1180 NSSTrustDomain_GenerateSymmetricKey (
  1181   NSSTrustDomain *td,
  1182   NSSAlgorithmAndParameters *ap,
  1183   PRUint32 keysize,
  1184   NSSToken *destination,
  1185   NSSCallback *uhhOpt
  1188     nss_SetError(NSS_ERROR_NOT_FOUND);
  1189     return NULL;
  1192 NSS_IMPLEMENT NSSSymmetricKey *
  1193 NSSTrustDomain_GenerateSymmetricKeyFromPassword (
  1194   NSSTrustDomain *td,
  1195   NSSAlgorithmAndParameters *ap,
  1196   NSSUTF8 *passwordOpt, /* if null, prompt */
  1197   NSSToken *destinationOpt,
  1198   NSSCallback *uhhOpt
  1201     nss_SetError(NSS_ERROR_NOT_FOUND);
  1202     return NULL;
  1205 NSS_IMPLEMENT NSSSymmetricKey *
  1206 NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID (
  1207   NSSTrustDomain *td,
  1208   NSSOID *algorithm,
  1209   NSSItem *keyID,
  1210   NSSCallback *uhhOpt
  1213     nss_SetError(NSS_ERROR_NOT_FOUND);
  1214     return NULL;
  1217 NSS_IMPLEMENT NSSCryptoContext *
  1218 nssTrustDomain_CreateCryptoContext (
  1219   NSSTrustDomain *td,
  1220   NSSCallback *uhhOpt
  1223     return nssCryptoContext_Create(td, uhhOpt);
  1226 NSS_IMPLEMENT NSSCryptoContext *
  1227 NSSTrustDomain_CreateCryptoContext (
  1228   NSSTrustDomain *td,
  1229   NSSCallback *uhhOpt
  1232     return nssTrustDomain_CreateCryptoContext(td, uhhOpt);
  1235 NSS_IMPLEMENT NSSCryptoContext *
  1236 NSSTrustDomain_CreateCryptoContextForAlgorithm (
  1237   NSSTrustDomain *td,
  1238   NSSOID *algorithm
  1241     nss_SetError(NSS_ERROR_NOT_FOUND);
  1242     return NULL;
  1245 NSS_IMPLEMENT NSSCryptoContext *
  1246 NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters (
  1247   NSSTrustDomain *td,
  1248   NSSAlgorithmAndParameters *ap
  1251     nss_SetError(NSS_ERROR_NOT_FOUND);
  1252     return NULL;

mercurial