source: murachi/esteidfirefoxplugin/firefox/plugin-class.c @ 7d3ae3e

Last change on this file since 7d3ae3e 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: 10.4 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 <stdlib.h>
23#include <string.h>
24#include "plugin-class.h"
25#include "version.h"
26#include "cert-class.h"
27#include "dialogs.h"
28#include "esteid_sign.h"
29#include "esteid_map.h"
30#include "esteid_json.h"
31#include "l10n.h"
32#include "esteid_error.h"
33#include "npapi.h"
34#include "esteid_certinfo.h"
35#ifdef _WIN32
36#include "certselection-win.h"
37#include "esteid_dialog_common.h"
38#include "dialogs-win.h"
39extern HINSTANCE pluginInstance;
40#endif
41
42extern NPNetscapeFuncs* browserFunctions;
43extern char EstEID_error[1024];
44extern int EstEID_errorCode;
45
46bool allowedSite;
47char pluginLanguage[3];
48
49bool isAllowedSite() {
50        if(!allowedSite) {
51                sprintf(EstEID_error, "Site is not allowed");
52                EstEID_errorCode = ESTEID_SITE_NOT_ALLOWED;
53                EstEID_log("called from forbidden site");
54                return false;
55        }
56        return true;
57}
58
59bool pluginInvokeDefault(PluginInstance *obj, NPVariant *args, unsigned argCount, NPVariant *result) {
60        return false;
61}
62
63void pluginInvalidate() {
64}
65
66bool pluginSetProperty(PluginInstance *obj, NPIdentifier name, const NPVariant *variant) {
67        LOG_LOCATION;
68        if(isSameIdentifier(name, "pluginLanguage")) {
69                memset(pluginLanguage, '\0', 3);
70                if(NPVARIANT_IS_STRING(*variant)) {
71                        strncpy(pluginLanguage, NPVARIANT_TO_STRING(*variant).UTF8Characters, 2);
72                        return true;
73                }
74                return true;
75        }
76        return false;
77}
78
79bool pluginHasMethod(PluginInstance *obj, NPIdentifier name) {
80        return 
81                isSameIdentifier(name, "sign") ||
82                isSameIdentifier(name, "getCertificate") ||             
83                isSameIdentifier(name, "getVersion");
84}
85
86bool pluginHasProperty(NPClass *theClass, NPIdentifier name) {
87        return 
88                isSameIdentifier(name, "version") ||
89                isSameIdentifier(name, "errorMessage") ||
90                isSameIdentifier(name, "errorCode") ||
91                isSameIdentifier(name, "authCert") ||
92                isSameIdentifier(name, "pluginLanguage") ||
93                isSameIdentifier(name, "signCert");
94}
95
96void *getNativeWindowHandle(PluginInstance *obj) {
97        void *nativeWindowHandle = obj->nativeWindowHandle;
98#ifdef _WIN32
99        EstEID_log("_WIN32 detected, forcing nativeWindowHandle query from browser");
100        nativeWindowHandle = 0;
101#endif
102        if (!nativeWindowHandle) {
103                browserFunctions->getvalue(obj->npp, NPNVnetscapeWindow, &nativeWindowHandle);
104                EstEID_log("reading nativeWindowHandle=%p from browserFunctions", nativeWindowHandle);
105        }
106        else {
107                EstEID_log("reading nativeWindowHandle=%p from PluginInstance", nativeWindowHandle);
108        }
109        return nativeWindowHandle;
110}
111
112char *getLanguageFromOptions(PluginInstance *obj, NPVariant options) {
113        LOG_LOCATION;
114        NPObject *object = NPVARIANT_TO_OBJECT(options);
115        NPIdentifier identifier = browserFunctions->getstringidentifier("language");
116        NPVariant languageResult;
117        if (browserFunctions->getproperty(obj->npp, object, identifier, &languageResult) && NPVARIANT_IS_STRING(languageResult)) {
118                char *language = createStringFromNPVariant(&languageResult);
119                EstEID_log("returning language '%s'", language);
120                return language;
121        }
122        EstEID_log("unable to read language from options, returning empty string");
123        return "";
124}
125
126bool doSign(PluginInstance *obj, NPVariant *args, unsigned argCount, NPVariant *result) {
127        EstEID_log("obj=%p, name=sign argCount=%u", obj, argCount);
128
129        FAIL_IF_NOT_ALLOWED_SITE;
130
131        if (argCount < 2) {
132                browserFunctions->setexception(&obj->header, "Missing arguments");
133                return false;
134        }
135       
136        if(argCount > 2 && NPVARIANT_IS_OBJECT(args[2])){
137                strncpy(pluginLanguage, getLanguageFromOptions(obj, args[2]), 2);
138        }
139        //EstEID_setLocale(pluginLanguage);
140        EstEID_setLocale("ru");
141
142        void* wnd = getNativeWindowHandle(obj);
143
144        EstEID_PINPromptData pinPromptData = {promptForPIN, showAlert, wnd};
145        NPUTF8* certId = createStringFromNPVariant(&args[0]);
146        NPUTF8* hash = createStringFromNPVariant(&args[1]);
147        char *signature = NULL;
148
149#ifdef _WIN32
150        DialogData dialogData;
151        dialogData.pin2[0] = '\0';
152        dialogData.minPin2Length = 5;
153        dialogData.certId = certId;
154        dialogData.hash = hash;
155        dialogData.signature[0] = '\0';
156
157        CK_SLOT_ID slotId;     
158        if(EstEID_getSlotId(certId, &slotId)){
159                if(EstEID_isPinPad(slotId)) {
160                        signature = EstEID_sign(certId, hash, pinPromptData);
161                }
162                else {
163                        DialogBoxParam(pluginInstance, MAKEINTRESOURCEW(IDD_PIN_DIALOG), (HWND)wnd, Pin2DialogProc, (LPARAM)&dialogData);
164                        LOG_LOCATION;
165                        signature = (char*)malloc(SIGNATURE_BUFFER_SIZE); // check?
166                        strcpy(signature, dialogData.signature);
167                }
168        }
169        else {
170                return false;
171        }
172#else
173        signature = EstEID_sign(certId, hash, pinPromptData);
174#endif
175        LOG_LOCATION
176        if (signature) {
177                copyStringToNPVariant(signature, result);
178                free(signature);
179                return true;
180        }
181        else {
182                EstEID_log("EstEID_error=%s", EstEID_error);
183                browserFunctions->setexception(&obj->header, EstEID_error);
184                return false;
185        }
186}
187
188bool doGetCertificate(PluginInstance *obj, NPVariant *result) {
189        LOG_LOCATION;
190        FAIL_IF_NOT_ALLOWED_SITE;
191        char selectedCertID[33];
192        int dlg_result = 0;
193       
194#ifdef _WIN32
195        HWND ownerWindowHandle = (HWND)getNativeWindowHandle(obj);
196        EstEID_log("owner window handle passed to DialogBoxParam() = %08X", ownerWindowHandle);
197        dlg_result = (int)DialogBoxParam(pluginInstance, MAKEINTRESOURCE(IDD_CERTIFICATESELECTIONDLG), ownerWindowHandle, CertSelectionDialogProc, (LPARAM)selectedCertID);
198#else
199        dlg_result = promptForCertificate(getNativeWindowHandle(obj), selectedCertID);
200#endif
201        EstEID_log("Certificate selection dialog result = %i", dlg_result);
202        EstEID_log("Selected certificate ID = %s", selectedCertID);
203
204        if(dlg_result == IDCANCEL) {
205                sprintf(EstEID_error, "User canceled");
206                EstEID_errorCode = ESTEID_USER_CANCEL;
207                EstEID_log("EstEID_error = %s", EstEID_error);
208                browserFunctions->setexception(&obj->header, EstEID_error);     
209                return false;
210        }
211       
212        CertInstance *certInstance = (CertInstance *)browserFunctions->createobject(obj->npp, certClass());
213        certInstance->npp = obj->npp;
214        certInstance->certInfo = EstEID_mapClone(EstEID_getNonRepudiationCertById(selectedCertID));
215//      certInstance->certInfo = EstEID_mapClone(EstEID_getNonRepudiationCert());
216
217        EstEID_log("certObject=%p", certInstance);
218        OBJECT_TO_NPVARIANT((NPObject *)certInstance, *result);
219        EstEID_log("result=%p", result);       
220        return true;
221}
222
223bool doGetCertificates(PluginInstance *obj, NPVariant *result) {
224        LOG_LOCATION;
225        EstEID_log("obj=%p, name=doGetCertificates", obj);
226        NPObject *windowObject = NULL;
227        browserFunctions->getvalue(obj->npp, NPNVWindowNPObject, &windowObject);
228        NPVariant array;
229        browserFunctions->invoke(obj->npp, windowObject, browserFunctions->getstringidentifier("Array"), NULL, 0, &array);
230        EstEID_Certs *certs = EstEID_loadCerts();
231        for (int i = 0; i < certs->count; i++) {
232                EstEID_Map cert = certs->certs[i];
233                if (!EstEID_mapGet(cert, "usageNonRepudiation")) continue;
234                CertInstance *certInstance = (CertInstance *)browserFunctions->createobject(obj->npp, certClass());
235                certInstance->npp = obj->npp;
236                certInstance->certInfo = EstEID_mapClone(cert);
237                browserFunctions->retainobject((NPObject *)certInstance);
238                EstEID_log("certObject=%p", certInstance);
239                NPVariant *arg = (NPVariant *)browserFunctions->memalloc(sizeof(NPVariant));
240                OBJECT_TO_NPVARIANT((NPObject *)certInstance, *arg);
241                NPVariant ret;
242                browserFunctions->invoke(obj->npp, array.value.objectValue, browserFunctions->getstringidentifier("push"), arg, 1, &ret);
243        }
244        browserFunctions->retainobject(array.value.objectValue);
245        OBJECT_TO_NPVARIANT(array.value.objectValue, *result);
246        return true;
247}
248
249bool pluginGetProperty(PluginInstance *obj, NPIdentifier name, NPVariant *variant) {
250        LOG_LOCATION;
251        if (isSameIdentifier(name, "version"))
252                return copyStringToNPVariant(ESTEID_PLUGIN_VERSION, variant);
253        else if (isSameIdentifier(name, "errorMessage")){
254                EstEID_log("Reading error message: %s", EstEID_error);
255                return copyStringToNPVariant(EstEID_error, variant);
256        }
257        else if (isSameIdentifier(name, "errorCode")) {
258                INT32_TO_NPVARIANT(EstEID_errorCode, *variant);
259                EstEID_log("returning errorCode=%i", EstEID_errorCode);
260                return true;
261        }
262        else if (isSameIdentifier(name, "authCert") || isSameIdentifier(name, "signCert")){
263                return doGetCertificate(obj, variant);
264        }
265        else if (isSameIdentifier(name, "pluginLanguage")){
266                return copyStringToNPVariant(pluginLanguage, variant);
267        }
268        EstEID_log("returning false");
269        return false;
270}
271
272bool pluginInvoke(PluginInstance *obj, NPIdentifier name, NPVariant *args, unsigned argCount, NPVariant *result) {     
273        LOG_LOCATION;
274        EstEID_clear_error();
275        //EstEID_setLocale(pluginLanguage);
276        EstEID_setLocale("ru");
277
278        if (isSameIdentifier(name, "sign")) {
279                return doSign(obj, args, argCount, result);
280        }
281        if (isSameIdentifier(name, "getCertificate")) {
282                return doGetCertificate(obj, result);
283        }
284        if (isSameIdentifier(name, "getVersion")) {
285                return pluginGetProperty(obj, browserFunctions->getstringidentifier("version"), result);
286        }
287        EstEID_log("obj=%p, name=%p, argCount=%u", obj, name, argCount);
288        return false;
289}
290
291NPObject *pluginAllocate(NPP npp, NPClass *theClass) {
292        return(NPObject *)malloc(sizeof(PluginInstance));
293}
294
295void pluginDeallocate(PluginInstance *obj) {
296        free(obj);
297}
298
299static NPClass _class = {
300        NP_CLASS_STRUCT_VERSION,
301        (NPAllocateFunctionPtr)pluginAllocate,
302        (NPDeallocateFunctionPtr)pluginDeallocate,
303        (NPInvalidateFunctionPtr)pluginInvalidate,
304        (NPHasMethodFunctionPtr)pluginHasMethod,
305        (NPInvokeFunctionPtr)pluginInvoke,
306        (NPInvokeDefaultFunctionPtr)pluginInvokeDefault,
307        (NPHasPropertyFunctionPtr)pluginHasProperty,
308        (NPGetPropertyFunctionPtr)pluginGetProperty,
309        (NPSetPropertyFunctionPtr)pluginSetProperty,
310};
311
312NPClass *pluginClass() {
313        return &_class;
314}
315
316
Note: See TracBrowser for help on using the repository browser.