source: murachi/esteidfirefoxplugin/firefox/dialogs-win.c @ 5d188ab

Last change on this file since 5d188ab was 7d3ae3e, checked in by antonioaraujob <aaraujo@…>, 9 years ago

Agregados archivos fuentes del complemento esteidfirefoxplugin de Estonia para firmar electrónicamente un hash.

  • Property mode set to 100644
File size: 9.0 KB
Line 
1/*
2 * Estonian ID card plugin for web browsers
3 *
4 * Copyright (C) 2010-2011 Codeborne <info@codeborne.com>
5 *
6 * This is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 *
20 */
21
22#include <windows.h>
23#include <windowsx.h>
24#include <string.h>
25#include <atlconv.h>
26#include <atlstr.h>
27#include <commctrl.h>
28#include "esteid_log.h"
29#include "esteid_error.h"
30#include "esteid_sign.h"
31#include "resource.h"
32#include "l10n.h"
33#include "esteid_dialog_common.h"
34#include "pkcs11_errors.h"
35
36#define PINPAD_TIMER_ID 1
37
38extern HINSTANCE pluginInstance;
39extern char EstEID_error[1024];
40
41HWND dialogWindowHandle;
42HANDLE timerHandle;
43int countdownValue;
44
45void SetDialogItemText(HWND hwnd, UINT resourceID, LPCSTR text){
46        WCHAR unicodeBuf[512];
47        MultiByteToWideChar(CP_UTF8, 0, text, -1, unicodeBuf, sizeof(unicodeBuf) / sizeof(WCHAR)); 
48        SetDlgItemText(hwnd, resourceID, unicodeBuf);
49}
50
51void showAlert(void *nativeWindowHandle, const char *message) {
52        MessageBox((HWND)nativeWindowHandle, CA2W(message), CA2W(l10n("Error")), MB_OK | MB_ICONERROR);
53}
54
55BOOL isAcceptableLengthPIN2(HWND hwnd, UINT pinFieldId, unsigned int minPin2Length){
56        return SendDlgItemMessage(hwnd, pinFieldId, WM_GETTEXTLENGTH, NULL, NULL) >= minPin2Length;
57}
58
59void UpdateProgerssBar(HWND dialogWindowHandle, int countdownValue) {
60        SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETPOS, (WPARAM)countdownValue, 0L);
61}
62
63void KillCountdownTimer(){
64        KillTimer(dialogWindowHandle, 1);
65        EstEID_log("pinpad countdown timer killed");
66}
67
68void CountdownTimerProc() {
69        if(countdownValue > 0){
70                countdownValue--;
71                UpdateProgerssBar(dialogWindowHandle, countdownValue);
72        }
73        else {
74                KillCountdownTimer();
75        }
76}
77
78void SetPinDialogLabels(HWND windowHandle, char *certId, unsigned int *pin2Len) {
79        LOG_LOCATION; 
80
81//duplicate code
82        int certIndex;
83        EstEID_Certs *certs = EstEID_loadCerts();
84        EstEID_log("certs loaded");
85        if (!certs) {
86                EstEID_log("%s", EstEID_error);
87        }
88        else if ((certIndex = EstEID_findNonRepuditionCert(certs, certId)) == NOT_FOUND) {
89                EstEID_log("crd is changed");
90        }
91        EstEID_Map cert = certs->certs[certIndex];
92
93//duplicated code
94        char* name = EstEID_getFullNameWithPersonalCode(cert);
95
96        WCHAR label[512];
97        MultiByteToWideChar(CP_UTF8, 0, createDialogTitle(name), -1, label, sizeof(label) / sizeof(WCHAR));
98        SetWindowText(windowHandle, label);
99
100        SetDialogItemText(windowHandle, IDC_NAME, name);
101
102        *pin2Len = (unsigned)atoi(EstEID_mapGet(cert, "minPinLen"));
103
104        free(name);
105}
106
107void SetPinPadDialogLabels(HWND windowHandle, LPARAM lParam) {
108        WCHAR label[512];
109        MultiByteToWideChar(CP_UTF8, 0, createDialogTitle(((DialogData *)lParam)->name), -1, label, sizeof(label) / sizeof(WCHAR));
110        SetWindowText(windowHandle, label);
111
112        SetDialogItemText(windowHandle, IDC_NAME, ((DialogData *)lParam)->name);
113        if(((DialogData *)lParam)->message != NULL) {
114                SetDialogItemText(windowHandle, IDC_ERROR, ((DialogData *)lParam)->message);
115        }
116}
117
118INT_PTR SetMessageLabelColorToRed(WPARAM wParam) {
119        SetTextColor((HDC)wParam, RGB(255, 0, 0));
120        SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNFACE));
121        return (INT_PTR)GetStockObject(NULL_BRUSH);
122}
123
124CK_ULONG SetUpPin2Dialog(HWND hwnd, int retryCount, char* certId) {
125        char message[512];
126        CK_SLOT_ID slotId;
127
128        if(!EstEID_getSlotId(certId, &slotId)) {
129                return CKR_GENERAL_ERROR;
130        }
131        int remainingTries = EstEID_getRemainingTries(slotId);
132        EstEID_log("EstEID_getRemainingTries(slotID) = %i", remainingTries);
133        if (remainingTries == -1) {
134                return CKR_GENERAL_ERROR;
135        }               
136        if (!remainingTries) {         
137                sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED);
138                return CKR_PIN_LOCKED;
139        }
140        EstEID_log("retryCount = %i", retryCount);
141        if (remainingTries < 3) {
142                sprintf(message, "%s %i", l10n("Tries left:"), remainingTries);         
143                sprintf(message, "%s%s %i", (retryCount ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries);
144        }
145        else {
146                message[0] = 0;
147        }
148        SetDialogItemText(hwnd, IDC_ERROR, message);
149        SetDlgItemText(hwnd, IDC_PIN2, L"");   
150        return CKR_OK;
151}
152
153void EndDialogIfPIN2Blocked(HWND hwnd, int cardStatus) {
154        if(cardStatus == CKR_PIN_LOCKED) {
155                ShowWindow(hwnd, false);
156                showAlert(hwnd, l10n("PIN2 blocked, cannot sign!"));
157                EndDialog(hwnd, IDCANCEL);
158        }
159}
160
161INT_PTR CALLBACK Pin2DialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
162        static TCHAR *pin2;
163        static unsigned int minPin2Length;
164        static char* certId;
165        static char* hash;
166        static char* signature;
167        static int retryCount;
168        int cardStatus;
169        char* tmpSignature = NULL;
170        EstEID_PINPromptData pinPromptData = {NULL, NULL, NULL, NULL};
171
172        switch(message) {
173                case WM_INITDIALOG:
174                        dialogWindowHandle = hwnd;
175                        EstEID_log("PIN2 dialog window handle = %08X", dialogWindowHandle);
176                        SetPinDialogLabels(dialogWindowHandle, ((DialogData *)lParam)->certId, &minPin2Length);                         
177                        SetDialogItemText(dialogWindowHandle, IDC_PIN2_LABEL, l10n("For signing enter PIN2:"));
178                        SetDialogItemText(dialogWindowHandle, IDOK, l10n("Sign"));
179                        SetDialogItemText(dialogWindowHandle, IDCANCEL, l10n("Cancel"));
180                        pin2 = ((DialogData *)lParam)->pin2;
181                        certId = ((DialogData *)lParam)->certId;
182                        hash = ((DialogData *)lParam)->hash;
183                        signature = ((DialogData *)lParam)->signature;
184                        retryCount = 0;
185                        EndDialogIfPIN2Blocked(hwnd, SetUpPin2Dialog(hwnd, retryCount, certId));
186                        return true;
187                case WM_COMMAND:
188                        switch(LOWORD(wParam)) {
189                                case IDOK:
190                                        GetDlgItemText(hwnd, IDC_PIN2, pin2, PIN2_MAX_LEN);
191                                        pinPromptData.pin2 = strdup(CW2A(pin2)); //NB!!! vaata yle maluhaldus                                   
192                                        tmpSignature = EstEID_sign(strdup(certId), strdup(hash), pinPromptData); // duplicates used as EstEID_sign() will free them                                     
193                                        retryCount++;
194                                        if(tmpSignature) {
195                                                strcpy(signature, tmpSignature);
196                                                free(tmpSignature);
197                                        }
198                                        else {
199                                                cardStatus = SetUpPin2Dialog(hwnd, retryCount, certId);
200                                                if( cardStatus!= CKR_OK) {
201                                                        EndDialogIfPIN2Blocked(hwnd, cardStatus);
202                                                }
203                                                return true;
204                                        }
205                                case IDCANCEL:
206                                        dialogWindowHandle = 0;
207                                        EndDialog(hwnd, LOWORD(wParam));
208                                        EstEID_log("closing PIN2 dialog, focus is back @ %08X", GetFocus());
209                                        return true;
210                        }
211                        if(HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) == IDC_PIN2) {
212                                Button_Enable(GetDlgItem(hwnd, IDOK), isAcceptableLengthPIN2(hwnd, IDC_PIN2, minPin2Length));
213                        }
214                        return true;
215                case WM_CTLCOLORSTATIC:                 
216                        if(GetDlgItem(hwnd, IDC_ERROR) == ((HWND)lParam)){
217                                return SetMessageLabelColorToRed(wParam);
218                        }                       
219                default:
220                        return false;
221        }       
222}
223
224INT_PTR CALLBACK PinPadDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
225        switch(message) {
226                case WM_INITDIALOG:
227                        dialogWindowHandle = hwnd;
228
229                        SetPinPadDialogLabels(dialogWindowHandle, lParam);
230                        SetDialogItemText(hwnd, IDC_PINPAD_PIN2_LABEL, l10n("For signing enter PIN2 from PIN pad"));
231
232                        countdownValue = 30; // in seconds
233                        EstEID_log("initializing pinpad countdown timer with value %i", countdownValue);
234                        SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0L);
235                        SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETRANGE, 0, MAKELPARAM(0, countdownValue));
236                        UpdateProgerssBar(dialogWindowHandle, countdownValue);
237                        SendMessage(GetDlgItem(dialogWindowHandle, IDC_PROGRESSBAR), PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0L);
238                        SetTimer(dialogWindowHandle, 1, 1000, NULL);
239                        break;
240                case WM_DESTROY:
241                        KillCountdownTimer();
242                        break;
243                case WM_TIMER:
244                        CountdownTimerProc();
245                        break;
246                case WM_CTLCOLORSTATIC:
247                        if(GetDlgItem(hwnd, IDC_ERROR) == ((HWND)lParam)){
248                                return SetMessageLabelColorToRed(wParam);
249                        }
250                default:                       
251                        return false;
252        }
253        return DefWindowProc(hwnd, message, wParam, lParam);   
254}
255
256void closePinPadModalSheet() {
257        LOG_LOCATION;
258        EndDialog(dialogWindowHandle, IDCANCEL);
259}
260
261char *promptForPIN(void *nativeWindowHandle, const char *name, const char *message, unsigned int minPin2Length, int usePinPad) {       
262        LOG_LOCATION;
263        DialogData dialogData;
264
265        if(usePinPad){
266                dialogData.pin2[0] = '\0';
267                dialogData.name = name;
268                dialogData.message = message;
269                dialogData.minPin2Length = minPin2Length;
270                DialogBoxParamW(pluginInstance, MAKEINTRESOURCEW(IDD_PINPAD_DIALOG), (HWND)nativeWindowHandle, PinPadDialogProc, (LPARAM)&dialogData);
271        }
272        return strdup("");
273}
Note: See TracBrowser for help on using the repository browser.