void *getNativeWindowHandle(PluginInstance *obj) { void *nativeWindowHandle = obj->nativeWindowHandle; #ifdef _WIN32 EstEID_log("_WIN32 detected, forcing nativeWindowHandle query from browser"); nativeWindowHandle = 0; #endif if (!nativeWindowHandle) { browserFunctions->getvalue(obj->npp, NPNVnetscapeWindow, &nativeWindowHandle); EstEID_log("reading nativeWindowHandle=%p from browserFunctions", nativeWindowHandle); } else { EstEID_log("reading nativeWindowHandle=%p from PluginInstance", nativeWindowHandle); } return nativeWindowHandle; }
int EstEID_getSlotId(char* certId, CK_SLOT_ID* slotId) { int certIndex; EstEID_Certs *certs = EstEID_loadCerts(); EstEID_log("certs loaded"); if (!certs) { EstEID_log("%s", EstEID_error); return FALSE; } else if ((certIndex = EstEID_findNonRepuditionCert(certs, certId)) == NOT_FOUND) { EstEID_log("card is changed"); return FALSE; } *slotId = certs->slotIDs[certIndex]; return TRUE; }
void CEstEIDCertificate::readFromCertContext() { LOG_LOCATION; PCCERT_CONTEXT pCertContext = NULL; HCERTSTORE hCertStore = NULL; CRYPTUI_SELECTCERTIFICATE_STRUCT sel = {sizeof(sel)}; int counter = 0; hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY"); if(!hCertStore){ throw CryptoException(); } sel.pvCallbackData = &counter; sel.pFilterCallback = filter_proc; sel.rghDisplayStores = &hCertStore; sel.cDisplayStores = 1; #ifdef _SEB_BUILD EstEID_log("SEB build"); PCCERT_CONTEXT pCertContextForEnumeration = NULL; int certificatesCount = 0; while(pCertContextForEnumeration = CertEnumCertificatesInStore(hCertStore, pCertContextForEnumeration)) { if(isValidForSigning(pCertContextForEnumeration)) { certificatesCount++; pCertContext = pCertContextForEnumeration; } } EstEID_log("Certificates count %i", certificatesCount); if(certificatesCount != 1) { pCertContext = CryptUIDlgSelectCertificate(&sel); } #else pCertContext = CryptUIDlgSelectCertificate(&sel); #endif if(!pCertContext) { EstEID_log("User didn't select sertificate"); throw CryptoException(ESTEID_USER_CANCEL); } loadCertContexts(pCertContext); if(pCertContext){ CertFreeCertificateContext(pCertContext); } if(hCertStore) { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); } }
void EstEID_logInitInfo(CK_INFO info) { char *libraryDescription = EstEID_createString(info.libraryDescription, 32); char *manufacturerID = EstEID_createString(info.manufacturerID, 32); EstEID_log("cryptoki %i.%i, library %i.%i %s, %s", info.cryptokiVersion.major, info.cryptokiVersion.minor, info.libraryVersion.major, info.libraryVersion.minor, libraryDescription, manufacturerID); free(libraryDescription); free(manufacturerID); }
int EstEID_isPinPad(CK_SLOT_ID slotID) { CK_TOKEN_INFO tokenInfo; if (EstEID_CK_failure("C_GetTokenInfo", fl->C_GetTokenInfo(slotID, &tokenInfo))) return 0; EstEID_log("flags: %li (%lx)", tokenInfo.flags, tokenInfo.flags); if (tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) return 1; else return 0; }
THREAD_RETURN_TYPE EstEID_pinPadLogin(void* threadData) { #ifndef _WIN32 LOG_LOCATION; pthread_mutex_lock(&pinpad_thread_mutex); CK_SESSION_HANDLE session = ((EstEID_PINPadThreadData*)threadData)->session; CK_RV loginResult = fl->C_Login(session, CKU_USER, NULL, 0); ((EstEID_PINPadThreadData*)threadData)->result = loginResult; closePinPadModalSheet(); EstEID_log("modal sheet/dialog destroyed"); pinpad_thread_completed = TRUE; pthread_cond_broadcast(&pinpad_thread_condition); pthread_mutex_unlock(&pinpad_thread_mutex); pthread_exit(NULL); #else EstEID_PINPromptDataEx* pinPromptDataEx; LOG_LOCATION; WaitForSingleObject(pinpad_thread_mutex, INFINITE); pinPromptDataEx = (EstEID_PINPromptDataEx*)threadData; pinPromptDataEx->pinPromptData.promptFunction(NULL, pinPromptDataEx->name, pinPromptDataEx->message, 0, TRUE); ReleaseMutex(pinpad_thread_mutex); return TRUE; #endif }
void EstEID_logBase64(char *message, char* data, int dataLength) { char *base64; LOG_LOCATION; base64 = EstEID_base64Encode(data, dataLength); EstEID_log(message, base64); free(base64); }
INT_PTR CALLBACK PinPadDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: dialogWindowHandle = hwnd; SetPinDialogLabels(dialogWindowHandle, lParam); SetDialogItemText(hwnd, IDC_PINPAD_PIN2_LABEL, l10n("For signing enter PIN2 from PIN pad")); countdownValue = 30; // in seconds EstEID_log("initializing pinpad countdown timer with value %i", countdownValue); SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0L); SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETRANGE, 0, MAKELPARAM(0, countdownValue)); UpdateProgerssBar(dialogWindowHandle, countdownValue); SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0L); SetTimer(dialogWindowHandle, 1, 1000, NULL); break; case WM_DESTROY: KillCountdownTimer(); break; case WM_TIMER: CountdownTimerProc(); break; case WM_CTLCOLORSTATIC: if(GetDlgItem(hwnd, IDC_ERROR) == ((HWND)lParam)){ return SetMessageLabelColorToRed(wParam); } default: return false; } return DefWindowProc(hwnd, message, wParam, lParam); }
static GtkTreeModel* createAndFillModel() { GtkListStore *certificatesList = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); GtkTreeIter iterator; char *validTo = NULL; EstEID_Certs *certs = EstEID_loadCerts(); EstEID_log("%i certificates found", certs->count); for(int i = 0; i < certs->count; i++) { EstEID_Map cert = certs->certs[i]; if (!EstEID_mapGet(cert, "usageNonRepudiation")) continue; validTo = getDateFromDateTime(EstEID_mapGet(cert, "validTo")); gtk_list_store_append(certificatesList, &iterator); gtk_list_store_set(certificatesList, &iterator, 0, EstEID_mapGet(cert, "commonName"), 1, EstEID_mapGet(cert, "organizationName"), 2, validTo, 3, EstEID_mapGet(cert, "certHash"), -1); if(validTo) { free(validTo); validTo = NULL; } } return GTK_TREE_MODEL(certificatesList); }
int promptForCertificate(void *nativeWindowHandle, char* certId) { certId[0] = '\0'; GtkWidget *window = getGtkWindow(nativeWindowHandle); GtkWidget *dialog = gtk_dialog_new_with_buttons("Select certificate", GTK_WINDOW(window), // ToDo l10n GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); GtkWidget* certificatesView = createCertificateSelectionView(dialog); gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK, FALSE); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), certificatesView); setDialogProperties(dialog, window); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); gtk_widget_show_all(dialog); gint result = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_hide(dialog); int returnValue = IDCANCEL; if (result == GTK_RESPONSE_OK) { GtkTreeSelection* selectedRow = gtk_tree_view_get_selection(GTK_TREE_VIEW(certificatesView)); GtkTreeModel* model = NULL; GtkTreeIter iter; if(gtk_tree_selection_get_selected(selectedRow, &model, &iter)){ gchar* id; gtk_tree_model_get(model, &iter, 3, &id, -1); strcpy(certId, id); g_free(id); returnValue = IDOK; EstEID_log("promptForCertificate dialog returned cert ID %s", certId); } else { EstEID_log("promptForCertificate dialog returned without cert selection"); } } else { EstEID_log("promptForCertificate dialog canceled by user"); } gtk_widget_destroy(dialog); return returnValue; }
bool certGetProperty(CertInstance *obj, NPIdentifier name, NPVariant *variant) { NPUTF8* nameString = browserFunctions->utf8fromidentifier(name); EstEID_log("name=%s", (char *)nameString); const char *result = EstEID_mapGet(obj->certInfo, EstEID_getCertPropertyName(nameString)); browserFunctions->memfree(nameString); if (result) return copyStringToNPVariant(result, variant); return false; }
int EstEID_tokensChanged() { LOG_LOCATION; CK_SLOT_ID slotID; int changed = FALSE; while (fl->C_WaitForSlotEvent(CKF_DONT_BLOCK, &slotID, NULL_PTR) == CKR_OK) { EstEID_log("C_WaitForSlotEvent() pass cycle 1"); changed = TRUE; } if (!changed) { while (fl->C_WaitForSlotEvent(CKF_DONT_BLOCK, &slotID, NULL_PTR) == CKR_OK) { EstEID_log("C_WaitForSlotEvent() pass cycle 2"); changed = TRUE; } } EstEID_log("tokens change %sdetected", changed ? "" : "not "); return changed; }
int EstEID_CK_failure(const char *name, CK_RV result) { EstEID_clear_error(); if (result == CKR_OK || result == CKR_CRYPTOKI_ALREADY_INITIALIZED) return FAILURE; sprintf(EstEID_error, "%s error: %s (%li)", name, pkcs11_error_message(result), result); EstEID_errorCode = ESTEID_PKCS11_ERROR; EstEID_log("cryptoki error: %s", EstEID_error); return SUCCESS; }
char *EstEID_sign(char *certId, char *hash, EstEID_PINPromptData pinPromptData) { EstEID_log("called, hash=%s", hash); char *signature = NULL; int i; EstEID_log("calling EstEID_loadCerts()"); EstEID_Certs *certs = EstEID_loadCerts(); EstEID_log("certs loaded"); if (!certs) { EstEID_log("%s", EstEID_error); } else if ((i = EstEID_findNonRepuditionCert(certs, certId)) == NOT_FOUND) { snprintf(EstEID_error, sizeof(EstEID_error) - 1, "no cert has ID: %s", certId); EstEID_errorCode = ESTEID_CERT_NOT_FOUND_ERROR; EstEID_error[sizeof(EstEID_error) - 1] = 0; EstEID_log("%s", EstEID_error); } else if (EstEID_signHashHex(&signature, certs->slotIDs[i], certs->certs[i], hash, pinPromptData)) { EstEID_log("signature=%s", signature); } else { EstEID_log("%s", EstEID_error); } free(certId); free(hash); return signature; }
int EstEID_md5_failure(void *ptr) { EstEID_clear_error(); if (ptr) return FALSE; snprintf(EstEID_error, sizeof(EstEID_error) - 1, "Cert id creation failed"); EstEID_errorCode = ESTEID_MD5_ERROR; EstEID_error[sizeof(EstEID_error) - 1] = 0; EstEID_log("%s", EstEID_error); return TRUE; }
bool isAllowedSite() { if(!allowedSite) { sprintf(EstEID_error, "Site is not allowed"); EstEID_errorCode = ESTEID_SITE_NOT_ALLOWED; EstEID_log("called from forbidden site"); return false; } return true; }
int EstEID_dl_failure(const char *name, void *ptr) { EstEID_clear_error(); if (ptr) return FALSE; snprintf(EstEID_error, sizeof(EstEID_error) - 1, "%s failed: %s", name, library_error()); EstEID_errorCode = ESTEID_LIBRARY_LOAD_ERROR; EstEID_error[sizeof(EstEID_error) - 1] = 0; EstEID_log("dl error: %s", EstEID_error); return TRUE; }
std::string CEstEIDCertificate::dateToString(FILETIME *filetime) { EstEID_log(""); SYSTEMTIME systemtime; FileTimeToSystemTime(filetime, &systemtime); char buf[40] = {0}; sprintf_s(buf, "%02d.%02d.%04d %02d:%02d:%02d", systemtime.wDay, systemtime.wMonth, systemtime.wYear, systemtime.wHour, systemtime.wMinute, systemtime.wSecond); std::string result = buf; return result; }
int EstEID_getRemainingTries(CK_SLOT_ID slotID) { CK_TOKEN_INFO tokenInfo; if (EstEID_CK_failure("C_GetTokenInfo", fl->C_GetTokenInfo(slotID, &tokenInfo))) return -1; EstEID_log("flags: %li (%lx)", tokenInfo.flags, tokenInfo.flags); if (tokenInfo.flags & CKF_USER_PIN_LOCKED) return 0; else if (tokenInfo.flags & CKF_USER_PIN_FINAL_TRY) return 1; else if (tokenInfo.flags & CKF_USER_PIN_COUNT_LOW) return 2; else return 3; }
int EstEID_startInitializeCryptokiThread() { LOG_LOCATION; initialization_result = -1; FAIL_IF_THREAD_ERROR("CreateMutex", (initialization_mutex = CreateMutex(NULL, FALSE, NULL))); EstEID_log("initialization_mutex = %p", initialization_mutex); DWORD threadId; FAIL_IF_THREAD_ERROR("CreateThread", CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_initializeCryptokiThread, NULL, 0, &threadId)); return SUCCESS; }
INT_PTR CALLBACK CertSelectionDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static char* selectedCertID; switch(message) { case WM_INITDIALOG: buildCertificatesList(hwnd); selectedCertID = (char*)lParam; selectedCertID[0] = '\0'; break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: { int index = ListView_GetNextItem(GetDlgItem(hwnd, IDC_CERTIFICATESLIST), -1, LVNI_SELECTED); TCHAR unicodeSelectedCertID[256]; ListView_GetItemText(GetDlgItem(hwnd, IDC_CERTIFICATESLIST), index, 3, (LPTSTR)unicodeSelectedCertID, 33); strcpy(selectedCertID, CW2A(unicodeSelectedCertID)); EstEID_log("selected certificate id in dialog proc: %s", selectedCertID); } default: EndDialog(hwnd, LOWORD(wParam)); } break; case WM_NOTIFY: if(wParam == IDC_CERTIFICATESLIST) { switch(((LPNMHDR)lParam)->code) { case LVN_ITEMCHANGED: case NM_CLICK: Button_Enable(GetDlgItem(hwnd, IDOK), ((LPNMITEMACTIVATE)lParam)->iItem != -1); break; case LVN_ITEMACTIVATE: { int selectedCertIndex = ((LPNMITEMACTIVATE)lParam)->iItem; TCHAR unicodeSelectedCertID[256]; ListView_GetItemText(GetDlgItem(hwnd, IDC_CERTIFICATESLIST), selectedCertIndex, 3, (LPTSTR)unicodeSelectedCertID, 33); strcpy(selectedCertID, CW2A(unicodeSelectedCertID)); EstEID_log("dblcklicked certificate id in dialog proc: %s", selectedCertID); EndDialog(hwnd, LOWORD(wParam)); } } } default: return false; } return DefWindowProc(hwnd, message, wParam, lParam); }
char *promptForPIN(void *nativeWindowHandle, const char *name, const char *message) { GtkWidget *window = getGtkWindow(nativeWindowHandle); GtkWidget *entry = gtk_entry_new(); GtkWidget *dialog = createDialog(window, entry, name, message); gint result = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_hide(dialog); char *pin; if (result == GTK_RESPONSE_OK) { pin = strdup(gtk_entry_get_text(GTK_ENTRY(entry))); EstEID_log("promptForPIN\t got pin"); } else { pin = strdup(""); EstEID_log("promptForPIN\t user canceled"); } gtk_widget_destroy(dialog); return pin; }
void CEstEIDIEPluginBHO::mapInternalErrorCodes(unsigned int code) { EstEID_log("Mapping error code %Xh:", code, code); if(code == ESTEID_USER_CANCEL || code == 0x3E5 || code == 0xB7 || code == 0x05DE || code == SCARD_W_CANCELLED_BY_USER){ // 0x03E5 for ???; 0x05DE for SL base package; SCARD_W_CANCELLED_BY_USER (0x8010006E) for SK base package EstEID_log(" mapped to ESTEID_USER_CANCEL (%Xh)", ESTEID_USER_CANCEL); setError(ESTEID_USER_CANCEL); } else if(code == 0x80092004){ EstEID_log(" mapped to ESTEID_CERT_NOT_FOUND_ERROR (%Xh)", ESTEID_CERT_NOT_FOUND_ERROR); setError(ESTEID_CERT_NOT_FOUND_ERROR); } else if(code > 0x80000000) { EstEID_log(" mapped to ESTEID_CRYPTO_API_ERROR (%Xh)", ESTEID_CRYPTO_API_ERROR); setError(ESTEID_CRYPTO_API_ERROR); } else { EstEID_log(" mapped to ESTEID_UNKNOWN_ERROR (%Xh)", ESTEID_UNKNOWN_ERROR); setError(ESTEID_UNKNOWN_ERROR); } }
char *EstEID_getLocaleFromEnvironment() { char *result = NULL; char *lang = getenv("LANG"); if (lang && strlen(lang) >= 2) { result = (char *)malloc(3); strncpy(result, lang, 2); result[2] = 0; EstEID_log("locale from getenv('LANG'): %s => %s", lang, result); } return result; }
char *promptForPIN(void *nativeWindowHandle, const char *name, const char *message) { char *pin2; DialogData dialogData; dialogData.pin2[0] = '\0'; dialogData.name = name; dialogData.message = message; INT_PTR result = DialogBoxParamW(pluginInstance, MAKEINTRESOURCEW(IDD_PIN_DIALOG), (HWND)nativeWindowHandle, Pin2DialogProc, (LPARAM)&dialogData); if (result == IDOK) { pin2 = strdup(dialogData.pin2); memset(dialogData.pin2, '\0', PIN2_MAX_LEN + 2); EstEID_log("promptForPIN\t got pin"); } else { pin2 = strdup(""); EstEID_log("promptForPIN\t user canceled"); } return pin2; }
bool doGetCertificate(PluginInstance *obj, NPVariant *result) { LOG_LOCATION; FAIL_IF_NOT_ALLOWED_SITE; char selectedCertID[33]; int dlg_result = 0; #ifdef _WIN32 HWND ownerWindowHandle = (HWND)getNativeWindowHandle(obj); EstEID_log("owner window handle passed to DialogBoxParam() = %08X", ownerWindowHandle); dlg_result = (int)DialogBoxParam(pluginInstance, MAKEINTRESOURCE(IDD_CERTIFICATESELECTIONDLG), ownerWindowHandle, CertSelectionDialogProc, (LPARAM)selectedCertID); #else dlg_result = promptForCertificate(getNativeWindowHandle(obj), selectedCertID); #endif EstEID_log("Certificate selection dialog result = %i", dlg_result); EstEID_log("Selected certificate ID = %s", selectedCertID); if(dlg_result == IDCANCEL) { sprintf(EstEID_error, "User canceled"); EstEID_errorCode = ESTEID_USER_CANCEL; EstEID_log("EstEID_error = %s", EstEID_error); browserFunctions->setexception(&obj->header, EstEID_error); return false; } CertInstance *certInstance = (CertInstance *)browserFunctions->createobject(obj->npp, certClass()); certInstance->npp = obj->npp; certInstance->certInfo = EstEID_mapClone(EstEID_getNonRepudiationCertById(selectedCertID)); // certInstance->certInfo = EstEID_mapClone(EstEID_getNonRepudiationCert()); EstEID_log("certObject=%p", certInstance); OBJECT_TO_NPVARIANT((NPObject *)certInstance, *result); EstEID_log("result=%p", result); return true; }
bool doSign(PluginInstance *obj, NPVariant *args, unsigned argCount, NPVariant *result) { EstEID_log("obj=%p, name=sign argCount=%u", obj, argCount); FAIL_IF_NOT_ALLOWED_SITE; if (argCount < 2) { browserFunctions->setexception(&obj->header, "Missing arguments"); return false; } if(argCount > 2 && NPVARIANT_IS_OBJECT(args[2])){ strncpy(pluginLanguage, getLanguageFromOptions(obj, args[2]), 2); } EstEID_setLocale(pluginLanguage); if(argCount > 3 && NPVARIANT_IS_OBJECT(args[3])){ strcpy(promptMessage, createStringFromNPVariant(args[3])); } void* wnd = getNativeWindowHandle(obj); EstEID_PINPromptData pinPromptData = {promptForPIN, showAlert, wnd, promptMessage, NULL}; NPUTF8* certId = createStringFromNPVariant(&args[0]); NPUTF8* hash = createStringFromNPVariant(&args[1]); char *signature = NULL; signature = EstEID_sign(certId, hash, pinPromptData); LOG_LOCATION if (signature) { copyStringToNPVariant(signature, result); free(signature); return true; } else { EstEID_log("EstEID_error=%s", EstEID_error); browserFunctions->setexception(&obj->header, EstEID_error); return false; } }
STDMETHODIMP CEstEIDIEPluginBHO::SetSite(IUnknown* pUnkSite) { EstEID_log(""); IObjectWithSiteImpl<CEstEIDIEPluginBHO>::SetSite(pUnkSite); CComPtr<IServiceProvider> pSP; HRESULT hr = GetSite(IID_IServiceProvider, reinterpret_cast<LPVOID *>(&pSP)); if(S_OK != hr) { return hr; } hr = pSP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<LPVOID *>(&webBrowser)); return S_OK; }
bool pluginGetProperty(PluginInstance *obj, NPIdentifier name, NPVariant *variant) { LOG_LOCATION; if (isSameIdentifier(name, "version")) return copyStringToNPVariant(ESTEID_PLUGIN_VERSION, variant); else if (isSameIdentifier(name, "errorMessage")){ EstEID_log("Reading error message: %s", EstEID_error); return copyStringToNPVariant(EstEID_error, variant); } else if (isSameIdentifier(name, "errorCode")) { INT32_TO_NPVARIANT(EstEID_errorCode, *variant); EstEID_log("returning errorCode=%i", EstEID_errorCode); return true; } else if (isSameIdentifier(name, "authCert") || isSameIdentifier(name, "signCert")){ return doGetCertificate(obj, variant); } else if (isSameIdentifier(name, "pluginLanguage")){ return copyStringToNPVariant(pluginLanguage, variant); } EstEID_log("returning false"); return false; }
BOOL CEstEidPin2Dlg::OnInitDialog() { LOG_LOCATION; CDialog::OnInitDialog(); WCHAR label[512]; int certIndex; EstEID_Certs *certs = EstEID_loadCerts(); if (!certs) { EstEID_log("no certs found"); } else if ((certIndex = EstEID_findNonRepuditionCert(certs, ATL::CW2A(this->certId))) == NOT_FOUND) { EstEID_log("card is changed"); } EstEID_Map cert = certs->certs[certIndex]; char* name = EstEID_getFullNameWithPersonalCode(cert); MultiByteToWideChar(CP_UTF8, 0, name, -1, label, sizeof(label) / sizeof(WCHAR)); this->SetWindowText(label); SetDlgItemText(IDC_NAME, label); this->pin2MinLen = (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")); free(name); MultiByteToWideChar(CP_UTF8, 0, l10n("For signing enter PIN2:"), -1, label, sizeof(label) / sizeof(WCHAR)); SetDlgItemText(IDC_PIN2_LABEL, label); MultiByteToWideChar(CP_UTF8, 0, l10n("Sign"), -1, label, sizeof(label) / sizeof(WCHAR)); SetDlgItemText(IDOK, label); MultiByteToWideChar(CP_UTF8, 0, l10n("Cancel"), -1, label, sizeof(label) / sizeof(WCHAR)); SetDlgItemText(IDCANCEL, label); SetDlgItemText(IDC_ERROR, L""); EndDialogIfPIN2Blocked(SetUpPin2Dialog()); return TRUE; }