NS_IMETHODIMP nsNSSCertificate::GetAllTokenNames(uint32_t *aLength, PRUnichar*** aTokenNames) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; NS_ENSURE_ARG(aLength); NS_ENSURE_ARG(aTokenNames); *aLength = 0; *aTokenNames = NULL; /* Get the slots from NSS */ PK11SlotList *slots = NULL; PK11SlotListCleaner slotCleaner(slots); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting slots for \"%s\"\n", mCert->nickname)); slots = PK11_GetAllSlotsForCert(mCert, NULL); if (!slots) { if (PORT_GetError() == SEC_ERROR_NO_TOKEN) return NS_OK; // List of slots is empty, return empty array else return NS_ERROR_FAILURE; } /* read the token names from slots */ PK11SlotListElement *le; for (le = slots->head; le; le = le->next) { ++(*aLength); } *aTokenNames = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * (*aLength)); if (!*aTokenNames) { *aLength = 0; return NS_ERROR_OUT_OF_MEMORY; } uint32_t iToken; for (le = slots->head, iToken = 0; le; le = le->next, ++iToken) { char *token = PK11_GetTokenName(le->slot); (*aTokenNames)[iToken] = ToNewUnicode(NS_ConvertUTF8toUTF16(token)); if (!(*aTokenNames)[iToken]) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iToken, *aTokenNames); *aLength = 0; *aTokenNames = NULL; return NS_ERROR_OUT_OF_MEMORY; } } return NS_OK; }
void nsNSSCertificateDB::get_default_nickname(CERTCertificate *cert, nsIInterfaceRequestor* ctx, nsCString &nickname) { nickname.Truncate(); nsNSSShutDownPreventionLock locker; nsresult rv; CK_OBJECT_HANDLE keyHandle; CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB(); nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv)); if (NS_FAILED(rv)) return; nsCAutoString username; char *temp_un = CERT_GetCommonName(&cert->subject); if (temp_un) { username = temp_un; PORT_Free(temp_un); temp_un = nsnull; } nsCAutoString caname; char *temp_ca = CERT_GetOrgName(&cert->issuer); if (temp_ca) { caname = temp_ca; PORT_Free(temp_ca); temp_ca = nsnull; } nsAutoString tmpNickFmt; nssComponent->GetPIPNSSBundleString("nick_template", tmpNickFmt); NS_ConvertUTF16toUTF8 nickFmt(tmpNickFmt); nsCAutoString baseName; char *temp_nn = PR_smprintf(nickFmt.get(), username.get(), caname.get()); if (!temp_nn) { return; } else { baseName = temp_nn; PR_smprintf_free(temp_nn); temp_nn = nsnull; } nickname = baseName; /* * We need to see if the private key exists on a token, if it does * then we need to check for nicknames that already exist on the smart * card. */ PK11SlotInfo *slot = PK11_KeyForCertExists(cert, &keyHandle, ctx); PK11SlotInfoCleaner slotCleaner(slot); if (!slot) return; if (!PK11_IsInternal(slot)) { char *tmp = PR_smprintf("%s:%s", PK11_GetTokenName(slot), baseName.get()); if (!tmp) { nickname.Truncate(); return; } baseName = tmp; PR_smprintf_free(tmp); nickname = baseName; } int count = 1; while (true) { if ( count > 1 ) { char *tmp = PR_smprintf("%s #%d", baseName.get(), count); if (!tmp) { nickname.Truncate(); return; } nickname = tmp; PR_smprintf_free(tmp); } CERTCertificate *dummycert = nsnull; CERTCertificateCleaner dummycertCleaner(dummycert); if (PK11_IsInternal(slot)) { /* look up the nickname to make sure it isn't in use already */ dummycert = CERT_FindCertByNickname(defaultcertdb, nickname.get()); } else { /* * Check the cert against others that already live on the smart * card. */ dummycert = PK11_FindCertFromNickname(nickname.get(), ctx); if (dummycert != NULL) { /* * Make sure the subject names are different. */ if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual) { /* * There is another certificate with the same nickname and * the same subject name on the smart card, so let's use this * nickname. */ CERT_DestroyCertificate(dummycert); dummycert = NULL; } } } if (!dummycert) break; count++; } }