1 /***************************************************************************
2     begin       : Mon Mar 01 2004
3     copyright   : (C) 2004-2010 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14 
15 /*#define DEBUG_OHBCI_MODULE*/
16 
17 
18 
19 #include "ohbci_p.h"
20 #include "i18n_l.h"
21 #include <gwenhywfar/debug.h>
22 #include <gwenhywfar/misc.h>
23 #include <gwenhywfar/padd.h>
24 #include <gwenhywfar/gui.h>
25 #include <gwenhywfar/ctfile_be.h>
26 #include <gwenhywfar/ctplugin_be.h>
27 #include <gwenhywfar/ctf_context_be.h>
28 #include <gwenhywfar/text.h> /* DEBUG */
29 #include <gwenhywfar/cryptkeysym.h>
30 #include <gwenhywfar/cryptkeyrsa.h>
31 #include <gwenhywfar/smalltresor.h>
32 
33 #include <stdlib.h>
34 #include <assert.h>
35 #include <string.h>
36 
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <errno.h>
42 
43 #ifdef OS_WIN32
44 # define ftruncate chsize
45 #endif
46 
47 
48 
49 
GWEN_INHERIT(GWEN_CRYPT_TOKEN,GWEN_CRYPT_TOKEN_OHBCI)50 GWEN_INHERIT(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI)
51 
52 
53 GWEN_PLUGIN *ct_ohbci_factory(GWEN_PLUGIN_MANAGER *pm,
54                               const char *modName,
55                               const char *fileName)
56 {
57   GWEN_PLUGIN *pl;
58 
59   pl=GWEN_Crypt_TokenOHBCI_Plugin_new(pm, modName, fileName);
60   assert(pl);
61 
62   return pl;
63 }
64 
65 
66 
GWEN_Crypt_TokenOHBCI_Plugin_new(GWEN_PLUGIN_MANAGER * pm,const char * modName,const char * fileName)67 GWEN_PLUGIN *GWEN_Crypt_TokenOHBCI_Plugin_new(GWEN_PLUGIN_MANAGER *pm,
68                                               const char *modName,
69                                               const char *fileName)
70 {
71   GWEN_PLUGIN *pl;
72 
73   pl=GWEN_Crypt_Token_Plugin_new(pm,
74                                  GWEN_Crypt_Token_Device_File,
75                                  modName,
76                                  fileName);
77 
78   /* set virtual functions */
79   GWEN_Crypt_Token_Plugin_SetCreateTokenFn(pl,
80                                            GWEN_Crypt_TokenOHBCI_Plugin_CreateToken);
81   GWEN_Crypt_Token_Plugin_SetCheckTokenFn(pl,
82                                           GWEN_Crypt_TokenOHBCI_Plugin_CheckToken);
83 
84   return pl;
85 }
86 
87 
88 
GWEN_Crypt_TokenOHBCI_Plugin_CreateToken(GWEN_PLUGIN * pl,const char * name)89 GWEN_CRYPT_TOKEN *GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Plugin_CreateToken(GWEN_PLUGIN *pl,
90                                                                          const char *name)
91 {
92   GWEN_PLUGIN_MANAGER *pm;
93   GWEN_CRYPT_TOKEN *ct;
94 
95   assert(pl);
96 
97   pm=GWEN_Plugin_GetManager(pl);
98   assert(pm);
99 
100   ct=GWEN_Crypt_TokenOHBCI_new(pm, name);
101   assert(ct);
102 
103   return ct;
104 }
105 
106 
107 
GWEN_Crypt_TokenOHBCI_Plugin_CheckToken(GWEN_UNUSED GWEN_PLUGIN * pl,GWEN_BUFFER * name)108 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Plugin_CheckToken(GWEN_UNUSED GWEN_PLUGIN *pl,
109                                                           GWEN_BUFFER *name)
110 {
111   FILE *f;
112   const char *p;
113   char buffer[16];
114   int rv;
115 
116   if (GWEN_Buffer_GetUsedBytes(name)==0) {
117     DBG_ERROR(GWEN_LOGDOMAIN, "Empty name");
118     return GWEN_ERROR_BAD_NAME;
119   }
120 
121   p=GWEN_Buffer_GetStart(name);
122   if (access(p, F_OK)) {
123     DBG_ERROR(GWEN_LOGDOMAIN, "File [%s] does not exist", p);
124     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Info, "File does not exist");
125     return GWEN_ERROR_BAD_NAME;
126   }
127 
128   if (access(p, R_OK | W_OK)) {
129     DBG_ERROR(GWEN_LOGDOMAIN, "File exists but I have no writes on it");
130     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Info,
131                          "File exists but I have no writes on it");
132     return GWEN_ERROR_IO;
133   }
134 
135   f=fopen(p, "rb");
136   if (!f) {
137     DBG_ERROR(GWEN_LOGDOMAIN,
138               "File exists, I have all rights but still can't open it");
139     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice,
140                          "File exists, I have all rights but "
141                          "still can't open it");
142     return GWEN_ERROR_IO;
143   }
144 
145   rv=fread(buffer, sizeof(buffer), 1, f);
146   fclose(f);
147   if (rv!=1) {
148     DBG_INFO(GWEN_LOGDOMAIN, "This seems not to be an OpenHBCI keyfile");
149     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Info,
150                          "This seems not to be an OpenHBCI keyfile");
151     return GWEN_ERROR_NOT_SUPPORTED;
152   }
153 
154   if (rv!=1) {
155     DBG_INFO(GWEN_LOGDOMAIN, "This seems not to be an OpenHBCI keyfile (bad size)");
156     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice,
157                          "This seems not to be an OpenHBCI keyfile "
158                          "(bad size)");
159     return GWEN_ERROR_NOT_SUPPORTED;
160   }
161 
162   if ((unsigned char)(buffer[0])==GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM1) {
163     DBG_INFO(GWEN_LOGDOMAIN,
164              "Old OpenHBCI file detected");
165     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice,
166                          "Old OpenHBCI file detected");
167     return 0;
168   }
169   else if ((unsigned char)(buffer[0])==GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM2) {
170     DBG_INFO(GWEN_LOGDOMAIN,
171              "OpenHBCI file (<1.6) detected");
172     GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice,
173                          "OpenHBCI file (<1.6) detected");
174     return 0;
175   }
176   else if ((unsigned char)(buffer[0])==GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3) {
177     if ((unsigned char)(buffer[3])==GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER &&
178         strncmp(buffer+6,
179                 GWEN_CRYPT_TOKEN_OHBCI_NAME,
180                 strlen(GWEN_CRYPT_TOKEN_OHBCI_NAME))==0) {
181       DBG_INFO(GWEN_LOGDOMAIN,
182                "New OpenHBCI file (>=1.6) detected");
183       GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice,
184                            "New OpenHBCI file (>=1.6) detected");
185       return 0;
186     }
187   }
188 
189   DBG_INFO(GWEN_LOGDOMAIN,
190            "This seems not to be an OpenHBCI keyfile");
191   GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Notice,
192                        "This seems not to be an OpenHBCI keyfile");
193   return GWEN_ERROR_NOT_SUPPORTED;
194 }
195 
196 
197 
198 
199 
GWEN_Crypt_TokenOHBCI_new(GWEN_UNUSED GWEN_PLUGIN_MANAGER * pm,const char * name)200 GWEN_CRYPT_TOKEN *GWEN_Crypt_TokenOHBCI_new(GWEN_UNUSED GWEN_PLUGIN_MANAGER *pm,
201                                             const char *name)
202 {
203   GWEN_CRYPT_TOKEN *ct;
204   GWEN_CRYPT_TOKEN_OHBCI *lct;
205 
206   ct=GWEN_Crypt_TokenFile_new("ohbci", name);
207 
208   GWEN_NEW_OBJECT(GWEN_CRYPT_TOKEN_OHBCI, lct);
209   GWEN_INHERIT_SETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI,
210                        ct, lct,
211                        GWEN_Crypt_TokenOHBCI_FreeData);
212   lct->mediumTag=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3;
213   lct->vminor=GWEN_CRYPT_TOKEN_OHBCI_VMINOR;
214   lct->cryptoTag=GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_BF;
215 
216   /* set virtual functions */
217   lct->openFn=GWEN_Crypt_Token_SetOpenFn(ct, GWEN_Crypt_TokenOHBCI_Open);
218   lct->closeFn=GWEN_Crypt_Token_SetCloseFn(ct, GWEN_Crypt_TokenOHBCI_Close);
219   lct->createFn=GWEN_Crypt_Token_SetCreateFn(ct, GWEN_Crypt_TokenOHBCI_Create);
220   GWEN_Crypt_Token_SetChangePinFn(ct, GWEN_Crypt_TokenOHBCI_ChangePin);
221 
222   GWEN_Crypt_TokenFile_SetReadFn(ct, GWEN_Crypt_TokenOHBCI_Read);
223   GWEN_Crypt_TokenFile_SetWriteFn(ct, GWEN_Crypt_TokenOHBCI_Write);
224 
225   return ct;
226 }
227 
228 
229 
GWEN_Crypt_TokenOHBCI_FreeData(GWEN_UNUSED void * bp,void * p)230 void GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_FreeData(GWEN_UNUSED void *bp, void *p)
231 {
232   GWEN_CRYPT_TOKEN_OHBCI *lct;
233 
234   lct=(GWEN_CRYPT_TOKEN_OHBCI *) p;
235   memset(lct->password, 0, sizeof(lct->password));
236   GWEN_FREE_OBJECT(lct);
237 }
238 
239 
240 
241 
GWEN_Crypt_TokenOHBCI__EnsurePassword(GWEN_CRYPT_TOKEN * ct,int trynum,int confirm,uint32_t gid)242 int GWEN_Crypt_TokenOHBCI__EnsurePassword(GWEN_CRYPT_TOKEN *ct,
243                                           int trynum,
244                                           int confirm,
245                                           uint32_t gid)
246 {
247   GWEN_CRYPT_TOKEN_OHBCI *lct;
248 
249   assert(ct);
250   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
251   assert(lct);
252 
253   if (lct->passWordIsSet==0) {
254     char password[64];
255     int rv;
256     unsigned int pinLength=0;
257     uint32_t flags;
258 
259     /* create key from password */
260     memset(lct->password, 0, sizeof(lct->password));
261 
262     flags=0;
263     if (trynum)
264       flags|=GWEN_GUI_INPUT_FLAGS_RETRY;
265     if (confirm)
266       flags|=GWEN_GUI_INPUT_FLAGS_CONFIRM;
267     rv=GWEN_Crypt_Token_GetPin(ct,
268                                GWEN_Crypt_PinType_Access,
269                                GWEN_Crypt_PinEncoding_Ascii,
270                                flags,
271                                (unsigned char *)password,
272                                GWEN_CRYPT_TOKEN_OHBCI_PINMINLENGTH,
273                                sizeof(password)-1,
274                                &pinLength,
275                                gid);
276     if (rv) {
277       DBG_ERROR(GWEN_LOGDOMAIN, "Error asking for PIN, aborting (%d)", rv);
278       return rv;
279     }
280 
281     if (strlen(password)<GWEN_CRYPT_TOKEN_OHBCI_PINMINLENGTH) {
282       DBG_ERROR(GWEN_LOGDOMAIN,
283                 "Your program returned a shorter PIN than instructed!");
284       return GWEN_ERROR_GENERIC;
285     }
286 
287     DBG_NOTICE(GWEN_LOGDOMAIN, "Checking...");
288     if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT) {
289       DBG_NOTICE(GWEN_LOGDOMAIN, "New OpenHBCI file detected");
290 
291       rv=GWEN_Crypt_KeyDataFromText(password,
292                                     (unsigned char *)lct->password,
293                                     24);
294       if (rv) {
295         DBG_ERROR(GWEN_LOGDOMAIN,
296                   "Could not create key data from password (%d)", rv);
297         return GWEN_ERROR_GENERIC;
298       }
299     }
300     else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_OLD) {
301       DBG_NOTICE(GWEN_LOGDOMAIN, "Old OpenHBCI file detected");
302 
303       rv=GWEN_Gui_KeyDataFromText_OpenSSL(password,
304                                           (unsigned char *)lct->password,
305                                           16);
306       if (rv) {
307         if (rv==GWEN_ERROR_NOT_IMPLEMENTED) {
308           DBG_ERROR(GWEN_LOGDOMAIN,
309                     "OpenSSL-style password creation not supported with Libgcrypt!");
310         }
311         else {
312           DBG_ERROR(GWEN_LOGDOMAIN, "Could not create key data from password (%d)", rv);
313         }
314         return GWEN_ERROR_GENERIC;
315       }
316     }
317     else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_BF) {
318       DBG_NOTICE(GWEN_LOGDOMAIN, "New OpenHBCI (1.6+) file detected");
319       /* same as above but for different key type */
320       rv=GWEN_Crypt_KeyDataFromText(password,
321                                     (unsigned char *)lct->password,
322                                     16);
323       if (rv) {
324         DBG_ERROR(GWEN_LOGDOMAIN,
325                   "Could not create key data from password (%d)", rv);
326         return GWEN_ERROR_GENERIC;
327       }
328     }
329     else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_TRESOR) {
330       DBG_NOTICE(GWEN_LOGDOMAIN, "New OpenHBCI (1.8+) file detected");
331       strncpy(lct->password, password, sizeof(lct->password)-1);
332       lct->password[sizeof(lct->password)-1]=0;
333     }
334     else {
335       DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected crypto tag %d",
336                 lct->cryptoTag);
337       abort();
338     }
339 
340     lct->passWordIsSet=1;
341   }
342 
343   return 0;
344 }
345 
346 
347 
GWEN_Crypt_TokenOHBCI__DecryptFile(GWEN_CRYPT_TOKEN * ct,GWEN_BUFFER * fbuf,int trynum,uint32_t gid)348 int GWEN_Crypt_TokenOHBCI__DecryptFile(GWEN_CRYPT_TOKEN *ct,
349                                        GWEN_BUFFER *fbuf,
350                                        int trynum,
351                                        uint32_t gid)
352 {
353   GWEN_CRYPT_TOKEN_OHBCI *lct;
354   GWEN_CRYPT_KEY *key;
355   int err;
356   char password[64];
357   GWEN_BUFFER *rawbuf;
358   uint32_t size;
359   int rv;
360   unsigned int pinLength=0;
361 
362   assert(ct);
363   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
364   assert(lct);
365 
366   rv=GWEN_Crypt_TokenOHBCI__EnsurePassword(ct, trynum, 0, gid);
367   if (rv) {
368     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
369     return rv;
370   }
371 
372   if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT) {
373     key=GWEN_Crypt_KeyDes3K_fromData(GWEN_Crypt_CryptMode_Cbc, 24,
374                                      (const uint8_t *)lct->password, 24);
375   }
376   else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_OLD) {
377     key=GWEN_Crypt_KeyDes3K_fromData(GWEN_Crypt_CryptMode_Cbc, 16,
378                                      (const uint8_t *)lct->password, 16);
379   }
380   else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_BF) {
381     key=GWEN_Crypt_KeyBlowFish_fromData(GWEN_Crypt_CryptMode_Cbc, 16,
382                                         (const uint8_t *)lct->password, 16);
383   }
384   else {
385     DBG_ERROR(GWEN_LOGDOMAIN, "Unknown crypt tag, should not occur");
386     abort();
387   }
388 
389   /* decrypt file */
390   DBG_INFO(GWEN_LOGDOMAIN, "Decrypting file");
391   size=GWEN_Buffer_GetUsedBytes(fbuf);
392   rawbuf=GWEN_Buffer_new(0, size, 0, 1);
393   GWEN_Buffer_Rewind(fbuf);
394   err=GWEN_Crypt_Key_Decipher(key,
395                               (const uint8_t *)GWEN_Buffer_GetStart(fbuf),
396                               size,
397                               (uint8_t *)GWEN_Buffer_GetStart(rawbuf),
398                               &size);
399   if (err) {
400     DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
401     GWEN_Buffer_free(rawbuf);
402     GWEN_Crypt_Key_free(key);
403     if (pinLength)
404       GWEN_Crypt_Token_SetPinStatus(ct,
405                                     GWEN_Crypt_PinType_Access,
406                                     GWEN_Crypt_PinEncoding_Ascii,
407                                     (trynum
408                                      ?GWEN_GUI_INPUT_FLAGS_RETRY:0),
409                                     (unsigned char *)password,
410                                     pinLength,
411                                     0,
412                                     gid);
413     memset(password, 0, sizeof(password));
414     lct->passWordIsSet=0;
415     return GWEN_ERROR_BAD_PIN;
416   }
417 
418   /* advance buffer pointers since we wrote directly to the buffer */
419   GWEN_Buffer_IncrementPos(rawbuf, size);
420   GWEN_Buffer_AdjustUsedBytes(rawbuf);
421 
422   /* unpadd raw data */
423   DBG_INFO(GWEN_LOGDOMAIN, "Unpadding file");
424   if (GWEN_Padd_UnpaddWithAnsiX9_23(rawbuf)) {
425     DBG_ERROR(GWEN_LOGDOMAIN, "Could not unpadd keyfile, i.e. wrong PIN");
426     GWEN_Buffer_free(rawbuf);
427     GWEN_Crypt_Key_free(key);
428     /* TODO: Set Pin status */
429     lct->passWordIsSet=0;
430     if (pinLength)
431       GWEN_Crypt_Token_SetPinStatus(ct,
432                                     GWEN_Crypt_PinType_Access,
433                                     GWEN_Crypt_PinEncoding_Ascii,
434                                     (trynum?GWEN_GUI_INPUT_FLAGS_RETRY:0),
435                                     (unsigned char *)password,
436                                     pinLength,
437                                     0,
438                                     gid);
439     memset(password, 0, sizeof(password));
440     return GWEN_ERROR_BAD_PIN;
441   }
442   GWEN_Crypt_Key_free(key);
443 
444   /* parse raw data */
445   DBG_INFO(GWEN_LOGDOMAIN, "Parsing file");
446   GWEN_Buffer_Rewind(rawbuf);
447 
448   rv=GWEN_Crypt_TokenOHBCI__Decode(ct, rawbuf);
449   if (rv) {
450     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
451     GWEN_Buffer_free(rawbuf);
452     /* Set Pin status */
453     if (pinLength)
454       GWEN_Crypt_Token_SetPinStatus(ct,
455                                     GWEN_Crypt_PinType_Access,
456                                     GWEN_Crypt_PinEncoding_Ascii,
457                                     (trynum
458                                      ?GWEN_GUI_INPUT_FLAGS_RETRY:0),
459                                     (unsigned char *)password,
460                                     pinLength,
461                                     0,
462                                     gid);
463     memset(password, 0, sizeof(password));
464     lct->passWordIsSet=0;
465     return GWEN_ERROR_BAD_PIN;
466   }
467   GWEN_Buffer_free(rawbuf);
468   /* Set Pin status */
469   if (pinLength)
470     GWEN_Crypt_Token_SetPinStatus(ct,
471                                   GWEN_Crypt_PinType_Access,
472                                   GWEN_Crypt_PinEncoding_Ascii,
473                                   (trynum?GWEN_GUI_INPUT_FLAGS_RETRY:0),
474                                   (unsigned char *)password,
475                                   pinLength,
476                                   1,
477                                   gid);
478   memset(password, 0, sizeof(password));
479   return 0;
480 }
481 
482 
483 
GWEN_Crypt_TokenOHBCI__DecryptTresor(GWEN_CRYPT_TOKEN * ct,GWEN_BUFFER * fbuf,int trynum,uint32_t gid)484 int GWEN_Crypt_TokenOHBCI__DecryptTresor(GWEN_CRYPT_TOKEN *ct,
485                                          GWEN_BUFFER *fbuf,
486                                          int trynum,
487                                          uint32_t gid)
488 {
489   GWEN_CRYPT_TOKEN_OHBCI *lct;
490   GWEN_BUFFER *rawbuf;
491   uint32_t size;
492   int rv;
493 
494   assert(ct);
495   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
496   assert(lct);
497 
498   rv=GWEN_Crypt_TokenOHBCI__EnsurePassword(ct, trynum, 0, gid);
499   if (rv) {
500     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
501     return rv;
502   }
503 
504   size=GWEN_Buffer_GetUsedBytes(fbuf);
505   rawbuf=GWEN_Buffer_new(0, size, 0, 1);
506   GWEN_Buffer_Rewind(fbuf);
507   rv=GWEN_SmallTresor_Decrypt((const uint8_t *) GWEN_Buffer_GetStart(fbuf), size,
508                               lct->password,
509                               rawbuf,
510                               GWEN_CRYPT_TOKEN_OHBCI_TRESOR_PWD_ITERATIONS,
511                               GWEN_CRYPT_TOKEN_OHBCI_TRESOR_CRYPT_ITERATIONS);
512   if (rv<0) {
513     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
514     GWEN_Buffer_free(rawbuf);
515     if (lct->password[0])
516       GWEN_Crypt_Token_SetPinStatus(ct,
517                                     GWEN_Crypt_PinType_Access,
518                                     GWEN_Crypt_PinEncoding_Ascii,
519                                     (trynum?GWEN_GUI_INPUT_FLAGS_RETRY:0),
520                                     (unsigned char *)lct->password,
521                                     strlen(lct->password),
522                                     0,
523                                     gid);
524     memset(lct->password, 0, sizeof(lct->password));
525     lct->passWordIsSet=0;
526     return GWEN_ERROR_BAD_PIN;
527   }
528 
529   /* parse raw data */
530   DBG_INFO(GWEN_LOGDOMAIN, "Parsing file");
531   GWEN_Buffer_Rewind(rawbuf);
532 
533   rv=GWEN_Crypt_TokenOHBCI__Decode(ct, rawbuf);
534   if (rv) {
535     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
536     GWEN_Buffer_free(rawbuf);
537     /* Set Pin status */
538     if (lct->password[0])
539       GWEN_Crypt_Token_SetPinStatus(ct,
540                                     GWEN_Crypt_PinType_Access,
541                                     GWEN_Crypt_PinEncoding_Ascii,
542                                     (trynum?GWEN_GUI_INPUT_FLAGS_RETRY:0),
543                                     (unsigned char *)lct->password,
544                                     strlen(lct->password),
545                                     0,
546                                     gid);
547     memset(lct->password, 0, sizeof(lct->password));
548     lct->passWordIsSet=0;
549     return GWEN_ERROR_BAD_PIN;
550   }
551   GWEN_Buffer_free(rawbuf);
552   /* Set Pin status */
553   if (lct->password[0])
554     GWEN_Crypt_Token_SetPinStatus(ct,
555                                   GWEN_Crypt_PinType_Access,
556                                   GWEN_Crypt_PinEncoding_Ascii,
557                                   (trynum?GWEN_GUI_INPUT_FLAGS_RETRY:0),
558                                   (unsigned char *)lct->password,
559                                   strlen(lct->password),
560                                   1,
561                                   gid);
562   return 0;
563 }
564 
565 
566 
GWEN_Crypt_TokenOHBCI_Read(GWEN_CRYPT_TOKEN * ct,int fd,uint32_t gid)567 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Read(GWEN_CRYPT_TOKEN *ct, int fd, uint32_t gid)
568 {
569   GWEN_CRYPT_TOKEN_OHBCI *lct;
570   GWEN_BUFFER *rbuf;
571   GWEN_BUFFER *fbuf;
572   unsigned char c;
573   GWEN_TAG16 *tlv;
574   int i;
575 
576   assert(ct);
577   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
578   assert(lct);
579 
580   rbuf=GWEN_Buffer_new(0, 1024, 0, 1);
581   /* read file into rbuf */
582   while (1) {
583     char buffer[256];
584     int rv;
585 
586     rv=read(fd, buffer, sizeof(buffer));
587     if (rv==-1) {
588       DBG_ERROR(GWEN_LOGDOMAIN, "read: %s", strerror(errno));
589       return -1;
590     }
591     if (rv==0)
592       break;
593     GWEN_Buffer_AppendBytes(rbuf, buffer, rv);
594   }
595 
596   if (GWEN_Buffer_GetUsedBytes(rbuf)<3) {
597     DBG_ERROR(GWEN_LOGDOMAIN, "This seems not to be an OpenHBCI key file");
598     GWEN_Buffer_free(rbuf);
599     return -1;
600   }
601 
602   /* check whether this is a known OpenHBCI(2) keyfile */
603   GWEN_Buffer_Rewind(rbuf);
604   c=*GWEN_Buffer_GetStart(rbuf);
605   if (c!=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM1 &&
606       c!=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM2 &&
607       c!=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3) {
608     DBG_ERROR(GWEN_LOGDOMAIN, "This seems not to be an OpenHBCI key file");
609     GWEN_Buffer_free(rbuf);
610     return -1;
611   }
612   lct->mediumTag=c;
613   lct->cryptoTag=0;
614 
615   tlv=GWEN_Tag16_fromBuffer(rbuf, 0);
616   if (!tlv) {
617     DBG_ERROR(GWEN_LOGDOMAIN, "Bad file data");
618     GWEN_Buffer_free(rbuf);
619     return -1;
620   }
621 
622   fbuf=GWEN_Buffer_new(0, GWEN_Tag16_GetTagLength(tlv), 0, 1);
623   GWEN_Buffer_AppendBytes(fbuf,
624                           GWEN_Tag16_GetTagData(tlv),
625                           GWEN_Tag16_GetTagLength(tlv));
626   GWEN_Buffer_Rewind(fbuf);
627   GWEN_Buffer_free(rbuf);
628   GWEN_Tag16_free(tlv);
629   /* now fbuf contains the data from the crypt TLV */
630 
631 
632   for (i=0;; i++) {
633     int rv;
634 
635     if (i>GWEN_CRYPT_TOKEN_OHBCI_MAX_PIN_TRY) {
636       DBG_ERROR(GWEN_LOGDOMAIN,
637                 "No valid PIN within %d tries, giving up", i);
638       GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Critical,
639                            I18N("No valid PIN (tried too often), "
640                                 "aborting."));
641       GWEN_Buffer_free(fbuf);
642       return GWEN_ERROR_ABORTED;
643     }
644 
645     switch (lct->mediumTag) {
646     case GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM1:
647       lct->cryptoTag=GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_OLD;
648       rv=GWEN_Crypt_TokenOHBCI__DecryptFile(ct, fbuf, i, gid);
649       break;
650     case GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM2:
651       lct->cryptoTag=GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT;
652       rv=GWEN_Crypt_TokenOHBCI__DecryptFile(ct, fbuf, i, gid);
653       break;
654     case GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3:
655       lct->cryptoTag=0;
656       rv=GWEN_Crypt_TokenOHBCI__DecryptFile16(ct, fbuf, i, gid);
657       break;
658     default:
659       rv = GWEN_ERROR_NOT_SUPPORTED;
660       /* otherwise 'rv' might be uninitialized */
661     }
662     if (rv==0)
663       break;
664     else {
665       switch (rv) {
666       case GWEN_ERROR_USER_ABORTED:
667         DBG_INFO(GWEN_LOGDOMAIN, "Aborted by user");
668         GWEN_Buffer_free(fbuf);
669         return rv;
670       case GWEN_ERROR_BAD_PIN:
671         DBG_ERROR(GWEN_LOGDOMAIN, "Bad pin.");
672         GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Critical,
673                              I18N("Bad PIN, will try again"));
674         break;
675 
676       default:
677         DBG_INFO(GWEN_LOGDOMAIN, "Other error, giving up");
678         GWEN_Buffer_free(fbuf);
679         return rv;
680       }
681     }
682 
683   } /* for */
684   GWEN_Buffer_free(fbuf);
685 
686   lct->justCreated=0;
687 
688   return 0;
689 }
690 
691 
692 
GWEN_Crypt_TokenOHBCI__DecodeKey(GWEN_UNUSED GWEN_CRYPT_TOKEN * ct,GWEN_TAG16 * keyTlv,GWEN_DB_NODE * dbKeys,const char * keyName)693 void GWEN_Crypt_TokenOHBCI__DecodeKey(GWEN_UNUSED GWEN_CRYPT_TOKEN *ct,
694                                       GWEN_TAG16 *keyTlv,
695                                       GWEN_DB_NODE *dbKeys,
696                                       const char *keyName)
697 {
698   GWEN_BUFFER *dbuf;
699   const char *p;
700   int size;
701   GWEN_DB_NODE *node;
702   uint32_t flags;
703   const char defaultExpo[3]= {0x01, 0x00, 0x01};
704 
705   p=GWEN_Tag16_GetTagData(keyTlv);
706   size=GWEN_Tag16_GetTagLength(keyTlv);
707   if (size<2) {
708     DBG_ERROR(GWEN_LOGDOMAIN, "Tag too small to contain any subtag");
709     return;
710   }
711   /* create static buffer */
712   dbuf=GWEN_Buffer_new((char *)p, size, size, 0);
713   GWEN_Buffer_SubMode(dbuf, GWEN_BUFFER_MODE_DYNAMIC);
714 
715   node=GWEN_DB_GetGroup(dbKeys, GWEN_DB_FLAGS_DEFAULT, keyName);
716   assert(node);
717 
718   /* preset */
719   GWEN_DB_SetCharValue(node,
720                        GWEN_DB_FLAGS_OVERWRITE_VARS,
721                        "cryptAlgoId",
722                        "rsa");
723   GWEN_DB_SetIntValue(node,
724                       GWEN_DB_FLAGS_OVERWRITE_VARS,
725                       "keySize",
726                       96);
727   GWEN_DB_SetBinValue(node,
728                       GWEN_DB_FLAGS_OVERWRITE_VARS,
729                       "rsa/e",
730                       defaultExpo,
731                       sizeof(defaultExpo));
732   flags=0;
733   GWEN_DB_SetIntValue(node,
734                       GWEN_DB_FLAGS_OVERWRITE_VARS,
735                       "flags",
736                       flags);
737 
738   while (GWEN_Buffer_GetBytesLeft(dbuf)) {
739     const char *pp;
740     char *p;
741     GWEN_TAG16 *tlv;
742     unsigned int l;
743 
744     tlv=GWEN_Tag16_fromBuffer(dbuf, 0);
745     if (!tlv) {
746       DBG_ERROR(GWEN_LOGDOMAIN, "Bad file (no TLV)");
747       return;
748     }
749     p=0;
750     pp=(const char *)GWEN_Tag16_GetTagData(tlv);
751     l=GWEN_Tag16_GetTagLength(tlv);
752     if (pp && l) {
753       p=(char *)malloc(l+1);
754       assert(p);
755       memmove(p, pp, l);
756       p[l]=0;
757     }
758 
759     switch (GWEN_Tag16_GetTagType(tlv)) {
760     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_ISPUBLIC:
761       /* ignore this tag, since it is buggy in OpenHBCI(2) */
762       break;
763 
764     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_ISCRYPT:
765       /* no longer supported since 1.8*/
766       break;
767 
768     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_OWNER:
769       GWEN_DB_SetCharValue(node,
770                            GWEN_DB_FLAGS_OVERWRITE_VARS,
771                            "keyOwner",
772                            p);
773       break;
774 
775     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_VERSION:
776       assert(p);
777       GWEN_DB_SetIntValue(node,
778                           GWEN_DB_FLAGS_OVERWRITE_VARS,
779                           "keyVersion",
780                           atoi(p));
781       break;
782 
783     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_NUMBER:
784       assert(p);
785       GWEN_DB_SetIntValue(node,
786                           GWEN_DB_FLAGS_OVERWRITE_VARS,
787                           "keyNumber",
788                           atoi(p));
789       break;
790 
791     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_MODULUS:
792       if (p && l)
793         GWEN_DB_SetBinValue(node,
794                             GWEN_DB_FLAGS_OVERWRITE_VARS,
795                             "rsa/n",
796                             p, l);
797       break;
798 
799     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_EXP_OLD:
800       DBG_INFO(GWEN_LOGDOMAIN,
801                "Ignoring old exponent (%d), keeping default", l);
802       break;
803 
804     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_EXP:
805       if (p && l)
806         GWEN_DB_SetBinValue(node,
807                             GWEN_DB_FLAGS_OVERWRITE_VARS,
808                             "rsa/e",
809                             p, l);
810       break;
811 
812     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_N:
813       if (p && l)
814         GWEN_DB_SetBinValue(node,
815                             GWEN_DB_FLAGS_OVERWRITE_VARS,
816                             "rsa/n",
817                             p, l);
818       break;
819 
820     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_P:
821       if (p && l)
822         GWEN_DB_SetBinValue(node,
823                             GWEN_DB_FLAGS_OVERWRITE_VARS,
824                             "rsa/p",
825                             p, l);
826       break;
827 
828     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_Q:
829       if (p && l)
830         GWEN_DB_SetBinValue(node,
831                             GWEN_DB_FLAGS_OVERWRITE_VARS,
832                             "rsa/q",
833                             p, l);
834       break;
835 
836     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_D:
837       if (p && l)
838         GWEN_DB_SetBinValue(node,
839                             GWEN_DB_FLAGS_OVERWRITE_VARS,
840                             "rsa/d",
841                             p, l);
842       break;
843 
844     case GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_LEN:
845       if (p && l) {
846         int i;
847 
848         /* fix for some versions which stored keysize*8 */
849         i=atoi(p);
850         if (i>512)
851           i/=8;
852         GWEN_DB_SetIntValue(node,
853                             GWEN_DB_FLAGS_OVERWRITE_VARS,
854                             "keySize",
855                             i);
856       }
857       break;
858 
859     default:
860       DBG_WARN(GWEN_LOGDOMAIN, "Unknown tag %02x", GWEN_Tag16_GetTagType(tlv));
861       break;
862     } /* switch */
863 
864     GWEN_Tag16_free(tlv);
865     free(p);
866   } /* while */
867   GWEN_Buffer_free(dbuf);
868 }
869 
870 
871 
GWEN_Crypt_TokenOHBCI__Decode(GWEN_CRYPT_TOKEN * ct,GWEN_BUFFER * dbuf)872 int GWEN_Crypt_TokenOHBCI__Decode(GWEN_CRYPT_TOKEN *ct, GWEN_BUFFER *dbuf)
873 {
874   GWEN_CRYPT_TOKEN_OHBCI *lct;
875   GWEN_TAG16 *tlv;
876   int rv;
877   GWEN_DB_NODE *dbKeys;
878   GWEN_DB_NODE *dbKey;
879   GWEN_CRYPT_TOKEN_CONTEXT *fct;
880   const char *peerId=0;
881   uint32_t localSignSeq=0;
882   uint32_t remoteSignSeq=0;
883 
884   assert(ct);
885   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
886   assert(lct);
887 
888   tlv=GWEN_Tag16_fromBuffer(dbuf, 0);
889   GWEN_Buffer_Rewind(dbuf);
890   if (!tlv) {
891     DBG_ERROR(GWEN_LOGDOMAIN,
892               "File doesn't contain a TLV: Either bad pin or bad file");
893     return -1;
894   }
895 
896   if (GWEN_Tag16_GetTagType(tlv)!=GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER &&
897       GWEN_Tag16_GetTagType(tlv)!=GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MAJOR) {
898     DBG_ERROR(GWEN_LOGDOMAIN,
899               "File doesn't start with version info or header.");
900     GWEN_Tag16_free(tlv);
901     return -1;
902   }
903   GWEN_Tag16_free(tlv);
904 
905   fct=GWEN_CTF_Context_new();
906 
907   /* now parse it */
908   dbKeys=GWEN_DB_Group_new("keys");
909   while (GWEN_Buffer_GetBytesLeft(dbuf)) {
910     int i;
911     const char *pp;
912     char *p;
913     unsigned int l;
914 
915     tlv=GWEN_Tag16_fromBuffer(dbuf, 0);
916     if (!tlv) {
917       DBG_ERROR(GWEN_LOGDOMAIN,
918                 "File doesn't contain a TLV: Either bad pin or bad file");
919       GWEN_Crypt_Token_Context_free(fct);
920       return GWEN_ERROR_BAD_PIN;
921     }
922     p=0;
923     pp=(const char *)GWEN_Tag16_GetTagData(tlv);
924     l=GWEN_Tag16_GetTagLength(tlv);
925     if (pp && l) {
926       p=(char *)malloc(l+1);
927       assert(p);
928       memmove(p, pp, l);
929       p[l]=0;
930     }
931 
932     switch (GWEN_Tag16_GetTagType(tlv)) {
933     case GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MAJOR:
934       assert(p);
935       i=atoi(p);
936       DBG_INFO(GWEN_LOGDOMAIN, "OHBCI: Major version: %d", i);
937       if (i!=GWEN_CRYPT_TOKEN_OHBCI_VMAJOR) {
938         DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported keyfile version (%d)", i);
939         GWEN_Gui_ProgressLog(0,
940                              GWEN_LoggerLevel_Warning,
941                              "Basically this file type is supported.\n"
942                              "However, the major versions do not match,\n"
943                              "so this particular version is not supported");
944         free(p);
945         GWEN_Tag16_free(tlv);
946         GWEN_Crypt_Token_Context_free(fct);
947         return -1;
948       }
949       break;
950 
951     case GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MINOR:
952       assert(p);
953       i=atoi(p);
954       DBG_INFO(GWEN_LOGDOMAIN, "OHBCI: Minor version: %d", i);
955       if (i>GWEN_CRYPT_TOKEN_OHBCI_VMINOR) {
956         DBG_ERROR(GWEN_LOGDOMAIN,
957                   "Keyfile version is higher than mine (%d).\n",
958                   i);
959         GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Warning,
960                              "This key file file has been created with a "
961                              "newer library version.\n");
962         free(p);
963         GWEN_Tag16_free(tlv);
964         GWEN_Crypt_Token_Context_free(fct);
965         return GWEN_ERROR_NOT_SUPPORTED;
966       }
967       else if (i<GWEN_CRYPT_TOKEN_OHBCI_VMINOR) {
968         DBG_INFO(GWEN_LOGDOMAIN, "Will update this file upon unmount");
969       }
970       lct->vminor=i;
971       break;
972 
973     case GWEN_CRYPT_TOKEN_OHBCI_TAG_SEQ:
974       assert(p);
975       localSignSeq=atoi(p);
976       if (localSignSeq==0)
977         localSignSeq=1;
978       break;
979 
980     case GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_ID:
981       GWEN_Crypt_Token_Context_SetUserId(fct, p);
982       break;
983 
984     case GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_COUNTRY:
985       /* ignore */
986       break;
987 
988     case GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_CODE:
989       GWEN_Crypt_Token_Context_SetServiceId(fct, p);
990       break;
991 
992     case GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_SYSTEMID:
993       GWEN_Crypt_Token_Context_SetSystemId(fct, p);
994       break;
995 
996     case GWEN_CRYPT_TOKEN_OHBCI_TAG_SERVER_ADDR:
997       /* new in 1.4 */
998       GWEN_Crypt_Token_Context_SetAddress(fct, p);
999       break;
1000 
1001     case GWEN_CRYPT_TOKEN_OHBCI_TAG_SERVER_PORT:
1002       /* new in 1.4 */
1003       GWEN_Crypt_Token_Context_SetPort(fct, atoi(p));
1004       break;
1005 
1006     case GWEN_CRYPT_TOKEN_OHBCI_TAG_REMOTE_SEQ:
1007       /* new in 1.4 */
1008       remoteSignSeq=atoi(p);
1009       break;
1010 
1011     case GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PUBSIGNKEY:
1012     case GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PRIVSIGNKEY:
1013       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "localSignKey");
1014       break;
1015 
1016     case GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PUBCRYPTKEY:
1017     case GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PRIVCRYPTKEY:
1018       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "localCryptKey");
1019       break;
1020 
1021     case GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBSIGNKEY:
1022       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "remoteSignKey");
1023       break;
1024 
1025     case GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBCRYPTKEY:
1026       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "remoteCryptKey");
1027       break;
1028 
1029     /* handled again since 1.8 */
1030     case GWEN_CRYPT_TOKEN_OHBCI_TAG_TEMP_PUBSIGNKEY:
1031     case GWEN_CRYPT_TOKEN_OHBCI_TAG_TEMP_PRIVSIGNKEY:
1032       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "tempLocalSignKey");
1033       break;
1034 
1035     case GWEN_CRYPT_TOKEN_OHBCI_TAG_TEMP_PUBCRYPTKEY:
1036     case GWEN_CRYPT_TOKEN_OHBCI_TAG_TEMP_PRIVCRYPTKEY:
1037       DBG_INFO(GWEN_LOGDOMAIN,
1038                "Ignoring temporary crypt keys");
1039       break;
1040 
1041     case GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PRIVAUTHKEY:
1042       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "localAuthKey");
1043       break;
1044 
1045     case GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBAUTHKEY:
1046       GWEN_Crypt_TokenOHBCI__DecodeKey(ct, tlv, dbKeys, "remoteAuthKey");
1047       break;
1048 
1049     case GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER:
1050       /* ignore header here */
1051       break;
1052     default:
1053       DBG_WARN(GWEN_LOGDOMAIN, "Unknown tag %02x",
1054                GWEN_Tag16_GetTagType(tlv));
1055       break;
1056     } /* switch */
1057 
1058     GWEN_Tag16_free(tlv);
1059     free(p);
1060   } /* while */
1061 
1062 
1063   /* now check for keys */
1064   rv=0;
1065 
1066   /* local sign key */
1067   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1068                          "localSignKey");
1069   if (dbKey) {
1070     GWEN_CRYPT_KEY *key;
1071 
1072     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1073                         "rsa/isPublic", 0);
1074     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1075     if (!key) {
1076       rv=-1;
1077       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1078     }
1079     else {
1080       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1081       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1082       uint32_t klen;
1083 
1084       /* create key info */
1085       ki=GWEN_Crypt_Token_KeyInfo_new(0x0001, /* local sign key */
1086                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1087                                       GWEN_Crypt_Key_GetKeySize(key));
1088       assert(ki);
1089 
1090       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Sign Key"));
1091 
1092       /* get modulus */
1093       klen=sizeof(kbuf);
1094       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1095       if (rv) {
1096         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1097         GWEN_Crypt_Token_KeyInfo_free(ki);
1098         GWEN_Crypt_Key_free(key);
1099         return rv;
1100       }
1101       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1102 
1103       /* get exponent */
1104       klen=sizeof(kbuf);
1105       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1106       if (rv) {
1107         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1108         GWEN_Crypt_Token_KeyInfo_free(ki);
1109         GWEN_Crypt_Key_free(key);
1110         return rv;
1111       }
1112       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1113 
1114       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, localSignSeq);
1115       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1116       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1117 
1118       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1119                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1120                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1121                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1122                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1123                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
1124                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1125                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
1126                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
1127       GWEN_CTF_Context_SetLocalSignKeyInfo(fct, ki);
1128 
1129       /* set key */
1130       if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
1131         DBG_INFO(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1132         GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1133       }
1134       GWEN_CTF_Context_SetLocalSignKey(fct, key);
1135     }
1136   }
1137   else {
1138     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1139 
1140     /* create key info */
1141     ki=GWEN_Crypt_Token_KeyInfo_new(0x0001, /* local sign key */
1142                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1143     assert(ki);
1144 
1145     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Sign Key"));
1146     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1147                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1148                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1149                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1150                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
1151                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
1152     GWEN_CTF_Context_SetLocalSignKeyInfo(fct, ki);
1153   }
1154 
1155   /* local crypt key */
1156   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1157                          "localCryptKey");
1158   if (dbKey) {
1159     GWEN_CRYPT_KEY *key;
1160 
1161     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1162                         "rsa/isPublic", 0);
1163     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1164     if (!key) {
1165       rv=-1;
1166       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1167     }
1168     else {
1169       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1170       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1171       uint32_t klen;
1172 
1173       /* create key info */
1174       ki=GWEN_Crypt_Token_KeyInfo_new(0x0002, /* local crypt key */
1175                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1176                                       GWEN_Crypt_Key_GetKeySize(key));
1177       assert(ki);
1178       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Crypt Key"));
1179 
1180       /* get modulus */
1181       klen=sizeof(kbuf);
1182       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1183       if (rv) {
1184         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1185         GWEN_Crypt_Token_KeyInfo_free(ki);
1186         GWEN_Crypt_Key_free(key);
1187         return rv;
1188       }
1189       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1190 
1191       /* get exponent */
1192       klen=sizeof(kbuf);
1193       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1194       if (rv) {
1195         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1196         GWEN_Crypt_Token_KeyInfo_free(ki);
1197         GWEN_Crypt_Key_free(key);
1198         return rv;
1199       }
1200       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1201       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1202       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1203 
1204       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1205                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1206                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1207                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1208                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1209                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1210                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
1211                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANDECIPHER);
1212       GWEN_CTF_Context_SetLocalCryptKeyInfo(fct, ki);
1213       /* set key */
1214       GWEN_CTF_Context_SetLocalCryptKey(fct, key);
1215     }
1216   }
1217   else {
1218     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1219 
1220     /* create key info */
1221     ki=GWEN_Crypt_Token_KeyInfo_new(0x0002, /* local crypt key */
1222                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1223     assert(ki);
1224     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Crypt Key"));
1225     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1226                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1227                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1228                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1229                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
1230                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANDECIPHER);
1231     GWEN_CTF_Context_SetLocalCryptKeyInfo(fct, ki);
1232   }
1233 
1234   /* remote sign key */
1235   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1236                          "remoteSignKey");
1237   if (dbKey) {
1238     GWEN_CRYPT_KEY *key;
1239 
1240     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1241                         "rsa/isPublic", 1);
1242     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1243     if (!key) {
1244       rv=-1;
1245       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1246     }
1247     else {
1248       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1249       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1250       uint32_t klen;
1251 
1252       /* create key info */
1253       ki=GWEN_Crypt_Token_KeyInfo_new(0x0003, /* remote sign key */
1254                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1255                                       GWEN_Crypt_Key_GetKeySize(key));
1256       assert(ki);
1257       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Sign Key"));
1258 
1259       /* get modulus */
1260       klen=sizeof(kbuf);
1261       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1262       if (rv) {
1263         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1264         GWEN_Crypt_Token_KeyInfo_free(ki);
1265         GWEN_Crypt_Key_free(key);
1266         return rv;
1267       }
1268       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1269 
1270       /* get exponent */
1271       klen=sizeof(kbuf);
1272       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1273       if (rv) {
1274         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1275         GWEN_Crypt_Token_KeyInfo_free(ki);
1276         GWEN_Crypt_Key_free(key);
1277         return rv;
1278       }
1279       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1280 
1281       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, remoteSignSeq);
1282       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1283       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1284 
1285       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1286                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1287                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1288                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1289                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1290                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
1291                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1292                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY);
1293       GWEN_CTF_Context_SetRemoteSignKeyInfo(fct, ki);
1294 
1295       /* set key */
1296       if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN)
1297         GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1298       GWEN_CTF_Context_SetRemoteSignKey(fct, key);
1299     }
1300   }
1301   else {
1302     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1303 
1304     /* create key info */
1305     ki=GWEN_Crypt_Token_KeyInfo_new(0x0003, /* remote sign key */
1306                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1307     assert(ki);
1308     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Sign Key"));
1309     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1310                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1311                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1312                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1313                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY);
1314     GWEN_CTF_Context_SetRemoteSignKeyInfo(fct, ki);
1315   }
1316 
1317   /* remote crypt key */
1318   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1319                          "remoteCryptKey");
1320   if (dbKey) {
1321     GWEN_CRYPT_KEY *key;
1322 
1323     peerId=GWEN_DB_GetCharValue(dbKey, "keyOwner", 0, NULL);
1324     if (peerId) {
1325       DBG_INFO(0, "Got Peer Id [%s]", peerId);
1326     }
1327     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1328                         "rsa/isPublic", 1);
1329     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1330     if (!key) {
1331       rv=-1;
1332       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1333     }
1334     else {
1335       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1336       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1337       uint32_t klen;
1338 
1339       /* create key info */
1340       ki=GWEN_Crypt_Token_KeyInfo_new(0x0004, /* remote crypt key */
1341                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1342                                       GWEN_Crypt_Key_GetKeySize(key));
1343       assert(ki);
1344       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Crypt Key"));
1345 
1346       /* get modulus */
1347       klen=sizeof(kbuf);
1348       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1349       if (rv) {
1350         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1351         GWEN_Crypt_Token_KeyInfo_free(ki);
1352         GWEN_Crypt_Key_free(key);
1353         return rv;
1354       }
1355       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1356 
1357       /* get exponent */
1358       klen=sizeof(kbuf);
1359       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1360       if (rv) {
1361         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1362         GWEN_Crypt_Token_KeyInfo_free(ki);
1363         GWEN_Crypt_Key_free(key);
1364         return rv;
1365       }
1366       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1367       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1368       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1369       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1370                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1371                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1372                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1373                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1374                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1375                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER);
1376       GWEN_CTF_Context_SetRemoteCryptKeyInfo(fct, ki);
1377 
1378       /* set key */
1379       GWEN_CTF_Context_SetRemoteCryptKey(fct, key);
1380     }
1381   }
1382   else {
1383     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1384 
1385     /* create key info */
1386     ki=GWEN_Crypt_Token_KeyInfo_new(0x0004, /* remote crypt key */
1387                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1388     assert(ki);
1389     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Crypt Key"));
1390     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1391                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1392                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1393                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1394                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER);
1395     GWEN_CTF_Context_SetRemoteCryptKeyInfo(fct, ki);
1396   }
1397 
1398   /* local auth key */
1399   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1400                          "localAuthKey");
1401   if (dbKey) {
1402     GWEN_CRYPT_KEY *key;
1403 
1404     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1405                         "rsa/isPublic", 0);
1406     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1407     if (!key) {
1408       rv=-1;
1409       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1410     }
1411     else {
1412       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1413       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1414       uint32_t klen;
1415 
1416       /* create key info */
1417       ki=GWEN_Crypt_Token_KeyInfo_new(0x0005, /* local auth key */
1418                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1419                                       GWEN_Crypt_Key_GetKeySize(key));
1420       assert(ki);
1421       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Auth Key"));
1422 
1423       /* get modulus */
1424       klen=sizeof(kbuf);
1425       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1426       if (rv) {
1427         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1428         GWEN_Crypt_Token_KeyInfo_free(ki);
1429         GWEN_Crypt_Key_free(key);
1430         return rv;
1431       }
1432       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1433 
1434       /* get exponent */
1435       klen=sizeof(kbuf);
1436       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1437       if (rv) {
1438         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1439         GWEN_Crypt_Token_KeyInfo_free(ki);
1440         GWEN_Crypt_Key_free(key);
1441         return rv;
1442       }
1443       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1444       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1445       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1446       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1447                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1448                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1449                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1450                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1451                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1452                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN |
1453                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY);
1454       GWEN_CTF_Context_SetLocalAuthKeyInfo(fct, ki);
1455       /* set key */
1456       if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
1457         DBG_INFO(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1458         GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1459       }
1460       GWEN_CTF_Context_SetLocalAuthKey(fct, key);
1461     }
1462   }
1463   else {
1464     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1465 
1466     /* create key info */
1467     ki=GWEN_Crypt_Token_KeyInfo_new(0x0005, /* local auth key */
1468                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1469     assert(ki);
1470     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Auth Key"));
1471     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1472                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1473                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1474                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1475                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN |
1476                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY);
1477     GWEN_CTF_Context_SetLocalAuthKeyInfo(fct, ki);
1478   }
1479 
1480   /* remote auth key */
1481   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1482                          "remoteAuthKey");
1483   if (dbKey) {
1484     GWEN_CRYPT_KEY *key;
1485 
1486     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1487                         "rsa/isPublic", 1);
1488     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1489     if (!key) {
1490       rv=-1;
1491       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1492     }
1493     else {
1494       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1495       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1496       uint32_t klen;
1497 
1498       /* create key info */
1499       ki=GWEN_Crypt_Token_KeyInfo_new(0x0006, /* remote auth key */
1500                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1501                                       GWEN_Crypt_Key_GetKeySize(key));
1502       assert(ki);
1503       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Auth Key"));
1504 
1505       /* get modulus */
1506       klen=sizeof(kbuf);
1507       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1508       if (rv) {
1509         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1510         GWEN_Crypt_Token_KeyInfo_free(ki);
1511         GWEN_Crypt_Key_free(key);
1512         return rv;
1513       }
1514       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1515 
1516       /* get exponent */
1517       klen=sizeof(kbuf);
1518       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1519       if (rv) {
1520         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1521         GWEN_Crypt_Token_KeyInfo_free(ki);
1522         GWEN_Crypt_Key_free(key);
1523         return rv;
1524       }
1525       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1526       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1527       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1528       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1529                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1530                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1531                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1532                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1533                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1534                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY);
1535       GWEN_CTF_Context_SetRemoteAuthKeyInfo(fct, ki);
1536       /* set key */
1537       if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
1538         DBG_INFO(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1539         GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1540       }
1541       GWEN_CTF_Context_SetRemoteAuthKey(fct, key);
1542     }
1543   }
1544   else {
1545     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1546 
1547     /* create key info */
1548     ki=GWEN_Crypt_Token_KeyInfo_new(0x0006, /* remote auth key */
1549                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1550     assert(ki);
1551     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Auth Key"));
1552     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1553                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1554                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1555                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1556                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY);
1557     GWEN_CTF_Context_SetRemoteAuthKeyInfo(fct, ki);
1558   }
1559 
1560 
1561   /* temp local sign key */
1562   dbKey=GWEN_DB_GetGroup(dbKeys, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
1563                          "tempLocalSignKey");
1564   if (dbKey) {
1565     GWEN_CRYPT_KEY *key;
1566 
1567     GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
1568                         "rsa/isPublic", 0);
1569     key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
1570     if (!key) {
1571       rv=-1;
1572       DBG_ERROR(GWEN_LOGDOMAIN, "Bad key format");
1573     }
1574     else {
1575       GWEN_CRYPT_TOKEN_KEYINFO *ki;
1576       uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1577       uint32_t klen;
1578 
1579       /* create key info */
1580       ki=GWEN_Crypt_Token_KeyInfo_new(0x0007, /* temp local sign key */
1581                                       GWEN_Crypt_Key_GetCryptAlgoId(key),
1582                                       GWEN_Crypt_Key_GetKeySize(key));
1583       assert(ki);
1584 
1585       GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Temporary Local Sign Key"));
1586 
1587       /* get modulus */
1588       klen=sizeof(kbuf);
1589       rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1590       if (rv) {
1591         DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1592         GWEN_Crypt_Token_KeyInfo_free(ki);
1593         GWEN_Crypt_Key_free(key);
1594         return rv;
1595       }
1596       GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1597 
1598       /* get exponent */
1599       klen=sizeof(kbuf);
1600       rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1601       if (rv) {
1602         DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1603         GWEN_Crypt_Token_KeyInfo_free(ki);
1604         GWEN_Crypt_Key_free(key);
1605         return rv;
1606       }
1607       GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1608 
1609       GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1610       GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1611 
1612       GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1613                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1614                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1615                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1616                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1617                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
1618                                         GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1619                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
1620                                         GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
1621       GWEN_CTF_Context_SetTempLocalSignKeyInfo(fct, ki);
1622 
1623       /* set key */
1624       if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
1625         DBG_INFO(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1626         GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1627       }
1628       GWEN_CTF_Context_SetTempLocalSignKey(fct, key);
1629     }
1630   }
1631   else {
1632     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1633 
1634     /* create key info */
1635     ki=GWEN_Crypt_Token_KeyInfo_new(0x0007, /* temp local sign key */
1636                                     GWEN_Crypt_CryptAlgoId_Rsa, 96);
1637     assert(ki);
1638 
1639     GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Temporary Local Sign Key"));
1640     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1641                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1642                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1643                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1644                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
1645                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
1646     GWEN_CTF_Context_SetTempLocalSignKeyInfo(fct, ki);
1647   }
1648 
1649 
1650   /* finalize user and file context */
1651   GWEN_Crypt_Token_Context_SetId(fct, 1);            /* only one user */
1652   GWEN_Crypt_Token_Context_SetPeerId(fct, peerId);   /* only one user */
1653 
1654   GWEN_Crypt_Token_Context_SetSignKeyId(fct, 0x01);
1655   GWEN_Crypt_Token_Context_SetDecipherKeyId(fct, 0x02);
1656   GWEN_Crypt_Token_Context_SetVerifyKeyId(fct, 0x03);
1657   GWEN_Crypt_Token_Context_SetEncipherKeyId(fct, 0x04);
1658   GWEN_Crypt_Token_Context_SetAuthSignKeyId(fct, 0x05);
1659   GWEN_Crypt_Token_Context_SetAuthVerifyKeyId(fct, 0x06);
1660   GWEN_Crypt_Token_Context_SetTempSignKeyId(fct, 0x07);
1661 
1662   /* clear context list, add new context */
1663   GWEN_Crypt_TokenFile_AddContext(ct, fct);
1664 
1665   GWEN_DB_Group_free(dbKeys);
1666   return rv;
1667 }
1668 
1669 
1670 
GWEN_Crypt_TokenOHBCI__DecryptFile16(GWEN_CRYPT_TOKEN * ct,GWEN_BUFFER * dbuf,int tryNum,uint32_t gid)1671 int GWEN_Crypt_TokenOHBCI__DecryptFile16(GWEN_CRYPT_TOKEN *ct,
1672                                          GWEN_BUFFER *dbuf,
1673                                          int tryNum,
1674                                          uint32_t gid)
1675 {
1676   GWEN_CRYPT_TOKEN_OHBCI *lct;
1677   GWEN_TAG16 *tlv;
1678   int rv;
1679 
1680   assert(ct);
1681   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
1682   assert(lct);
1683 
1684   tlv=GWEN_Tag16_fromBuffer(dbuf, 0);
1685   GWEN_Buffer_Rewind(dbuf);
1686   if (!tlv) {
1687     DBG_ERROR(GWEN_LOGDOMAIN,
1688               "File doesn't contain a TLV: Either bad pin or bad file");
1689     return GWEN_ERROR_BAD_PIN;
1690   }
1691 
1692   if (GWEN_Tag16_GetTagType(tlv)!=GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER) {
1693     DBG_ERROR(GWEN_LOGDOMAIN, "File doesn't start with header tag.");
1694     GWEN_Tag16_free(tlv);
1695     return GWEN_ERROR_GENERIC;
1696   }
1697   GWEN_Tag16_free(tlv);
1698 
1699   /* now parse it */
1700   while (GWEN_Buffer_GetBytesLeft(dbuf)) {
1701     int i;
1702     const char *pp;
1703     char *p;
1704     unsigned int l;
1705 
1706     tlv=GWEN_Tag16_fromBuffer(dbuf, 0);
1707     if (!tlv) {
1708       DBG_ERROR(GWEN_LOGDOMAIN,
1709                 "File doesn't contain a TLV: Either bad pin or bad file");
1710       return GWEN_ERROR_BAD_PIN;
1711     }
1712     p=0;
1713     pp=(const char *)GWEN_Tag16_GetTagData(tlv);
1714     l=GWEN_Tag16_GetTagLength(tlv);
1715     if (pp && l) {
1716       p=(char *)malloc(l+1);
1717       assert(p);
1718       memmove(p, pp, l);
1719       p[l]=0;
1720     }
1721 
1722     switch (GWEN_Tag16_GetTagType(tlv)) {
1723     case GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER:
1724       if (strcasecmp(p, GWEN_CRYPT_TOKEN_OHBCI_NAME)!=0) {
1725         DBG_ERROR(GWEN_LOGDOMAIN, "Bad header (%s)", p);
1726         free(p);
1727         GWEN_Tag16_free(tlv);
1728         return -1;
1729       }
1730       break;
1731 
1732     case GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MAJOR:
1733       i=atoi(p);
1734       if (i!=GWEN_CRYPT_TOKEN_OHBCI_VMAJOR) {
1735         DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported keyfile version (%d)", i);
1736         GWEN_Gui_ProgressLog(0,
1737                              GWEN_LoggerLevel_Warning,
1738                              "Basically this file type is supported.\n"
1739                              "However, the major versions do not match,\n"
1740                              "so this particular version is not supported");
1741         free(p);
1742         GWEN_Tag16_free(tlv);
1743         return -1;
1744       }
1745       break;
1746 
1747     case GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MINOR:
1748       i=atoi(p);
1749       if (i>GWEN_CRYPT_TOKEN_OHBCI_VMINOR) {
1750         DBG_WARN(GWEN_LOGDOMAIN,
1751                  "Keyfile version is higher than mine (%d).\n",
1752                  i);
1753         GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Warning,
1754                              "This key file file has been created with a "
1755                              "newer library version.\n");
1756         free(p);
1757         GWEN_Tag16_free(tlv);
1758         return -1;
1759       }
1760       else if (i<GWEN_CRYPT_TOKEN_OHBCI_VMINOR) {
1761         DBG_INFO(GWEN_LOGDOMAIN,
1762                  "Will update this file upon unmount (%d)", i);
1763       }
1764       lct->vminor=i;
1765       break;
1766 
1767     case GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_OLD:
1768     case GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT:
1769     case GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_BF: {
1770       GWEN_BUFFER *fbuf;
1771 
1772       lct->cryptoTag=GWEN_Tag16_GetTagType(tlv);
1773       fbuf=GWEN_Buffer_new(0, GWEN_Tag16_GetTagLength(tlv), 0, 1);
1774       GWEN_Buffer_AppendBytes(fbuf,
1775                               GWEN_Tag16_GetTagData(tlv),
1776                               GWEN_Tag16_GetTagLength(tlv));
1777       GWEN_Buffer_Rewind(fbuf);
1778       rv=GWEN_Crypt_TokenOHBCI__DecryptFile(ct, fbuf, tryNum, gid);
1779       GWEN_Buffer_free(fbuf);
1780       if (rv) {
1781         free(p);
1782         GWEN_Tag16_free(tlv);
1783         return rv;
1784       }
1785       break;
1786     }
1787 
1788     case GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_TRESOR: {
1789       GWEN_BUFFER *fbuf;
1790 
1791       lct->cryptoTag=GWEN_Tag16_GetTagType(tlv);
1792       fbuf=GWEN_Buffer_new(0, GWEN_Tag16_GetTagLength(tlv), 0, 1);
1793       GWEN_Buffer_AppendBytes(fbuf,
1794                               GWEN_Tag16_GetTagData(tlv),
1795                               GWEN_Tag16_GetTagLength(tlv));
1796       GWEN_Buffer_Rewind(fbuf);
1797       rv=GWEN_Crypt_TokenOHBCI__DecryptTresor(ct, fbuf, tryNum, gid);
1798       GWEN_Buffer_free(fbuf);
1799       if (rv) {
1800         free(p);
1801         GWEN_Tag16_free(tlv);
1802         return rv;
1803       }
1804       break;
1805     }
1806 
1807     default:
1808       DBG_WARN(GWEN_LOGDOMAIN, "Unknown tag %02x",
1809                GWEN_Tag16_GetTagType(tlv));
1810       break;
1811     } /* switch */
1812 
1813     GWEN_Tag16_free(tlv);
1814     free(p);
1815   } /* while */
1816 
1817   return 0;
1818 }
1819 
1820 
1821 
GWEN_Crypt_TokenOHBCI__EncodeKey(const GWEN_CRYPT_KEY * key,GWEN_CRYPT_TOKEN_CONTEXT * fct,unsigned int tagType,int wantPublic,int isCrypt,GWEN_BUFFER * dbuf)1822 int GWEN_Crypt_TokenOHBCI__EncodeKey(const GWEN_CRYPT_KEY *key,
1823                                      GWEN_CRYPT_TOKEN_CONTEXT *fct,
1824                                      unsigned int tagType,
1825                                      int wantPublic,
1826                                      int isCrypt,
1827                                      GWEN_BUFFER *dbuf)
1828 {
1829   GWEN_DB_NODE *dbKey;
1830   int err;
1831   const void *p;
1832   unsigned int bs;
1833   char *pp;
1834   uint32_t pos;
1835   char numbuf[16];
1836 
1837   if (!key) {
1838     DBG_INFO(GWEN_LOGDOMAIN, "No key");
1839     return 0;
1840   }
1841   dbKey=GWEN_DB_Group_new("key");
1842   err=GWEN_Crypt_KeyRsa_toDb(key, dbKey, wantPublic);
1843   if (err) {
1844     DBG_ERROR_ERR(GWEN_LOGDOMAIN, err);
1845     GWEN_DB_Group_free(dbKey);
1846     return err;
1847   }
1848 
1849   GWEN_Buffer_AppendByte(dbuf, tagType & 0xff);
1850   /* remember pos to insert size later */
1851   pos=GWEN_Buffer_GetPos(dbuf);
1852   GWEN_Buffer_AppendBytes(dbuf, "00", 2);
1853 
1854   /* always write "NO" for "isPublic", since OpenHBCI always writes "NO"
1855    * due to a bug */
1856   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_ISPUBLIC,
1857                               "NO",
1858                               -1,
1859                               dbuf);
1860   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_ISCRYPT,
1861                               isCrypt?"YES":"NO",
1862                               -1,
1863                               dbuf);
1864 
1865   snprintf(numbuf, sizeof(numbuf), "%d", GWEN_Crypt_Key_GetKeyNumber(key));
1866   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_NUMBER,
1867                               numbuf,
1868                               -1,
1869                               dbuf);
1870   snprintf(numbuf, sizeof(numbuf), "%d", GWEN_Crypt_Key_GetKeyVersion(key));
1871   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_VERSION,
1872                               numbuf,
1873                               -1,
1874                               dbuf);
1875   snprintf(numbuf, sizeof(numbuf), "%d", GWEN_Crypt_Key_GetKeySize(key));
1876   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_LEN,
1877                               numbuf,
1878                               -1,
1879                               dbuf);
1880 
1881   /* write key owner again */
1882   if (tagType==GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBCRYPTKEY) {
1883     const char *s;
1884 
1885     s=GWEN_Crypt_Token_Context_GetPeerId(fct);
1886     if (s)
1887       GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_OWNER,
1888                                   s, -1, dbuf);
1889   }
1890 
1891   p=GWEN_DB_GetBinValue(dbKey, "rsa/e", 0, 0, 0, &bs);
1892   if (p && bs)
1893     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_EXP, p, bs, dbuf);
1894 
1895   p=GWEN_DB_GetBinValue(dbKey, "rsa/n", 0, 0, 0, &bs);
1896   if (p && bs) {
1897     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_MODULUS, p, bs, dbuf);
1898     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_N, p, bs, dbuf);
1899   }
1900   else {
1901     DBG_WARN(GWEN_LOGDOMAIN, "No modulus !");
1902   }
1903 
1904   p=GWEN_DB_GetBinValue(dbKey, "rsa/p", 0, 0, 0, &bs);
1905   if (p && bs)
1906     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_P, p, bs, dbuf);
1907 
1908   p=GWEN_DB_GetBinValue(dbKey, "rsa/q", 0, 0, 0, &bs);
1909   if (p && bs)
1910     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_Q, p, bs, dbuf);
1911 
1912   p=GWEN_DB_GetBinValue(dbKey, "rsa/d", 0, 0, 0, &bs);
1913   if (p && bs)
1914     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_KEY_D, p, bs, dbuf);
1915 
1916   GWEN_DB_Group_free(dbKey);
1917   bs=(GWEN_Buffer_GetPos(dbuf)-pos)-2;
1918   pp=GWEN_Buffer_GetStart(dbuf)+pos;
1919   pp[0]=bs & 0xff;
1920   pp[1]=(bs>>8) & 0xff;
1921 
1922   return 0;
1923 }
1924 
1925 
1926 
GWEN_Crypt_TokenOHBCI_Encode(GWEN_CRYPT_TOKEN * ct,GWEN_BUFFER * dbuf)1927 int GWEN_Crypt_TokenOHBCI_Encode(GWEN_CRYPT_TOKEN *ct, GWEN_BUFFER *dbuf)
1928 {
1929   GWEN_CRYPT_TOKEN_OHBCI *lct;
1930   char numbuf[16];
1931   const char *p;
1932   GWEN_CRYPT_TOKEN_CONTEXT *fct;
1933   GWEN_CRYPT_KEY *key;
1934   GWEN_CRYPT_TOKEN_KEYINFO *ki;
1935 
1936   assert(ct);
1937   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
1938   assert(lct);
1939 
1940   /* get the only context */
1941   fct=GWEN_Crypt_TokenFile_GetContext(ct, 0);
1942   if (!fct) {
1943     DBG_ERROR(GWEN_LOGDOMAIN,
1944               "Crypt token does not contain a file context");
1945     return GWEN_ERROR_INVALID;
1946   }
1947 
1948   /* write header again */
1949   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER,
1950                               GWEN_CRYPT_TOKEN_OHBCI_NAME,
1951                               -1, dbuf);
1952 
1953   if (lct->mediumTag!=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3) {
1954     /* do not include version info here for ohbci files after 1.5 */
1955     snprintf(numbuf, sizeof(numbuf), "%d", GWEN_CRYPT_TOKEN_OHBCI_VMAJOR);
1956     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MAJOR,
1957                                 numbuf, -1, dbuf);
1958 
1959     snprintf(numbuf, sizeof(numbuf), "%d", GWEN_CRYPT_TOKEN_OHBCI_VMINOR);
1960     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MINOR,
1961                                 numbuf, -1, dbuf);
1962   }
1963 
1964   ki=GWEN_CTF_Context_GetLocalSignKeyInfo(fct);
1965   if (ki) {
1966     snprintf(numbuf, sizeof(numbuf), "%d", GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki));
1967     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_SEQ, numbuf, -1, dbuf);
1968   }
1969   key=GWEN_CTF_Context_GetLocalSignKey(fct);
1970   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
1971                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PUBSIGNKEY,
1972                                        1, 0, dbuf)) {
1973     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
1974     return -1;
1975   }
1976 
1977   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
1978                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PRIVSIGNKEY,
1979                                        0, 0, dbuf)) {
1980     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
1981     return -1;
1982   }
1983 
1984   key=GWEN_CTF_Context_GetLocalCryptKey(fct);
1985   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
1986                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PUBCRYPTKEY,
1987                                        1, 1, dbuf)) {
1988     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
1989     return -1;
1990   }
1991 
1992   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
1993                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PRIVCRYPTKEY,
1994                                        0, 1, dbuf)) {
1995     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
1996     return -1;
1997   }
1998 
1999   p=GWEN_Crypt_Token_Context_GetUserId(fct);
2000   if (p && *p)
2001     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_ID,
2002                                 p, -1, dbuf);
2003 
2004   key=GWEN_CTF_Context_GetRemoteSignKey(fct);
2005   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
2006                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBSIGNKEY,
2007                                        1, 0, dbuf)) {
2008     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
2009     return -1;
2010   }
2011 
2012   key=GWEN_CTF_Context_GetRemoteCryptKey(fct);
2013   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
2014                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBCRYPTKEY,
2015                                        1, 1, dbuf)) {
2016     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
2017     return -1;
2018   }
2019 
2020   snprintf(numbuf, sizeof(numbuf), "%d", 280);
2021   GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_COUNTRY,
2022                               numbuf, -1, dbuf);
2023 
2024   p=GWEN_Crypt_Token_Context_GetServiceId(fct);
2025   if (p && *p)
2026     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_CODE,
2027                                 p, -1, dbuf);
2028 
2029   p=GWEN_Crypt_Token_Context_GetSystemId(fct);
2030   if (p && *p)
2031     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_SYSTEMID,
2032                                 p, -1, dbuf);
2033 
2034   /* new in 1.4 */
2035   p=GWEN_Crypt_Token_Context_GetAddress(fct);
2036   if (p && *p) {
2037     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_SERVER_ADDR,
2038                                 p, -1, dbuf);
2039     snprintf(numbuf, sizeof(numbuf), "%d",
2040              GWEN_Crypt_Token_Context_GetPort(fct));
2041     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_SERVER_PORT,
2042                                 numbuf, -1, dbuf);
2043   }
2044 
2045   /* new in 1.4 */
2046   ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(fct);
2047   if (ki) {
2048     snprintf(numbuf, sizeof(numbuf), "%d", GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki));
2049     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_REMOTE_SEQ,
2050                                 numbuf, -1, dbuf);
2051   }
2052 
2053   /* new in 1.7 */
2054   key=GWEN_CTF_Context_GetLocalAuthKey(fct);
2055   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
2056                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_USER_PRIVAUTHKEY,
2057                                        0, 0, dbuf)) {
2058     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
2059     return -1;
2060   }
2061 
2062   key=GWEN_CTF_Context_GetRemoteAuthKey(fct);
2063   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
2064                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_INST_PUBAUTHKEY,
2065                                        1, 0, dbuf)) {
2066     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
2067     return -1;
2068   }
2069 
2070   /* new in 1.8 */
2071   ki=GWEN_CTF_Context_GetTempLocalSignKeyInfo(fct);
2072   key=GWEN_CTF_Context_GetTempLocalSignKey(fct);
2073   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
2074                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_TEMP_PUBSIGNKEY,
2075                                        1, 0, dbuf)) {
2076     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
2077     return -1;
2078   }
2079 
2080   if (GWEN_Crypt_TokenOHBCI__EncodeKey(key, fct,
2081                                        GWEN_CRYPT_TOKEN_OHBCI_TAG_TEMP_PRIVSIGNKEY,
2082                                        0, 0, dbuf)) {
2083     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key");
2084     return -1;
2085   }
2086 
2087   return 0;
2088 }
2089 
2090 
2091 
GWEN_Crypt_TokenOHBCI_Write(GWEN_CRYPT_TOKEN * ct,int fd,GWEN_UNUSED int cre,uint32_t gid)2092 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Write(GWEN_CRYPT_TOKEN *ct, int fd, GWEN_UNUSED int cre, uint32_t gid)
2093 {
2094   GWEN_CRYPT_TOKEN_OHBCI *lct;
2095   int rv;
2096   GWEN_BUFFER *fbuf;
2097   GWEN_BUFFER *rawbuf;
2098   char *p;
2099   unsigned int bs;
2100 
2101   assert(ct);
2102   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
2103   assert(lct);
2104 
2105   if (!GWEN_Crypt_Token_GetTokenName(ct)) {
2106     DBG_ERROR(GWEN_LOGDOMAIN, "No medium name given");
2107     return -1;
2108   }
2109 
2110   /* maybe update key file */
2111   if ((GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_ALLOW_UPDATE) &&
2112       ((lct->mediumTag!=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3) ||
2113        (lct->cryptoTag!=GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_TRESOR))) {
2114     DBG_WARN(GWEN_LOGDOMAIN,
2115              "Updating ancient key file to new one");
2116     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Warning,
2117                          I18N("Updating ancient key file to new one"));
2118     lct->passWordIsSet=0;
2119     lct->mediumTag=GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3;
2120     lct->cryptoTag=GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_TRESOR;
2121   }
2122 
2123   /* create raw data */
2124   rawbuf=GWEN_Buffer_new(0, 1024, 0, 1);
2125   rv=GWEN_Crypt_TokenOHBCI_Encode(ct, rawbuf);
2126   if (rv) {
2127     DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode key file (%d)", rv);
2128     return -1;
2129   }
2130 
2131 #ifdef DEBUG_OHBCI_MODULE
2132   if (1) {
2133     FILE *f;
2134 
2135     f=fopen("encoded.medium", "w+b");
2136     if (f) {
2137       if (1!=fwrite(GWEN_Buffer_GetStart(rawbuf),
2138                     GWEN_Buffer_GetUsedBytes(rawbuf),
2139                     1, f)) {
2140         DBG_ERROR(GWEN_LOGDOMAIN, "Could not save encoded file.");
2141       }
2142       if (fclose(f)) {
2143         DBG_ERROR(GWEN_LOGDOMAIN, "Could not close encoded file.");
2144       }
2145     }
2146     else {
2147       DBG_ERROR(GWEN_LOGDOMAIN, "Could not open encoded file.");
2148     }
2149   }
2150 #endif
2151 
2152   /* create key from password */
2153   rv=GWEN_Crypt_TokenOHBCI__EnsurePassword(ct, 0, 1 /* always let user confirm new password on write */, gid);
2154   if (rv) {
2155     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2156     GWEN_Buffer_free(rawbuf);
2157     return rv;
2158   }
2159 
2160   if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_TRESOR) {
2161     /* encrypt file */
2162     bs=GWEN_Buffer_GetUsedBytes(rawbuf);
2163     GWEN_Buffer_Rewind(rawbuf);
2164     fbuf=GWEN_Buffer_new(0, bs+128, 0, 1);
2165     GWEN_Buffer_ReserveBytes(fbuf, 4);
2166     rv=GWEN_SmallTresor_Encrypt((const uint8_t *)GWEN_Buffer_GetStart(rawbuf), bs,
2167                                 lct->password,
2168                                 fbuf,
2169                                 GWEN_CRYPT_TOKEN_OHBCI_TRESOR_PWD_ITERATIONS,
2170                                 GWEN_CRYPT_TOKEN_OHBCI_TRESOR_CRYPT_ITERATIONS);
2171     if (rv<0) {
2172       DBG_ERROR(GWEN_LOGDOMAIN, "Could not encode keyfile");
2173       GWEN_Buffer_free(fbuf);
2174       GWEN_Buffer_free(rawbuf);
2175       return GWEN_ERROR_GENERIC;
2176     }
2177 
2178     GWEN_Buffer_free(rawbuf);
2179   }
2180   else {
2181     GWEN_CRYPT_KEY *key;
2182 
2183     if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT) {
2184       key=GWEN_Crypt_KeyDes3K_fromData(GWEN_Crypt_CryptMode_Cbc, 24,
2185                                        (const uint8_t *)lct->password, 24);
2186     }
2187     else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_OLD) {
2188       key=GWEN_Crypt_KeyDes3K_fromData(GWEN_Crypt_CryptMode_Cbc, 16,
2189                                        (const uint8_t *)lct->password, 16);
2190     }
2191     else if (lct->cryptoTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_CRYPT_BF) {
2192       key=GWEN_Crypt_KeyBlowFish_fromData(GWEN_Crypt_CryptMode_Cbc, 16,
2193                                           (const uint8_t *)lct->password, 16);
2194     }
2195     else {
2196       DBG_ERROR(GWEN_LOGDOMAIN, "Unknown crypt tag, should not occur");
2197       abort();
2198     }
2199 
2200     if (!key) {
2201       DBG_ERROR(GWEN_LOGDOMAIN, "Could not create key");
2202       GWEN_Buffer_free(rawbuf);
2203       return GWEN_ERROR_GENERIC;
2204     }
2205 
2206     /* padd raw data */
2207     if (GWEN_Padd_PaddWithAnsiX9_23(rawbuf)) {
2208       DBG_ERROR(GWEN_LOGDOMAIN, "Could not padd keyfile");
2209       GWEN_Crypt_Key_free(key);
2210       GWEN_Buffer_free(rawbuf);
2211       return GWEN_ERROR_GENERIC;
2212     }
2213 
2214     /* encrypt file */
2215     bs=GWEN_Buffer_GetUsedBytes(rawbuf);
2216     GWEN_Buffer_Rewind(rawbuf);
2217     fbuf=GWEN_Buffer_new(0, bs+128, 0, 1);
2218     GWEN_Buffer_ReserveBytes(fbuf, 4);
2219     rv=GWEN_Crypt_Key_Encipher(key,
2220                                (const uint8_t *)GWEN_Buffer_GetStart(rawbuf),
2221                                bs,
2222                                (uint8_t *)GWEN_Buffer_GetStart(fbuf),
2223                                &bs);
2224     GWEN_Buffer_free(rawbuf);
2225     GWEN_Crypt_Key_free(key);
2226     if (rv) {
2227       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2228       GWEN_Buffer_free(fbuf);
2229       return rv;
2230     }
2231     GWEN_Buffer_IncrementPos(fbuf, bs);
2232     GWEN_Buffer_AdjustUsedBytes(fbuf);
2233   }
2234 
2235   /* insert crypto tag and make it own the content of fbuf */
2236   GWEN_Buffer_Rewind(fbuf);
2237   bs=GWEN_Buffer_GetUsedBytes(fbuf);
2238   GWEN_Buffer_InsertBytes(fbuf, "000", 3);
2239   p=GWEN_Buffer_GetStart(fbuf);
2240   p[0]=(unsigned char)(lct->cryptoTag);
2241   p[1]=(unsigned char)(bs & 0xff);
2242   p[2]=(unsigned char)((bs>>8) & 0xff);
2243 
2244   /* for new-typ media create envelope */
2245   if (lct->mediumTag==GWEN_CRYPT_TOKEN_OHBCI_TAG_MEDIUM3) {
2246     char numbuf[16];
2247     GWEN_BUFFER *dbuf;
2248 
2249     /* this is a new medium type, create envelope */
2250     dbuf=GWEN_Buffer_new(0, 2048, 0, 1);
2251     /* prepare container tag */
2252     GWEN_Buffer_AppendBytes(dbuf, "000", 3);
2253 
2254     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_HEADER,
2255                                 GWEN_CRYPT_TOKEN_OHBCI_NAME, -1, dbuf);
2256     snprintf(numbuf, sizeof(numbuf), "%d", GWEN_CRYPT_TOKEN_OHBCI_VMAJOR);
2257     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MAJOR,
2258                                 numbuf, -1, dbuf);
2259 
2260     snprintf(numbuf, sizeof(numbuf), "%d", GWEN_CRYPT_TOKEN_OHBCI_VMINOR);
2261     GWEN_Tag16_DirectlyToBuffer(GWEN_CRYPT_TOKEN_OHBCI_TAG_VERSION_MINOR,
2262                                 numbuf, -1, dbuf);
2263     /* write complete medium into new tag */
2264     GWEN_Buffer_AppendBytes(dbuf,
2265                             GWEN_Buffer_GetStart(fbuf),
2266                             GWEN_Buffer_GetUsedBytes(fbuf));
2267     p=GWEN_Buffer_GetStart(dbuf);
2268     bs=GWEN_Buffer_GetUsedBytes(dbuf)-3; /* subtract medium tag bytes */
2269     p[0]=(unsigned char)(lct->mediumTag);
2270     p[1]=(unsigned char)(bs & 0xff);
2271     p[2]=(unsigned char)((bs>>8) & 0xff);
2272     /* swap buffers */
2273     GWEN_Buffer_free(fbuf);
2274     fbuf=dbuf;
2275     GWEN_Buffer_Rewind(fbuf);
2276   }
2277 
2278   if (ftruncate(fd, 0)==-1) {
2279     DBG_ERROR(GWEN_LOGDOMAIN,
2280               "ftruncate(%s): %s",
2281               GWEN_Crypt_Token_GetTokenName(ct),
2282               strerror(errno));
2283     GWEN_Buffer_free(fbuf);
2284     return GWEN_ERROR_GENERIC;
2285   }
2286 
2287   p=GWEN_Buffer_GetStart(fbuf);
2288   bs=GWEN_Buffer_GetUsedBytes(fbuf);
2289   while (bs) {
2290     ssize_t rv;
2291 
2292     rv=write(fd, p, bs);
2293     if (rv==-1) {
2294       if (errno!=EINTR) {
2295         DBG_ERROR(GWEN_LOGDOMAIN,
2296                   "write(%s): %s",
2297                   GWEN_Crypt_Token_GetTokenName(ct),
2298                   strerror(errno));
2299         GWEN_Buffer_free(fbuf);
2300         return GWEN_ERROR_GENERIC;
2301       }
2302     }
2303     else if (rv==0)
2304       break;
2305     else {
2306       p+=rv;
2307       bs-=rv;
2308     }
2309   } /* while */
2310 
2311   GWEN_Buffer_free(fbuf);
2312 
2313   lct->justCreated=0;
2314 
2315   return 0;
2316 }
2317 
2318 
2319 
GWEN_Crypt_TokenOHBCI_ChangePin(GWEN_CRYPT_TOKEN * ct,GWEN_UNUSED int admin,GWEN_UNUSED uint32_t gid)2320 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_ChangePin(GWEN_CRYPT_TOKEN *ct,
2321                                                   GWEN_UNUSED int admin,
2322                                                   GWEN_UNUSED uint32_t gid)
2323 {
2324   GWEN_CRYPT_TOKEN_OHBCI *lct;
2325 
2326   assert(ct);
2327   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
2328   assert(lct);
2329 
2330   /* just reset the password so it will be asked for upon write */
2331   lct->passWordIsSet=0;
2332   memset(lct->password, 0, sizeof(lct->password));
2333 
2334   return 0;
2335 }
2336 
2337 
2338 
GWEN_Crypt_TokenOHBCI_Create(GWEN_CRYPT_TOKEN * ct,uint32_t gid)2339 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Create(GWEN_CRYPT_TOKEN *ct, uint32_t gid)
2340 {
2341   GWEN_CRYPT_TOKEN_OHBCI *lct;
2342   GWEN_CRYPT_TOKEN_CONTEXT *fct;
2343   GWEN_CRYPT_TOKEN_KEYINFO *ki;
2344   int rv;
2345 
2346   assert(ct);
2347   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
2348   assert(lct);
2349 
2350   lct->justCreated=1;
2351 
2352   fct=GWEN_CTF_Context_new();
2353 
2354   /* create user and file context */
2355   GWEN_Crypt_Token_Context_SetId(fct, 1);            /* only one user */
2356   GWEN_Crypt_Token_Context_SetSignKeyId(fct, 0x01);
2357   GWEN_Crypt_Token_Context_SetDecipherKeyId(fct, 0x02);
2358   GWEN_Crypt_Token_Context_SetVerifyKeyId(fct, 0x03);
2359   GWEN_Crypt_Token_Context_SetEncipherKeyId(fct, 0x04);
2360   GWEN_Crypt_Token_Context_SetAuthSignKeyId(fct, 0x05);
2361   GWEN_Crypt_Token_Context_SetAuthVerifyKeyId(fct, 0x06);
2362 
2363   /* create key info */
2364   ki=GWEN_Crypt_Token_KeyInfo_new(0x0001, /* local sign key */
2365                                   GWEN_Crypt_CryptAlgoId_Rsa,
2366                                   96);
2367   assert(ki);
2368   GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Sign Key"));
2369 
2370   GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2371                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
2372                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2373                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2374                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN |
2375                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2376                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER);
2377   GWEN_CTF_Context_SetLocalSignKeyInfo(fct, ki);
2378 
2379   /* create key info */
2380   ki=GWEN_Crypt_Token_KeyInfo_new(0x0002, /* local crypt key */
2381                                   GWEN_Crypt_CryptAlgoId_Rsa,
2382                                   96);
2383   assert(ki);
2384   GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Crypt Key"));
2385   GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2386                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2387                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
2388                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANDECIPHER |
2389                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2390                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER);
2391   GWEN_CTF_Context_SetLocalCryptKeyInfo(fct, ki);
2392 
2393   /* create key info */
2394   ki=GWEN_Crypt_Token_KeyInfo_new(0x0003, /* remote sign key */
2395                                   GWEN_Crypt_CryptAlgoId_Rsa,
2396                                   96);
2397   assert(ki);
2398   GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Sign Key"));
2399 
2400   GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2401                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
2402                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2403                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2404                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2405                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER);
2406   GWEN_CTF_Context_SetRemoteSignKeyInfo(fct, ki);
2407 
2408   /* create key info */
2409   ki=GWEN_Crypt_Token_KeyInfo_new(0x0004, /* remote crypt key */
2410                                   GWEN_Crypt_CryptAlgoId_Rsa,
2411                                   96);
2412   assert(ki);
2413   GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Crypt Key"));
2414 
2415   GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2416                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2417                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
2418                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2419                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER);
2420   GWEN_CTF_Context_SetRemoteCryptKeyInfo(fct, ki);
2421 
2422   /* create key info */
2423   ki=GWEN_Crypt_Token_KeyInfo_new(0x0005, /* local auth key */
2424                                   GWEN_Crypt_CryptAlgoId_Rsa,
2425                                   96);
2426   assert(ki);
2427   GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2428                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2429                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN |
2430                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2431                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2432                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER);
2433   GWEN_CTF_Context_SetLocalAuthKeyInfo(fct, ki);
2434   GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Local Auth Key"));
2435 
2436   /* create key info */
2437   ki=GWEN_Crypt_Token_KeyInfo_new(0x0006, /* remote auth key */
2438                                   GWEN_Crypt_CryptAlgoId_Rsa,
2439                                   96);
2440   assert(ki);
2441   GWEN_Crypt_Token_KeyInfo_SetKeyDescr(ki, I18N("Remote Auth Key"));
2442 
2443   GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2444                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2445                                     GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2446                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2447                                     GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER);
2448   GWEN_CTF_Context_SetRemoteAuthKeyInfo(fct, ki);
2449 
2450   /* add context */
2451   GWEN_Crypt_TokenFile_AddContext(ct, fct);
2452 
2453   assert(lct->createFn);
2454   rv=lct->createFn(ct, gid);
2455   if (rv) {
2456     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2457     return rv;
2458   }
2459 
2460   return 0;
2461 }
2462 
2463 
2464 
GWEN_Crypt_TokenOHBCI_Open(GWEN_CRYPT_TOKEN * ct,int manage,uint32_t gid)2465 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Open(GWEN_CRYPT_TOKEN *ct, int manage, uint32_t gid)
2466 {
2467   GWEN_CRYPT_TOKEN_OHBCI *lct;
2468   int rv;
2469 
2470   assert(ct);
2471   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
2472   assert(lct);
2473 
2474   assert(lct->openFn);
2475   rv=lct->openFn(ct, manage, gid);
2476   if (rv) {
2477     DBG_INFO(GWEN_LOGDOMAIN, "here");
2478     return rv;
2479   }
2480 
2481   return 0;
2482 }
2483 
2484 
2485 
GWEN_Crypt_TokenOHBCI_Close(GWEN_CRYPT_TOKEN * ct,int abandon,uint32_t gid)2486 int GWENHYWFAR_CB GWEN_Crypt_TokenOHBCI_Close(GWEN_CRYPT_TOKEN *ct, int abandon, uint32_t gid)
2487 {
2488   GWEN_CRYPT_TOKEN_OHBCI *lct;
2489   int rv;
2490 
2491   assert(ct);
2492   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_OHBCI, ct);
2493   assert(lct);
2494 
2495   assert(lct->closeFn);
2496   rv=lct->closeFn(ct, abandon, gid);
2497   if (rv) {
2498     DBG_INFO(GWEN_LOGDOMAIN, "here");
2499     return rv;
2500   }
2501 
2502   memset(lct->password, 0, sizeof(lct->password));
2503   lct->passWordIsSet=0;
2504 
2505   return 0;
2506 }
2507 
2508 
2509 
2510