gwenhywfar  4.8.0beta
ctfile.c
Go to the documentation of this file.
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 
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  int fd;
44  GWEN_CRYPT_TOKEN_FILE *lct;
45  GWEN_FSLOCK_RESULT lres;
46  const char *fname;
47 
48  assert(ct);
49  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
50  assert(lct);
51 
53  if (!fname) {
54  DBG_ERROR(GWEN_LOGDOMAIN, "No name of the crypt token set - maybe you need to set the key file as token name? Cannot lock token.");
55  return GWEN_ERROR_IO;
56  }
57 
58  lct->lock=GWEN_FSLock_new(fname,
60  lres=GWEN_FSLock_Lock(lct->lock, 10000, gid);
61  if (lres!=GWEN_FSLock_ResultOk) {
62  GWEN_FSLock_free(lct->lock);
63  lct->lock=0;
64  DBG_ERROR(GWEN_LOGDOMAIN, "Could not lock file");
67  else
68  return GWEN_ERROR_IO;
69  }
70  else {
72  "Keyfile [%s] locked.",
74  }
75 
76  if (wr) {
77  /* write file */
79  O_RDWR|O_CREAT
80 #ifdef OS_WIN32
81  | O_BINARY
82 #endif
83  ,
84  S_IRUSR|S_IWUSR | lct->keyfile_mode);
85  }
86  else {
87  /* Remember the access permissions when opening the file */
88  struct stat statbuffer;
89  if (!stat(GWEN_Crypt_Token_GetTokenName(ct), &statbuffer)) {
90  /* Save the access mode, but masked by the bit masks for
91  user/group/other permissions */
92  lct->keyfile_mode =
93  statbuffer.st_mode & (S_IRWXU
94 #ifndef OS_WIN32
95  | S_IRWXG | S_IRWXO
96 #endif
97  );
98  }
99  else {
101  "stat(%s): %s",
103  strerror(errno));
104 
105  GWEN_FSLock_Unlock(lct->lock);
106  GWEN_FSLock_free(lct->lock);
107  lct->lock=0;
109  "Keyfile [%s] unlocked.",
111  return GWEN_ERROR_IO;
112  }
113 
114  /* and open the file */
115  fd=open(GWEN_Crypt_Token_GetTokenName(ct),
116  O_RDONLY
117 #ifdef OS_WIN32
118  | O_BINARY
119 #endif
120  );
121  }
122 
123  if (fd==-1) {
125  "open(%s): %s",
127  strerror(errno));
128  GWEN_FSLock_Unlock(lct->lock);
129  GWEN_FSLock_free(lct->lock);
130  lct->lock=0;
132  "Keyfile [%s] unlocked.",
134  return GWEN_ERROR_IO;
135  }
136 
137  lct->fd=fd;
138 
139  return 0;
140 }
141 
142 
143 
145  GWEN_CRYPT_TOKEN_FILE *lct;
146  GWEN_FSLOCK_RESULT lres;
147  struct stat st;
148 
149  assert(ct);
150  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
151  assert(lct);
152 
153  if (lct->fd==-1) {
154  DBG_ERROR(GWEN_LOGDOMAIN, "Keyfile \"%s\"not open",
156  return GWEN_ERROR_INTERNAL;
157  }
158 
159  if (close(lct->fd)) {
160  DBG_ERROR(GWEN_LOGDOMAIN, "close(%s): %s",
161  GWEN_Crypt_Token_GetTokenName(ct), strerror(errno));
162  lct->fd=-1;
163  GWEN_FSLock_Unlock(lct->lock);
164  GWEN_FSLock_free(lct->lock);
165  lct->lock=0;
167  "Keyfile [%s] unlocked.",
169  return GWEN_ERROR_IO;
170  }
171  lct->fd=-1;
172 
173  lres=GWEN_FSLock_Unlock(lct->lock);
174  if (lres!=GWEN_FSLock_ResultOk) {
175  DBG_WARN(GWEN_LOGDOMAIN, "Error removing lock from \"%s\": %d",
177  }
178  GWEN_FSLock_free(lct->lock);
179  lct->lock=0;
181  "Keyfile [%s] unlocked.",
183 
184  /* get times */
185  if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
187  "stat(%s): %s",
189  strerror(errno));
190  return GWEN_ERROR_IO;
191  }
192 
193 #ifndef OS_WIN32
194  if (st.st_mode & 0007) {
196  "WARNING: Your keyfile \"%s\" is accessible by every user on your computer!\n"
197  "Nobody but you should have access to the file. You \n"
198  "should probably change this with \"chmod 600 %s\"",
202  "WARNING: Your keyfile is accessible ny every user on your computer!\n"
203  "Nobody but you should have access to the file.");
204  }
205 #endif
206  lct->mtime=st.st_mtime;
207  lct->ctime=st.st_ctime;
208 
209  return 0;
210 }
211 
212 
213 
215  GWEN_CRYPT_TOKEN_FILE *lct;
216 
217  assert(ct);
218  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
219  assert(lct);
220 
221  assert(lct->readFn);
222  if (lseek(lct->fd, 0, SEEK_SET)==-1) {
223  DBG_ERROR(GWEN_LOGDOMAIN, "lseek(%s): %s",
225  strerror(errno));
226  return GWEN_ERROR_IO;
227  }
228  return lct->readFn(ct, lct->fd, gid);
229 }
230 
231 
232 
233 int GWEN_Crypt_TokenFile__Write(GWEN_CRYPT_TOKEN *ct, int cr, uint32_t gid){
234  GWEN_CRYPT_TOKEN_FILE *lct;
235 
236  assert(ct);
237  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
238  assert(lct);
239 
240  if (lct->writeFn==0) {
242  "No write function in crypt token type \"%s\"",
245  }
246 
247  if (lseek(lct->fd, 0, SEEK_SET)==-1) {
248  DBG_ERROR(GWEN_LOGDOMAIN, "lseek(%s): %s",
250  strerror(errno));
251  return GWEN_ERROR_IO;
252  }
253  return lct->writeFn(ct, lct->fd, cr, gid);
254 }
255 
256 
257 
259  GWEN_CRYPT_TOKEN_FILE *lct;
260  int rv;
261 
262  assert(ct);
263  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
264  assert(lct);
265 
266  /* clear context list, it will be reloaded */
267  GWEN_Crypt_Token_Context_List_Clear(lct->contextList);
268 
269  /* open file */
270  rv=GWEN_Crypt_TokenFile__OpenFile(ct, 0, gid);
271  if (rv) {
273  "Could not open keyfile for reading (%d)", rv);
274  return rv;
275  }
276 
277  /* read file */
278  rv=GWEN_Crypt_TokenFile__Read(ct, gid);
279  if (rv) {
280  DBG_INFO(GWEN_LOGDOMAIN, "Error reading keyfile");
282  return rv;
283  }
284 
285  /* close file */
287  if (rv) {
288  DBG_INFO(GWEN_LOGDOMAIN, "Could not close keyfile");
289  return rv;
290  }
291 
292  return 0;
293 }
294 
295 
296 
297 int GWEN_Crypt_TokenFile__WriteFile(GWEN_CRYPT_TOKEN *ct, int cr, uint32_t gid){
298  GWEN_CRYPT_TOKEN_FILE *lct;
299  int rv;
300 
301  assert(ct);
302  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
303  assert(lct);
304 
305  /* open file */
306  rv=GWEN_Crypt_TokenFile__OpenFile(ct, 1, gid);
307  if (rv) {
309  "Could not open keyfile for writing (%d)", rv);
310  return rv;
311  }
312 
313  /* write file */
314  rv=GWEN_Crypt_TokenFile__Write(ct, cr, gid);
315  if (rv) {
316  DBG_INFO(GWEN_LOGDOMAIN, "Error writing keyfile");
318  return rv;
319  }
320 
321  /* close file */
323  if (rv) {
324  DBG_INFO(GWEN_LOGDOMAIN, "Could not close keyfile");
325  return rv;
326  }
327 
328  return 0;
329 }
330 
331 
332 
334  GWEN_CRYPT_TOKEN_FILE *lct;
335  struct stat st;
336 
337  assert(ct);
338  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
339  assert(lct);
340 
341  if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
343  "stat(%s): %s",
345  strerror(errno));
346  return -1;
347  }
348  if (lct->mtime!=st.st_mtime ||
349  lct->ctime!=st.st_ctime) {
350  int rv;
351 
352  /* file has changed, reload it */
354  "Keyfile changed externally, reloading it");
355  /* read file */
356  rv=GWEN_Crypt_TokenFile__ReadFile(ct, gid);
357  if (rv) {
358  DBG_WARN(GWEN_LOGDOMAIN, "Error reloading keyfile");
359  return rv;
360  }
361  }
362  else {
363  DBG_NOTICE(GWEN_LOGDOMAIN, "Keyfile unchanged, not reloading");
364  }
365  return 0;
366 }
367 
368 
369 
371  GWEN_CRYPT_TOKEN_FILE *lct;
372 
373  assert(ct);
374  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
375  assert(lct);
376 
377  /* make sure the context is a file context */
378  assert(GWEN_CTF_Context_IsOfThisType(ctx));
379  GWEN_Crypt_Token_Context_List_Add(ctx, lct->contextList);
380 }
381 
382 
383 
385  GWEN_CRYPT_TOKEN_FILE *lct;
387 
388  assert(ct);
389  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
390  assert(lct);
391 
392  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
393  while(ctx) {
394  if (idx==0)
395  return ctx;
396  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
397  idx--;
398  }
399 
400  return NULL;
401 }
402 
403 
404 
407  GWEN_CRYPT_TOKEN_FILE *lct;
409 
410  assert(ct);
411  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
412  assert(lct);
413 
414  of=lct->readFn;
415  lct->readFn=f;
416 
417  return of;
418 }
419 
420 
421 
424  GWEN_CRYPT_TOKEN_FILE *lct;
426 
427  assert(ct);
428  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
429  assert(lct);
430 
431  of=lct->writeFn;
432  lct->writeFn=f;
433 
434  return of;
435 }
436 
437 
438 
440  GWEN_CRYPT_TOKEN_FILE *lct;
441  struct stat st;
442  int fd;
443  int rv;
444 
445  assert(ct);
446  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
447  assert(lct);
448 
450  DBG_ERROR(GWEN_LOGDOMAIN, "No medium name given");
451  return GWEN_ERROR_INVALID;
452  }
453 
454  if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
455  if (errno!=ENOENT) {
457  "stat(%s): %s",
459  strerror(errno));
460  return GWEN_ERROR_IO;
461  }
462  }
463  else {
465  "Keyfile \"%s\" already exists, will not create it",
467  return GWEN_ERROR_INVALID;
468  }
469 
470 
471  /* create file */
472  fd=open(GWEN_Crypt_Token_GetTokenName(ct),
473  O_RDWR | O_CREAT | O_EXCL
474 #ifdef OS_WIN32
475  | O_BINARY
476 #endif
477  ,
478  S_IRUSR|S_IWUSR);
479 
480 
481  if (fd==-1) {
483  "open(%s): %s",
485  strerror(errno));
486  return GWEN_ERROR_IO;
487  }
488 
489  close(fd);
490 
491  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 1, gid);
492  if (rv) {
493  DBG_INFO(GWEN_LOGDOMAIN, "here");
494  return rv;
495  }
496 
497  return 0;
498 }
499 
500 
501 
503  GWEN_CRYPT_TOKEN_FILE *lct;
504  int rv;
505 
506  assert(ct);
507  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
508  assert(lct);
509 
510  rv=GWEN_Crypt_TokenFile__ReadFile(ct, gid);
511  if (rv) {
512  DBG_INFO(GWEN_LOGDOMAIN, "here");
513  return rv;
514  }
515 
516  return 0;
517 }
518 
519 
520 
521 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Close(GWEN_CRYPT_TOKEN *ct, int abandon, uint32_t gid){
522  GWEN_CRYPT_TOKEN_FILE *lct;
523  int rv;
524 
525  assert(ct);
526  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
527  assert(lct);
528 
529  if (!abandon)
530  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
531  else
532  rv=0;
533 
534  /* free/reset all data */
535  GWEN_Crypt_Token_Context_List_Clear(lct->contextList);
536  lct->mtime=0;
537  lct->ctime=0;
538 
539  return rv;
540 }
541 
542 
543 
544 
546  uint32_t *pIdList,
547  uint32_t *pCount,
548  uint32_t gid) {
549  GWEN_CRYPT_TOKEN_FILE *lct;
551  int i;
552  int rv;
553 
554  assert(ct);
555  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
556  assert(lct);
557 
558  /* reload if needed */
560  if (rv) {
561  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
562  return rv;
563  }
564 
565  /* count keys */
566  i=0;
567  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
568  while(ctx) {
570  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
571  }
572 
573  /* if no buffer given just return number of keys */
574  if (pIdList==NULL) {
575  *pCount=i;
576  return 0;
577  }
578 
579  if (*pCount<i) {
580  DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
582  }
583 
584  *pCount=i;
585  i=0;
586  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
587  while(ctx) {
588  int j;
589 
590  for (j=1; j<=GWEN_CRYPT_TOKEN_CONTEXT_KEYS; j++)
591  *(pIdList++)=(i<<16)+j;
592 
593  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
594  i++;
595  }
596 
597  return 0;
598 }
599 
600 
601 
604  uint32_t id,
605  uint32_t flags,
606  uint32_t gid) {
607  GWEN_CRYPT_TOKEN_FILE *lct;
610  int i;
611  int rv;
612 
613  assert(ct);
614  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
615  assert(lct);
616 
617  /* reload if needed */
619  if (rv) {
620  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
621  return NULL;
622  }
623 
624  i=id>>16;
625  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
626  while(ctx) {
627  if (i==0)
628  break;
629  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
630  i--;
631  }
632 
633  if (ctx==NULL) {
634  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
635  return NULL;
636  }
637 
638  switch(id & 0xffff) {
639  case 1: ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
640  case 2: ki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx); break;
641  case 3: ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx); break;
642  case 4: ki=GWEN_CTF_Context_GetRemoteCryptKeyInfo(ctx); break;
643  case 5: ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
644  case 6: ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx); break;
645  case 7: ki=GWEN_CTF_Context_GetTempLocalSignKeyInfo(ctx); break;
646  default:
647  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
648  return NULL;
649  }
650 
651  if (ki==NULL) {
652  DBG_INFO(GWEN_LOGDOMAIN, "No key info stored for key %d", id);
653  return NULL;
654  }
655 
656  return ki;
657 }
658 
659 
660 
661 #if 0
662 int GWENHYWFAR_CB
664  uint32_t id,
665  const GWEN_CRYPT_TOKEN_KEYINFO *ki,
666  uint32_t gid) {
667  GWEN_CRYPT_TOKEN_FILE *lct;
669  int i;
670  int rv;
672  GWEN_CRYPT_KEY *key;
673  uint32_t flags;
674 
675  assert(ct);
676  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
677  assert(lct);
678 
680 
681  /* reload if needed */
683  if (rv) {
684  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
685  return rv;
686  }
687 
688  i=id>>16;
689  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
690  while(ctx) {
691  if (i==0)
692  break;
693  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
694  i--;
695  }
696 
697  if (ctx==NULL) {
698  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
699  return GWEN_ERROR_NOT_FOUND;
700  }
701 
703  assert(nki);
704  switch(id & 0xffff) {
705  case 1:
708  break;
709  case 2:
712  break;
713  case 3:
716  break;
717  case 4:
720  break;
721  case 5:
724  break;
725  case 6:
728  break;
729  default:
730  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
732  return GWEN_ERROR_NOT_FOUND;
733  }
734 
735  /* replace key if modulus and exponent are given */
736  if ((flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) &&
738  id!=1 && /* don't change local keys */
739  id!=2 &&
740  id!=5) {
741  GWEN_CRYPT_KEY *nkey;
742 
748  assert(nkey);
749 
754 
755  /* replace public key */
756  switch(id & 0xffff) {
757  case 3: /* remote sign key */
759  break;
760  case 4: /* remote crypt key */
762  break;
763  case 6: /* remote auth key */
765  break;
766  default:
768  "Can't set modulus and exponent for private key");
769  GWEN_Crypt_Key_free(nkey);
770  return GWEN_ERROR_INVALID;
771  }
773  I18N("Public key replaced"));
774  }
775  else {
776  if (key) {
777  if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
779  if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
781  }
782  }
783 
784  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
785  if (rv) {
786  DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
788  I18N("Unable to write key file"));
789  return rv;
790  }
791 
793  I18N("Key file saved"));
794 
795  return 0;
796 }
797 #endif
798 
799 
800 int GWENHYWFAR_CB
802  uint32_t id,
803  const GWEN_CRYPT_TOKEN_KEYINFO *ski,
804  uint32_t gid) {
805  GWEN_CRYPT_TOKEN_FILE *lct;
807  int i;
808  int rv;
810  GWEN_CRYPT_KEY *key;
811  uint32_t flags;
812  uint32_t nflags;
813 
814  assert(ct);
815  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
816  assert(lct);
817 
819 
820  /* reload if needed */
822  if (rv) {
823  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
824  return rv;
825  }
826 
827  i=id>>16;
828  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
829  while(ctx) {
830  if (i==0)
831  break;
832  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
833  i--;
834  }
835 
836  if (ctx==NULL) {
837  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
838  return GWEN_ERROR_NOT_FOUND;
839  }
840 
841  switch(id & 0xffff) {
842  case 1:
845  break;
846  case 2:
849  break;
850  case 3:
853  break;
854  case 4:
857  break;
858  case 5:
861  break;
862  case 6:
865  break;
866  case 7:
869  break;
870  default:
871  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
872  return GWEN_ERROR_NOT_FOUND;
873  }
874  assert(ki);
875 
877 
879  /* ignore for now */
880  }
881 
884  nflags|=(flags & GWEN_CRYPT_TOKEN_KEYFLAGS_ACTIONMASK);
885  }
886 
887  if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION) {
891  if (key)
893  DBG_INFO(GWEN_LOGDOMAIN, "Setting key version");
894  }
895 
900  DBG_INFO(GWEN_LOGDOMAIN, "Setting signature counter");
901  }
902 
903  if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER) {
907  if (key)
909  DBG_INFO(GWEN_LOGDOMAIN, "Setting key number");
910  }
911 
912  /* replace key if modulus and exponent are given */
913  if ((flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) &&
914  (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT) &&
915  id!=1 && /* don't change local keys */
916  id!=2 &&
917  id!=5 &&
918  id!=7) {
919  GWEN_CRYPT_KEY *nkey;
920 
935  assert(nkey);
936 
937  if (nflags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
939  if (nflags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
941 
942  /* replace public key */
943  switch(id & 0xffff) {
944  case 3: /* remote sign key */
946  break;
947  case 4: /* remote crypt key */
949  break;
950  case 6: /* remote auth key */
952  break;
953  default:
955  "Can't set modulus and exponent for private key");
956  GWEN_Crypt_Key_free(nkey);
957  return GWEN_ERROR_INVALID;
958  }
960  I18N("Public key replaced"));
961  }
962  else {
963  if (key) {
964  if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
966  if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
968  }
969  }
970 
972 
973  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
974  if (rv) {
975  DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
977  I18N("Unable to write key file"));
978  return rv;
979  }
980 
982  I18N("Key file saved"));
983 
984  return 0;
985 }
986 
987 
988 
989 int GWENHYWFAR_CB
990 GWEN_Crypt_TokenFile__ActivateKey(GWEN_CRYPT_TOKEN *ct, uint32_t id, uint32_t gid) {
991  GWEN_CRYPT_TOKEN_FILE *lct;
993  int rv;
994  int i;
995  uint32_t keyNum;
996  uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
997  uint32_t klen;
1000  GWEN_CRYPT_KEY *key;
1001 
1002  assert(ct);
1003  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1004  assert(lct);
1005 
1006  /* reload if needed */
1008  if (rv) {
1009  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1010  return rv;
1011  }
1012 
1013  keyNum=id & 0xffff;
1014 
1015  i=id>>16;
1016  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1017  while(ctx) {
1018  if (i==0)
1019  break;
1020  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1021  i--;
1022  }
1023 
1024  if (ctx==NULL) {
1025  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
1026  return GWEN_ERROR_NOT_FOUND;
1027  }
1028 
1030  if (key==NULL) {
1031  DBG_ERROR(GWEN_LOGDOMAIN, "No temporary local sign key.");
1032  return GWEN_ERROR_NOT_FOUND;
1033  }
1034  key=GWEN_Crypt_KeyRsa_dup(key);
1035 
1036  /* set key */
1037  if (keyNum==1)
1039  else if (keyNum==6)
1041  else {
1043  I18N("Invalid key id %02x"), id);
1044  GWEN_Crypt_Key_free(key);
1045  return GWEN_ERROR_NO_DATA;
1046  }
1047  if (cki==NULL) {
1049  I18N("No key info found"));
1050  GWEN_Crypt_Key_free(key);
1051  return GWEN_ERROR_NO_DATA;
1052  }
1053 
1054  /* update key info for the key */
1056  assert(ki);
1057 
1058  /* get modulus */
1059  klen=sizeof(kbuf);
1060  rv=GWEN_Crypt_KeyRsa_GetModulus(key, kbuf, &klen);
1061  if (rv) {
1062  DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
1064  GWEN_Crypt_Key_free(key);
1065  return rv;
1066  }
1067  GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
1068 
1069  /* get exponent */
1070  klen=sizeof(kbuf);
1071  rv=GWEN_Crypt_KeyRsa_GetExponent(key, kbuf, &klen);
1072  if (rv) {
1073  DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
1075  GWEN_Crypt_Key_free(key);
1076  return rv;
1077  }
1078  GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
1081 
1082  if (keyNum==1) {
1084  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1086  }
1089  GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1090  GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1091  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1092  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1099  }
1100  else if (keyNum==6) {
1102  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
1104  }
1107  GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
1108  GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
1109  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
1110  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
1117  }
1118 
1119  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1120  if (rv) {
1121  DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1123  I18N("Unable to write key file"));
1124  return rv;
1125  }
1126 
1128  I18N("Key file saved"));
1129 
1130  return 0;
1131 }
1132 
1133 
1134 
1135 int GWENHYWFAR_CB
1137  uint32_t *pIdList,
1138  uint32_t *pCount,
1139  uint32_t gid) {
1140  GWEN_CRYPT_TOKEN_FILE *lct;
1142  int i;
1143  int rv;
1144 
1145  assert(ct);
1146  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1147  assert(lct);
1148 
1149  /* reload if needed */
1151  if (rv) {
1152  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1153  return rv;
1154  }
1155 
1156  /* count keys */
1157  i=0;
1158  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1159  while(ctx) {
1160  i++;
1161  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1162  }
1163 
1164  /* store number of entries */
1165  *pCount=i;
1166 
1167  /* if no buffer given just return number of keys */
1168  if (pIdList==NULL)
1169  return 0;
1170 
1171  if (*pCount<i) {
1172  DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
1174  }
1175 
1176  i=1;
1177  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1178  while(ctx) {
1179  *(pIdList++)=i;
1180  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1181  i++;
1182  }
1183 
1184  return 0;
1185 }
1186 
1187 
1188 
1191  uint32_t id,
1192  uint32_t gid) {
1193  GWEN_CRYPT_TOKEN_FILE *lct;
1195  int rv;
1196 
1197  assert(ct);
1198  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1199  assert(lct);
1200 
1201  /* reload if needed */
1203  if (rv) {
1204  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1205  return NULL;
1206  }
1207 
1208  if (id==0) {
1209  DBG_INFO(GWEN_LOGDOMAIN, "Invalid context id 0");
1210  return NULL;
1211  }
1212 
1213  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1214  while(ctx) {
1215  if (GWEN_Crypt_Token_Context_GetId(ctx)==id)
1216  break;
1217  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1218  }
1219 
1220  if (ctx==NULL) {
1221  DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", id);
1222  return NULL;
1223  }
1224 
1225  return ctx;
1226 }
1227 
1228 
1229 
1230 int GWENHYWFAR_CB
1232  uint32_t id,
1233  const GWEN_CRYPT_TOKEN_CONTEXT *nctx,
1234  uint32_t gid) {
1235  GWEN_CRYPT_TOKEN_FILE *lct;
1237  int rv;
1238  const char *s;
1239 
1240  assert(ct);
1241  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1242  assert(lct);
1243 
1244  if (id==0) {
1245  DBG_INFO(GWEN_LOGDOMAIN, "Invalid context id 0");
1246  return GWEN_ERROR_INVALID;
1247  }
1248 
1249  /* reload if needed */
1251  if (rv) {
1252  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1253  return rv;
1254  }
1255 
1256  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1257  while(ctx) {
1258  if (GWEN_Crypt_Token_Context_GetId(ctx)==id)
1259  break;
1260  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1261  }
1262 
1263  if (ctx==NULL) {
1264  DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", id);
1265  return GWEN_ERROR_NOT_FOUND;
1266  }
1267 
1268  /* copy user data from context */
1282 
1283  return 0;
1284 }
1285 
1286 
1287 
1289  GWEN_CRYPT_TOKEN_FILE *lct;
1291  int i;
1292  int rv;
1293 
1294  assert(ct);
1295  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1296  assert(lct);
1297 
1298  /* reload if needed */
1300  if (rv) {
1301  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1302  return NULL;
1303  }
1304 
1305  i=id>>16;
1306  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1307  while(ctx) {
1308  if (i==0)
1309  break;
1310  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1311  i--;
1312  }
1313 
1314  if (ctx==NULL) {
1315  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
1316  return NULL;
1317  }
1318 
1319  switch(id & 0xffff) {
1320  case 1: return GWEN_CTF_Context_GetLocalSignKey(ctx);
1321  case 2: return GWEN_CTF_Context_GetLocalCryptKey(ctx);
1322  case 3: return GWEN_CTF_Context_GetRemoteSignKey(ctx);
1323  case 4: return GWEN_CTF_Context_GetRemoteCryptKey(ctx);
1324  case 5: return GWEN_CTF_Context_GetLocalAuthKey(ctx);
1325  case 6: return GWEN_CTF_Context_GetRemoteAuthKey(ctx);
1326  default:
1327  DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
1328  return NULL;
1329  }
1330 }
1331 
1332 
1333 
1334 int GWENHYWFAR_CB
1336  uint32_t keyId,
1338  const uint8_t *pInData,
1339  uint32_t inLen,
1340  uint8_t *pSignatureData,
1341  uint32_t *pSignatureLen,
1342  uint32_t *pSeqCounter,
1343  uint32_t gid) {
1344  GWEN_CRYPT_TOKEN_FILE *lct;
1346  GWEN_CRYPT_KEY *k;
1347  int keyNum;
1348  GWEN_BUFFER *srcBuf;
1349  int i;
1350  int rv;
1352 
1353  assert(ct);
1354  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1355  assert(lct);
1356 
1357  DBG_INFO(GWEN_LOGDOMAIN, "Signing with key %d", keyId);
1359 
1360  /* reload if needed */
1362  if (rv) {
1363  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1364  return rv;
1365  }
1366 
1367  /* get context */
1368  i=(keyId>>16);
1369  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1370  if (ctx==NULL) {
1371  DBG_ERROR(GWEN_LOGDOMAIN, "Token has no context");
1372  return GWEN_ERROR_NOT_FOUND;
1373  }
1374  while(ctx) {
1375  if (i==0)
1376  break;
1377  DBG_ERROR(GWEN_LOGDOMAIN, "Checking token %d (i==%d)",
1379  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1380  i--;
1381  }
1382 
1383  if (ctx==NULL) {
1384  DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1385  return GWEN_ERROR_NOT_FOUND;
1386  }
1387 
1388  /* get key */
1389  keyNum=keyId & 0xffff;
1390  if (keyNum!=1 && keyNum!=5) {
1391  /* neither localSignKey nor localAuthKey */
1392  DBG_INFO(GWEN_LOGDOMAIN, "Bad key for signing (%x)", keyId);
1393  return GWEN_ERROR_INVALID;
1394  }
1395 
1396  k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1397  if (k==NULL) {
1398  DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
1399  return GWEN_ERROR_NOT_FOUND;
1400  }
1401 
1402  /* copy to a buffer for padding */
1403  srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1404 
1405  if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1406  const GWEN_CRYPT_TOKEN_KEYINFO *ki;
1407  int nbits;
1408  const uint8_t *modPtr;
1409  uint32_t modLen;
1410  GWEN_MDIGEST *md;
1411 
1412  switch(keyId & 0xffff) {
1413  case 1: ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
1414  case 5: ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
1415  default: ki=NULL;
1416  }
1417 
1418  if (ki==NULL) {
1419  DBG_ERROR(GWEN_LOGDOMAIN, "No information for key %d", keyNum);
1420  GWEN_Buffer_free(srcBuf);
1421  return GWEN_ERROR_GENERIC;
1422  }
1423 
1424  /* calculate real number of bits */
1427  nbits=modLen*8;
1428  while(modLen && *modPtr==0) {
1429  nbits-=8;
1430  modLen--;
1431  modPtr++;
1432  }
1433  if (modLen) {
1434  uint8_t b=*modPtr;
1435  int i;
1436  uint8_t mask=0x80;
1437 
1438  for (i=0; i<8; i++) {
1439  if (b & mask)
1440  break;
1441  nbits--;
1442  mask>>=1;
1443  }
1444  }
1445 
1446  if (nbits==0) {
1447  DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
1448  GWEN_Buffer_free(srcBuf);
1449  return GWEN_ERROR_GENERIC;
1450  }
1451 
1453  GWEN_Buffer_AllocRoom(srcBuf, modLen);
1454 
1455  rv=GWEN_Padd_AddPkcs1Pss((uint8_t*) GWEN_Buffer_GetStart(srcBuf),
1457  nbits,
1458  pInData, inLen,
1459  inLen,
1460  md);
1461  GWEN_MDigest_free(md);
1462  if (rv<0) {
1463  DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
1464  GWEN_Buffer_free(srcBuf);
1465  return rv;
1466  }
1467 
1468  GWEN_Buffer_IncrementPos(srcBuf, rv);
1470  }
1471  else {
1472  GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
1473 
1474  /* padd according to given algo */
1475  rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1476  if (rv) {
1477  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1478  GWEN_Buffer_free(srcBuf);
1479  return rv;
1480  }
1481  }
1482 
1483  /* sign with key */
1484  rv=GWEN_Crypt_Key_Sign(k,
1485  (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
1486  GWEN_Buffer_GetUsedBytes(srcBuf),
1487  pSignatureData,
1488  pSignatureLen);
1489  GWEN_Buffer_free(srcBuf);
1490  if (rv) {
1491  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1492  return rv;
1493  }
1494 
1495  if (pSeqCounter) {
1497 
1498  /* signature sequence counter is to be incremented */
1499  switch(keyId & 0xffff) {
1500  case 1: ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
1501  case 5: ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
1502  default: ki=NULL;
1503  }
1504  if (ki &&
1506  unsigned int seq;
1507 
1509  *pSeqCounter=seq;
1511 
1512  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1513  if (rv) {
1514  DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1515  return rv;
1516  }
1517  }
1518  else {
1519  DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
1520  *pSeqCounter=0;
1521  }
1522  }
1523 
1524  return 0;
1525 }
1526 
1527 
1528 
1529 int GWENHYWFAR_CB
1531  uint32_t keyId,
1533  const uint8_t *pInData,
1534  uint32_t inLen,
1535  const uint8_t *pSignatureData,
1536  uint32_t signatureLen,
1537  uint32_t seqCounter,
1538  uint32_t gid) {
1539  GWEN_CRYPT_TOKEN_FILE *lct;
1541  GWEN_CRYPT_KEY *k;
1542  int keyNum;
1543  int i;
1544  int rv;
1546 
1547  assert(ct);
1548  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1549  assert(lct);
1550 
1551  DBG_INFO(GWEN_LOGDOMAIN, "Verifying with key %d", keyId);
1552 
1554 
1555  /* reload if needed */
1557  if (rv) {
1558  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1559  return rv;
1560  }
1561 
1562  /* get context */
1563  i=(keyId>>16);
1564  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1565  while(ctx) {
1566  if (i==0)
1567  break;
1568  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1569  i--;
1570  }
1571 
1572  if (ctx==NULL) {
1573  DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1574  return GWEN_ERROR_NOT_FOUND;
1575  }
1576 
1577  /* get key */
1578  keyNum=keyId & 0xffff;
1579  if (keyNum!=1 && keyNum!=3 && keyNum!=6) {
1580  /* neither remoteSignKey nor remoteAuthKey */
1581  DBG_INFO(GWEN_LOGDOMAIN, "Bad key for verifying (%x)", keyId);
1582  return GWEN_ERROR_INVALID;
1583  }
1584 
1585  k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1586  if (k==NULL) {
1587  DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
1588  return GWEN_ERROR_NO_KEY;
1589  }
1590 
1591  if (aid==GWEN_Crypt_PaddAlgoId_Iso9796_2 ||
1592  aid==GWEN_Crypt_PaddAlgoId_Pkcs1_2 ||
1593  aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1594  GWEN_BUFFER *tbuf;
1595  uint32_t l;
1596 
1597  /* these algos add random numbers, we must use encrypt fn here and
1598  * compare the decrypted and unpadded data with the source data */
1599  tbuf=GWEN_Buffer_new(0, signatureLen+16, 0, 0);
1602  pSignatureData, signatureLen,
1603  (uint8_t*)GWEN_Buffer_GetStart(tbuf),
1604  &l);
1605  if (rv<0) {
1606  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1607  GWEN_Buffer_free(tbuf);
1608  return rv;
1609  }
1610  GWEN_Buffer_IncrementPos(tbuf, l);
1612 
1613  if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
1614  const GWEN_CRYPT_TOKEN_KEYINFO *ki;
1615  int nbits;
1616  const uint8_t *modPtr;
1617  uint32_t modLen;
1618  GWEN_MDIGEST *md;
1619 
1620  if (keyNum==3)
1622  else
1624  if (ki==NULL) {
1625  DBG_ERROR(GWEN_LOGDOMAIN, "No information for key %d", keyNum);
1626  GWEN_Buffer_free(tbuf);
1627  return GWEN_ERROR_GENERIC;
1628  }
1629 
1630  /* calculate real number of bits */
1633  nbits=modLen*8;
1634  while(modLen && *modPtr==0) {
1635  nbits-=8;
1636  modLen--;
1637  modPtr++;
1638  }
1639  if (modLen) {
1640  uint8_t b=*modPtr;
1641  int i;
1642  uint8_t mask=0x80;
1643 
1644  for (i=0; i<8; i++) {
1645  if (b & mask)
1646  break;
1647  nbits--;
1648  mask>>=1;
1649  }
1650  }
1651 
1652  if (nbits==0) {
1653  DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
1654  GWEN_Buffer_free(tbuf);
1655  return GWEN_ERROR_GENERIC;
1656  }
1657 
1659  rv=GWEN_Padd_VerifyPkcs1Pss((const uint8_t*) GWEN_Buffer_GetStart(tbuf),
1661  nbits,
1662  pInData, inLen,
1663  inLen,
1664  md);
1665  GWEN_MDigest_free(md);
1666  if (rv<0) {
1667  DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
1668  return rv;
1669  }
1670  }
1671  else {
1672  rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
1673  if (rv<0) {
1674  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1675  GWEN_Buffer_free(tbuf);
1676  return rv;
1677  }
1678  l=GWEN_Buffer_GetUsedBytes(tbuf);
1679 
1680  if (l!=inLen) {
1681  DBG_ERROR(GWEN_LOGDOMAIN, "Signature length doesn't match");
1682  GWEN_Buffer_free(tbuf);
1683  return GWEN_ERROR_VERIFY;
1684  }
1685  if (memcmp(pInData, GWEN_Buffer_GetStart(tbuf), l)!=0) {
1686  DBG_ERROR(GWEN_LOGDOMAIN, "Signature doesn't match:");
1687  GWEN_Buffer_free(tbuf);
1688  return GWEN_ERROR_VERIFY;
1689  }
1690  }
1691  }
1692  else {
1693  GWEN_BUFFER *srcBuf;
1694 
1695  /* copy to a buffer for padding */
1696  srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1697  GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
1698 
1699  /* padd according to given algo */
1700  rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1701  if (rv) {
1702  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1703  GWEN_Buffer_free(srcBuf);
1704  return rv;
1705  }
1706 
1707  /* verify with key */
1708  rv=GWEN_Crypt_Key_Verify(k,
1709  (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
1710  GWEN_Buffer_GetUsedBytes(srcBuf),
1711  pSignatureData,
1712  signatureLen);
1713  GWEN_Buffer_free(srcBuf);
1714  if (rv) {
1715  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1716  return rv;
1717  }
1718  }
1719 
1720  if (seqCounter) {
1722 
1723  /* signature sequence counter is to be checked */
1724  if (keyNum==3)
1726  else
1728  if (ki &&
1730  unsigned int seq;
1731 
1733 
1734  if (seq>=seqCounter) {
1735  DBG_WARN(GWEN_LOGDOMAIN, "Bad remote sequence counter (possibly replay attack!)");
1736  return GWEN_ERROR_VERIFY;
1737  }
1739 
1740  /* write file */
1741  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
1742  if (rv) {
1743  DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
1744  return rv;
1745  }
1746  }
1747  else {
1748  DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
1749  }
1750 
1751  }
1752 
1753  return 0;
1754 }
1755 
1756 
1757 
1758 int GWENHYWFAR_CB
1760  uint32_t keyId,
1762  const uint8_t *pInData,
1763  uint32_t inLen,
1764  uint8_t *pOutData,
1765  uint32_t *pOutLen,
1766  uint32_t gid) {
1767  GWEN_CRYPT_TOKEN_FILE *lct;
1769  GWEN_CRYPT_KEY *k;
1770  int keyNum;
1771  GWEN_BUFFER *srcBuf;
1772  int i;
1773  int rv;
1774 
1775  assert(ct);
1776  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1777  assert(lct);
1778 
1779  DBG_INFO(GWEN_LOGDOMAIN, "Enciphering with key %d", keyId);
1780 
1781  /* reload if needed */
1783  if (rv) {
1784  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1785  return rv;
1786  }
1787 
1788  /* get context */
1789  i=(keyId>>16);
1790  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1791  while(ctx) {
1792  if (i==0)
1793  break;
1794  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1795  i--;
1796  }
1797 
1798  if (ctx==NULL) {
1799  DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1800  return GWEN_ERROR_NOT_FOUND;
1801  }
1802 
1803  /* get key */
1804  keyNum=keyId & 0xffff;
1805  if (keyNum!=2 && keyNum!=4) {
1806  /* not remoteCryptKey */
1807  DBG_INFO(GWEN_LOGDOMAIN, "Bad key for encrypting (%x)", keyId);
1808  return GWEN_ERROR_INVALID;
1809  }
1810 
1811  k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1812  if (k==NULL) {
1813  DBG_INFO(GWEN_LOGDOMAIN, "Key %d not found", keyId);
1814  return GWEN_ERROR_NOT_FOUND;
1815  }
1816 
1817  /* copy to a buffer for padding */
1818  srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
1819  GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
1820  GWEN_Buffer_Rewind(srcBuf);
1821 
1822  /* padd according to given algo */
1823  rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
1824  if (rv) {
1825  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1826  GWEN_Buffer_free(srcBuf);
1827  return rv;
1828  }
1829 
1830  /* encipher with key */
1832  (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
1833  GWEN_Buffer_GetUsedBytes(srcBuf),
1834  pOutData,
1835  pOutLen);
1836  GWEN_Buffer_free(srcBuf);
1837  if (rv) {
1838  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1839  return rv;
1840  }
1841 
1842  return 0;
1843 }
1844 
1845 
1846 
1847 int GWENHYWFAR_CB
1849  uint32_t keyId,
1851  const uint8_t *pInData,
1852  uint32_t inLen,
1853  uint8_t *pOutData,
1854  uint32_t *pOutLen,
1855  uint32_t gid) {
1856  GWEN_CRYPT_TOKEN_FILE *lct;
1858  GWEN_CRYPT_KEY *k;
1859  int keyNum;
1860  GWEN_BUFFER *tbuf;
1861  int i;
1862  int rv;
1863  uint32_t l;
1864 
1865  assert(ct);
1866  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1867  assert(lct);
1868 
1869  DBG_INFO(GWEN_LOGDOMAIN, "Deciphering with key %d", keyId);
1870 
1871  /* reload if needed */
1873  if (rv) {
1874  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1875  return rv;
1876  }
1877 
1878  /* get context */
1879  i=(keyId>>16);
1880  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1881  while(ctx) {
1882  if (i==0)
1883  break;
1884  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1885  i--;
1886  }
1887 
1888  if (ctx==NULL) {
1889  DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
1890  return GWEN_ERROR_NOT_FOUND;
1891  }
1892 
1893  /* get key */
1894  keyNum=keyId & 0xffff;
1895  if (keyNum!=2 && keyNum!=4) {
1896  /* not localCryptKey */
1897  DBG_INFO(GWEN_LOGDOMAIN, "Bad key for decrypting (%x)", keyId);
1898  return GWEN_ERROR_INVALID;
1899  }
1900 
1901  k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
1902  if (k==NULL) {
1903  DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
1904  return GWEN_ERROR_NOT_FOUND;
1905  }
1906 
1907  /* decipher with key */
1908  tbuf=GWEN_Buffer_new(0, inLen+16, 0, 1);
1911  pInData, inLen,
1912  (uint8_t*)GWEN_Buffer_GetStart(tbuf), &l);
1913  if (rv<0) {
1914  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1915  GWEN_Buffer_free(tbuf);
1916  return rv;
1917  }
1918  GWEN_Buffer_IncrementPos(tbuf, l);
1920 
1921  /* unpadd according to given algo */
1922  rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
1923  if (rv) {
1924  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1925  GWEN_Buffer_free(tbuf);
1926  return rv;
1927  }
1928 
1929  /* copy resulting data to given buffer */
1930  l=GWEN_Buffer_GetUsedBytes(tbuf);
1931  if (l>*pOutLen) {
1932  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1933  GWEN_Buffer_free(tbuf);
1935  }
1936  memmove(pOutData, GWEN_Buffer_GetStart(tbuf), l);
1937  *pOutLen=l;
1938  GWEN_Buffer_free(tbuf);
1939 
1940  return 0;
1941 }
1942 
1943 
1944 
1945 int GWENHYWFAR_CB
1947  uint32_t keyId,
1948  const GWEN_CRYPT_CRYPTALGO *a,
1949  uint32_t gid) {
1950  GWEN_CRYPT_TOKEN_FILE *lct;
1951  GWEN_CRYPT_KEY *pubKey;
1952  GWEN_CRYPT_KEY *secKey;
1953  int rv;
1954  uint32_t keyNum;
1956  int i;
1957  uint8_t kbuf[GWEN_CRYPT_KEYRSA_MAX_KEYLENGTH];
1958  uint32_t klen;
1961  int sizeInBits;
1962 
1963  assert(ct);
1964  lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
1965  assert(lct);
1966 
1967  /* reload if needed */
1969  if (rv) {
1970  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1971  return rv;
1972  }
1973 
1974  keyNum=keyId & 0xffff;
1975 
1976  /* check key id */
1977  if (keyNum!=1 && keyNum!=2 && keyNum!=5 && keyNum!=7) {
1978  DBG_INFO(GWEN_LOGDOMAIN, "Can only generate local keys.");
1980  I18N("Can only generate local keys."));
1981  return GWEN_ERROR_NOT_SUPPORTED;
1982  }
1983 
1984  /* check for algo */
1985  if (GWEN_Crypt_CryptAlgo_GetId(a)!=GWEN_Crypt_CryptAlgoId_Rsa) {
1986  DBG_INFO(GWEN_LOGDOMAIN, "Only RSA keys supported.");
1988  I18N("Only RSA keys supported."));
1989  return GWEN_ERROR_NOT_SUPPORTED;
1990  }
1991 
1992  /* get context */
1993  i=(keyId>>16);
1994  ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
1995  while(ctx) {
1996  if (i==0)
1997  break;
1998  ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
1999  i--;
2000  }
2001 
2003  if (sizeInBits>0) {
2004  /* generate key pair with precise number of bits */
2005  DBG_DEBUG(GWEN_LOGDOMAIN, "Creating key pair using %d bits", sizeInBits);
2006  rv=GWEN_Crypt_KeyRsa_GeneratePair2(sizeInBits,
2009  &pubKey,
2010  &secKey);
2011  }
2012  else {
2013  /* generate key pair the old way, just using the chunksize */
2014  DBG_INFO(GWEN_LOGDOMAIN, "Creating key pair using %d bytes", GWEN_Crypt_CryptAlgo_GetChunkSize(a));
2018  &pubKey,
2019  &secKey);
2020  }
2021  if (rv) {
2022  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2024  I18N("Could not generate key"));
2025  return rv;
2026  }
2027 
2029  I18N("Key generated"));
2030 
2031  /* set key */
2032  if (keyNum==1)
2034  else if (keyNum==2)
2036  else if (keyNum==5)
2038  else if (keyNum==7)
2040  else
2041  cki=NULL;
2042 
2043  if (cki==NULL) {
2045  I18N("No key info found"));
2046  return GWEN_ERROR_NO_DATA;
2047  }
2048 
2049  /* update key info for the key */
2051  assert(ki);
2052 
2053  /* get modulus */
2054  klen=sizeof(kbuf);
2055  rv=GWEN_Crypt_KeyRsa_GetModulus(pubKey, kbuf, &klen);
2056  if (rv) {
2057  DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
2059  GWEN_Crypt_Key_free(pubKey);
2060  return rv;
2061  }
2062  GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
2063 
2064  /* get exponent */
2065  klen=sizeof(kbuf);
2066  rv=GWEN_Crypt_KeyRsa_GetExponent(pubKey, kbuf, &klen);
2067  if (rv) {
2068  DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
2070  GWEN_Crypt_Key_free(pubKey);
2071  return rv;
2072  }
2073  GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
2076 
2077  if (keyNum==1) {
2079  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
2081  }
2082  GWEN_CTF_Context_SetLocalSignKey(ctx, secKey);
2084  GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2085  GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2086  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2087  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2094  }
2095  else if (keyNum==2) {
2096  GWEN_CTF_Context_SetLocalCryptKey(ctx, secKey);
2098  GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2099  GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2100  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2101  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2107  }
2108  else if (keyNum==5) {
2110  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
2112  }
2113  GWEN_CTF_Context_SetLocalAuthKey(ctx, secKey);
2115  GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2116  GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2117  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2118  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2125  }
2126  else if (keyNum==7) {
2128  DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
2130  }
2133  GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
2134  GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
2135  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
2136  GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
2143  }
2144 
2145  /* the public key is not used */
2146  GWEN_Crypt_Key_free(pubKey);
2147 
2148  rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
2149  if (rv) {
2150  DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
2152  I18N("Unable to write key file"));
2153  return rv;
2154  }
2155 
2157  I18N("Key generated and set"));
2158 
2159  return 0;
2160 }
2161 
2162 
2163 
2164 
2165 
2166 
2169  GWEN_CRYPT_TOKEN_FILE *lct;
2170 
2171  lct=(GWEN_CRYPT_TOKEN_FILE*) p;
2172  GWEN_Crypt_Token_Context_List_free(lct->contextList);
2173 
2174  GWEN_FREE_OBJECT(lct);
2175 }
2176 
2177 
2178 
2180  const char *tokenName) {
2181  GWEN_CRYPT_TOKEN *ct;
2182  GWEN_CRYPT_TOKEN_FILE *lct;
2183 
2184  ct=GWEN_Crypt_Token_new(GWEN_Crypt_Token_Device_File, typeName, tokenName);
2185  assert(ct);
2186 
2187  GWEN_NEW_OBJECT(GWEN_CRYPT_TOKEN_FILE, lct);
2188  lct->contextList=GWEN_Crypt_Token_Context_List_new();
2189  GWEN_INHERIT_SETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct, lct,
2206 
2207  return ct;
2208 }
2209 
2210 
2211 
2212 
2213