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++; } }
nsresult GetSlotWithMechanism(uint32_t aMechanism, nsIInterfaceRequestor *m_ctx, PK11SlotInfo** aSlot) { nsNSSShutDownPreventionLock locker; PK11SlotList * slotList = nullptr; char16_t** tokenNameList = nullptr; nsITokenDialogs * dialogs; char16_t *unicodeTokenChosen; PK11SlotListElement *slotElement, *tmpSlot; uint32_t numSlots = 0, i = 0; bool canceled; nsresult rv = NS_OK; *aSlot = nullptr; // Get the slot slotList = PK11_GetAllTokens(MapGenMechToAlgoMech(aMechanism), true, true, m_ctx); if (!slotList || !slotList->head) { rv = NS_ERROR_FAILURE; goto loser; } if (!slotList->head->next) { /* only one slot available, just return it */ *aSlot = slotList->head->slot; } else { // Gerenate a list of slots and ask the user to choose // tmpSlot = slotList->head; while (tmpSlot) { numSlots++; tmpSlot = tmpSlot->next; } // Allocate the slot name buffer // tokenNameList = static_cast<char16_t**>(nsMemory::Alloc(sizeof(char16_t *) * numSlots)); if (!tokenNameList) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; } i = 0; slotElement = PK11_GetFirstSafe(slotList); while (slotElement) { tokenNameList[i] = UTF8ToNewUnicode(nsDependentCString(PK11_GetTokenName(slotElement->slot))); slotElement = PK11_GetNextSafe(slotList, slotElement, false); if (tokenNameList[i]) i++; else { // OOM. adjust numSlots so we don't free unallocated memory. numSlots = i; PK11_FreeSlotListElement(slotList, slotElement); rv = NS_ERROR_OUT_OF_MEMORY; goto loser; } } /* Throw up the token list dialog and get back the token */ rv = getNSSDialogs((void**)&dialogs, NS_GET_IID(nsITokenDialogs), NS_TOKENDIALOGS_CONTRACTID); if (NS_FAILED(rv)) goto loser; { nsPSMUITracker tracker; if (!tokenNameList || !*tokenNameList) { rv = NS_ERROR_OUT_OF_MEMORY; } else if (tracker.isUIForbidden()) { rv = NS_ERROR_NOT_AVAILABLE; } else { rv = dialogs->ChooseToken(m_ctx, (const char16_t**)tokenNameList, numSlots, &unicodeTokenChosen, &canceled); } } NS_RELEASE(dialogs); if (NS_FAILED(rv)) goto loser; if (canceled) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; } // Get the slot // slotElement = PK11_GetFirstSafe(slotList); nsAutoString tokenStr(unicodeTokenChosen); while (slotElement) { if (tokenStr.Equals(NS_ConvertUTF8toUTF16(PK11_GetTokenName(slotElement->slot)))) { *aSlot = slotElement->slot; PK11_FreeSlotListElement(slotList, slotElement); break; } slotElement = PK11_GetNextSafe(slotList, slotElement, false); } if(!(*aSlot)) { rv = NS_ERROR_FAILURE; goto loser; } } // Get a reference to the slot // PK11_ReferenceSlot(*aSlot); loser: if (slotList) { PK11_FreeSlotList(slotList); } if (tokenNameList) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(numSlots, tokenNameList); } return rv; }
/* Returns the password passed in in the text file. * Uses the password once and nulls it out to prevent * PKCS11 from calling us forever. */ static char *GetFilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) { char* phrases, *phrase; PRFileDesc *fd; PRInt32 nb; const char *pwFile = (const char *)arg; int i; const long maxPwdFileSize = 4096; char* tokenName = NULL; int tokenLen = 0; if (!pwFile) return 0; if (retry) return 0; /* no good retrying - the files contents will be the same */ phrases = PORT_ZAlloc(maxPwdFileSize); if (!phrases) return 0; /* out of memory */ fd = PR_Open(pwFile, PR_RDONLY, 0); if (!fd) { fprintf(stderr, "%s: No password file \"%s\" exists.\n", me, pwFile); PORT_Free(phrases); return NULL; } nb = PR_Read(fd, phrases, maxPwdFileSize); PR_Close(fd); if (nb == 0) { fprintf(stderr, "%s: password file contains no data\n", me); PORT_Free(phrases); return NULL; } if (slot) { tokenName = PK11_GetTokenName(slot); if (tokenName) tokenLen = PORT_Strlen(tokenName); } i = 0; do { int startphrase = i; int phraseLen; /* handle the Windows EOL case */ while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++; /* terminate passphrase */ phrases[i++] = '\0'; /* clean up any EOL before the start of the next passphrase */ while ( (i < nb) && (phrases[i] == '\r' || phrases[i] == '\n')) phrases[i++] = '\0'; /* now analyze the current passphrase */ phrase = &phrases[startphrase]; if (!tokenName) break; if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue; phraseLen = PORT_Strlen(phrase); if (phraseLen < (tokenLen + 1)) continue; if (phrase[tokenLen] != ':') continue; phrase = &phrase[tokenLen + 1]; break; } while (i < nb); phrase = PORT_Strdup((char*)phrase); PORT_Free(phrases); return phrase; }
/* * generate an RSA signature key * * e is fixed at 3, without discussion. That would not be wise if these * keys were to be used for encryption, but for signatures there are some * real speed advantages. * See also: https://www.imperialviolet.org/2012/03/16/rsae.html */ void rsasigkey(int nbits, char *configdir, char *password) { SECStatus rv; PK11RSAGenParams rsaparams = { nbits, (long) E }; secuPWData pwdata = { PW_NONE, NULL }; PK11SlotInfo *slot = NULL; SECKEYPrivateKey *privkey = NULL; SECKEYPublicKey *pubkey = NULL; unsigned char *bundp = NULL; mpz_t n; mpz_t e; size_t bs; char n_str[3 + MAXBITS / 4 + 1]; realtime_t now = realnow(); mpz_init(n); mpz_init(e); if (password == NULL) { pwdata.source = PW_NONE; } else { /* check if passwd == configdir/nsspassword */ size_t cdl = strlen(configdir); size_t pwl = strlen(password); static const char suf[] = "/nsspassword"; if (pwl == cdl + sizeof(suf) - 1 && memeq(password, configdir, cdl) && memeq(password + cdl, suf, sizeof(suf))) pwdata.source = PW_FROMFILE; else pwdata.source = PW_PLAINTEXT; } pwdata.data = password; PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1); rv = NSS_InitReadWrite(configdir); if (rv != SECSuccess) { fprintf(stderr, "%s: NSS_InitReadWrite(%s) returned %d\n", me, configdir, PR_GetError()); exit(1); } #ifdef FIPS_CHECK if (PK11_IsFIPS() && !FIPSCHECK_verify(NULL, NULL)) { fprintf(stderr, "FIPS HMAC integrity verification test failed.\n"); exit(1); } #endif if (PK11_IsFIPS() && !password) { fprintf(stderr, "%s: On FIPS mode a password is required\n", me); exit(1); } PK11_SetPasswordFunc(GetModulePassword); /* Good for now but someone may want to use a hardware token */ slot = PK11_GetInternalKeySlot(); /* In which case this may be better */ /* slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, password ? &pwdata : NULL); */ /* or the user may specify the name of a token. */ #if 0 if (PK11_IsFIPS() || !PK11_IsInternal(slot)) { rv = PK11_Authenticate(slot, PR_FALSE, &pwdata); if (rv != SECSuccess) { fprintf(stderr, "%s: could not authenticate to token '%s'\n", me, PK11_GetTokenName(slot)); return; } } #endif /* 0 */ /* Do some random-number initialization. */ UpdateNSS_RNG(); /* Log in to the token */ if (password) { rv = PK11_Authenticate(slot, PR_FALSE, &pwdata); if (rv != SECSuccess) { fprintf(stderr, "%s: could not authenticate to token '%s'\n", me, PK11_GetTokenName(slot)); return; } } privkey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaparams, &pubkey, PR_TRUE, password ? PR_TRUE : PR_FALSE, &pwdata); /* inTheToken, isSensitive, passwordCallbackFunction */ if (!privkey) { fprintf(stderr, "%s: key pair generation failed: \"%d\"\n", me, PORT_GetError()); return; } /*privkey->wincx = &pwdata;*/ PORT_Assert(pubkey != NULL); fprintf(stderr, "Generated RSA key pair using the NSS database\n"); SECItemToHex(getModulus(pubkey), n_str); assert(!mpz_set_str(n, n_str, 16)); /* and the output */ report("output...\n"); /* deliberate extra newline */ printf("\t# RSA %d bits %s %s", nbits, outputhostname, ctime(&now.real_secs)); /* ctime provides \n */ printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n"); bundp = bundle(E, n, &bs); printf("\t#pubkey=%s\n", conv(bundp, bs, 's')); /* RFC2537ish format */ printf("\tModulus: %s\n", hexOut(getModulus(pubkey))); printf("\tPublicExponent: %s\n", hexOut(getPublicExponent(pubkey))); SECItem *ckaID = PK11_MakeIDFromPubKey(getModulus(pubkey)); if (ckaID != NULL) { printf("\t# everything after this point is CKA_ID in hex format - not the real values \n"); printf("\tPrivateExponent: %s\n", hexOut(ckaID)); printf("\tPrime1: %s\n", hexOut(ckaID)); printf("\tPrime2: %s\n", hexOut(ckaID)); printf("\tExponent1: %s\n", hexOut(ckaID)); printf("\tExponent2: %s\n", hexOut(ckaID)); printf("\tCoefficient: %s\n", hexOut(ckaID)); printf("\tCKAIDNSS: %s\n", hexOut(ckaID)); SECITEM_FreeItem(ckaID, PR_TRUE); } if (privkey) SECKEY_DestroyPrivateKey(privkey); if (pubkey) SECKEY_DestroyPublicKey(pubkey); (void) NSS_Shutdown(); (void) PR_Cleanup(); }
char* PR_CALLBACK PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) { nsNSSShutDownPreventionLock locker; nsresult rv = NS_OK; PRUnichar *password = nsnull; PRBool value = PR_FALSE; nsIInterfaceRequestor *ir = static_cast<nsIInterfaceRequestor*>(arg); nsCOMPtr<nsIPrompt> proxyPrompt; /* TODO: Retry should generate a different dialog message */ /* if (retry) return nsnull; */ if (!ir) { nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); if (!wwatch) return nsnull; nsCOMPtr<nsIPrompt> prompter; wwatch->GetNewPrompter(0, getter_AddRefs(prompter)); if (!prompter) return nsnull; NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIPrompt), prompter, NS_PROXY_SYNC, getter_AddRefs(proxyPrompt)); if (!proxyPrompt) return nsnull; } else { // The interface requestor object may not be safe, so // proxy the call to get the nsIPrompt. nsCOMPtr<nsIInterfaceRequestor> proxiedCallbacks; NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIInterfaceRequestor), ir, NS_PROXY_SYNC, getter_AddRefs(proxiedCallbacks)); // Get the desired interface nsCOMPtr<nsIPrompt> prompt(do_GetInterface(proxiedCallbacks)); if (!prompt) { NS_ASSERTION(PR_FALSE, "callbacks does not implement nsIPrompt"); return nsnull; } // Finally, get a proxy for the nsIPrompt NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIPrompt), prompt, NS_PROXY_SYNC, getter_AddRefs(proxyPrompt)); } if (PK11_ProtectedAuthenticationPath(slot)) return ShowProtectedAuthPrompt(slot, ir); nsAutoString promptString; nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv)); if (NS_FAILED(rv)) return nsnull; const PRUnichar* formatStrings[1] = { ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(slot))) }; rv = nssComponent->PIPBundleFormatStringFromName("CertPassPrompt", formatStrings, 1, promptString); nsMemory::Free(const_cast<PRUnichar*>(formatStrings[0])); if (NS_FAILED(rv)) return nsnull; { nsPSMUITracker tracker; if (tracker.isUIForbidden()) { rv = NS_ERROR_NOT_AVAILABLE; } else { rv = proxyPrompt->PromptPassword(nsnull, promptString.get(), &password, nsnull, nsnull, &value); } } if (NS_SUCCEEDED(rv) && value) { char* str = ToNewUTF8String(nsDependentString(password)); NS_Free(password); return str; } return nsnull; }
/************************************************************************* * * S e t D e f a u l t M o d u l e * */ Error SetDefaultModule(char *moduleName, char *slotName, char *mechanisms) { SECMODModule *module = NULL; PK11SlotInfo *slot; int s, i; unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings, numMechanismStrings); PRBool found = PR_FALSE; Error errcode = UNSPECIFIED_ERR; mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags); module = SECMOD_FindModule(moduleName); if (!module) { PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName); errcode = NO_SUCH_MODULE_ERR; goto loser; } /* Go through each slot */ for (s = 0; s < module->slotCount; s++) { slot = module->slots[s]; if ((slotName != NULL) && !((strcmp(PK11_GetSlotName(slot), slotName) == 0) || (strcmp(PK11_GetTokenName(slot), slotName) == 0))) { /* we are only interested in changing the one slot */ continue; } found = PR_TRUE; /* Go through each mechanism */ for (i = 0; i < pk11_DefaultArraySize; i++) { if (pk11_DefaultArray[i].flag & mechFlags) { /* Enable this default mechanism */ PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]), PR_TRUE); } } } if (slotName && !found) { PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName); errcode = NO_SUCH_SLOT_ERR; goto loser; } /* Delete and re-add module to save changes */ if (SECMOD_UpdateModule(module) != SECSuccess) { PR_fprintf(PR_STDERR, errStrings[DEFAULT_FAILED_ERR], moduleName); errcode = DEFAULT_FAILED_ERR; goto loser; } PR_fprintf(PR_STDOUT, msgStrings[DEFAULT_SUCCESS_MSG]); errcode = SUCCESS; loser: if (module) { SECMOD_DestroyModule(module); } return errcode; }
/*********************************************************************** * * L i s t M o d u l e * * Lists detailed information about the named module. */ Error ListModule(char *moduleName) { SECMODModule *module = NULL; PK11SlotInfo *slot; int slotnum; CK_INFO modinfo; CK_SLOT_INFO slotinfo; CK_TOKEN_INFO tokeninfo; char *ciphers, *mechanisms; size_t reasonIdx; Error rv = SUCCESS; if (!moduleName) { return SUCCESS; } module = SECMOD_FindModule(moduleName); if (!module) { PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName); rv = NO_SUCH_MODULE_ERR; goto loser; } if ((module->loaded) && (PK11_GetModInfo(module, &modinfo) != SECSuccess)) { PR_fprintf(PR_STDERR, errStrings[MOD_INFO_ERR], moduleName); rv = MOD_INFO_ERR; goto loser; } /* Module info */ PR_fprintf(PR_STDOUT, "\n-----------------------------------------------------------\n"); PR_fprintf(PR_STDOUT, "Name: %s\n", module->commonName); if (module->internal || !module->dllName) { PR_fprintf(PR_STDOUT, "Library file: **Internal ONLY module**\n"); } else { PR_fprintf(PR_STDOUT, "Library file: %s\n", module->dllName); } if (module->loaded) { PR_fprintf(PR_STDOUT, "Manufacturer: %.32s\n", modinfo.manufacturerID); PR_fprintf(PR_STDOUT, "Description: %.32s\n", modinfo.libraryDescription); PR_fprintf(PR_STDOUT, "PKCS #11 Version %d.%d\n", modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor); PR_fprintf(PR_STDOUT, "Library Version: %d.%d\n", modinfo.libraryVersion.major, modinfo.libraryVersion.minor); } else { PR_fprintf(PR_STDOUT, "* Module not loaded\n"); } /* Get cipher and mechanism flags */ ciphers = getStringFromFlags(module->ssl[0], cipherStrings, numCipherStrings); if (ciphers[0] == '\0') { ciphers = "None"; } PR_fprintf(PR_STDOUT, "Cipher Enable Flags: %s\n", ciphers); mechanisms = NULL; if (module->slotCount > 0) { mechanisms = getStringFromFlags( PK11_GetDefaultFlags(module->slots[0]), mechanismStrings, numMechanismStrings); } if ((mechanisms == NULL) || (mechanisms[0] == '\0')) { mechanisms = "None"; } PR_fprintf(PR_STDOUT, "Default Mechanism Flags: %s\n", mechanisms); #define PAD " " /* Loop over each slot */ for (slotnum = 0; slotnum < module->slotCount; slotnum++) { slot = module->slots[slotnum]; if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) { PR_fprintf(PR_STDERR, errStrings[SLOT_INFO_ERR], PK11_GetSlotName(slot)); rv = SLOT_INFO_ERR; continue; } /* Slot Info */ PR_fprintf(PR_STDOUT, "\n" PAD "Slot: %s\n", PK11_GetSlotName(slot)); mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot), mechanismStrings, numMechanismStrings); if (mechanisms[0] == '\0') { mechanisms = "None"; } PR_fprintf(PR_STDOUT, PAD "Slot Mechanism Flags: %s\n", mechanisms); PR_fprintf(PR_STDOUT, PAD "Manufacturer: %.32s\n", slotinfo.manufacturerID); if (PK11_IsHW(slot)) { PR_fprintf(PR_STDOUT, PAD "Type: Hardware\n"); } else { PR_fprintf(PR_STDOUT, PAD "Type: Software\n"); } PR_fprintf(PR_STDOUT, PAD "Version Number: %d.%d\n", slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor); PR_fprintf(PR_STDOUT, PAD "Firmware Version: %d.%d\n", slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor); if (PK11_IsDisabled(slot)) { reasonIdx = PK11_GetDisabledReason(slot); if (reasonIdx < numDisableReasonStr) { PR_fprintf(PR_STDOUT, PAD "Status: DISABLED (%s)\n", disableReasonStr[reasonIdx]); } else { PR_fprintf(PR_STDOUT, PAD "Status: DISABLED\n"); } } else { PR_fprintf(PR_STDOUT, PAD "Status: Enabled\n"); } if (PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) { PR_fprintf(PR_STDERR, errStrings[TOKEN_INFO_ERR], PK11_GetTokenName(slot)); rv = TOKEN_INFO_ERR; continue; } /* Token Info */ PR_fprintf(PR_STDOUT, PAD "Token Name: %.32s\n", tokeninfo.label); PR_fprintf(PR_STDOUT, PAD "Token Manufacturer: %.32s\n", tokeninfo.manufacturerID); PR_fprintf(PR_STDOUT, PAD "Token Model: %.16s\n", tokeninfo.model); PR_fprintf(PR_STDOUT, PAD "Token Serial Number: %.16s\n", tokeninfo.serialNumber); PR_fprintf(PR_STDOUT, PAD "Token Version: %d.%d\n", tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor); PR_fprintf(PR_STDOUT, PAD "Token Firmware Version: %d.%d\n", tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor); if (tokeninfo.flags & CKF_WRITE_PROTECTED) { PR_fprintf(PR_STDOUT, PAD "Access: Write Protected\n"); } else { PR_fprintf(PR_STDOUT, PAD "Access: NOT Write Protected\n"); } if (tokeninfo.flags & CKF_LOGIN_REQUIRED) { PR_fprintf(PR_STDOUT, PAD "Login Type: Login required\n"); } else { PR_fprintf(PR_STDOUT, PAD "Login Type: Public (no login required)\n"); } if (tokeninfo.flags & CKF_USER_PIN_INITIALIZED) { PR_fprintf(PR_STDOUT, PAD "User Pin: Initialized\n"); } else { PR_fprintf(PR_STDOUT, PAD "User Pin: NOT Initialized\n"); } } PR_fprintf(PR_STDOUT, "\n-----------------------------------------------------------\n"); loser: if (module) { SECMOD_DestroyModule(module); } return rv; }
// // This is the main loop. // void SmartCardMonitoringThread::Execute() { PK11SlotInfo *slot; const char *tokenName = nsnull; // // populate token names for already inserted tokens. // PK11SlotList *sl = PK11_FindSlotsByNames(mModule->dllName, nsnull, nsnull, true); PK11SlotListElement *sle; if (sl) { for (sle=PK11_GetFirstSafe(sl); sle; sle=PK11_GetNextSafe(sl,sle,false)) { SetTokenName(PK11_GetSlotID(sle->slot), PK11_GetTokenName(sle->slot), PK11_GetSlotSeries(sle->slot)); } PK11_FreeSlotList(sl); } // loop starts.. do { slot = SECMOD_WaitForAnyTokenEvent(mModule, 0, PR_SecondsToInterval(1) ); if (slot == nsnull) { break; } // now we have a potential insertion or removal event, see if the slot // is present to determine which it is... if (PK11_IsPresent(slot)) { // insertion CK_SLOT_ID slotID = PK11_GetSlotID(slot); PRUint32 series = PK11_GetSlotSeries(slot); // skip spurious insertion events... if (series != GetTokenSeries(slotID)) { // if there's a token name, then we have not yet issued a remove // event for the previous token, do so now... tokenName = GetTokenName(slotID); if (tokenName) { SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName); } tokenName = PK11_GetTokenName(slot); // save the token name and series SetTokenName(slotID, tokenName, series); SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_INSERT), tokenName); } } else { // retrieve token name CK_SLOT_ID slotID = PK11_GetSlotID(slot); tokenName = GetTokenName(slotID); // if there's not a token name, then the software isn't expecting // a (or another) remove event. if (tokenName) { SendEvent(NS_LITERAL_STRING(SMARTCARDEVENT_REMOVE), tokenName); // clear the token name (after we send it) SetTokenName(slotID, nsnull, 0); } } PK11_FreeSlot(slot); } while (1); }
char *getNSSPassword(PK11SlotInfo *slot, PRBool retry, void *arg) { secuPWData *pwdInfo = (secuPWData *)arg; PRFileDesc *fd; PRInt32 nb; /*number of bytes*/ char* password; char* strings; char* token=NULL; const long maxPwdFileSize = NSSpwdfilesize; int i, tlen=0; if (slot) { token = PK11_GetTokenName(slot); if (token) { tlen = PORT_Strlen(token); /* libreswan_log("authentication needed for token name %s with length %d",token,tlen); */ } else { return 0; } } else { return 0; } if(retry) return 0; strings=PORT_ZAlloc(maxPwdFileSize); if(!strings) { libreswan_log("Not able to allocate memory for reading NSS password file"); return 0; } if(pwdInfo->source == PW_FROMFILE) { if(pwdInfo->data !=NULL) { fd = PR_Open(pwdInfo->data, PR_RDONLY, 0); if (!fd) { PORT_Free(strings); libreswan_log("No password file \"%s\" exists.", pwdInfo->data); return 0; } nb = PR_Read(fd, strings, maxPwdFileSize); PR_Close(fd); if (nb == 0) { libreswan_log("password file contains no data"); PORT_Free(strings); return 0; } i = 0; do { int start = i; int slen; while (strings[i] != '\r' && strings[i] != '\n' && i < nb) i++; strings[i++] = '\0'; while ( (i<nb) && (strings[i] == '\r' || strings[i] == '\n')) { strings[i++] = '\0'; } password = &strings[start]; if (PORT_Strncmp(password, token, tlen)) continue; slen = PORT_Strlen(password); if (slen < (tlen+1)) continue; if (password[tlen] != ':') continue; password = &password[tlen+1]; break; } while (i<nb); password = PORT_Strdup((char*)password); PORT_Free(strings); /* libreswan_log("Password passed to NSS is %s with length %d", password, PORT_Strlen(password)); */ return password; } else { libreswan_log("File with Password to NSS DB is not provided"); return 0; } } libreswan_log("nss password source is not specified as file"); return 0; }