1 /***************************************************************************
2     begin       : Wed Mar 16 2005
3     copyright   : (C) 2005-2010 by Martin Preuss
4     email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *          Please see toplevel file COPYING for license details           *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #define DISABLE_DEBUGLOG
15 
16 
17 #include "ctfile_p.h"
18 #include "i18n_l.h"
19 #include <gwenhywfar/ctf_context_be.h>
20 #include <gwenhywfar/misc.h>
21 #include <gwenhywfar/debug.h>
22 #include <gwenhywfar/padd.h>
23 #include <gwenhywfar/cryptkeyrsa.h>
24 #include <gwenhywfar/text.h>
25 
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 
34 
35 
GWEN_INHERIT(GWEN_CRYPT_TOKEN,GWEN_CRYPT_TOKEN_FILE)36 GWEN_INHERIT(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE)
37 
38 
39 
40 
41 
42 int GWEN_Crypt_TokenFile__OpenFile(GWEN_CRYPT_TOKEN *ct, int wr, uint32_t gid)
43 {
44   int fd;
45   GWEN_CRYPT_TOKEN_FILE *lct;
46   GWEN_FSLOCK_RESULT lres;
47   const char *fname;
48 
49   assert(ct);
50   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
51   assert(lct);
52 
53   fname = GWEN_Crypt_Token_GetTokenName(ct);
54   if (!fname) {
55     DBG_ERROR(GWEN_LOGDOMAIN,
56               "No name of the crypt token set - maybe you need to set the key file as token name? Cannot lock token.");
57     return GWEN_ERROR_IO;
58   }
59 
60   lct->lock=GWEN_FSLock_new(fname,
61                             GWEN_FSLock_TypeFile);
62   lres=GWEN_FSLock_Lock(lct->lock, 10000, gid);
63   if (lres!=GWEN_FSLock_ResultOk) {
64     GWEN_FSLock_free(lct->lock);
65     lct->lock=0;
66     DBG_ERROR(GWEN_LOGDOMAIN, "Could not lock file");
67     if (lres==GWEN_FSLock_ResultUserAbort)
68       return GWEN_ERROR_USER_ABORTED;
69     else
70       return GWEN_ERROR_IO;
71   }
72   else {
73     DBG_INFO(GWEN_LOGDOMAIN,
74              "Keyfile [%s] locked.",
75              GWEN_Crypt_Token_GetTokenName(ct));
76   }
77 
78   if (wr) {
79     /* write file */
80     fd=open(GWEN_Crypt_Token_GetTokenName(ct),
81             O_RDWR|O_CREAT
82 #ifdef OS_WIN32
83             | O_BINARY
84 #endif
85             ,
86             S_IRUSR|S_IWUSR | lct->keyfile_mode);
87   }
88   else {
89     /* Remember the access permissions when opening the file */
90     struct stat statbuffer;
91     if (!stat(GWEN_Crypt_Token_GetTokenName(ct), &statbuffer)) {
92       /* Save the access mode, but masked by the bit masks for
93       user/group/other permissions */
94       lct->keyfile_mode =
95         statbuffer.st_mode & (S_IRWXU
96 #ifndef OS_WIN32
97                               | S_IRWXG | S_IRWXO
98 #endif
99                              );
100     }
101     else {
102       DBG_ERROR(GWEN_LOGDOMAIN,
103                 "stat(%s): %s",
104                 GWEN_Crypt_Token_GetTokenName(ct),
105                 strerror(errno));
106 
107       GWEN_FSLock_Unlock(lct->lock);
108       GWEN_FSLock_free(lct->lock);
109       lct->lock=0;
110       DBG_INFO(GWEN_LOGDOMAIN,
111                "Keyfile [%s] unlocked.",
112                GWEN_Crypt_Token_GetTokenName(ct));
113       return GWEN_ERROR_IO;
114     }
115 
116     /* and open the file */
117     fd=open(GWEN_Crypt_Token_GetTokenName(ct),
118             O_RDONLY
119 #ifdef OS_WIN32
120             | O_BINARY
121 #endif
122            );
123   }
124 
125   if (fd==-1) {
126     DBG_ERROR(GWEN_LOGDOMAIN,
127               "open(%s): %s",
128               GWEN_Crypt_Token_GetTokenName(ct),
129               strerror(errno));
130     GWEN_FSLock_Unlock(lct->lock);
131     GWEN_FSLock_free(lct->lock);
132     lct->lock=0;
133     DBG_INFO(GWEN_LOGDOMAIN,
134              "Keyfile [%s] unlocked.",
135              GWEN_Crypt_Token_GetTokenName(ct));
136     return GWEN_ERROR_IO;
137   }
138 
139   lct->fd=fd;
140 
141   return 0;
142 }
143 
144 
145 
GWEN_Crypt_TokenFile__CloseFile(GWEN_CRYPT_TOKEN * ct,uint32_t gid)146 int GWEN_Crypt_TokenFile__CloseFile(GWEN_CRYPT_TOKEN *ct, uint32_t gid)
147 {
148   GWEN_CRYPT_TOKEN_FILE *lct;
149   GWEN_FSLOCK_RESULT lres;
150   struct stat st;
151 
152   assert(ct);
153   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
154   assert(lct);
155 
156   if (lct->fd==-1) {
157     DBG_ERROR(GWEN_LOGDOMAIN, "Keyfile \"%s\"not open",
158               GWEN_Crypt_Token_GetTokenName(ct));
159     return GWEN_ERROR_INTERNAL;
160   }
161 
162   if (close(lct->fd)) {
163     DBG_ERROR(GWEN_LOGDOMAIN, "close(%s): %s",
164               GWEN_Crypt_Token_GetTokenName(ct), strerror(errno));
165     lct->fd=-1;
166     GWEN_FSLock_Unlock(lct->lock);
167     GWEN_FSLock_free(lct->lock);
168     lct->lock=0;
169     DBG_INFO(GWEN_LOGDOMAIN,
170              "Keyfile [%s] unlocked.",
171              GWEN_Crypt_Token_GetTokenName(ct));
172     return GWEN_ERROR_IO;
173   }
174   lct->fd=-1;
175 
176   lres=GWEN_FSLock_Unlock(lct->lock);
177   if (lres!=GWEN_FSLock_ResultOk) {
178     DBG_WARN(GWEN_LOGDOMAIN, "Error removing lock from \"%s\": %d",
179              GWEN_Crypt_Token_GetTokenName(ct), lres);
180   }
181   GWEN_FSLock_free(lct->lock);
182   lct->lock=0;
183   DBG_INFO(GWEN_LOGDOMAIN,
184            "Keyfile [%s] unlocked.",
185            GWEN_Crypt_Token_GetTokenName(ct));
186 
187   /* get times */
188   if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
189     DBG_ERROR(GWEN_LOGDOMAIN,
190               "stat(%s): %s",
191               GWEN_Crypt_Token_GetTokenName(ct),
192               strerror(errno));
193     return GWEN_ERROR_IO;
194   }
195 
196 #ifndef OS_WIN32
197   if (st.st_mode & 0007) {
198     DBG_WARN(GWEN_LOGDOMAIN,
199              "WARNING: Your keyfile \"%s\" is accessible by every user on your computer!\n"
200              "Nobody but you should have access to the file. You \n"
201              "should probably change this with \"chmod 600 %s\"",
202              GWEN_Crypt_Token_GetTokenName(ct),
203              GWEN_Crypt_Token_GetTokenName(ct));
204     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Warning,
205                          "WARNING: Your keyfile is accessible ny every user on your computer!\n"
206                          "Nobody but you should have access to the file.");
207   }
208 #endif
209   lct->mtime=st.st_mtime;
210   lct->ctime=st.st_ctime;
211 
212   return 0;
213 }
214 
215 
216 
GWEN_Crypt_TokenFile__Read(GWEN_CRYPT_TOKEN * ct,uint32_t gid)217 int GWEN_Crypt_TokenFile__Read(GWEN_CRYPT_TOKEN *ct, uint32_t gid)
218 {
219   GWEN_CRYPT_TOKEN_FILE *lct;
220 
221   assert(ct);
222   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
223   assert(lct);
224 
225   assert(lct->readFn);
226   if (lseek(lct->fd, 0, SEEK_SET)==-1) {
227     DBG_ERROR(GWEN_LOGDOMAIN, "lseek(%s): %s",
228               GWEN_Crypt_Token_GetTokenName(ct),
229               strerror(errno));
230     return GWEN_ERROR_IO;
231   }
232   return lct->readFn(ct, lct->fd, gid);
233 }
234 
235 
236 
GWEN_Crypt_TokenFile__Write(GWEN_CRYPT_TOKEN * ct,int cr,uint32_t gid)237 int GWEN_Crypt_TokenFile__Write(GWEN_CRYPT_TOKEN *ct, int cr, uint32_t gid)
238 {
239   GWEN_CRYPT_TOKEN_FILE *lct;
240 
241   assert(ct);
242   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
243   assert(lct);
244 
245   if (lct->writeFn==0) {
246     DBG_WARN(GWEN_LOGDOMAIN,
247              "No write function in crypt token type \"%s\"",
248              GWEN_Crypt_Token_GetTypeName(ct));
249     return GWEN_ERROR_NOT_SUPPORTED;
250   }
251 
252   if (lseek(lct->fd, 0, SEEK_SET)==-1) {
253     DBG_ERROR(GWEN_LOGDOMAIN, "lseek(%s): %s",
254               GWEN_Crypt_Token_GetTokenName(ct),
255               strerror(errno));
256     return GWEN_ERROR_IO;
257   }
258   return lct->writeFn(ct, lct->fd, cr, gid);
259 }
260 
261 
262 
GWEN_Crypt_TokenFile__ReadFile(GWEN_CRYPT_TOKEN * ct,uint32_t gid)263 int GWEN_Crypt_TokenFile__ReadFile(GWEN_CRYPT_TOKEN *ct, uint32_t gid)
264 {
265   GWEN_CRYPT_TOKEN_FILE *lct;
266   int rv;
267 
268   assert(ct);
269   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
270   assert(lct);
271 
272   /* clear context list, it will be reloaded */
273   GWEN_Crypt_Token_Context_List_Clear(lct->contextList);
274 
275   /* open file */
276   rv=GWEN_Crypt_TokenFile__OpenFile(ct, 0, gid);
277   if (rv) {
278     DBG_INFO(GWEN_LOGDOMAIN,
279              "Could not open keyfile for reading (%d)", rv);
280     return rv;
281   }
282 
283   /* read file */
284   rv=GWEN_Crypt_TokenFile__Read(ct, gid);
285   if (rv) {
286     DBG_INFO(GWEN_LOGDOMAIN, "Error reading keyfile");
287     GWEN_Crypt_TokenFile__CloseFile(ct, gid);
288     return rv;
289   }
290 
291   /* close file */
292   rv=GWEN_Crypt_TokenFile__CloseFile(ct, gid);
293   if (rv) {
294     DBG_INFO(GWEN_LOGDOMAIN, "Could not close keyfile");
295     return rv;
296   }
297 
298   return 0;
299 }
300 
301 
302 
GWEN_Crypt_TokenFile__WriteFile(GWEN_CRYPT_TOKEN * ct,int cr,uint32_t gid)303 int GWEN_Crypt_TokenFile__WriteFile(GWEN_CRYPT_TOKEN *ct, int cr, uint32_t gid)
304 {
305   GWEN_CRYPT_TOKEN_FILE *lct;
306   int rv;
307 
308   assert(ct);
309   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
310   assert(lct);
311 
312   /* open file */
313   rv=GWEN_Crypt_TokenFile__OpenFile(ct, 1, gid);
314   if (rv) {
315     DBG_INFO(GWEN_LOGDOMAIN,
316              "Could not open keyfile for writing (%d)", rv);
317     return rv;
318   }
319 
320   /* write file */
321   rv=GWEN_Crypt_TokenFile__Write(ct, cr, gid);
322   if (rv) {
323     DBG_INFO(GWEN_LOGDOMAIN, "Error writing keyfile");
324     GWEN_Crypt_TokenFile__CloseFile(ct, gid);
325     return rv;
326   }
327 
328   /* close file */
329   rv=GWEN_Crypt_TokenFile__CloseFile(ct, gid);
330   if (rv) {
331     DBG_INFO(GWEN_LOGDOMAIN, "Could not close keyfile");
332     return rv;
333   }
334 
335   return 0;
336 }
337 
338 
339 
GWEN_Crypt_TokenFile__ReloadIfNeeded(GWEN_CRYPT_TOKEN * ct,uint32_t gid)340 int GWEN_Crypt_TokenFile__ReloadIfNeeded(GWEN_CRYPT_TOKEN *ct, uint32_t gid)
341 {
342   GWEN_CRYPT_TOKEN_FILE *lct;
343   struct stat st;
344 
345   assert(ct);
346   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
347   assert(lct);
348 
349   if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
350     DBG_ERROR(GWEN_LOGDOMAIN,
351               "stat(%s): %s",
352               GWEN_Crypt_Token_GetTokenName(ct),
353               strerror(errno));
354     return -1;
355   }
356   if (lct->mtime!=st.st_mtime ||
357       lct->ctime!=st.st_ctime) {
358     int rv;
359 
360     /* file has changed, reload it */
361     DBG_NOTICE(GWEN_LOGDOMAIN,
362                "Keyfile changed externally, reloading it");
363     /* read file */
364     rv=GWEN_Crypt_TokenFile__ReadFile(ct, gid);
365     if (rv) {
366       DBG_WARN(GWEN_LOGDOMAIN, "Error reloading keyfile");
367       return rv;
368     }
369   }
370   else {
371     DBG_NOTICE(GWEN_LOGDOMAIN, "Keyfile unchanged, not reloading");
372   }
373   return 0;
374 }
375 
376 
377 
GWEN_Crypt_TokenFile_AddContext(GWEN_CRYPT_TOKEN * ct,GWEN_CRYPT_TOKEN_CONTEXT * ctx)378 void GWEN_Crypt_TokenFile_AddContext(GWEN_CRYPT_TOKEN *ct, GWEN_CRYPT_TOKEN_CONTEXT *ctx)
379 {
380   GWEN_CRYPT_TOKEN_FILE *lct;
381 
382   assert(ct);
383   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
384   assert(lct);
385 
386   /* make sure the context is a file context */
387   assert(GWEN_CTF_Context_IsOfThisType(ctx));
388   GWEN_Crypt_Token_Context_List_Add(ctx, lct->contextList);
389 }
390 
391 
392 
GWEN_Crypt_TokenFile_GetContext(GWEN_CRYPT_TOKEN * ct,int idx)393 GWEN_CRYPT_TOKEN_CONTEXT *GWEN_Crypt_TokenFile_GetContext(GWEN_CRYPT_TOKEN *ct, int idx)
394 {
395   GWEN_CRYPT_TOKEN_FILE *lct;
396   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
397 
398   assert(ct);
399   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
400   assert(lct);
401 
402   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
403   while (ctx) {
404     if (idx==0)
405       return ctx;
406     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
407     idx--;
408   }
409 
410   return NULL;
411 }
412 
413 
414 
GWEN_Crypt_TokenFile_SetReadFn(GWEN_CRYPT_TOKEN * ct,GWEN_CRYPT_TOKEN_FILE_READ_FN f)415 GWEN_CRYPT_TOKEN_FILE_READ_FN GWEN_Crypt_TokenFile_SetReadFn(GWEN_CRYPT_TOKEN *ct,
416                                                              GWEN_CRYPT_TOKEN_FILE_READ_FN f)
417 {
418   GWEN_CRYPT_TOKEN_FILE *lct;
419   GWEN_CRYPT_TOKEN_FILE_READ_FN of;
420 
421   assert(ct);
422   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
423   assert(lct);
424 
425   of=lct->readFn;
426   lct->readFn=f;
427 
428   return of;
429 }
430 
431 
432 
GWEN_Crypt_TokenFile_SetWriteFn(GWEN_CRYPT_TOKEN * ct,GWEN_CRYPT_TOKEN_FILE_WRITE_FN f)433 GWEN_CRYPT_TOKEN_FILE_WRITE_FN GWEN_Crypt_TokenFile_SetWriteFn(GWEN_CRYPT_TOKEN *ct,
434                                                                GWEN_CRYPT_TOKEN_FILE_WRITE_FN f)
435 {
436   GWEN_CRYPT_TOKEN_FILE *lct;
437   GWEN_CRYPT_TOKEN_FILE_WRITE_FN of;
438 
439   assert(ct);
440   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
441   assert(lct);
442 
443   of=lct->writeFn;
444   lct->writeFn=f;
445 
446   return of;
447 }
448 
449 
450 
GWEN_Crypt_TokenFile_Create(GWEN_CRYPT_TOKEN * ct,uint32_t gid)451 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Create(GWEN_CRYPT_TOKEN *ct, uint32_t gid)
452 {
453   GWEN_CRYPT_TOKEN_FILE *lct;
454   struct stat st;
455   int fd;
456   int rv;
457 
458   assert(ct);
459   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
460   assert(lct);
461 
462   if (!GWEN_Crypt_Token_GetTokenName(ct)) {
463     DBG_ERROR(GWEN_LOGDOMAIN, "No medium name given");
464     return GWEN_ERROR_INVALID;
465   }
466 
467   if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
468     if (errno!=ENOENT) {
469       DBG_ERROR(GWEN_LOGDOMAIN,
470                 "Error trying to access key file \"%s\": %s",
471                 GWEN_Crypt_Token_GetTokenName(ct),
472                 strerror(errno));
473       return GWEN_ERROR_IO;
474     }
475   }
476   else {
477     DBG_ERROR(GWEN_LOGDOMAIN,
478               "Keyfile \"%s\" already exists, will not create it",
479               GWEN_Crypt_Token_GetTokenName(ct));
480     return GWEN_ERROR_INVALID;
481   }
482 
483 
484   /* create file */
485   fd=open(GWEN_Crypt_Token_GetTokenName(ct),
486           O_RDWR | O_CREAT | O_EXCL
487 #ifdef OS_WIN32
488           | O_BINARY
489 #endif
490           ,
491           S_IRUSR|S_IWUSR);
492 
493 
494   if (fd==-1) {
495     DBG_ERROR(GWEN_LOGDOMAIN,
496               "open(%s): %s",
497               GWEN_Crypt_Token_GetTokenName(ct),
498               strerror(errno));
499     return GWEN_ERROR_IO;
500   }
501 
502   close(fd);
503 
504   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 1, gid);
505   if (rv) {
506     DBG_INFO(GWEN_LOGDOMAIN, "here");
507     return rv;
508   }
509 
510   return 0;
511 }
512 
513 
514 
GWEN_Crypt_TokenFile_Open(GWEN_CRYPT_TOKEN * ct,GWEN_UNUSED int admin,uint32_t gid)515 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Open(GWEN_CRYPT_TOKEN *ct, GWEN_UNUSED int admin, uint32_t gid)
516 {
517   GWEN_CRYPT_TOKEN_FILE *lct;
518   int rv;
519 
520   assert(ct);
521   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
522   assert(lct);
523 
524   rv=GWEN_Crypt_TokenFile__ReadFile(ct, gid);
525   if (rv) {
526     DBG_INFO(GWEN_LOGDOMAIN, "here");
527     return rv;
528   }
529 
530   return 0;
531 }
532 
533 
534 
GWEN_Crypt_TokenFile_Close(GWEN_CRYPT_TOKEN * ct,int abandon,uint32_t gid)535 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Close(GWEN_CRYPT_TOKEN *ct, int abandon, uint32_t gid)
536 {
537   GWEN_CRYPT_TOKEN_FILE *lct;
538   int rv;
539 
540   assert(ct);
541   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
542   assert(lct);
543 
544   if (!abandon)
545     rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
546   else
547     rv=0;
548 
549   /* free/reset all data */
550   GWEN_Crypt_Token_Context_List_Clear(lct->contextList);
551   lct->mtime=0;
552   lct->ctime=0;
553 
554   return rv;
555 }
556 
557 
558 
559 
GWEN_Crypt_TokenFile__GetKeyIdList(GWEN_CRYPT_TOKEN * ct,uint32_t * pIdList,uint32_t * pCount,uint32_t gid)560 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__GetKeyIdList(GWEN_CRYPT_TOKEN *ct,
561                                                      uint32_t *pIdList,
562                                                      uint32_t *pCount,
563                                                      uint32_t gid)
564 {
565   GWEN_CRYPT_TOKEN_FILE *lct;
566   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
567   int i;
568   int rv;
569 
570   assert(ct);
571   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
572   assert(lct);
573 
574   /* reload if needed */
575   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
576   if (rv) {
577     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
578     return rv;
579   }
580 
581   /* count keys */
582   i=0;
583   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
584   while (ctx) {
585     i+=GWEN_CRYPT_TOKEN_CONTEXT_KEYS;
586     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
587   }
588 
589   /* if no buffer given just return number of keys */
590   if (pIdList==NULL) {
591     *pCount=i;
592     return 0;
593   }
594 
595   if (*pCount<i) {
596     DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
597     return GWEN_ERROR_BUFFER_OVERFLOW;
598   }
599 
600   *pCount=i;
601   i=0;
602   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
603   while (ctx) {
604     int j;
605 
606     for (j=1; j<=GWEN_CRYPT_TOKEN_CONTEXT_KEYS; j++)
607       *(pIdList++)=(i<<16)+j;
608 
609     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
610     i++;
611   }
612 
613   return 0;
614 }
615 
616 
617 
GWEN_Crypt_TokenFile__GetKeyInfo(GWEN_CRYPT_TOKEN * ct,uint32_t id,GWEN_UNUSED uint32_t flags,uint32_t gid)618 const GWEN_CRYPT_TOKEN_KEYINFO *GWENHYWFAR_CB GWEN_Crypt_TokenFile__GetKeyInfo(GWEN_CRYPT_TOKEN *ct,
619                                                                                uint32_t id,
620                                                                                GWEN_UNUSED uint32_t flags,
621                                                                                uint32_t gid)
622 {
623   GWEN_CRYPT_TOKEN_FILE *lct;
624   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
625   GWEN_CRYPT_TOKEN_KEYINFO *ki;
626   int i;
627   int rv;
628 
629   assert(ct);
630   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
631   assert(lct);
632 
633   /* reload if needed */
634   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
635   if (rv) {
636     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
637     return NULL;
638   }
639 
640   i=id>>16;
641   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
642   while (ctx) {
643     if (i==0)
644       break;
645     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
646     i--;
647   }
648 
649   if (ctx==NULL) {
650     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
651     return NULL;
652   }
653 
654   switch (id & 0xffff) {
655   case 1:
656     ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
657     break;
658   case 2:
659     ki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx);
660     break;
661   case 3:
662     ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
663     break;
664   case 4:
665     ki=GWEN_CTF_Context_GetRemoteCryptKeyInfo(ctx);
666     break;
667   case 5:
668     ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
669     break;
670   case 6:
671     ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
672     break;
673   case 7:
674     ki=GWEN_CTF_Context_GetTempLocalSignKeyInfo(ctx);
675     break;
676   default:
677     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
678     return NULL;
679   }
680 
681   if (ki==NULL) {
682     DBG_INFO(GWEN_LOGDOMAIN, "No key info stored for key %d", id);
683     return NULL;
684   }
685 
686   return ki;
687 }
688 
689 
690 
691 #if 0
692 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__SetKeyInfo(GWEN_CRYPT_TOKEN *ct,
693                                                    uint32_t id,
694                                                    const GWEN_CRYPT_TOKEN_KEYINFO *ki,
695                                                    uint32_t gid)
696 {
697   GWEN_CRYPT_TOKEN_FILE *lct;
698   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
699   int i;
700   int rv;
701   GWEN_CRYPT_TOKEN_KEYINFO *nki;
702   GWEN_CRYPT_KEY *key;
703   uint32_t flags;
704 
705   assert(ct);
706   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
707   assert(lct);
708 
709   flags=GWEN_Crypt_Token_KeyInfo_GetFlags(ki);
710 
711   /* reload if needed */
712   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
713   if (rv) {
714     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
715     return rv;
716   }
717 
718   i=id>>16;
719   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
720   while (ctx) {
721     if (i==0)
722       break;
723     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
724     i--;
725   }
726 
727   if (ctx==NULL) {
728     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
729     return GWEN_ERROR_NOT_FOUND;
730   }
731 
732   nki=GWEN_Crypt_Token_KeyInfo_dup(ki);
733   assert(nki);
734   switch (id & 0xffff) {
735   case 1:
736     GWEN_CTF_Context_SetLocalSignKeyInfo(ctx, nki);
737     key=GWEN_CTF_Context_GetLocalSignKey(ctx);
738     break;
739   case 2:
740     GWEN_CTF_Context_SetLocalCryptKeyInfo(ctx, nki);
741     key=GWEN_CTF_Context_GetLocalCryptKey(ctx);
742     break;
743   case 3:
744     GWEN_CTF_Context_SetRemoteSignKeyInfo(ctx, nki);
745     key=GWEN_CTF_Context_GetRemoteSignKey(ctx);
746     break;
747   case 4:
748     GWEN_CTF_Context_SetRemoteCryptKeyInfo(ctx, nki);
749     key=GWEN_CTF_Context_GetRemoteCryptKey(ctx);
750     break;
751   case 5:
752     GWEN_CTF_Context_SetLocalAuthKeyInfo(ctx, nki);
753     key=GWEN_CTF_Context_GetLocalAuthKey(ctx);
754     break;
755   case 6:
756     GWEN_CTF_Context_SetRemoteAuthKeyInfo(ctx, nki);
757     key=GWEN_CTF_Context_GetRemoteAuthKey(ctx);
758     break;
759   default:
760     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
761     GWEN_Crypt_Token_KeyInfo_free(nki);
762     return GWEN_ERROR_NOT_FOUND;
763   }
764 
765   /* replace key if modulus and exponent are given */
766   if ((flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) &&
767       (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT) &&
768       id!=1 && /* don't change local keys */
769       id!=2 &&
770       id!=5) {
771     GWEN_CRYPT_KEY *nkey;
772 
773     nkey=GWEN_Crypt_KeyRsa_fromModExp(GWEN_Crypt_Token_KeyInfo_GetKeySize(ki),
774                                       GWEN_Crypt_Token_KeyInfo_GetModulusData(ki),
775                                       GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki),
776                                       GWEN_Crypt_Token_KeyInfo_GetExponentData(ki),
777                                       GWEN_Crypt_Token_KeyInfo_GetExponentLen(ki));
778     assert(nkey);
779 
780     if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
781       GWEN_Crypt_Key_SetKeyNumber(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
782     if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
783       GWEN_Crypt_Key_SetKeyVersion(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
784 
785     /* replace public key */
786     switch (id & 0xffff) {
787     case 3: /* remote sign key */
788       GWEN_CTF_Context_SetRemoteSignKey(ctx, nkey);
789       break;
790     case 4: /* remote crypt key */
791       GWEN_CTF_Context_SetRemoteCryptKey(ctx, nkey);
792       break;
793     case 6: /* remote auth key */
794       GWEN_CTF_Context_SetRemoteAuthKey(ctx, nkey);
795       break;
796     default:
797       DBG_ERROR(GWEN_LOGDOMAIN,
798                 "Can't set modulus and exponent for private key");
799       GWEN_Crypt_Key_free(nkey);
800       return GWEN_ERROR_INVALID;
801     }
802     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
803                          I18N("Public key replaced"));
804   }
805   else {
806     if (key) {
807       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
808         GWEN_Crypt_Key_SetKeyNumber(key, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
809       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
810         GWEN_Crypt_Key_SetKeyVersion(key, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
811     }
812   }
813 
814   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
815   if (rv) {
816     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
817     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
818                          I18N("Unable to write key file"));
819     return rv;
820   }
821 
822   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
823                        I18N("Key file saved"));
824 
825   return 0;
826 }
827 #endif
828 
829 
GWEN_Crypt_TokenFile__SetKeyInfo(GWEN_CRYPT_TOKEN * ct,uint32_t id,const GWEN_CRYPT_TOKEN_KEYINFO * ski,uint32_t gid)830 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__SetKeyInfo(GWEN_CRYPT_TOKEN *ct,
831                                                    uint32_t id,
832                                                    const GWEN_CRYPT_TOKEN_KEYINFO *ski,
833                                                    uint32_t gid)
834 {
835   GWEN_CRYPT_TOKEN_FILE *lct;
836   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
837   int i;
838   int rv;
839   GWEN_CRYPT_TOKEN_KEYINFO *ki;
840   GWEN_CRYPT_KEY *key;
841   uint32_t flags;
842   uint32_t nflags;
843 
844   assert(ct);
845   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
846   assert(lct);
847 
848   flags=GWEN_Crypt_Token_KeyInfo_GetFlags(ski);
849 
850   /* reload if needed */
851   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
852   if (rv) {
853     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
854     return rv;
855   }
856 
857   i=id>>16;
858   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
859   while (ctx) {
860     if (i==0)
861       break;
862     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
863     i--;
864   }
865 
866   if (ctx==NULL) {
867     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
868     return GWEN_ERROR_NOT_FOUND;
869   }
870 
871   switch (id & 0xffff) {
872   case 1:
873     ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
874     key=GWEN_CTF_Context_GetLocalSignKey(ctx);
875     break;
876   case 2:
877     ki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx);
878     key=GWEN_CTF_Context_GetLocalCryptKey(ctx);
879     break;
880   case 3:
881     ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
882     key=GWEN_CTF_Context_GetRemoteSignKey(ctx);
883     break;
884   case 4:
885     ki=GWEN_CTF_Context_GetRemoteCryptKeyInfo(ctx);
886     key=GWEN_CTF_Context_GetRemoteCryptKey(ctx);
887     break;
888   case 5:
889     ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
890     key=GWEN_CTF_Context_GetLocalAuthKey(ctx);
891     break;
892   case 6:
893     ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
894     key=GWEN_CTF_Context_GetRemoteAuthKey(ctx);
895     break;
896   case 7:
897     ki=GWEN_CTF_Context_GetTempLocalSignKeyInfo(ctx);
898     key=GWEN_CTF_Context_GetTempLocalSignKey(ctx);
899     break;
900   default:
901     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
902     return GWEN_ERROR_NOT_FOUND;
903   }
904   assert(ki);
905 
906   nflags=GWEN_Crypt_Token_KeyInfo_GetFlags(ki);
907 
908   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSTATUS) {
909     /* ignore for now */
910   }
911 
912   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS) {
913     nflags&=~GWEN_CRYPT_TOKEN_KEYFLAGS_ACTIONMASK;
914     nflags|=(flags & GWEN_CRYPT_TOKEN_KEYFLAGS_ACTIONMASK);
915   }
916 
917   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION) {
918     uint32_t i32=GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ski);
919     GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, i32);
920     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION;
921     if (key)
922       GWEN_Crypt_Key_SetKeyVersion(key, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ski));
923     DBG_INFO(GWEN_LOGDOMAIN, "Setting key version");
924   }
925 
926   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER) {
927     uint32_t i32=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ski);
928     GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, i32);
929     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER;
930     DBG_INFO(GWEN_LOGDOMAIN, "Setting signature counter");
931   }
932 
933   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER) {
934     uint32_t i32=GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ski);
935     GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, i32);
936     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER;
937     if (key)
938       GWEN_Crypt_Key_SetKeyNumber(key, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ski));
939     DBG_INFO(GWEN_LOGDOMAIN, "Setting key number");
940   }
941 
942   /* replace key if modulus and exponent are given */
943   if ((flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) &&
944       (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT) &&
945       id!=1 && /* don't change local keys */
946       id!=2 &&
947       id!=5 &&
948       id!=7) {
949     GWEN_CRYPT_KEY *nkey;
950 
951     GWEN_Crypt_Token_KeyInfo_SetKeySize(ki, GWEN_Crypt_Token_KeyInfo_GetKeySize(ski));
952     GWEN_Crypt_Token_KeyInfo_SetModulus(ki,
953                                         GWEN_Crypt_Token_KeyInfo_GetModulusData(ski),
954                                         GWEN_Crypt_Token_KeyInfo_GetModulusLen(ski));
955     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS;
956     GWEN_Crypt_Token_KeyInfo_SetExponent(ki,
957                                          GWEN_Crypt_Token_KeyInfo_GetExponentData(ski),
958                                          GWEN_Crypt_Token_KeyInfo_GetExponentLen(ski));
959     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT;
960     nkey=GWEN_Crypt_KeyRsa_fromModExp(GWEN_Crypt_Token_KeyInfo_GetKeySize(ski),
961                                       GWEN_Crypt_Token_KeyInfo_GetModulusData(ski),
962                                       GWEN_Crypt_Token_KeyInfo_GetModulusLen(ski),
963                                       GWEN_Crypt_Token_KeyInfo_GetExponentData(ski),
964                                       GWEN_Crypt_Token_KeyInfo_GetExponentLen(ski));
965     assert(nkey);
966 
967     if (nflags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
968       GWEN_Crypt_Key_SetKeyNumber(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
969     if (nflags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
970       GWEN_Crypt_Key_SetKeyVersion(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
971 
972     /* replace public key */
973     switch (id & 0xffff) {
974     case 3: /* remote sign key */
975       GWEN_CTF_Context_SetRemoteSignKey(ctx, nkey);
976       break;
977     case 4: /* remote crypt key */
978       GWEN_CTF_Context_SetRemoteCryptKey(ctx, nkey);
979       break;
980     case 6: /* remote auth key */
981       GWEN_CTF_Context_SetRemoteAuthKey(ctx, nkey);
982       break;
983     default:
984       DBG_ERROR(GWEN_LOGDOMAIN,
985                 "Can't set modulus and exponent for private key");
986       GWEN_Crypt_Key_free(nkey);
987       return GWEN_ERROR_INVALID;
988     }
989     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
990                          I18N("Public key replaced"));
991   }
992   else {
993     if (key) {
994       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
995         GWEN_Crypt_Key_SetKeyNumber(key, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
996       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
997         GWEN_Crypt_Key_SetKeyVersion(key, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
998     }
999   }
1000 
1001   GWEN_Crypt_Token_KeyInfo_SetFlags(ki, nflags);
1002 
1003   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1004   if (rv) {
1005     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1006     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
1007                          I18N("Unable to write key file"));
1008     return rv;
1009   }
1010 
1011   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
1012                        I18N("Key file saved"));
1013 
1014   return 0;
1015 }
1016 
1017 
1018 
GWEN_Crypt_TokenFile__ActivateKey(GWEN_CRYPT_TOKEN * ct,uint32_t id,uint32_t gid)1019 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__ActivateKey(GWEN_CRYPT_TOKEN *ct, uint32_t id, uint32_t gid)
1020 {
1021   GWEN_CRYPT_TOKEN_FILE *lct;
1022   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1023   int rv;
1024   int i;
1025   uint32_t keyNum;
1026   uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1027   uint32_t klen;
1028   GWEN_CRYPT_TOKEN_KEYINFO *cki=NULL;
1029   GWEN_CRYPT_TOKEN_KEYINFO *ki;
1030   GWEN_CRYPT_KEY *key;
1031 
1032   assert(ct);
1033   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1034   assert(lct);
1035 
1036   /* reload if needed */
1037   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1038   if (rv) {
1039     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1040     return rv;
1041   }
1042 
1043   keyNum=id & 0xffff;
1044 
1045   i=id>>16;
1046   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1047   while (ctx) {
1048     if (i==0)
1049       break;
1050     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1051     i--;
1052   }
1053 
1054   if (ctx==NULL) {
1055     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
1056     return GWEN_ERROR_NOT_FOUND;
1057   }
1058 
1059   key=GWEN_CTF_Context_GetTempLocalSignKey(ctx);
1060   if (key==NULL) {
1061     DBG_ERROR(GWEN_LOGDOMAIN, "No temporary local sign key.");
1062     return GWEN_ERROR_NOT_FOUND;
1063   }
1064   key=GWEN_Crypt_KeyRsa_dup(key);
1065 
1066   /* set key */
1067   if (keyNum==1)
1068     cki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
1069   else if (keyNum==6)
1070     cki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
1071   else {
1072     GWEN_Gui_ProgressLog2(gid, GWEN_LoggerLevel_Error,
1073                           I18N("Invalid key id %02x"), id);
1074     GWEN_Crypt_Key_free(key);
1075     return GWEN_ERROR_NO_DATA;
1076   }
1077   if (cki==NULL) {
1078     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
1079                          I18N("No key info found"));
1080     GWEN_Crypt_Key_free(key);
1081     return GWEN_ERROR_NO_DATA;
1082   }
1083 
1084   /* update key info for the key */
1085   ki=GWEN_Crypt_Token_KeyInfo_dup(cki);
1086   assert(ki);
1087 
1088   /* get modulus */
1089   klen=sizeof(kbuf);
1090   rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1091   if (rv) {
1092     DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1093     GWEN_Crypt_Token_KeyInfo_free(ki);
1094     GWEN_Crypt_Key_free(key);
1095     return rv;
1096   }
1097   GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1098 
1099   /* get exponent */
1100   klen=sizeof(kbuf);
1101   rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1102   if (rv) {
1103     DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1104     GWEN_Crypt_Token_KeyInfo_free(ki);
1105     GWEN_Crypt_Key_free(key);
1106     return rv;
1107   }
1108   GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1109   GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(key));
1110   GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(key));
1111 
1112   if (keyNum==1) {
1113     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
1114       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1115       GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1116     }
1117     GWEN_CTF_Context_SetLocalSignKey(ctx, key);
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_Crypt_Token_KeyInfo_SetSignCounter(ki, 1);
1128     GWEN_CTF_Context_SetLocalSignKeyInfo(ctx, ki);
1129   }
1130   else if (keyNum==6) {
1131     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
1132       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1133       GWEN_Crypt_KeyRsa_AddFlags(key, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
1134     }
1135     GWEN_CTF_Context_SetLocalAuthKey(ctx, key);
1136     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
1137                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1138                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1139                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1140                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1141                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
1142                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
1143                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
1144                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
1145     GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, 1);
1146     GWEN_CTF_Context_SetLocalAuthKeyInfo(ctx, ki);
1147   }
1148 
1149   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1150   if (rv) {
1151     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1152     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
1153                          I18N("Unable to write key file"));
1154     return rv;
1155   }
1156 
1157   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
1158                        I18N("Key file saved"));
1159 
1160   return 0;
1161 }
1162 
1163 
1164 
GWEN_Crypt_TokenFile__GetContextIdList(GWEN_CRYPT_TOKEN * ct,uint32_t * pIdList,uint32_t * pCount,uint32_t gid)1165 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__GetContextIdList(GWEN_CRYPT_TOKEN *ct,
1166                                                          uint32_t *pIdList,
1167                                                          uint32_t *pCount,
1168                                                          uint32_t gid)
1169 {
1170   GWEN_CRYPT_TOKEN_FILE *lct;
1171   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1172   int i;
1173   int rv;
1174 
1175   assert(ct);
1176   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1177   assert(lct);
1178 
1179   /* reload if needed */
1180   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1181   if (rv) {
1182     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1183     return rv;
1184   }
1185 
1186   /* count keys */
1187   i=0;
1188   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1189   while (ctx) {
1190     i++;
1191     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1192   }
1193 
1194   /* store number of entries */
1195   *pCount=i;
1196 
1197   /* if no buffer given just return number of keys */
1198   if (pIdList==NULL)
1199     return 0;
1200 
1201   if (*pCount<i) {
1202     DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
1203     return GWEN_ERROR_BUFFER_OVERFLOW;
1204   }
1205 
1206   i=1;
1207   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1208   while (ctx) {
1209     *(pIdList++)=i;
1210     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1211     i++;
1212   }
1213 
1214   return 0;
1215 }
1216 
1217 
1218 
GWEN_Crypt_TokenFile__GetContext(GWEN_CRYPT_TOKEN * ct,uint32_t id,uint32_t gid)1219 const GWEN_CRYPT_TOKEN_CONTEXT *GWENHYWFAR_CB GWEN_Crypt_TokenFile__GetContext(GWEN_CRYPT_TOKEN *ct,
1220                                                                                uint32_t id,
1221                                                                                uint32_t gid)
1222 {
1223   GWEN_CRYPT_TOKEN_FILE *lct;
1224   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1225   int rv;
1226 
1227   assert(ct);
1228   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1229   assert(lct);
1230 
1231   /* reload if needed */
1232   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1233   if (rv) {
1234     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1235     return NULL;
1236   }
1237 
1238   if (id==0) {
1239     DBG_INFO(GWEN_LOGDOMAIN, "Invalid context id 0");
1240     return NULL;
1241   }
1242 
1243   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1244   while (ctx) {
1245     if (GWEN_Crypt_Token_Context_GetId(ctx)==id)
1246       break;
1247     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1248   }
1249 
1250   if (ctx==NULL) {
1251     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", id);
1252     return NULL;
1253   }
1254 
1255   return ctx;
1256 }
1257 
1258 
1259 
GWEN_Crypt_TokenFile__SetContext(GWEN_CRYPT_TOKEN * ct,uint32_t id,const GWEN_CRYPT_TOKEN_CONTEXT * nctx,uint32_t gid)1260 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__SetContext(GWEN_CRYPT_TOKEN *ct,
1261                                                    uint32_t id,
1262                                                    const GWEN_CRYPT_TOKEN_CONTEXT *nctx,
1263                                                    uint32_t gid)
1264 {
1265   GWEN_CRYPT_TOKEN_FILE *lct;
1266   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1267   int rv;
1268   const char *s;
1269 
1270   assert(ct);
1271   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1272   assert(lct);
1273 
1274   if (id==0) {
1275     DBG_INFO(GWEN_LOGDOMAIN, "Invalid context id 0");
1276     return GWEN_ERROR_INVALID;
1277   }
1278 
1279   /* reload if needed */
1280   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1281   if (rv) {
1282     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1283     return rv;
1284   }
1285 
1286   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1287   while (ctx) {
1288     if (GWEN_Crypt_Token_Context_GetId(ctx)==id)
1289       break;
1290     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1291   }
1292 
1293   if (ctx==NULL) {
1294     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", id);
1295     return GWEN_ERROR_NOT_FOUND;
1296   }
1297 
1298   /* copy user data from context */
1299   s=GWEN_Crypt_Token_Context_GetServiceId(nctx);
1300   GWEN_Crypt_Token_Context_SetServiceId(ctx, s);
1301   s=GWEN_Crypt_Token_Context_GetUserId(nctx);
1302   GWEN_Crypt_Token_Context_SetUserId(ctx, s);
1303   s=GWEN_Crypt_Token_Context_GetUserName(nctx);
1304   GWEN_Crypt_Token_Context_SetUserName(ctx, s);
1305   s=GWEN_Crypt_Token_Context_GetPeerId(nctx);
1306   GWEN_Crypt_Token_Context_SetPeerId(ctx, s);
1307   s=GWEN_Crypt_Token_Context_GetAddress(nctx);
1308   GWEN_Crypt_Token_Context_SetAddress(ctx, s);
1309   GWEN_Crypt_Token_Context_SetPort(ctx, GWEN_Crypt_Token_Context_GetPort(nctx));
1310   s=GWEN_Crypt_Token_Context_GetSystemId(nctx);
1311   GWEN_Crypt_Token_Context_SetSystemId(ctx, s);
1312 
1313   return 0;
1314 }
1315 
1316 
1317 
GWEN_Crypt_TokenFile__GetKey(GWEN_CRYPT_TOKEN * ct,uint32_t id,uint32_t gid)1318 GWEN_CRYPT_KEY *GWEN_Crypt_TokenFile__GetKey(GWEN_CRYPT_TOKEN *ct, uint32_t id, uint32_t gid)
1319 {
1320   GWEN_CRYPT_TOKEN_FILE *lct;
1321   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1322   int i;
1323   int rv;
1324 
1325   assert(ct);
1326   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1327   assert(lct);
1328 
1329   /* reload if needed */
1330   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1331   if (rv) {
1332     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1333     return NULL;
1334   }
1335 
1336   i=id>>16;
1337   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1338   while (ctx) {
1339     if (i==0)
1340       break;
1341     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1342     i--;
1343   }
1344 
1345   if (ctx==NULL) {
1346     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
1347     return NULL;
1348   }
1349 
1350   switch (id & 0xffff) {
1351   case 1:
1352     return GWEN_CTF_Context_GetLocalSignKey(ctx);
1353   case 2:
1354     return GWEN_CTF_Context_GetLocalCryptKey(ctx);
1355   case 3:
1356     return GWEN_CTF_Context_GetRemoteSignKey(ctx);
1357   case 4:
1358     return GWEN_CTF_Context_GetRemoteCryptKey(ctx);
1359   case 5:
1360     return GWEN_CTF_Context_GetLocalAuthKey(ctx);
1361   case 6:
1362     return GWEN_CTF_Context_GetRemoteAuthKey(ctx);
1363   default:
1364     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
1365     return NULL;
1366   }
1367 }
1368 
1369 
1370 
GWEN_Crypt_TokenFile__Sign(GWEN_CRYPT_TOKEN * ct,uint32_t keyId,GWEN_CRYPT_PADDALGO * a,const uint8_t * pInData,uint32_t inLen,uint8_t * pSignatureData,uint32_t * pSignatureLen,uint32_t * pSeqCounter,uint32_t gid)1371 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__Sign(GWEN_CRYPT_TOKEN *ct,
1372                                              uint32_t keyId,
1373                                              GWEN_CRYPT_PADDALGO *a,
1374                                              const uint8_t *pInData,
1375                                              uint32_t inLen,
1376                                              uint8_t *pSignatureData,
1377                                              uint32_t *pSignatureLen,
1378                                              uint32_t *pSeqCounter,
1379                                              uint32_t gid)
1380 {
1381   GWEN_CRYPT_TOKEN_FILE *lct;
1382   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1383   GWEN_CRYPT_KEY *k;
1384   int keyNum;
1385   GWEN_BUFFER *srcBuf;
1386   int i;
1387   int rv;
1388   GWEN_CRYPT_PADDALGOID aid;
1389 
1390   assert(ct);
1391   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1392   assert(lct);
1393 
1394   DBG_INFO(GWEN_LOGDOMAIN, "Signing with key %d", keyId);
1395   aid=GWEN_Crypt_PaddAlgo_GetId(a);
1396 
1397   /* reload if needed */
1398   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1399   if (rv) {
1400     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1401     return rv;
1402   }
1403 
1404   /* get context */
1405   i=(keyId>>16);
1406   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1407   if (ctx==NULL) {
1408     DBG_ERROR(GWEN_LOGDOMAIN, "Token has no context");
1409     return GWEN_ERROR_NOT_FOUND;
1410   }
1411   while (ctx) {
1412     if (i==0)
1413       break;
1414     DBG_ERROR(GWEN_LOGDOMAIN, "Checking token %d (i==%d)",
1415               GWEN_Crypt_Token_Context_GetId(ctx), i);
1416     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1417     i--;
1418   }
1419 
1420   if (ctx==NULL) {
1421     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1422     return GWEN_ERROR_NOT_FOUND;
1423   }
1424 
1425   /* get key */
1426   keyNum=keyId & 0xffff;
1427   if (keyNum!=1 && keyNum!=5) {
1428     /* neither localSignKey nor localAuthKey */
1429     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for signing (%x)", keyId);
1430     return GWEN_ERROR_INVALID;
1431   }
1432 
1433   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1434   if (k==NULL) {
1435     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
1436     return GWEN_ERROR_NOT_FOUND;
1437   }
1438 
1439   /* copy to a buffer for padding */
1440   srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1441 
1442   if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1443     const GWEN_CRYPT_TOKEN_KEYINFO *ki;
1444     int nbits;
1445     const uint8_t *modPtr;
1446     uint32_t modLen;
1447     GWEN_MDIGEST *md;
1448 
1449     switch (keyId & 0xffff) {
1450     case 1:
1451       ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
1452       break;
1453     case 5:
1454       ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
1455       break;
1456     default:
1457       ki=NULL;
1458     }
1459 
1460     if (ki==NULL) {
1461       DBG_ERROR(GWEN_LOGDOMAIN, "No information for key %d", keyNum);
1462       GWEN_Buffer_free(srcBuf);
1463       return GWEN_ERROR_GENERIC;
1464     }
1465 
1466     /* calculate real number of bits */
1467     modPtr=GWEN_Crypt_Token_KeyInfo_GetModulusData(ki);
1468     modLen=GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki);
1469     nbits=modLen*8;
1470     while (modLen && *modPtr==0) {
1471       nbits-=8;
1472       modLen--;
1473       modPtr++;
1474     }
1475     if (modLen) {
1476       uint8_t b=*modPtr;
1477       int i;
1478       uint8_t mask=0x80;
1479 
1480       for (i=0; i<8; i++) {
1481         if (b & mask)
1482           break;
1483         nbits--;
1484         mask>>=1;
1485       }
1486     }
1487 
1488     if (nbits==0) {
1489       DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
1490       GWEN_Buffer_free(srcBuf);
1491       return GWEN_ERROR_GENERIC;
1492     }
1493 
1494     md=GWEN_MDigest_Sha256_new();
1495     GWEN_Buffer_AllocRoom(srcBuf, modLen);
1496 
1497     rv=GWEN_Padd_AddPkcs1Pss((uint8_t *) GWEN_Buffer_GetStart(srcBuf),
1498                              GWEN_Buffer_GetMaxUnsegmentedWrite(srcBuf),
1499                              nbits,
1500                              pInData, inLen,
1501                              inLen,
1502                              md);
1503     GWEN_MDigest_free(md);
1504     if (rv<0) {
1505       DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
1506       GWEN_Buffer_free(srcBuf);
1507       return rv;
1508     }
1509 
1510     GWEN_Buffer_IncrementPos(srcBuf, rv);
1511     GWEN_Buffer_AdjustUsedBytes(srcBuf);
1512   }
1513   else {
1514     GWEN_Buffer_AppendBytes(srcBuf, (const char *)pInData, inLen);
1515 
1516     /* padd according to given algo */
1517     rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1518     if (rv) {
1519       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1520       GWEN_Buffer_free(srcBuf);
1521       return rv;
1522     }
1523   }
1524 
1525   /* sign with key */
1526   rv=GWEN_Crypt_Key_Sign(k,
1527                          (const uint8_t *)GWEN_Buffer_GetStart(srcBuf),
1528                          GWEN_Buffer_GetUsedBytes(srcBuf),
1529                          pSignatureData,
1530                          pSignatureLen);
1531   GWEN_Buffer_free(srcBuf);
1532   if (rv) {
1533     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1534     return rv;
1535   }
1536 
1537   if (pSeqCounter) {
1538     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1539 
1540     /* signature sequence counter is to be incremented */
1541     switch (keyId & 0xffff) {
1542     case 1:
1543       ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
1544       break;
1545     case 5:
1546       ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
1547       break;
1548     default:
1549       ki=NULL;
1550     }
1551     if (ki &&
1552         (GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER)) {
1553       unsigned int seq;
1554 
1555       seq=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki);
1556       *pSeqCounter=seq;
1557       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, ++seq);
1558 
1559       rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1560       if (rv) {
1561         DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1562         return rv;
1563       }
1564     }
1565     else {
1566       DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
1567       *pSeqCounter=0;
1568     }
1569   }
1570 
1571   return 0;
1572 }
1573 
1574 
1575 
GWEN_Crypt_TokenFile__Verify(GWEN_CRYPT_TOKEN * ct,uint32_t keyId,GWEN_CRYPT_PADDALGO * a,const uint8_t * pInData,uint32_t inLen,const uint8_t * pSignatureData,uint32_t signatureLen,uint32_t seqCounter,uint32_t gid)1576 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__Verify(GWEN_CRYPT_TOKEN *ct,
1577                                                uint32_t keyId,
1578                                                GWEN_CRYPT_PADDALGO *a,
1579                                                const uint8_t *pInData,
1580                                                uint32_t inLen,
1581                                                const uint8_t *pSignatureData,
1582                                                uint32_t signatureLen,
1583                                                uint32_t seqCounter,
1584                                                uint32_t gid)
1585 {
1586   GWEN_CRYPT_TOKEN_FILE *lct;
1587   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1588   GWEN_CRYPT_KEY *k;
1589   int keyNum;
1590   int i;
1591   int rv;
1592   GWEN_CRYPT_PADDALGOID aid;
1593 
1594   assert(ct);
1595   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1596   assert(lct);
1597 
1598   DBG_INFO(GWEN_LOGDOMAIN, "Verifying with key %d", keyId);
1599 
1600   aid=GWEN_Crypt_PaddAlgo_GetId(a);
1601 
1602   /* reload if needed */
1603   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1604   if (rv) {
1605     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1606     return rv;
1607   }
1608 
1609   /* get context */
1610   i=(keyId>>16);
1611   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1612   while (ctx) {
1613     if (i==0)
1614       break;
1615     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1616     i--;
1617   }
1618 
1619   if (ctx==NULL) {
1620     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1621     return GWEN_ERROR_NOT_FOUND;
1622   }
1623 
1624   /* get key */
1625   keyNum=keyId & 0xffff;
1626   if (keyNum!=1 && keyNum!=3 && keyNum!=6) {
1627     /* neither remoteSignKey nor remoteAuthKey */
1628     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for verifying (%x)", keyId);
1629     return GWEN_ERROR_INVALID;
1630   }
1631 
1632   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1633   if (k==NULL) {
1634     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
1635     return GWEN_ERROR_NO_KEY;
1636   }
1637 
1638   if (aid==GWEN_Crypt_PaddAlgoId_Iso9796_2 ||
1639       aid==GWEN_Crypt_PaddAlgoId_Pkcs1_2 ||
1640       aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1641     GWEN_BUFFER *tbuf;
1642     uint32_t l;
1643 
1644     /* these algos add random numbers, we must use encrypt fn here and
1645      * compare the decrypted and unpadded data with the source data */
1646     tbuf=GWEN_Buffer_new(0, signatureLen+16, 0, 0);
1647     l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
1648     rv=GWEN_Crypt_Key_Encipher(k,
1649                                pSignatureData, signatureLen,
1650                                (uint8_t *)GWEN_Buffer_GetStart(tbuf),
1651                                &l);
1652     if (rv<0) {
1653       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1654       GWEN_Buffer_free(tbuf);
1655       return rv;
1656     }
1657     GWEN_Buffer_IncrementPos(tbuf, l);
1658     GWEN_Buffer_AdjustUsedBytes(tbuf);
1659 
1660     if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1661       const GWEN_CRYPT_TOKEN_KEYINFO *ki;
1662       int nbits;
1663       const uint8_t *modPtr;
1664       uint32_t modLen;
1665       GWEN_MDIGEST *md;
1666 
1667       if (keyNum==3)
1668         ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
1669       else
1670         ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
1671       if (ki==NULL) {
1672         DBG_ERROR(GWEN_LOGDOMAIN, "No information for key %d", keyNum);
1673         GWEN_Buffer_free(tbuf);
1674         return GWEN_ERROR_GENERIC;
1675       }
1676 
1677       /* calculate real number of bits */
1678       modPtr=GWEN_Crypt_Token_KeyInfo_GetModulusData(ki);
1679       modLen=GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki);
1680       nbits=modLen*8;
1681       while (modLen && *modPtr==0) {
1682         nbits-=8;
1683         modLen--;
1684         modPtr++;
1685       }
1686       if (modLen) {
1687         uint8_t b=*modPtr;
1688         int i;
1689         uint8_t mask=0x80;
1690 
1691         for (i=0; i<8; i++) {
1692           if (b & mask)
1693             break;
1694           nbits--;
1695           mask>>=1;
1696         }
1697       }
1698 
1699       if (nbits==0) {
1700         DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
1701         GWEN_Buffer_free(tbuf);
1702         return GWEN_ERROR_GENERIC;
1703       }
1704 
1705       md=GWEN_MDigest_Sha256_new();
1706       rv=GWEN_Padd_VerifyPkcs1Pss((const uint8_t *) GWEN_Buffer_GetStart(tbuf),
1707                                   GWEN_Buffer_GetUsedBytes(tbuf),
1708                                   nbits,
1709                                   pInData, inLen,
1710                                   inLen,
1711                                   md);
1712       GWEN_MDigest_free(md);
1713       if (rv<0) {
1714         DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
1715         GWEN_Buffer_free(tbuf);
1716         return rv;
1717       }
1718     }
1719     else {
1720       rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
1721       if (rv<0) {
1722         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1723         GWEN_Buffer_free(tbuf);
1724         return rv;
1725       }
1726       l=GWEN_Buffer_GetUsedBytes(tbuf);
1727 
1728       if (l!=inLen) {
1729         DBG_ERROR(GWEN_LOGDOMAIN, "Signature length doesn't match");
1730         GWEN_Buffer_free(tbuf);
1731         return GWEN_ERROR_VERIFY;
1732       }
1733       if (memcmp(pInData, GWEN_Buffer_GetStart(tbuf), l)!=0) {
1734         DBG_ERROR(GWEN_LOGDOMAIN, "Signature doesn't match:");
1735         GWEN_Buffer_free(tbuf);
1736         return GWEN_ERROR_VERIFY;
1737       }
1738     }
1739     GWEN_Buffer_free(tbuf);
1740   }
1741   else {
1742     GWEN_BUFFER *srcBuf;
1743 
1744     /* copy to a buffer for padding */
1745     srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1746     GWEN_Buffer_AppendBytes(srcBuf, (const char *)pInData, inLen);
1747 
1748     /* padd according to given algo */
1749     rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1750     if (rv) {
1751       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1752       GWEN_Buffer_free(srcBuf);
1753       return rv;
1754     }
1755 
1756     /* verify with key */
1757     rv=GWEN_Crypt_Key_Verify(k,
1758                              (const uint8_t *)GWEN_Buffer_GetStart(srcBuf),
1759                              GWEN_Buffer_GetUsedBytes(srcBuf),
1760                              pSignatureData,
1761                              signatureLen);
1762     GWEN_Buffer_free(srcBuf);
1763     if (rv) {
1764       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1765       return rv;
1766     }
1767   }
1768 
1769   if (seqCounter) {
1770     GWEN_CRYPT_TOKEN_KEYINFO *ki;
1771 
1772     /* signature sequence counter is to be checked */
1773     if (keyNum==3)
1774       ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
1775     else
1776       ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
1777     if (ki &&
1778         (GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER)) {
1779       unsigned int seq;
1780 
1781       seq=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki);
1782 
1783       if (seq>=seqCounter) {
1784         DBG_WARN(GWEN_LOGDOMAIN, "Bad remote sequence counter (possibly replay attack!)");
1785         return GWEN_ERROR_VERIFY;
1786       }
1787       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, seqCounter);
1788 
1789       /* write file */
1790       rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1791       if (rv) {
1792         DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1793         return rv;
1794       }
1795     }
1796     else {
1797       DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
1798     }
1799 
1800   }
1801 
1802   return 0;
1803 }
1804 
1805 
1806 
GWEN_Crypt_TokenFile__Encipher(GWEN_CRYPT_TOKEN * ct,uint32_t keyId,GWEN_CRYPT_PADDALGO * a,const uint8_t * pInData,uint32_t inLen,uint8_t * pOutData,uint32_t * pOutLen,uint32_t gid)1807 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__Encipher(GWEN_CRYPT_TOKEN *ct,
1808                                                  uint32_t keyId,
1809                                                  GWEN_CRYPT_PADDALGO *a,
1810                                                  const uint8_t *pInData,
1811                                                  uint32_t inLen,
1812                                                  uint8_t *pOutData,
1813                                                  uint32_t *pOutLen,
1814                                                  uint32_t gid)
1815 {
1816   GWEN_CRYPT_TOKEN_FILE *lct;
1817   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1818   GWEN_CRYPT_KEY *k;
1819   int keyNum;
1820   GWEN_BUFFER *srcBuf;
1821   int i;
1822   int rv;
1823 
1824   assert(ct);
1825   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1826   assert(lct);
1827 
1828   DBG_INFO(GWEN_LOGDOMAIN, "Enciphering with key %d", keyId);
1829 
1830   /* reload if needed */
1831   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1832   if (rv) {
1833     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1834     return rv;
1835   }
1836 
1837   /* get context */
1838   i=(keyId>>16);
1839   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1840   while (ctx) {
1841     if (i==0)
1842       break;
1843     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1844     i--;
1845   }
1846 
1847   if (ctx==NULL) {
1848     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1849     return GWEN_ERROR_NOT_FOUND;
1850   }
1851 
1852   /* get key */
1853   keyNum=keyId & 0xffff;
1854   if (keyNum!=2 && keyNum!=4) {
1855     /* not remoteCryptKey */
1856     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for encrypting (%x)", keyId);
1857     return GWEN_ERROR_INVALID;
1858   }
1859 
1860   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1861   if (k==NULL) {
1862     DBG_INFO(GWEN_LOGDOMAIN, "Key %d not found", keyId);
1863     return GWEN_ERROR_NOT_FOUND;
1864   }
1865 
1866   /* copy to a buffer for padding */
1867   srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1868   GWEN_Buffer_AppendBytes(srcBuf, (const char *)pInData, inLen);
1869   GWEN_Buffer_Rewind(srcBuf);
1870 
1871   /* padd according to given algo */
1872   rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1873   if (rv) {
1874     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1875     GWEN_Buffer_free(srcBuf);
1876     return rv;
1877   }
1878 
1879   /* encipher with key */
1880   rv=GWEN_Crypt_Key_Encipher(k,
1881                              (const uint8_t *)GWEN_Buffer_GetStart(srcBuf),
1882                              GWEN_Buffer_GetUsedBytes(srcBuf),
1883                              pOutData,
1884                              pOutLen);
1885   GWEN_Buffer_free(srcBuf);
1886   if (rv) {
1887     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1888     return rv;
1889   }
1890 
1891   return 0;
1892 }
1893 
1894 
1895 
GWEN_Crypt_TokenFile__Decipher(GWEN_CRYPT_TOKEN * ct,uint32_t keyId,GWEN_CRYPT_PADDALGO * a,const uint8_t * pInData,uint32_t inLen,uint8_t * pOutData,uint32_t * pOutLen,uint32_t gid)1896 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__Decipher(GWEN_CRYPT_TOKEN *ct,
1897                                                  uint32_t keyId,
1898                                                  GWEN_CRYPT_PADDALGO *a,
1899                                                  const uint8_t *pInData,
1900                                                  uint32_t inLen,
1901                                                  uint8_t *pOutData,
1902                                                  uint32_t *pOutLen,
1903                                                  uint32_t gid)
1904 {
1905   GWEN_CRYPT_TOKEN_FILE *lct;
1906   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
1907   GWEN_CRYPT_KEY *k;
1908   int keyNum;
1909   GWEN_BUFFER *tbuf;
1910   int i;
1911   int rv;
1912   uint32_t l;
1913 
1914   assert(ct);
1915   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1916   assert(lct);
1917 
1918   DBG_INFO(GWEN_LOGDOMAIN, "Deciphering with key %d", keyId);
1919 
1920   /* reload if needed */
1921   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
1922   if (rv) {
1923     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1924     return rv;
1925   }
1926 
1927   /* get context */
1928   i=(keyId>>16);
1929   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1930   while (ctx) {
1931     if (i==0)
1932       break;
1933     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1934     i--;
1935   }
1936 
1937   if (ctx==NULL) {
1938     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1939     return GWEN_ERROR_NOT_FOUND;
1940   }
1941 
1942   /* get key */
1943   keyNum=keyId & 0xffff;
1944   if (keyNum!=2 && keyNum!=4) {
1945     /* not localCryptKey */
1946     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for decrypting (%x)", keyId);
1947     return GWEN_ERROR_INVALID;
1948   }
1949 
1950   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1951   if (k==NULL) {
1952     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
1953     return GWEN_ERROR_NOT_FOUND;
1954   }
1955 
1956   /* decipher with key */
1957   tbuf=GWEN_Buffer_new(0, inLen+16, 0, 1);
1958   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
1959   rv=GWEN_Crypt_Key_Decipher(k,
1960                              pInData, inLen,
1961                              (uint8_t *)GWEN_Buffer_GetStart(tbuf), &l);
1962   if (rv<0) {
1963     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1964     GWEN_Buffer_free(tbuf);
1965     return rv;
1966   }
1967   GWEN_Buffer_IncrementPos(tbuf, l);
1968   GWEN_Buffer_AdjustUsedBytes(tbuf);
1969 
1970   /* unpadd according to given algo */
1971   rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
1972   if (rv) {
1973     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1974     GWEN_Buffer_free(tbuf);
1975     return rv;
1976   }
1977 
1978   /* copy resulting data to given buffer */
1979   l=GWEN_Buffer_GetUsedBytes(tbuf);
1980   if (l>*pOutLen) {
1981     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1982     GWEN_Buffer_free(tbuf);
1983     return GWEN_ERROR_BUFFER_OVERFLOW;
1984   }
1985   memmove(pOutData, GWEN_Buffer_GetStart(tbuf), l);
1986   *pOutLen=l;
1987   GWEN_Buffer_free(tbuf);
1988 
1989   return 0;
1990 }
1991 
1992 
1993 
GWEN_Crypt_TokenFile__GenerateKey(GWEN_CRYPT_TOKEN * ct,uint32_t keyId,const GWEN_CRYPT_CRYPTALGO * a,uint32_t gid)1994 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__GenerateKey(GWEN_CRYPT_TOKEN *ct,
1995                                                     uint32_t keyId,
1996                                                     const GWEN_CRYPT_CRYPTALGO *a,
1997                                                     uint32_t gid)
1998 {
1999   GWEN_CRYPT_TOKEN_FILE *lct;
2000   GWEN_CRYPT_KEY *pubKey;
2001   GWEN_CRYPT_KEY *secKey;
2002   int rv;
2003   uint32_t keyNum;
2004   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
2005   int i;
2006   uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
2007   uint32_t klen;
2008   GWEN_CRYPT_TOKEN_KEYINFO *cki;
2009   GWEN_CRYPT_TOKEN_KEYINFO *ki;
2010 
2011   assert(ct);
2012   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
2013   assert(lct);
2014 
2015   /* reload if needed */
2016   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
2017   if (rv) {
2018     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2019     return rv;
2020   }
2021 
2022   keyNum=keyId & 0xffff;
2023 
2024   /* check key id */
2025   if (keyNum!=1 && keyNum!=2 && keyNum!=5 && keyNum!=7) {
2026     DBG_INFO(GWEN_LOGDOMAIN, "Can only generate local keys.");
2027     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
2028                          I18N("Can only generate local keys."));
2029     return GWEN_ERROR_NOT_SUPPORTED;
2030   }
2031 
2032   /* check for algo */
2033   if (GWEN_Crypt_CryptAlgo_GetId(a)!=GWEN_Crypt_CryptAlgoId_Rsa) {
2034     DBG_INFO(GWEN_LOGDOMAIN, "Only RSA keys supported.");
2035     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
2036                          I18N("Only RSA keys supported."));
2037     return GWEN_ERROR_NOT_SUPPORTED;
2038   }
2039 
2040   /* get context */
2041   i=(keyId>>16);
2042   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
2043   while (ctx) {
2044     if (i==0)
2045       break;
2046     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
2047     i--;
2048   }
2049 
2050   /* generate key pair */
2051   DBG_INFO(GWEN_LOGDOMAIN, "Creating key pair using %d bytes", GWEN_Crypt_CryptAlgo_GetChunkSize(a));
2052   rv=GWEN_Crypt_KeyRsa_GeneratePair(GWEN_Crypt_CryptAlgo_GetChunkSize(a),
2053                                     (GWEN_Crypt_Token_GetModes(ct) &
2054                                      GWEN_CRYPT_TOKEN_MODE_EXP_65537)?1:0,
2055                                     &pubKey,
2056                                     &secKey);
2057   if (rv) {
2058     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2059     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
2060                          I18N("Could not generate key"));
2061     return rv;
2062   }
2063 
2064   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
2065                        I18N("Key generated"));
2066 
2067   /* set key */
2068   if (keyNum==1)
2069     cki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
2070   else if (keyNum==2)
2071     cki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx);
2072   else if (keyNum==5)
2073     cki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
2074   else if (keyNum==7)
2075     cki=GWEN_CTF_Context_GetTempLocalSignKeyInfo(ctx);
2076   else
2077     cki=NULL;
2078 
2079   if (cki==NULL) {
2080     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
2081                          I18N("No key info found"));
2082     return GWEN_ERROR_NO_DATA;
2083   }
2084 
2085   /* update key info for the key */
2086   ki=GWEN_Crypt_Token_KeyInfo_dup(cki);
2087   assert(ki);
2088 
2089   /* get modulus */
2090   klen=sizeof(kbuf);
2091   rv=GWEN_Crypt_KeyRsa_GetModulus(pubKey, kbuf, &klen);
2092   if (rv) {
2093     DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
2094     GWEN_Crypt_Token_KeyInfo_free(ki);
2095     GWEN_Crypt_Key_free(pubKey);
2096     return rv;
2097   }
2098   GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
2099 
2100   /* get exponent */
2101   klen=sizeof(kbuf);
2102   rv=GWEN_Crypt_KeyRsa_GetExponent(pubKey, kbuf, &klen);
2103   if (rv) {
2104     DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
2105     GWEN_Crypt_Token_KeyInfo_free(ki);
2106     GWEN_Crypt_Key_free(pubKey);
2107     return rv;
2108   }
2109   GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
2110   GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(pubKey));
2111   GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(pubKey));
2112 
2113   if (keyNum==1) {
2114     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
2115       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
2116       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
2117     }
2118     GWEN_CTF_Context_SetLocalSignKey(ctx, secKey);
2119     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2120                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2121                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2122                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2123                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2124                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
2125                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2126                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2127                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
2128     GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, 1);
2129     GWEN_CTF_Context_SetLocalSignKeyInfo(ctx, ki);
2130   }
2131   else if (keyNum==2) {
2132     GWEN_CTF_Context_SetLocalCryptKey(ctx, secKey);
2133     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2134                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2135                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2136                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2137                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2138                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
2139                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2140                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
2141                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANDECIPHER);
2142     GWEN_CTF_Context_SetLocalCryptKeyInfo(ctx, ki);
2143   }
2144   else if (keyNum==5) {
2145     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
2146       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
2147       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
2148     }
2149     GWEN_CTF_Context_SetLocalAuthKey(ctx, secKey);
2150     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2151                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2152                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2153                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2154                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2155                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
2156                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2157                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2158                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
2159     GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, 1);
2160     GWEN_CTF_Context_SetLocalAuthKeyInfo(ctx, ki);
2161   }
2162   else if (keyNum==7) {
2163     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN) {
2164       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
2165       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
2166     }
2167     GWEN_CTF_Context_SetTempLocalSignKey(ctx, secKey);
2168     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
2169                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2170                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2171                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2172                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2173                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
2174                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
2175                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
2176                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
2177     GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, 1);
2178     GWEN_CTF_Context_SetTempLocalSignKeyInfo(ctx, ki);
2179   }
2180 
2181   /* the public key is not used */
2182   GWEN_Crypt_Key_free(pubKey);
2183 
2184   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
2185   if (rv) {
2186     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
2187     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
2188                          I18N("Unable to write key file"));
2189     return rv;
2190   }
2191 
2192   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
2193                        I18N("Key generated and set"));
2194 
2195   return 0;
2196 }
2197 
2198 
2199 
2200 
2201 
2202 
2203 GWENHYWFAR_CB
GWEN_Crypt_TokenFile_freeData(GWEN_UNUSED void * bp,void * p)2204 void GWEN_Crypt_TokenFile_freeData(GWEN_UNUSED void *bp, void *p)
2205 {
2206   GWEN_CRYPT_TOKEN_FILE *lct;
2207 
2208   lct=(GWEN_CRYPT_TOKEN_FILE *) p;
2209   GWEN_Crypt_Token_Context_List_free(lct->contextList);
2210 
2211   GWEN_FREE_OBJECT(lct);
2212 }
2213 
2214 
2215 
GWEN_Crypt_TokenFile_new(const char * typeName,const char * tokenName)2216 GWEN_CRYPT_TOKEN *GWEN_Crypt_TokenFile_new(const char *typeName,
2217                                            const char *tokenName)
2218 {
2219   GWEN_CRYPT_TOKEN *ct;
2220   GWEN_CRYPT_TOKEN_FILE *lct;
2221 
2222   ct=GWEN_Crypt_Token_new(GWEN_Crypt_Token_Device_File, typeName, tokenName);
2223   assert(ct);
2224 
2225   GWEN_NEW_OBJECT(GWEN_CRYPT_TOKEN_FILE, lct);
2226   lct->contextList=GWEN_Crypt_Token_Context_List_new();
2227   GWEN_INHERIT_SETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct, lct,
2228                        GWEN_Crypt_TokenFile_freeData);
2229   GWEN_Crypt_Token_SetOpenFn(ct, GWEN_Crypt_TokenFile_Open);
2230   GWEN_Crypt_Token_SetCreateFn(ct, GWEN_Crypt_TokenFile_Create);
2231   GWEN_Crypt_Token_SetCloseFn(ct, GWEN_Crypt_TokenFile_Close);
2232   GWEN_Crypt_Token_SetGetKeyIdListFn(ct, GWEN_Crypt_TokenFile__GetKeyIdList);
2233   GWEN_Crypt_Token_SetGetKeyInfoFn(ct, GWEN_Crypt_TokenFile__GetKeyInfo);
2234   GWEN_Crypt_Token_SetSetKeyInfoFn(ct, GWEN_Crypt_TokenFile__SetKeyInfo);
2235   GWEN_Crypt_Token_SetGetContextIdListFn(ct, GWEN_Crypt_TokenFile__GetContextIdList);
2236   GWEN_Crypt_Token_SetGetContextFn(ct, GWEN_Crypt_TokenFile__GetContext);
2237   GWEN_Crypt_Token_SetSetContextFn(ct, GWEN_Crypt_TokenFile__SetContext);
2238   GWEN_Crypt_Token_SetSignFn(ct, GWEN_Crypt_TokenFile__Sign);
2239   GWEN_Crypt_Token_SetVerifyFn(ct, GWEN_Crypt_TokenFile__Verify);
2240   GWEN_Crypt_Token_SetEncipherFn(ct, GWEN_Crypt_TokenFile__Encipher);
2241   GWEN_Crypt_Token_SetDecipherFn(ct, GWEN_Crypt_TokenFile__Decipher);
2242   GWEN_Crypt_Token_SetGenerateKeyFn(ct, GWEN_Crypt_TokenFile__GenerateKey);
2243   GWEN_Crypt_Token_SetActivateKeyFn(ct, GWEN_Crypt_TokenFile__ActivateKey);
2244 
2245   return ct;
2246 }
2247 
2248 
2249 
2250 
2251 
2252