ctfile.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $
00005     begin       : Wed Mar 16 2005
00006     copyright   : (C) 2005 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *          Please see toplevel file COPYING for license details           *
00011  ***************************************************************************/
00012 
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016 
00017 
00018 #include "ctfile_p.h"
00019 #include "i18n_l.h"
00020 #include <gwenhywfar/ctf_context_be.h>
00021 #include <gwenhywfar/misc.h>
00022 #include <gwenhywfar/debug.h>
00023 #include <gwenhywfar/padd.h>
00024 #include <gwenhywfar/cryptkeyrsa.h>
00025 #include <gwenhywfar/text.h>
00026 
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <fcntl.h>
00030 #include <string.h>
00031 #include <errno.h>
00032 #include <stdlib.h>
00033 #include <unistd.h>
00034 
00035 
00036 
00037 GWEN_INHERIT(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE)
00038 
00039 
00040 
00041 
00042 
00043 int GWEN_Crypt_TokenFile__OpenFile(GWEN_CRYPT_TOKEN *ct, int wr, uint32_t gid){
00044   int fd;
00045   GWEN_CRYPT_TOKEN_FILE *lct;
00046   GWEN_FSLOCK_RESULT lres;
00047 
00048   assert(ct);
00049   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00050   assert(lct);
00051 
00052   lct->lock=GWEN_FSLock_new(GWEN_Crypt_Token_GetTokenName(ct),
00053                             GWEN_FSLock_TypeFile);
00054   lres=GWEN_FSLock_Lock(lct->lock, 10000, gid);
00055   if (lres!=GWEN_FSLock_ResultOk) {
00056     GWEN_FSLock_free(lct->lock);
00057     lct->lock=0;
00058     DBG_ERROR(GWEN_LOGDOMAIN, "Could not lock file");
00059     if (lres==GWEN_FSLock_ResultUserAbort)
00060       return GWEN_ERROR_USER_ABORTED;
00061     else
00062       return GWEN_ERROR_IO;
00063   }
00064   else {
00065     DBG_INFO(GWEN_LOGDOMAIN,
00066              "Keyfile [%s] locked.",
00067              GWEN_Crypt_Token_GetTokenName(ct));
00068   }
00069 
00070   if (wr) {
00071     /* write file */
00072     fd=open(GWEN_Crypt_Token_GetTokenName(ct),
00073             O_RDWR|O_CREAT
00074 #ifdef OS_WIN32
00075             | O_BINARY
00076 #endif
00077             ,
00078             S_IRUSR|S_IWUSR | lct->keyfile_mode);
00079   }
00080   else {
00081     /* Remember the access permissions when opening the file */
00082     struct stat statbuffer;
00083     if (!stat(GWEN_Crypt_Token_GetTokenName(ct), &statbuffer)) {
00084       /* Save the access mode, but masked by the bit masks for
00085          user/group/other permissions */
00086       lct->keyfile_mode = 
00087         statbuffer.st_mode & (S_IRWXU
00088 #ifndef OS_WIN32
00089                               | S_IRWXG | S_IRWXO
00090 #endif
00091                               );
00092     }
00093     else {
00094       DBG_ERROR(GWEN_LOGDOMAIN,
00095                 "stat(%s): %s",
00096                 GWEN_Crypt_Token_GetTokenName(ct),
00097                 strerror(errno));
00098 
00099       GWEN_FSLock_Unlock(lct->lock);
00100       GWEN_FSLock_free(lct->lock);
00101       lct->lock=0;
00102       DBG_INFO(GWEN_LOGDOMAIN,
00103                "Keyfile [%s] unlocked.",
00104                GWEN_Crypt_Token_GetTokenName(ct));
00105       return GWEN_ERROR_IO;
00106     }
00107 
00108     /* and open the file */
00109     fd=open(GWEN_Crypt_Token_GetTokenName(ct),
00110             O_RDONLY
00111 #ifdef OS_WIN32
00112             | O_BINARY
00113 #endif
00114            );
00115   }
00116 
00117   if (fd==-1) {
00118     DBG_ERROR(GWEN_LOGDOMAIN,
00119               "open(%s): %s",
00120               GWEN_Crypt_Token_GetTokenName(ct),
00121               strerror(errno));
00122     GWEN_FSLock_Unlock(lct->lock);
00123     GWEN_FSLock_free(lct->lock);
00124     lct->lock=0;
00125     DBG_INFO(GWEN_LOGDOMAIN,
00126              "Keyfile [%s] unlocked.",
00127              GWEN_Crypt_Token_GetTokenName(ct));
00128     return GWEN_ERROR_IO;
00129   }
00130 
00131   lct->fd=fd;
00132 
00133   return 0;
00134 }
00135 
00136 
00137 
00138 int GWEN_Crypt_TokenFile__CloseFile(GWEN_CRYPT_TOKEN *ct, uint32_t gid){
00139   GWEN_CRYPT_TOKEN_FILE *lct;
00140   GWEN_FSLOCK_RESULT lres;
00141   struct stat st;
00142 
00143   assert(ct);
00144   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00145   assert(lct);
00146 
00147   if (lct->fd==-1) {
00148     DBG_ERROR(GWEN_LOGDOMAIN, "Keyfile \"%s\"not open",
00149               GWEN_Crypt_Token_GetTokenName(ct));
00150     return GWEN_ERROR_INTERNAL;
00151   }
00152 
00153   if (close(lct->fd)) {
00154     DBG_ERROR(GWEN_LOGDOMAIN, "close(%s): %s",
00155               GWEN_Crypt_Token_GetTokenName(ct), strerror(errno));
00156     lct->fd=-1;
00157     GWEN_FSLock_Unlock(lct->lock);
00158     GWEN_FSLock_free(lct->lock);
00159     lct->lock=0;
00160     DBG_INFO(GWEN_LOGDOMAIN,
00161              "Keyfile [%s] unlocked.",
00162              GWEN_Crypt_Token_GetTokenName(ct));
00163     return GWEN_ERROR_IO;
00164   }
00165   lct->fd=-1;
00166 
00167   lres=GWEN_FSLock_Unlock(lct->lock);
00168   if (lres!=GWEN_FSLock_ResultOk) {
00169     DBG_WARN(GWEN_LOGDOMAIN, "Error removing lock from \"%s\": %d",
00170              GWEN_Crypt_Token_GetTokenName(ct), lres);
00171   }
00172   GWEN_FSLock_free(lct->lock);
00173   lct->lock=0;
00174   DBG_INFO(GWEN_LOGDOMAIN,
00175            "Keyfile [%s] unlocked.",
00176            GWEN_Crypt_Token_GetTokenName(ct));
00177 
00178   /* get times */
00179   if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
00180     DBG_ERROR(GWEN_LOGDOMAIN,
00181               "stat(%s): %s",
00182               GWEN_Crypt_Token_GetTokenName(ct),
00183               strerror(errno));
00184     return GWEN_ERROR_IO;
00185   }
00186 
00187 #ifndef OS_WIN32
00188   if (st.st_mode & 0007) {
00189     DBG_WARN(GWEN_LOGDOMAIN,
00190              "WARNING: Your keyfile \"%s\" is world accessible!\n"
00191              "Nobody but you should have access to the file. You \n"
00192              "should probably change this with \"chmod 600 %s\"",
00193              GWEN_Crypt_Token_GetTokenName(ct),
00194              GWEN_Crypt_Token_GetTokenName(ct));
00195     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Warning,
00196                          "WARNING: Your keyfile is world accessible!\n"
00197                          "Nobody but you should have access to the file.");
00198   }
00199 #endif
00200   lct->mtime=st.st_mtime;
00201   lct->ctime=st.st_ctime;
00202 
00203   return 0;
00204 }
00205 
00206 
00207 
00208 int GWEN_Crypt_TokenFile__Read(GWEN_CRYPT_TOKEN *ct, uint32_t gid){
00209   GWEN_CRYPT_TOKEN_FILE *lct;
00210 
00211   assert(ct);
00212   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00213   assert(lct);
00214 
00215   assert(lct->readFn);
00216   if (lseek(lct->fd, 0, SEEK_SET)==-1) {
00217     DBG_ERROR(GWEN_LOGDOMAIN, "lseek(%s): %s",
00218               GWEN_Crypt_Token_GetTokenName(ct),
00219               strerror(errno));
00220     return GWEN_ERROR_IO;
00221   }
00222   return lct->readFn(ct, lct->fd, gid);
00223 }
00224 
00225 
00226 
00227 int GWEN_Crypt_TokenFile__Write(GWEN_CRYPT_TOKEN *ct, int cr, uint32_t gid){
00228   GWEN_CRYPT_TOKEN_FILE *lct;
00229 
00230   assert(ct);
00231   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00232   assert(lct);
00233 
00234   if (lct->writeFn==0) {
00235     DBG_WARN(GWEN_LOGDOMAIN,
00236              "No write function in crypt token type \"%s\"",
00237              GWEN_Crypt_Token_GetTypeName(ct));
00238     return GWEN_ERROR_NOT_SUPPORTED;
00239   }
00240 
00241   if (lseek(lct->fd, 0, SEEK_SET)==-1) {
00242     DBG_ERROR(GWEN_LOGDOMAIN, "lseek(%s): %s",
00243               GWEN_Crypt_Token_GetTokenName(ct),
00244               strerror(errno));
00245     return GWEN_ERROR_IO;
00246   }
00247   return lct->writeFn(ct, lct->fd, cr, gid);
00248 }
00249 
00250 
00251 
00252 int GWEN_Crypt_TokenFile__ReadFile(GWEN_CRYPT_TOKEN *ct, uint32_t gid){
00253   GWEN_CRYPT_TOKEN_FILE *lct;
00254   int rv;
00255 
00256   assert(ct);
00257   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00258   assert(lct);
00259 
00260   /* clear context list, it will be reloaded */
00261   GWEN_Crypt_Token_Context_List_Clear(lct->contextList);
00262 
00263   /* open file */
00264   rv=GWEN_Crypt_TokenFile__OpenFile(ct, 0, gid);
00265   if (rv) {
00266     DBG_INFO(GWEN_LOGDOMAIN,
00267              "Could not open keyfile for reading (%d)", rv);
00268     return rv;
00269   }
00270 
00271   /* read file */
00272   rv=GWEN_Crypt_TokenFile__Read(ct, gid);
00273   if (rv) {
00274     DBG_INFO(GWEN_LOGDOMAIN, "Error reading keyfile");
00275     GWEN_Crypt_TokenFile__CloseFile(ct, gid);
00276     return rv;
00277   }
00278 
00279   /* close file */
00280   rv=GWEN_Crypt_TokenFile__CloseFile(ct, gid);
00281   if (rv) {
00282     DBG_INFO(GWEN_LOGDOMAIN, "Could not close keyfile");
00283     return rv;
00284   }
00285 
00286   return 0;
00287 }
00288 
00289 
00290 
00291 int GWEN_Crypt_TokenFile__WriteFile(GWEN_CRYPT_TOKEN *ct, int cr, uint32_t gid){
00292   GWEN_CRYPT_TOKEN_FILE *lct;
00293   int rv;
00294 
00295   assert(ct);
00296   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00297   assert(lct);
00298 
00299   /* open file */
00300   rv=GWEN_Crypt_TokenFile__OpenFile(ct, 1, gid);
00301   if (rv) {
00302     DBG_INFO(GWEN_LOGDOMAIN,
00303              "Could not open keyfile for writing (%d)", rv);
00304     return rv;
00305   }
00306 
00307   /* write file */
00308   rv=GWEN_Crypt_TokenFile__Write(ct, cr, gid);
00309   if (rv) {
00310     DBG_INFO(GWEN_LOGDOMAIN, "Error writing keyfile");
00311     GWEN_Crypt_TokenFile__CloseFile(ct, gid);
00312     return rv;
00313   }
00314 
00315   /* close file */
00316   rv=GWEN_Crypt_TokenFile__CloseFile(ct, gid);
00317   if (rv) {
00318     DBG_INFO(GWEN_LOGDOMAIN, "Could not close keyfile");
00319     return rv;
00320   }
00321 
00322   return 0;
00323 }
00324 
00325 
00326 
00327 int GWEN_Crypt_TokenFile__ReloadIfNeeded(GWEN_CRYPT_TOKEN *ct, uint32_t gid){
00328   GWEN_CRYPT_TOKEN_FILE *lct;
00329   struct stat st;
00330 
00331   assert(ct);
00332   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00333   assert(lct);
00334 
00335   if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
00336     DBG_ERROR(GWEN_LOGDOMAIN,
00337               "stat(%s): %s",
00338               GWEN_Crypt_Token_GetTokenName(ct),
00339               strerror(errno));
00340     return -1;
00341   }
00342   if (lct->mtime!=st.st_mtime ||
00343       lct->ctime!=st.st_ctime) {
00344     int rv;
00345 
00346     /* file has changed, reload it */
00347     DBG_NOTICE(GWEN_LOGDOMAIN,
00348                "Keyfile changed externally, reloading it");
00349     /* read file */
00350     rv=GWEN_Crypt_TokenFile__ReadFile(ct, gid);
00351     if (rv) {
00352       DBG_WARN(GWEN_LOGDOMAIN, "Error reloading keyfile");
00353       return rv;
00354     }
00355   }
00356   else {
00357     DBG_NOTICE(GWEN_LOGDOMAIN, "Keyfile unchanged, not reloading");
00358   }
00359   return 0;
00360 }
00361 
00362 
00363 
00364 void GWEN_Crypt_TokenFile_AddContext(GWEN_CRYPT_TOKEN *ct, GWEN_CRYPT_TOKEN_CONTEXT *ctx) {
00365   GWEN_CRYPT_TOKEN_FILE *lct;
00366 
00367   assert(ct);
00368   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00369   assert(lct);
00370 
00371   /* make sure the context is a file context */
00372   assert(GWEN_CTF_Context_IsOfThisType(ctx));
00373   GWEN_Crypt_Token_Context_List_Add(ctx, lct->contextList);
00374 }
00375 
00376 
00377 
00378 GWEN_CRYPT_TOKEN_CONTEXT *GWEN_Crypt_TokenFile_GetContext(GWEN_CRYPT_TOKEN *ct, int idx) {
00379   GWEN_CRYPT_TOKEN_FILE *lct;
00380   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
00381 
00382   assert(ct);
00383   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00384   assert(lct);
00385 
00386   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
00387   while(ctx) {
00388     if (idx==0)
00389       return ctx;
00390     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
00391     idx--;
00392   }
00393 
00394   return NULL;
00395 }
00396 
00397 
00398 
00399 GWEN_CRYPT_TOKEN_FILE_READ_FN GWEN_Crypt_TokenFile_SetReadFn(GWEN_CRYPT_TOKEN *ct,
00400                                                              GWEN_CRYPT_TOKEN_FILE_READ_FN f) {
00401   GWEN_CRYPT_TOKEN_FILE *lct;
00402   GWEN_CRYPT_TOKEN_FILE_READ_FN of;
00403 
00404   assert(ct);
00405   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00406   assert(lct);
00407 
00408   of=lct->readFn;
00409   lct->readFn=f;
00410 
00411   return of;
00412 }
00413 
00414 
00415 
00416 GWEN_CRYPT_TOKEN_FILE_WRITE_FN GWEN_Crypt_TokenFile_SetWriteFn(GWEN_CRYPT_TOKEN *ct,
00417                                                                GWEN_CRYPT_TOKEN_FILE_WRITE_FN f) {
00418   GWEN_CRYPT_TOKEN_FILE *lct;
00419   GWEN_CRYPT_TOKEN_FILE_WRITE_FN of;
00420 
00421   assert(ct);
00422   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00423   assert(lct);
00424 
00425   of=lct->writeFn;
00426   lct->writeFn=f;
00427 
00428   return of;
00429 }
00430 
00431 
00432 
00433 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Create(GWEN_CRYPT_TOKEN *ct, uint32_t gid){
00434   GWEN_CRYPT_TOKEN_FILE *lct;
00435   struct stat st;
00436   int fd;
00437   int rv;
00438 
00439   assert(ct);
00440   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00441   assert(lct);
00442 
00443   if (!GWEN_Crypt_Token_GetTokenName(ct)) {
00444     DBG_ERROR(GWEN_LOGDOMAIN, "No medium name given");
00445     return GWEN_ERROR_INVALID;
00446   }
00447 
00448   if (stat(GWEN_Crypt_Token_GetTokenName(ct), &st)) {
00449     if (errno!=ENOENT) {
00450       DBG_ERROR(GWEN_LOGDOMAIN,
00451                 "stat(%s): %s",
00452                 GWEN_Crypt_Token_GetTokenName(ct),
00453                 strerror(errno));
00454       return GWEN_ERROR_IO;
00455     }
00456   }
00457   else {
00458     DBG_ERROR(GWEN_LOGDOMAIN,
00459               "Keyfile \"%s\" already exists, will not create it",
00460               GWEN_Crypt_Token_GetTokenName(ct));
00461     return GWEN_ERROR_INVALID;
00462   }
00463 
00464 
00465   /* create file */
00466   fd=open(GWEN_Crypt_Token_GetTokenName(ct),
00467           O_RDWR | O_CREAT | O_EXCL
00468 #ifdef OS_WIN32
00469           | O_BINARY
00470 #endif
00471           ,
00472           S_IRUSR|S_IWUSR);
00473 
00474 
00475   if (fd==-1) {
00476     DBG_ERROR(GWEN_LOGDOMAIN,
00477               "open(%s): %s",
00478               GWEN_Crypt_Token_GetTokenName(ct),
00479               strerror(errno));
00480     return GWEN_ERROR_IO;
00481   }
00482 
00483   close(fd);
00484 
00485   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 1, gid);
00486   if (rv) {
00487     DBG_INFO(GWEN_LOGDOMAIN, "here");
00488     return rv;
00489   }
00490 
00491   return 0;
00492 }
00493 
00494 
00495 
00496 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Open(GWEN_CRYPT_TOKEN *ct, GWEN_UNUSED int admin, uint32_t gid){
00497   GWEN_CRYPT_TOKEN_FILE *lct;
00498   int rv;
00499 
00500   assert(ct);
00501   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00502   assert(lct);
00503 
00504   rv=GWEN_Crypt_TokenFile__ReadFile(ct, gid);
00505   if (rv) {
00506     DBG_INFO(GWEN_LOGDOMAIN, "here");
00507     return rv;
00508   }
00509 
00510   return 0;
00511 }
00512 
00513 
00514 
00515 int GWENHYWFAR_CB GWEN_Crypt_TokenFile_Close(GWEN_CRYPT_TOKEN *ct, int abandon, uint32_t gid){
00516   GWEN_CRYPT_TOKEN_FILE *lct;
00517   int rv;
00518 
00519   assert(ct);
00520   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00521   assert(lct);
00522 
00523   if (!abandon)
00524     rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
00525   else
00526     rv=0;
00527 
00528   /* free/reset all data */
00529   GWEN_Crypt_Token_Context_List_Clear(lct->contextList);
00530   lct->mtime=0;
00531   lct->ctime=0;
00532 
00533   return rv;
00534 }
00535 
00536 
00537 
00538 
00539 int GWENHYWFAR_CB GWEN_Crypt_TokenFile__GetKeyIdList(GWEN_CRYPT_TOKEN *ct,
00540                                                      uint32_t *pIdList,
00541                                                      uint32_t *pCount,
00542                                                      uint32_t gid) {
00543   GWEN_CRYPT_TOKEN_FILE *lct;
00544   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
00545   int i;
00546   int rv;
00547 
00548   assert(ct);
00549   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00550   assert(lct);
00551 
00552   /* reload if needed */
00553   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
00554   if (rv) {
00555     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00556     return rv;
00557   }
00558 
00559   /* count keys */
00560   i=0;
00561   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
00562   while(ctx) {
00563     i+=GWEN_CRYPT_TOKEN_CONTEXT_KEYS;
00564     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
00565   }
00566 
00567   /* if no buffer given just return number of keys */
00568   if (pIdList==NULL) {
00569     *pCount=i;
00570     return 0;
00571   }
00572 
00573   if (*pCount<i) {
00574     DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00575     return GWEN_ERROR_BUFFER_OVERFLOW;
00576   }
00577 
00578   *pCount=i;
00579   i=0;
00580   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
00581   while(ctx) {
00582     int j;
00583 
00584     for (j=1; j<=GWEN_CRYPT_TOKEN_CONTEXT_KEYS; j++)
00585       *(pIdList++)=(i<<16)+j;
00586 
00587     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
00588     i++;
00589   }
00590 
00591   return 0;
00592 }
00593 
00594 
00595 
00596 const GWEN_CRYPT_TOKEN_KEYINFO* GWENHYWFAR_CB 
00597 GWEN_Crypt_TokenFile__GetKeyInfo(GWEN_CRYPT_TOKEN *ct,
00598                                  uint32_t id,
00599                                  uint32_t flags,
00600                                  uint32_t gid) {
00601   GWEN_CRYPT_TOKEN_FILE *lct;
00602   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
00603   GWEN_CRYPT_TOKEN_KEYINFO *ki;
00604   int i;
00605   int rv;
00606 
00607   assert(ct);
00608   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00609   assert(lct);
00610 
00611   /* reload if needed */
00612   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
00613   if (rv) {
00614     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00615     return NULL;
00616   }
00617 
00618   i=id>>16;
00619   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
00620   while(ctx) {
00621     if (i==0)
00622       break;
00623     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
00624     i--;
00625   }
00626 
00627   if (ctx==NULL) {
00628     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
00629     return NULL;
00630   }
00631 
00632   switch(id & 0xffff) {
00633   case 1: ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
00634   case 2: ki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx); break;
00635   case 3: ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx); break;
00636   case 4: ki=GWEN_CTF_Context_GetRemoteCryptKeyInfo(ctx); break;
00637   case 5: ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
00638   case 6: ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx); break;
00639   default:
00640     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
00641     return NULL;
00642   }
00643 
00644   if (ki==NULL) {
00645     DBG_INFO(GWEN_LOGDOMAIN, "No key info stored for key %d", id);
00646     return NULL;
00647   }
00648 
00649   return ki;
00650 }
00651 
00652 
00653 
00654 #if 0
00655 int GWENHYWFAR_CB 
00656 GWEN_Crypt_TokenFile__SetKeyInfo(GWEN_CRYPT_TOKEN *ct,
00657                                  uint32_t id,
00658                                  const GWEN_CRYPT_TOKEN_KEYINFO *ki,
00659                                  uint32_t gid) {
00660   GWEN_CRYPT_TOKEN_FILE *lct;
00661   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
00662   int i;
00663   int rv;
00664   GWEN_CRYPT_TOKEN_KEYINFO *nki;
00665   GWEN_CRYPT_KEY *key;
00666   uint32_t flags;
00667 
00668   assert(ct);
00669   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00670   assert(lct);
00671 
00672   flags=GWEN_Crypt_Token_KeyInfo_GetFlags(ki);
00673 
00674   /* reload if needed */
00675   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
00676   if (rv) {
00677     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00678     return rv;
00679   }
00680 
00681   i=id>>16;
00682   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
00683   while(ctx) {
00684     if (i==0)
00685       break;
00686     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
00687     i--;
00688   }
00689 
00690   if (ctx==NULL) {
00691     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
00692     return GWEN_ERROR_NOT_FOUND;
00693   }
00694 
00695   nki=GWEN_Crypt_Token_KeyInfo_dup(ki);
00696   assert(nki);
00697   switch(id & 0xffff) {
00698   case 1:
00699     GWEN_CTF_Context_SetLocalSignKeyInfo(ctx, nki);
00700     key=GWEN_CTF_Context_GetLocalSignKey(ctx);
00701     break;
00702   case 2:
00703     GWEN_CTF_Context_SetLocalCryptKeyInfo(ctx, nki);
00704     key=GWEN_CTF_Context_GetLocalCryptKey(ctx);
00705     break;
00706   case 3:
00707     GWEN_CTF_Context_SetRemoteSignKeyInfo(ctx, nki);
00708     key=GWEN_CTF_Context_GetRemoteSignKey(ctx);
00709     break;
00710   case 4:
00711     GWEN_CTF_Context_SetRemoteCryptKeyInfo(ctx, nki);
00712     key=GWEN_CTF_Context_GetRemoteCryptKey(ctx);
00713     break;
00714   case 5:
00715     GWEN_CTF_Context_SetLocalAuthKeyInfo(ctx, nki);
00716     key=GWEN_CTF_Context_GetLocalAuthKey(ctx);
00717     break;
00718   case 6:
00719     GWEN_CTF_Context_SetRemoteAuthKeyInfo(ctx, nki);
00720     key=GWEN_CTF_Context_GetRemoteAuthKey(ctx);
00721     break;
00722   default:
00723     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
00724     GWEN_Crypt_Token_KeyInfo_free(nki);
00725     return GWEN_ERROR_NOT_FOUND;
00726   }
00727 
00728   /* replace key if modulus and exponent are given */
00729   if ((flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) &&
00730       (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT) &&
00731       id!=1 && /* don't change local keys */
00732       id!=2 &&
00733       id!=5) {
00734     GWEN_CRYPT_KEY *nkey;
00735 
00736     nkey=GWEN_Crypt_KeyRsa_fromModExp(GWEN_Crypt_Token_KeyInfo_GetKeySize(ki),
00737                                       GWEN_Crypt_Token_KeyInfo_GetModulusData(ki),
00738                                       GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki),
00739                                       GWEN_Crypt_Token_KeyInfo_GetExponentData(ki),
00740                                       GWEN_Crypt_Token_KeyInfo_GetExponentLen(ki));
00741     assert(nkey);
00742 
00743     if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
00744       GWEN_Crypt_Key_SetKeyNumber(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
00745     if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
00746       GWEN_Crypt_Key_SetKeyVersion(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
00747 
00748     /* replace public key */
00749     switch(id & 0xffff) {
00750     case 3: /* remote sign key */
00751       GWEN_CTF_Context_SetRemoteSignKey(ctx, nkey);
00752       break;
00753     case 4: /* remote crypt key */
00754       GWEN_CTF_Context_SetRemoteCryptKey(ctx, nkey);
00755       break;
00756     case 6: /* remote auth key */
00757       GWEN_CTF_Context_SetRemoteAuthKey(ctx, nkey);
00758       break;
00759     default:
00760       DBG_ERROR(GWEN_LOGDOMAIN,
00761                 "Can't set modulus and exponent for private key");
00762       GWEN_Crypt_Key_free(nkey);
00763       return GWEN_ERROR_INVALID;
00764     }
00765     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
00766                          I18N("Public key replaced"));
00767   }
00768   else {
00769     if (key) {
00770       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
00771         GWEN_Crypt_Key_SetKeyNumber(key, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
00772       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
00773         GWEN_Crypt_Key_SetKeyVersion(key, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
00774     }
00775   }
00776 
00777   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
00778   if (rv) {
00779     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
00780     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
00781                          I18N("Unable to write key file"));
00782     return rv;
00783   }
00784 
00785   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
00786                        I18N("Key file saved"));
00787 
00788   return 0;
00789 }
00790 #endif
00791 
00792 
00793 int GWENHYWFAR_CB 
00794 GWEN_Crypt_TokenFile__SetKeyInfo(GWEN_CRYPT_TOKEN *ct,
00795                                  uint32_t id,
00796                                  const GWEN_CRYPT_TOKEN_KEYINFO *ski,
00797                                  uint32_t gid) {
00798   GWEN_CRYPT_TOKEN_FILE *lct;
00799   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
00800   int i;
00801   int rv;
00802   GWEN_CRYPT_TOKEN_KEYINFO *ki;
00803   GWEN_CRYPT_KEY *key;
00804   uint32_t flags;
00805   uint32_t nflags;
00806 
00807   assert(ct);
00808   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00809   assert(lct);
00810 
00811   flags=GWEN_Crypt_Token_KeyInfo_GetFlags(ski);
00812 
00813   /* reload if needed */
00814   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
00815   if (rv) {
00816     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00817     return rv;
00818   }
00819 
00820   i=id>>16;
00821   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
00822   while(ctx) {
00823     if (i==0)
00824       break;
00825     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
00826     i--;
00827   }
00828 
00829   if (ctx==NULL) {
00830     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
00831     return GWEN_ERROR_NOT_FOUND;
00832   }
00833 
00834   switch(id & 0xffff) {
00835   case 1:
00836     ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
00837     key=GWEN_CTF_Context_GetLocalSignKey(ctx);
00838     break;
00839   case 2:
00840     ki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx);
00841     key=GWEN_CTF_Context_GetLocalCryptKey(ctx);
00842     break;
00843   case 3:
00844     ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
00845     key=GWEN_CTF_Context_GetRemoteSignKey(ctx);
00846     break;
00847   case 4:
00848     ki=GWEN_CTF_Context_GetRemoteCryptKeyInfo(ctx);
00849     key=GWEN_CTF_Context_GetRemoteCryptKey(ctx);
00850     break;
00851   case 5:
00852     ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
00853     key=GWEN_CTF_Context_GetLocalAuthKey(ctx);
00854     break;
00855   case 6:
00856     ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
00857     key=GWEN_CTF_Context_GetRemoteAuthKey(ctx);
00858     break;
00859   default:
00860     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
00861     return GWEN_ERROR_NOT_FOUND;
00862   }
00863   assert(ki);
00864 
00865   nflags=GWEN_Crypt_Token_KeyInfo_GetFlags(ki);
00866 
00867   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSTATUS) {
00868     /* ignore for now */
00869   }
00870 
00871   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS) {
00872     nflags&=~GWEN_CRYPT_TOKEN_KEYFLAGS_ACTIONMASK;
00873     nflags|=(flags & GWEN_CRYPT_TOKEN_KEYFLAGS_ACTIONMASK);
00874   }
00875 
00876   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION) {
00877     uint32_t i=GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ski);
00878     GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, i);
00879     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION;
00880     if (key)
00881       GWEN_Crypt_Key_SetKeyVersion(key, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ski));
00882     DBG_INFO(GWEN_LOGDOMAIN, "Setting key version");
00883   }
00884 
00885   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER) {
00886     uint32_t i=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ski);
00887     GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, i);
00888     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER;
00889     DBG_INFO(GWEN_LOGDOMAIN, "Setting signature counter");
00890   }
00891 
00892   if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER) {
00893     uint32_t i=GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ski);
00894     GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, i);
00895     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER;
00896     if (key)
00897       GWEN_Crypt_Key_SetKeyNumber(key, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ski));
00898     DBG_INFO(GWEN_LOGDOMAIN, "Setting key number");
00899   }
00900 
00901   /* replace key if modulus and exponent are given */
00902   if ((flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS) &&
00903       (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT) &&
00904       id!=1 && /* don't change local keys */
00905       id!=2 &&
00906       id!=5) {
00907     GWEN_CRYPT_KEY *nkey;
00908 
00909     GWEN_Crypt_Token_KeyInfo_SetKeySize(ki, GWEN_Crypt_Token_KeyInfo_GetKeySize(ski));
00910     GWEN_Crypt_Token_KeyInfo_SetModulus(ki,
00911                                         GWEN_Crypt_Token_KeyInfo_GetModulusData(ski),
00912                                         GWEN_Crypt_Token_KeyInfo_GetModulusLen(ski));
00913     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS;
00914     GWEN_Crypt_Token_KeyInfo_SetExponent(ki,
00915                                          GWEN_Crypt_Token_KeyInfo_GetExponentData(ski),
00916                                          GWEN_Crypt_Token_KeyInfo_GetExponentLen(ski));
00917     nflags|=GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT;
00918     nkey=GWEN_Crypt_KeyRsa_fromModExp(GWEN_Crypt_Token_KeyInfo_GetKeySize(ski),
00919                                       GWEN_Crypt_Token_KeyInfo_GetModulusData(ski),
00920                                       GWEN_Crypt_Token_KeyInfo_GetModulusLen(ski),
00921                                       GWEN_Crypt_Token_KeyInfo_GetExponentData(ski),
00922                                       GWEN_Crypt_Token_KeyInfo_GetExponentLen(ski));
00923     assert(nkey);
00924 
00925     if (nflags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
00926       GWEN_Crypt_Key_SetKeyNumber(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
00927     if (nflags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
00928       GWEN_Crypt_Key_SetKeyVersion(nkey, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
00929 
00930     /* replace public key */
00931     switch(id & 0xffff) {
00932     case 3: /* remote sign key */
00933       GWEN_CTF_Context_SetRemoteSignKey(ctx, nkey);
00934       break;
00935     case 4: /* remote crypt key */
00936       GWEN_CTF_Context_SetRemoteCryptKey(ctx, nkey);
00937       break;
00938     case 6: /* remote auth key */
00939       GWEN_CTF_Context_SetRemoteAuthKey(ctx, nkey);
00940       break;
00941     default:
00942       DBG_ERROR(GWEN_LOGDOMAIN,
00943                 "Can't set modulus and exponent for private key");
00944       GWEN_Crypt_Key_free(nkey);
00945       return GWEN_ERROR_INVALID;
00946     }
00947     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
00948                          I18N("Public key replaced"));
00949   }
00950   else {
00951     if (key) {
00952       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER)
00953         GWEN_Crypt_Key_SetKeyNumber(key, GWEN_Crypt_Token_KeyInfo_GetKeyNumber(ki));
00954       if (flags & GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION)
00955         GWEN_Crypt_Key_SetKeyVersion(key, GWEN_Crypt_Token_KeyInfo_GetKeyVersion(ki));
00956     }
00957   }
00958 
00959   GWEN_Crypt_Token_KeyInfo_SetFlags(ki, nflags);
00960 
00961   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
00962   if (rv) {
00963     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
00964     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
00965                          I18N("Unable to write key file"));
00966     return rv;
00967   }
00968 
00969   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
00970                        I18N("Key file saved"));
00971 
00972   return 0;
00973 }
00974 
00975 
00976 
00977 int GWENHYWFAR_CB
00978 GWEN_Crypt_TokenFile__GetContextIdList(GWEN_CRYPT_TOKEN *ct,
00979                                        uint32_t *pIdList,
00980                                        uint32_t *pCount,
00981                                        uint32_t gid) {
00982   GWEN_CRYPT_TOKEN_FILE *lct;
00983   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
00984   int i;
00985   int rv;
00986 
00987   assert(ct);
00988   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
00989   assert(lct);
00990 
00991   /* reload if needed */
00992   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
00993   if (rv) {
00994     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00995     return rv;
00996   }
00997 
00998   /* count keys */
00999   i=0;
01000   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01001   while(ctx) {
01002     i++;
01003     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01004   }
01005 
01006   /* store number of entries */
01007   *pCount=i;
01008 
01009   /* if no buffer given just return number of keys */
01010   if (pIdList==NULL)
01011     return 0;
01012 
01013   if (*pCount<i) {
01014     DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
01015     return GWEN_ERROR_BUFFER_OVERFLOW;
01016   }
01017 
01018   i=1;
01019   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01020   while(ctx) {
01021     *(pIdList++)=i;
01022     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01023     i++;
01024   }
01025 
01026   return 0;
01027 }
01028 
01029 
01030 
01031 const GWEN_CRYPT_TOKEN_CONTEXT* GWENHYWFAR_CB 
01032 GWEN_Crypt_TokenFile__GetContext(GWEN_CRYPT_TOKEN *ct,
01033                                  uint32_t id,
01034                                  uint32_t gid) {
01035   GWEN_CRYPT_TOKEN_FILE *lct;
01036   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01037   int rv;
01038 
01039   assert(ct);
01040   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01041   assert(lct);
01042 
01043   /* reload if needed */
01044   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01045   if (rv) {
01046     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01047     return NULL;
01048   }
01049 
01050   if (id==0) {
01051     DBG_INFO(GWEN_LOGDOMAIN, "Invalid context id 0");
01052     return NULL;
01053   }
01054 
01055   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01056   while(ctx) {
01057     if (GWEN_Crypt_Token_Context_GetId(ctx)==id)
01058       break;
01059     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01060   }
01061 
01062   if (ctx==NULL) {
01063     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", id);
01064     return NULL;
01065   }
01066 
01067   return ctx;
01068 }
01069 
01070 
01071 
01072 int GWENHYWFAR_CB 
01073 GWEN_Crypt_TokenFile__SetContext(GWEN_CRYPT_TOKEN *ct,
01074                                  uint32_t id,
01075                                  const GWEN_CRYPT_TOKEN_CONTEXT *nctx,
01076                                  uint32_t gid) {
01077   GWEN_CRYPT_TOKEN_FILE *lct;
01078   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01079   int rv;
01080   const char *s;
01081 
01082   assert(ct);
01083   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01084   assert(lct);
01085 
01086   if (id==0) {
01087     DBG_INFO(GWEN_LOGDOMAIN, "Invalid context id 0");
01088     return GWEN_ERROR_INVALID;
01089   }
01090 
01091   /* reload if needed */
01092   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01093   if (rv) {
01094     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01095     return rv;
01096   }
01097 
01098   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01099   while(ctx) {
01100     if (GWEN_Crypt_Token_Context_GetId(ctx)==id)
01101       break;
01102     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01103   }
01104 
01105   if (ctx==NULL) {
01106     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", id);
01107     return GWEN_ERROR_NOT_FOUND;
01108   }
01109 
01110   /* copy user data from context */
01111   s=GWEN_Crypt_Token_Context_GetServiceId(nctx);
01112   GWEN_Crypt_Token_Context_SetServiceId(ctx, s);
01113   s=GWEN_Crypt_Token_Context_GetUserId(nctx);
01114   GWEN_Crypt_Token_Context_SetUserId(ctx, s);
01115   s=GWEN_Crypt_Token_Context_GetUserName(nctx);
01116   GWEN_Crypt_Token_Context_SetUserName(ctx, s);
01117   s=GWEN_Crypt_Token_Context_GetPeerId(nctx);
01118   GWEN_Crypt_Token_Context_SetPeerId(ctx, s);
01119   s=GWEN_Crypt_Token_Context_GetAddress(nctx);
01120   GWEN_Crypt_Token_Context_SetAddress(ctx, s);
01121   GWEN_Crypt_Token_Context_SetPort(ctx, GWEN_Crypt_Token_Context_GetPort(nctx));
01122   s=GWEN_Crypt_Token_Context_GetSystemId(nctx);
01123   GWEN_Crypt_Token_Context_SetSystemId(ctx, s);
01124 
01125   return 0;
01126 }
01127 
01128 
01129 
01130 GWEN_CRYPT_KEY *GWEN_Crypt_TokenFile__GetKey(GWEN_CRYPT_TOKEN *ct, uint32_t id, uint32_t gid) {
01131   GWEN_CRYPT_TOKEN_FILE *lct;
01132   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01133   int i;
01134   int rv;
01135 
01136   assert(ct);
01137   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01138   assert(lct);
01139 
01140   /* reload if needed */
01141   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01142   if (rv) {
01143     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01144     return NULL;
01145   }
01146 
01147   i=id>>16;
01148   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01149   while(ctx) {
01150     if (i==0)
01151       break;
01152     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01153     i--;
01154   }
01155 
01156   if (ctx==NULL) {
01157     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (context out of range)", id);
01158     return NULL;
01159   }
01160 
01161   switch(id & 0xffff) {
01162   case 1: return GWEN_CTF_Context_GetLocalSignKey(ctx);
01163   case 2: return GWEN_CTF_Context_GetLocalCryptKey(ctx);
01164   case 3: return GWEN_CTF_Context_GetRemoteSignKey(ctx);
01165   case 4: return GWEN_CTF_Context_GetRemoteCryptKey(ctx);
01166   case 5: return GWEN_CTF_Context_GetLocalAuthKey(ctx);
01167   case 6: return GWEN_CTF_Context_GetRemoteAuthKey(ctx);
01168   default:
01169     DBG_INFO(GWEN_LOGDOMAIN, "No key by id [%x] known (key id out of range)", id);
01170     return NULL;
01171   }
01172 }
01173 
01174 
01175 
01176 int GWENHYWFAR_CB
01177 GWEN_Crypt_TokenFile__Sign(GWEN_CRYPT_TOKEN *ct,
01178                            uint32_t keyId,
01179                            GWEN_CRYPT_PADDALGO *a,
01180                            const uint8_t *pInData,
01181                            uint32_t inLen,
01182                            uint8_t *pSignatureData,
01183                            uint32_t *pSignatureLen,
01184                            uint32_t *pSeqCounter,
01185                            uint32_t gid) {
01186   GWEN_CRYPT_TOKEN_FILE *lct;
01187   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01188   GWEN_CRYPT_KEY *k;
01189   int keyNum;
01190   GWEN_BUFFER *srcBuf;
01191   int i;
01192   int rv;
01193 
01194   assert(ct);
01195   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01196   assert(lct);
01197 
01198   DBG_INFO(GWEN_LOGDOMAIN, "Signing with key %d", keyId);
01199 
01200   /* reload if needed */
01201   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01202   if (rv) {
01203     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01204     return rv;
01205   }
01206 
01207   /* get context */
01208   i=(keyId>>16);
01209   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01210   if (ctx==NULL) {
01211     DBG_ERROR(GWEN_LOGDOMAIN, "Token has no context");
01212     return GWEN_ERROR_NOT_FOUND;
01213   }
01214   while(ctx) {
01215     if (i==0)
01216       break;
01217     DBG_ERROR(GWEN_LOGDOMAIN, "Checking token %d (i==%d)",
01218               GWEN_Crypt_Token_Context_GetId(ctx), i);
01219     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01220     i--;
01221   }
01222 
01223   if (ctx==NULL) {
01224     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01225     return GWEN_ERROR_NOT_FOUND;
01226   }
01227 
01228   /* get key */
01229   keyNum=keyId & 0xffff;
01230   if (keyNum!=1 && keyNum!=5) {
01231     /* neither localSignKey nor localAuthKey */
01232     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for signing (%x)", keyId);
01233     return GWEN_ERROR_INVALID;
01234   }
01235 
01236   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01237   if (k==NULL) {
01238     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
01239     return GWEN_ERROR_NOT_FOUND;
01240   }
01241 
01242   /* copy to a buffer for padding */
01243   srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
01244   GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
01245 
01246   /* padd according to given algo */
01247   rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
01248   if (rv) {
01249     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01250     GWEN_Buffer_free(srcBuf);
01251     return rv;
01252   }
01253 
01254   /* sign with key */
01255   rv=GWEN_Crypt_Key_Sign(k,
01256                          (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
01257                          GWEN_Buffer_GetUsedBytes(srcBuf),
01258                          pSignatureData,
01259                          pSignatureLen);
01260   GWEN_Buffer_free(srcBuf);
01261   if (rv) {
01262     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01263     return rv;
01264   }
01265 
01266   if (pSeqCounter) {
01267     GWEN_CRYPT_TOKEN_KEYINFO *ki;
01268 
01269     /* signature sequence counter is to be incremented */
01270     switch(keyId & 0xffff) {
01271     case 1:  ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
01272     case 5:  ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
01273     default: ki=NULL;
01274     }
01275     if (ki &&
01276         (GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER)) {
01277       unsigned int seq;
01278 
01279       seq=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki);
01280       *pSeqCounter=seq;
01281       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, ++seq);
01282 
01283       rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
01284       if (rv) {
01285         DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
01286         return rv;
01287       }
01288     }
01289     else {
01290       DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
01291       *pSeqCounter=0;
01292     }
01293   }
01294 
01295   return 0;
01296 }
01297 
01298 
01299 
01300 int GWENHYWFAR_CB
01301 GWEN_Crypt_TokenFile__Verify(GWEN_CRYPT_TOKEN *ct,
01302                              uint32_t keyId,
01303                              GWEN_CRYPT_PADDALGO *a,
01304                              const uint8_t *pInData,
01305                              uint32_t inLen,
01306                              const uint8_t *pSignatureData,
01307                              uint32_t signatureLen,
01308                              uint32_t seqCounter,
01309                              uint32_t gid) {
01310   GWEN_CRYPT_TOKEN_FILE *lct;
01311   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01312   GWEN_CRYPT_KEY *k;
01313   int keyNum;
01314   int i;
01315   int rv;
01316   GWEN_CRYPT_PADDALGOID aid;
01317 
01318   assert(ct);
01319   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01320   assert(lct);
01321 
01322   DBG_INFO(GWEN_LOGDOMAIN, "Verifying with key %d", keyId);
01323 
01324   aid=GWEN_Crypt_PaddAlgo_GetId(a);
01325 
01326   /* reload if needed */
01327   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01328   if (rv) {
01329     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01330     return rv;
01331   }
01332 
01333   /* get context */
01334   i=(keyId>>16);
01335   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01336   while(ctx) {
01337     if (i==0)
01338       break;
01339     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01340     i--;
01341   }
01342 
01343   if (ctx==NULL) {
01344     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01345     return GWEN_ERROR_NOT_FOUND;
01346   }
01347 
01348   /* get key */
01349   keyNum=keyId & 0xffff;
01350   if (keyNum!=1 && keyNum!=3 && keyNum!=6) {
01351     /* neither remoteSignKey nor remoteAuthKey */
01352     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for verifying (%x)", keyId);
01353     return GWEN_ERROR_INVALID;
01354   }
01355 
01356   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01357   if (k==NULL) {
01358     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
01359     return GWEN_ERROR_NO_KEY;
01360   }
01361 
01362   if (aid==GWEN_Crypt_PaddAlgoId_Iso9796_2 ||
01363       aid==GWEN_Crypt_PaddAlgoId_Pkcs1_2) {
01364     GWEN_BUFFER *tbuf;
01365     uint32_t l;
01366 
01367     /* these algos add random numbers, we must use encrypt fn here and
01368      * compare the decrypted and unpadded data with the source data */
01369     tbuf=GWEN_Buffer_new(0, signatureLen+16, 0, 0);
01370     l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
01371     rv=GWEN_Crypt_Key_Encipher(k,
01372                                pSignatureData, signatureLen,
01373                                (uint8_t*)GWEN_Buffer_GetStart(tbuf),
01374                                &l);
01375     if (rv<0) {
01376       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01377       GWEN_Buffer_free(tbuf);
01378       return rv;
01379     }
01380     GWEN_Buffer_IncrementPos(tbuf, l);
01381     GWEN_Buffer_AdjustUsedBytes(tbuf);
01382 
01383     rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
01384     if (rv<0) {
01385       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01386       GWEN_Buffer_free(tbuf);
01387       return rv;
01388     }
01389     l=GWEN_Buffer_GetUsedBytes(tbuf);
01390 
01391     if (l!=inLen) {
01392       DBG_ERROR(GWEN_LOGDOMAIN, "Signature length doesn't match");
01393       GWEN_Buffer_free(tbuf);
01394       return GWEN_ERROR_VERIFY;
01395     }
01396     if (memcmp(pInData, GWEN_Buffer_GetStart(tbuf), l)!=0) {
01397       DBG_ERROR(GWEN_LOGDOMAIN, "Signature doesn't match:");
01398       GWEN_Buffer_free(tbuf);
01399       return GWEN_ERROR_VERIFY;
01400     }
01401   }
01402   else {
01403     GWEN_BUFFER *srcBuf;
01404 
01405     /* copy to a buffer for padding */
01406     srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
01407     GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
01408 
01409     /* padd according to given algo */
01410     rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
01411     if (rv) {
01412       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01413       GWEN_Buffer_free(srcBuf);
01414       return rv;
01415     }
01416 
01417     /* sign with key */
01418     rv=GWEN_Crypt_Key_Verify(k,
01419                              (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
01420                              GWEN_Buffer_GetUsedBytes(srcBuf),
01421                              pSignatureData,
01422                              signatureLen);
01423     GWEN_Buffer_free(srcBuf);
01424     if (rv) {
01425       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01426       return rv;
01427     }
01428   }
01429 
01430   if (seqCounter) {
01431     GWEN_CRYPT_TOKEN_KEYINFO *ki;
01432 
01433     /* signature sequence counter is to be checked */
01434     if (keyNum==3)
01435       ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
01436     else
01437       ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
01438     if (ki &&
01439         (GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER)) {
01440       unsigned int seq;
01441 
01442       seq=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki);
01443 
01444       if (seq>=seqCounter) {
01445         DBG_WARN(GWEN_LOGDOMAIN, "Bad remote sequence counter (possibly replay attack!)");
01446         return GWEN_ERROR_VERIFY;
01447       }
01448       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, seqCounter);
01449 
01450       /* write file */
01451       rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
01452       if (rv) {
01453         DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
01454         return rv;
01455       }
01456     }
01457     else {
01458       DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
01459     }
01460 
01461   }
01462 
01463   return 0;
01464 }
01465 
01466 
01467 
01468 int GWENHYWFAR_CB
01469 GWEN_Crypt_TokenFile__Encipher(GWEN_CRYPT_TOKEN *ct,
01470                                uint32_t keyId,
01471                                GWEN_CRYPT_PADDALGO *a,
01472                                const uint8_t *pInData,
01473                                uint32_t inLen,
01474                                uint8_t *pOutData,
01475                                uint32_t *pOutLen,
01476                                uint32_t gid) {
01477   GWEN_CRYPT_TOKEN_FILE *lct;
01478   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01479   GWEN_CRYPT_KEY *k;
01480   int keyNum;
01481   GWEN_BUFFER *srcBuf;
01482   int i;
01483   int rv;
01484 
01485   assert(ct);
01486   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01487   assert(lct);
01488 
01489   DBG_INFO(GWEN_LOGDOMAIN, "Enciphering with key %d", keyId);
01490 
01491   /* reload if needed */
01492   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01493   if (rv) {
01494     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01495     return rv;
01496   }
01497 
01498   /* get context */
01499   i=(keyId>>16);
01500   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01501   while(ctx) {
01502     if (i==0)
01503       break;
01504     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01505     i--;
01506   }
01507 
01508   if (ctx==NULL) {
01509     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01510     return GWEN_ERROR_NOT_FOUND;
01511   }
01512 
01513   /* get key */
01514   keyNum=keyId & 0xffff;
01515   if (keyNum!=2 && keyNum!=4) {
01516     /* not remoteCryptKey */
01517     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for encrypting (%x)", keyId);
01518     return GWEN_ERROR_INVALID;
01519   }
01520 
01521   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01522   if (k==NULL) {
01523     DBG_INFO(GWEN_LOGDOMAIN, "Key %d not found", keyId);
01524     return GWEN_ERROR_NOT_FOUND;
01525   }
01526 
01527   /* copy to a buffer for padding */
01528   srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
01529   GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
01530   GWEN_Buffer_Rewind(srcBuf);
01531 
01532   /* padd according to given algo */
01533   rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
01534   if (rv) {
01535     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01536     GWEN_Buffer_free(srcBuf);
01537     return rv;
01538   }
01539 
01540   /* encipher with key */
01541   rv=GWEN_Crypt_Key_Encipher(k,
01542                              (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
01543                              GWEN_Buffer_GetUsedBytes(srcBuf),
01544                              pOutData,
01545                              pOutLen);
01546   GWEN_Buffer_free(srcBuf);
01547   if (rv) {
01548     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01549     return rv;
01550   }
01551 
01552   return 0;
01553 }
01554 
01555 
01556 
01557 int GWENHYWFAR_CB
01558 GWEN_Crypt_TokenFile__Decipher(GWEN_CRYPT_TOKEN *ct,
01559                                uint32_t keyId,
01560                                GWEN_CRYPT_PADDALGO *a,
01561                                const uint8_t *pInData,
01562                                uint32_t inLen,
01563                                uint8_t *pOutData,
01564                                uint32_t *pOutLen,
01565                                uint32_t gid) {
01566   GWEN_CRYPT_TOKEN_FILE *lct;
01567   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01568   GWEN_CRYPT_KEY *k;
01569   int keyNum;
01570   GWEN_BUFFER *tbuf;
01571   int i;
01572   int rv;
01573   uint32_t l;
01574 
01575   assert(ct);
01576   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01577   assert(lct);
01578 
01579   DBG_INFO(GWEN_LOGDOMAIN, "Deciphering with key %d", keyId);
01580 
01581   /* reload if needed */
01582   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01583   if (rv) {
01584     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01585     return rv;
01586   }
01587 
01588   /* get context */
01589   i=(keyId>>16);
01590   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01591   while(ctx) {
01592     if (i==0)
01593       break;
01594     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01595     i--;
01596   }
01597 
01598   if (ctx==NULL) {
01599     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01600     return GWEN_ERROR_NOT_FOUND;
01601   }
01602 
01603   /* get key */
01604   keyNum=keyId & 0xffff;
01605   if (keyNum!=2 && keyNum!=4) {
01606     /* not localCryptKey */
01607     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for decrypting (%x)", keyId);
01608     return GWEN_ERROR_INVALID;
01609   }
01610 
01611   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01612   if (k==NULL) {
01613     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
01614     return GWEN_ERROR_NOT_FOUND;
01615   }
01616 
01617   /* decipher with key */
01618   tbuf=GWEN_Buffer_new(0, inLen+16, 0, 1);
01619   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
01620   rv=GWEN_Crypt_Key_Decipher(k,
01621                              pInData, inLen,
01622                              (uint8_t*)GWEN_Buffer_GetStart(tbuf), &l);
01623   if (rv<0) {
01624     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01625     GWEN_Buffer_free(tbuf);
01626     return rv;
01627   }
01628   GWEN_Buffer_IncrementPos(tbuf, l);
01629   GWEN_Buffer_AdjustUsedBytes(tbuf);
01630 
01631   /* unpadd according to given algo */
01632   rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
01633   if (rv) {
01634     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01635     GWEN_Buffer_free(tbuf);
01636     return rv;
01637   }
01638 
01639   /* copy resulting data to given buffer */
01640   l=GWEN_Buffer_GetUsedBytes(tbuf);
01641   if (l>*pOutLen) {
01642     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01643     GWEN_Buffer_free(tbuf);
01644     return GWEN_ERROR_BUFFER_OVERFLOW;
01645   }
01646   memmove(pOutData, GWEN_Buffer_GetStart(tbuf), l);
01647   *pOutLen=l;
01648   GWEN_Buffer_free(tbuf);
01649 
01650   return 0;
01651 }
01652 
01653 
01654 
01655 int GWENHYWFAR_CB
01656 GWEN_Crypt_TokenFile__GenerateKey(GWEN_CRYPT_TOKEN *ct,
01657                                   uint32_t keyId,
01658                                   const GWEN_CRYPT_CRYPTALGO *a,
01659                                   uint32_t gid) {
01660   GWEN_CRYPT_TOKEN_FILE *lct;
01661   GWEN_CRYPT_KEY *pubKey;
01662   GWEN_CRYPT_KEY *secKey;
01663   int rv;
01664   uint32_t keyNum;
01665   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01666   int i;
01667   uint8_t kbuf[256];
01668   uint32_t klen;
01669   GWEN_CRYPT_TOKEN_KEYINFO *cki;
01670   GWEN_CRYPT_TOKEN_KEYINFO *ki;
01671 
01672   assert(ct);
01673   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01674   assert(lct);
01675 
01676   /* reload if needed */
01677   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01678   if (rv) {
01679     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01680     return rv;
01681   }
01682 
01683   keyNum=keyId & 0xffff;
01684 
01685   /* check key id */
01686   if (keyNum!=1 && keyNum!=2 && keyNum!=5) {
01687     DBG_INFO(GWEN_LOGDOMAIN, "Can only generate local keys.");
01688     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01689                          I18N("Can only generate local keys."));
01690     return GWEN_ERROR_NOT_SUPPORTED;
01691   }
01692 
01693   /* check for algo */
01694   if (GWEN_Crypt_CryptAlgo_GetId(a)!=GWEN_Crypt_CryptAlgoId_Rsa) {
01695     DBG_INFO(GWEN_LOGDOMAIN, "Only RSA keys supported.");
01696     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01697                          I18N("Only RSA keys supported."));
01698     return GWEN_ERROR_NOT_SUPPORTED;
01699   }
01700 
01701   /* get context */
01702   i=(keyId>>16);
01703   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01704   while(ctx) {
01705     if (i==0)
01706       break;
01707     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01708     i--;
01709   }
01710 
01711   /* generate key pair */
01712   rv=GWEN_Crypt_KeyRsa_GeneratePair(GWEN_Crypt_CryptAlgo_GetChunkSize(a),
01713                                     (GWEN_Crypt_Token_GetModes(ct) &
01714                                      GWEN_CRYPT_TOKEN_MODE_EXP_65537)?1:0,
01715                                     &pubKey,
01716                                     &secKey);
01717   if (rv) {
01718     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01719     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01720                          I18N("Could not generate key"));
01721     return rv;
01722   }
01723 
01724   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
01725                        I18N("Key generated"));
01726 
01727   /* set key */
01728   if (keyNum==1)
01729     cki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
01730   else if (keyNum==3)
01731     cki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx);
01732   else
01733       cki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
01734   if (cki==NULL) {
01735     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01736                          I18N("No key info found"));
01737     return GWEN_ERROR_NO_DATA;
01738   }
01739 
01740   /* update key info for the key */
01741   ki=GWEN_Crypt_Token_KeyInfo_dup(cki);
01742   assert(ki);
01743 
01744   /* get modulus */
01745   klen=sizeof(kbuf);
01746   rv=GWEN_Crypt_KeyRsa_GetModulus(pubKey, kbuf, &klen);
01747   if (rv) {
01748     DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
01749     GWEN_Crypt_Token_KeyInfo_free(ki);
01750     GWEN_Crypt_Key_free(pubKey);
01751     return rv;
01752   }
01753   GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
01754 
01755   /* get exponent */
01756   klen=sizeof(kbuf);
01757   rv=GWEN_Crypt_KeyRsa_GetExponent(pubKey, kbuf, &klen);
01758   if (rv) {
01759     DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
01760     GWEN_Crypt_Token_KeyInfo_free(ki);
01761     GWEN_Crypt_Key_free(pubKey);
01762     return rv;
01763   }
01764   GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
01765   GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(pubKey));
01766   GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(pubKey));
01767 
01768   if (keyNum==1) {
01769     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN){
01770       DBG_ERROR(0, "Adding mode \"direct sign\" to key");
01771       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
01772     }
01773     GWEN_CTF_Context_SetLocalSignKey(ctx, secKey);
01774     GWEN_CTF_Context_SetLocalSignKeyInfo(ctx, ki);
01775     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
01776                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
01777                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
01778                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
01779                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
01780                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
01781                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
01782                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
01783                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
01784   }
01785   else if (keyNum==2) {
01786     GWEN_CTF_Context_SetLocalCryptKey(ctx, secKey);
01787     GWEN_CTF_Context_SetLocalCryptKeyInfo(ctx, ki);
01788     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
01789                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
01790                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
01791                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
01792                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
01793                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
01794                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
01795                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
01796                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANDECIPHER);
01797   }
01798   else {
01799     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN){
01800       DBG_ERROR(0, "Adding mode \"direct sign\" to key");
01801       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
01802     }
01803     GWEN_CTF_Context_SetLocalAuthKey(ctx, secKey);
01804     GWEN_CTF_Context_SetLocalAuthKeyInfo(ctx, ki);
01805     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
01806                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
01807                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
01808                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
01809                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
01810                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
01811                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
01812                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
01813                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
01814   }
01815 
01816   /* the public key is not used */
01817   GWEN_Crypt_Key_free(pubKey);
01818 
01819   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
01820   if (rv) {
01821     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
01822     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01823                          I18N("Unable to write key file"));
01824     return rv;
01825   }
01826 
01827   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
01828                        I18N("Key generated and set"));
01829 
01830   return 0;
01831 }
01832 
01833 
01834 
01835 
01836 
01837 
01838 GWENHYWFAR_CB
01839 void GWEN_Crypt_TokenFile_freeData(GWEN_UNUSED void *bp, void *p) {
01840   GWEN_CRYPT_TOKEN_FILE *lct;
01841 
01842   lct=(GWEN_CRYPT_TOKEN_FILE*) p;
01843   GWEN_Crypt_Token_Context_List_free(lct->contextList);
01844 
01845   GWEN_FREE_OBJECT(lct);
01846 }
01847 
01848 
01849 
01850 GWEN_CRYPT_TOKEN *GWEN_Crypt_TokenFile_new(const char *typeName,
01851                                            const char *tokenName) {
01852   GWEN_CRYPT_TOKEN *ct;
01853   GWEN_CRYPT_TOKEN_FILE *lct;
01854 
01855   ct=GWEN_Crypt_Token_new(GWEN_Crypt_Token_Device_File, typeName, tokenName);
01856   assert(ct);
01857 
01858   GWEN_NEW_OBJECT(GWEN_CRYPT_TOKEN_FILE, lct);
01859   lct->contextList=GWEN_Crypt_Token_Context_List_new();
01860   GWEN_INHERIT_SETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct, lct,
01861                        GWEN_Crypt_TokenFile_freeData);
01862   GWEN_Crypt_Token_SetOpenFn(ct, GWEN_Crypt_TokenFile_Open);
01863   GWEN_Crypt_Token_SetCreateFn(ct, GWEN_Crypt_TokenFile_Create);
01864   GWEN_Crypt_Token_SetCloseFn(ct, GWEN_Crypt_TokenFile_Close);
01865   GWEN_Crypt_Token_SetGetKeyIdListFn(ct, GWEN_Crypt_TokenFile__GetKeyIdList);
01866   GWEN_Crypt_Token_SetGetKeyInfoFn(ct, GWEN_Crypt_TokenFile__GetKeyInfo);
01867   GWEN_Crypt_Token_SetSetKeyInfoFn(ct, GWEN_Crypt_TokenFile__SetKeyInfo);
01868   GWEN_Crypt_Token_SetGetContextIdListFn(ct, GWEN_Crypt_TokenFile__GetContextIdList);
01869   GWEN_Crypt_Token_SetGetContextFn(ct, GWEN_Crypt_TokenFile__GetContext);
01870   GWEN_Crypt_Token_SetSetContextFn(ct, GWEN_Crypt_TokenFile__SetContext);
01871   GWEN_Crypt_Token_SetSignFn(ct, GWEN_Crypt_TokenFile__Sign);
01872   GWEN_Crypt_Token_SetVerifyFn(ct, GWEN_Crypt_TokenFile__Verify);
01873   GWEN_Crypt_Token_SetEncipherFn(ct, GWEN_Crypt_TokenFile__Encipher);
01874   GWEN_Crypt_Token_SetDecipherFn(ct, GWEN_Crypt_TokenFile__Decipher);
01875   GWEN_Crypt_Token_SetGenerateKeyFn(ct, GWEN_Crypt_TokenFile__GenerateKey);
01876 
01877   return ct;
01878 }
01879 
01880 
01881 
01882 
01883 

doxygen