nssCertificateList_DoCallback(certList, token_callback, &token_cb);
PK11_FindCertFromNickname(char *nickname, void *wincx) {#ifdef NSS_CLASSIC    PK11SlotInfo *slot;    int count=0;    CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot,				 		CKO_CERTIFICATE, &count, wincx);    CERTCertificate *cert;    if (certID == CK_INVALID_HANDLE) return NULL;    cert = PK11_MakeCertFromHandle(slot,certID[0],NULL);    PK11_FreeSlot(slot);    PORT_Free(certID);    return cert;#else    CERTCertificate *rvCert = NULL;    NSSCertificate *cert = NULL;    NSSUsage usage;    NSSToken *token;    PK11SlotInfo *slot = NULL;    char *nickCopy;    char *delimit = NULL;    char *tokenName;    NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();    usage.anyUsage = PR_TRUE;    nickCopy = PORT_Strdup(nickname);    if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) {	tokenName = nickCopy;	nickname = delimit + 1;	*delimit = '\0';	/* find token by name */	token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);	if (token) {		slot = PK11_ReferenceSlot(token->pk11slot);	}	*delimit = ':';    } else {	slot = PK11_GetInternalKeySlot();	token = PK11Slot_GetNSSToken(slot);    }    if (token) {	nssTokenCertSearch search;	struct token_cbstr token_cb;	nssList *certList;	if (!PK11_IsFriendly(slot)) {	    if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {		PK11_FreeSlot(slot);		return NULL;	    }	}	/* find best cert on token */	if (!nssToken_SearchCerts(token, NULL)) {	    /* token certs are in cache, filter the list of token certs to	     * match the nickname	     */	    certList = filter_token_certs_nickname(token, nickname);	    if (certList) {		nssCertificateList_DoCallback(certList, 		                              get_newest_cert, 		                              (void *)&cert);	    }	} else {	    /* find matching certs on the token */	    certList = nssList_Create(NULL, PR_FALSE);	    if (!certList) return NULL;	    /* first, get all matching certs from the cache */	    (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, 	                                                      nickname, 	                                                      certList);	    /* set the search criteria */	    token_cb.callback = get_newest_cert;	    token_cb.cbarg = (void *)&cert;	    token_cb.token = token;	    search.callback = token_callback;	    search.cbarg = &token_cb;	    search.cached = certList;	    search.searchType = nssTokenSearchType_TokenOnly;	    /* then filter the list of cached certs for only those on the	     * token	     */	    nssCertificateList_DoCallback(certList, 	                                  token_callback, 	                                  &token_cb);	    /* now search the token */	    nssToken_TraverseCertificatesByNickname(token, NULL, 	                                            (NSSUTF8 *)nickname,	                                            &search);	}	if (certList) {	    nssList_Clear(certList, cert_destructor);	    nssList_Destroy(certList);	}	/* if it wasn't found, repeat the process for email address */	if (!cert) {	    if (!nssToken_SearchCerts(token, NULL)) {		certList = filter_token_certs_email(token, nickname);		if (certList) {		    nssCertificateList_DoCallback(certList, 		                                  get_newest_cert, 		                                  (void *)&cert);		}	    } else {		certList = nssList_Create(NULL, PR_FALSE);		if (!certList) return NULL;		(void)nssTrustDomain_GetCertsForEmailAddressFromCache(		                                                  defaultTD, 	                                                          nickname, 	                                                          certList);		search.cached = certList;		nssCertificateList_DoCallback(certList, 		                              token_callback,		                              &token_cb);		nssToken_TraverseCertificatesByEmail(token, NULL, 		                                     (NSSASCII7 *)nickname,		                                     &search);	    }	    if (certList) {		nssList_Clear(certList, cert_destructor);		nssList_Destroy(certList);	    }	}	if (cert) {	    (void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1);	    rvCert = STAN_GetCERTCertificate(cert);	}    }    if (slot) {	PK11_FreeSlot(slot);    }    if (nickCopy) PORT_Free(nickCopy);    return rvCert;#endif}