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   GWEN_CRYPT_PADDALGOID aid;
01194 
01195   assert(ct);
01196   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01197   assert(lct);
01198 
01199   DBG_INFO(GWEN_LOGDOMAIN, "Signing with key %d", keyId);
01200   aid=GWEN_Crypt_PaddAlgo_GetId(a);
01201 
01202   /* reload if needed */
01203   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01204   if (rv) {
01205     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01206     return rv;
01207   }
01208 
01209   /* get context */
01210   i=(keyId>>16);
01211   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01212   if (ctx==NULL) {
01213     DBG_ERROR(GWEN_LOGDOMAIN, "Token has no context");
01214     return GWEN_ERROR_NOT_FOUND;
01215   }
01216   while(ctx) {
01217     if (i==0)
01218       break;
01219     DBG_ERROR(GWEN_LOGDOMAIN, "Checking token %d (i==%d)",
01220               GWEN_Crypt_Token_Context_GetId(ctx), i);
01221     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01222     i--;
01223   }
01224 
01225   if (ctx==NULL) {
01226     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01227     return GWEN_ERROR_NOT_FOUND;
01228   }
01229 
01230   /* get key */
01231   keyNum=keyId & 0xffff;
01232   if (keyNum!=1 && keyNum!=5) {
01233     /* neither localSignKey nor localAuthKey */
01234     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for signing (%x)", keyId);
01235     return GWEN_ERROR_INVALID;
01236   }
01237 
01238   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01239   if (k==NULL) {
01240     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
01241     return GWEN_ERROR_NOT_FOUND;
01242   }
01243 
01244   /* copy to a buffer for padding */
01245   srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
01246 
01247   if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
01248     const GWEN_CRYPT_TOKEN_KEYINFO *ki;
01249     int nbits;
01250     const uint8_t *modPtr;
01251     uint32_t modLen;
01252     GWEN_MDIGEST *md;
01253 
01254     switch(keyId & 0xffff) {
01255     case 1:  ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
01256     case 5:  ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
01257     default: ki=NULL;
01258     }
01259 
01260     if (ki==NULL) {
01261       DBG_ERROR(GWEN_LOGDOMAIN, "No information for key %d", keyNum);
01262       GWEN_Buffer_free(srcBuf);
01263       return GWEN_ERROR_GENERIC;
01264     }
01265 
01266     /* calculate real number of bits */
01267     modPtr=GWEN_Crypt_Token_KeyInfo_GetModulusData(ki);
01268     modLen=GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki);
01269     nbits=modLen*8;
01270     while(modLen && *modPtr==0) {
01271       nbits-=8;
01272       modLen--;
01273       modPtr++;
01274     }
01275     if (modLen) {
01276       uint8_t b=*modPtr;
01277       int i;
01278       uint8_t mask=0x80;
01279 
01280       for (i=0; i<8; i++) {
01281         if (b & mask)
01282           break;
01283         nbits--;
01284         mask>>=1;
01285       }
01286     }
01287 
01288     if (nbits==0) {
01289       DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
01290       GWEN_Buffer_free(srcBuf);
01291       return GWEN_ERROR_GENERIC;
01292     }
01293 
01294     md=GWEN_MDigest_Sha256_new();
01295     GWEN_Buffer_AllocRoom(srcBuf, modLen);
01296 
01297     rv=GWEN_Padd_AddPkcs1Pss((uint8_t*) GWEN_Buffer_GetStart(srcBuf),
01298                              GWEN_Buffer_GetMaxUnsegmentedWrite(srcBuf),
01299                              nbits,
01300                              pInData, inLen,
01301                              inLen,
01302                              md);
01303     GWEN_MDigest_free(md);
01304     if (rv<0) {
01305       DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
01306       GWEN_Buffer_free(srcBuf);
01307       return rv;
01308     }
01309 
01310     GWEN_Buffer_IncrementPos(srcBuf, rv);
01311     GWEN_Buffer_AdjustUsedBytes(srcBuf);
01312   }
01313   else {
01314     GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
01315 
01316     /* padd according to given algo */
01317     rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
01318     if (rv) {
01319       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01320       GWEN_Buffer_free(srcBuf);
01321       return rv;
01322     }
01323   }
01324 
01325   /* sign with key */
01326   rv=GWEN_Crypt_Key_Sign(k,
01327                          (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
01328                          GWEN_Buffer_GetUsedBytes(srcBuf),
01329                          pSignatureData,
01330                          pSignatureLen);
01331   GWEN_Buffer_free(srcBuf);
01332   if (rv) {
01333     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01334     return rv;
01335   }
01336 
01337   if (pSeqCounter) {
01338     GWEN_CRYPT_TOKEN_KEYINFO *ki;
01339 
01340     /* signature sequence counter is to be incremented */
01341     switch(keyId & 0xffff) {
01342     case 1:  ki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx); break;
01343     case 5:  ki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx); break;
01344     default: ki=NULL;
01345     }
01346     if (ki &&
01347         (GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER)) {
01348       unsigned int seq;
01349 
01350       seq=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki);
01351       *pSeqCounter=seq;
01352       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, ++seq);
01353 
01354       rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
01355       if (rv) {
01356         DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
01357         return rv;
01358       }
01359     }
01360     else {
01361       DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
01362       *pSeqCounter=0;
01363     }
01364   }
01365 
01366   return 0;
01367 }
01368 
01369 
01370 
01371 int GWENHYWFAR_CB
01372 GWEN_Crypt_TokenFile__Verify(GWEN_CRYPT_TOKEN *ct,
01373                              uint32_t keyId,
01374                              GWEN_CRYPT_PADDALGO *a,
01375                              const uint8_t *pInData,
01376                              uint32_t inLen,
01377                              const uint8_t *pSignatureData,
01378                              uint32_t signatureLen,
01379                              uint32_t seqCounter,
01380                              uint32_t gid) {
01381   GWEN_CRYPT_TOKEN_FILE *lct;
01382   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01383   GWEN_CRYPT_KEY *k;
01384   int keyNum;
01385   int i;
01386   int rv;
01387   GWEN_CRYPT_PADDALGOID aid;
01388 
01389   assert(ct);
01390   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01391   assert(lct);
01392 
01393   DBG_INFO(GWEN_LOGDOMAIN, "Verifying with key %d", keyId);
01394 
01395   aid=GWEN_Crypt_PaddAlgo_GetId(a);
01396 
01397   /* reload if needed */
01398   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01399   if (rv) {
01400     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01401     return rv;
01402   }
01403 
01404   /* get context */
01405   i=(keyId>>16);
01406   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01407   while(ctx) {
01408     if (i==0)
01409       break;
01410     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01411     i--;
01412   }
01413 
01414   if (ctx==NULL) {
01415     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01416     return GWEN_ERROR_NOT_FOUND;
01417   }
01418 
01419   /* get key */
01420   keyNum=keyId & 0xffff;
01421   if (keyNum!=1 && keyNum!=3 && keyNum!=6) {
01422     /* neither remoteSignKey nor remoteAuthKey */
01423     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for verifying (%x)", keyId);
01424     return GWEN_ERROR_INVALID;
01425   }
01426 
01427   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01428   if (k==NULL) {
01429     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
01430     return GWEN_ERROR_NO_KEY;
01431   }
01432 
01433   if (aid==GWEN_Crypt_PaddAlgoId_Iso9796_2 ||
01434            aid==GWEN_Crypt_PaddAlgoId_Pkcs1_2 ||
01435            aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
01436     GWEN_BUFFER *tbuf;
01437     uint32_t l;
01438 
01439     /* these algos add random numbers, we must use encrypt fn here and
01440      * compare the decrypted and unpadded data with the source data */
01441     tbuf=GWEN_Buffer_new(0, signatureLen+16, 0, 0);
01442     l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
01443     rv=GWEN_Crypt_Key_Encipher(k,
01444                                pSignatureData, signatureLen,
01445                                (uint8_t*)GWEN_Buffer_GetStart(tbuf),
01446                                &l);
01447     if (rv<0) {
01448       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01449       GWEN_Buffer_free(tbuf);
01450       return rv;
01451     }
01452     GWEN_Buffer_IncrementPos(tbuf, l);
01453     GWEN_Buffer_AdjustUsedBytes(tbuf);
01454 
01455     if (aid==GWEN_Crypt_PaddAlgoId_Pkcs1_Pss_Sha256) {
01456       const GWEN_CRYPT_TOKEN_KEYINFO *ki;
01457       int nbits;
01458       const uint8_t *modPtr;
01459       uint32_t modLen;
01460       GWEN_MDIGEST *md;
01461 
01462       if (keyNum==3)
01463         ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
01464       else
01465         ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
01466       if (ki==NULL) {
01467         DBG_ERROR(GWEN_LOGDOMAIN, "No information for key %d", keyNum);
01468         GWEN_Buffer_free(tbuf);
01469         return GWEN_ERROR_GENERIC;
01470       }
01471 
01472       /* calculate real number of bits */
01473       modPtr=GWEN_Crypt_Token_KeyInfo_GetModulusData(ki);
01474       modLen=GWEN_Crypt_Token_KeyInfo_GetModulusLen(ki);
01475       nbits=modLen*8;
01476       while(modLen && *modPtr==0) {
01477         nbits-=8;
01478         modLen--;
01479         modPtr++;
01480       }
01481       if (modLen) {
01482         uint8_t b=*modPtr;
01483         int i;
01484         uint8_t mask=0x80;
01485 
01486         for (i=0; i<8; i++) {
01487           if (b & mask)
01488             break;
01489           nbits--;
01490           mask>>=1;
01491         }
01492       }
01493 
01494       if (nbits==0) {
01495         DBG_ERROR(GWEN_LOGDOMAIN, "Empty modulus");
01496         GWEN_Buffer_free(tbuf);
01497         return GWEN_ERROR_GENERIC;
01498       }
01499 
01500       md=GWEN_MDigest_Sha256_new();
01501       rv=GWEN_Padd_VerifyPkcs1Pss((const uint8_t*) GWEN_Buffer_GetStart(tbuf),
01502                                   GWEN_Buffer_GetUsedBytes(tbuf),
01503                                   nbits,
01504                                   pInData, inLen,
01505                                   inLen,
01506                                   md);
01507       GWEN_MDigest_free(md);
01508       if (rv<0) {
01509         DBG_ERROR(GWEN_LOGDOMAIN, "here (%d)", rv);
01510         return rv;
01511       }
01512     }
01513     else {
01514       rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
01515       if (rv<0) {
01516         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01517         GWEN_Buffer_free(tbuf);
01518         return rv;
01519       }
01520       l=GWEN_Buffer_GetUsedBytes(tbuf);
01521 
01522       if (l!=inLen) {
01523         DBG_ERROR(GWEN_LOGDOMAIN, "Signature length doesn't match");
01524         GWEN_Buffer_free(tbuf);
01525         return GWEN_ERROR_VERIFY;
01526       }
01527       if (memcmp(pInData, GWEN_Buffer_GetStart(tbuf), l)!=0) {
01528         DBG_ERROR(GWEN_LOGDOMAIN, "Signature doesn't match:");
01529         GWEN_Buffer_free(tbuf);
01530         return GWEN_ERROR_VERIFY;
01531       }
01532     }
01533   }
01534   else {
01535     GWEN_BUFFER *srcBuf;
01536 
01537     /* copy to a buffer for padding */
01538     srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
01539     GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
01540 
01541     /* padd according to given algo */
01542     rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
01543     if (rv) {
01544       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01545       GWEN_Buffer_free(srcBuf);
01546       return rv;
01547     }
01548 
01549     /* verify with key */
01550     rv=GWEN_Crypt_Key_Verify(k,
01551                              (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
01552                              GWEN_Buffer_GetUsedBytes(srcBuf),
01553                              pSignatureData,
01554                              signatureLen);
01555     GWEN_Buffer_free(srcBuf);
01556     if (rv) {
01557       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01558       return rv;
01559     }
01560   }
01561 
01562   if (seqCounter) {
01563     GWEN_CRYPT_TOKEN_KEYINFO *ki;
01564 
01565     /* signature sequence counter is to be checked */
01566     if (keyNum==3)
01567       ki=GWEN_CTF_Context_GetRemoteSignKeyInfo(ctx);
01568     else
01569       ki=GWEN_CTF_Context_GetRemoteAuthKeyInfo(ctx);
01570     if (ki &&
01571         (GWEN_Crypt_Token_KeyInfo_GetFlags(ki) & GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER)) {
01572       unsigned int seq;
01573 
01574       seq=GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki);
01575 
01576       if (seq>=seqCounter) {
01577         DBG_WARN(GWEN_LOGDOMAIN, "Bad remote sequence counter (possibly replay attack!)");
01578         return GWEN_ERROR_VERIFY;
01579       }
01580       GWEN_Crypt_Token_KeyInfo_SetSignCounter(ki, seqCounter);
01581 
01582       /* write file */
01583       rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
01584       if (rv) {
01585         DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
01586         return rv;
01587       }
01588     }
01589     else {
01590       DBG_WARN(GWEN_LOGDOMAIN, "No sign counter for key %04x", keyId);
01591     }
01592 
01593   }
01594 
01595   return 0;
01596 }
01597 
01598 
01599 
01600 int GWENHYWFAR_CB
01601 GWEN_Crypt_TokenFile__Encipher(GWEN_CRYPT_TOKEN *ct,
01602                                uint32_t keyId,
01603                                GWEN_CRYPT_PADDALGO *a,
01604                                const uint8_t *pInData,
01605                                uint32_t inLen,
01606                                uint8_t *pOutData,
01607                                uint32_t *pOutLen,
01608                                uint32_t gid) {
01609   GWEN_CRYPT_TOKEN_FILE *lct;
01610   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01611   GWEN_CRYPT_KEY *k;
01612   int keyNum;
01613   GWEN_BUFFER *srcBuf;
01614   int i;
01615   int rv;
01616 
01617   assert(ct);
01618   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01619   assert(lct);
01620 
01621   DBG_INFO(GWEN_LOGDOMAIN, "Enciphering with key %d", keyId);
01622 
01623   /* reload if needed */
01624   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01625   if (rv) {
01626     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01627     return rv;
01628   }
01629 
01630   /* get context */
01631   i=(keyId>>16);
01632   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01633   while(ctx) {
01634     if (i==0)
01635       break;
01636     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01637     i--;
01638   }
01639 
01640   if (ctx==NULL) {
01641     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01642     return GWEN_ERROR_NOT_FOUND;
01643   }
01644 
01645   /* get key */
01646   keyNum=keyId & 0xffff;
01647   if (keyNum!=2 && keyNum!=4) {
01648     /* not remoteCryptKey */
01649     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for encrypting (%x)", keyId);
01650     return GWEN_ERROR_INVALID;
01651   }
01652 
01653   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01654   if (k==NULL) {
01655     DBG_INFO(GWEN_LOGDOMAIN, "Key %d not found", keyId);
01656     return GWEN_ERROR_NOT_FOUND;
01657   }
01658 
01659   /* copy to a buffer for padding */
01660   srcBuf=GWEN_Buffer_new(0, inLen, 0, 0);
01661   GWEN_Buffer_AppendBytes(srcBuf, (const char*)pInData, inLen);
01662   GWEN_Buffer_Rewind(srcBuf);
01663 
01664   /* padd according to given algo */
01665   rv=GWEN_Padd_ApplyPaddAlgo(a, srcBuf);
01666   if (rv) {
01667     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01668     GWEN_Buffer_free(srcBuf);
01669     return rv;
01670   }
01671 
01672   /* encipher with key */
01673   rv=GWEN_Crypt_Key_Encipher(k,
01674                              (const uint8_t*)GWEN_Buffer_GetStart(srcBuf),
01675                              GWEN_Buffer_GetUsedBytes(srcBuf),
01676                              pOutData,
01677                              pOutLen);
01678   GWEN_Buffer_free(srcBuf);
01679   if (rv) {
01680     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01681     return rv;
01682   }
01683 
01684   return 0;
01685 }
01686 
01687 
01688 
01689 int GWENHYWFAR_CB
01690 GWEN_Crypt_TokenFile__Decipher(GWEN_CRYPT_TOKEN *ct,
01691                                uint32_t keyId,
01692                                GWEN_CRYPT_PADDALGO *a,
01693                                const uint8_t *pInData,
01694                                uint32_t inLen,
01695                                uint8_t *pOutData,
01696                                uint32_t *pOutLen,
01697                                uint32_t gid) {
01698   GWEN_CRYPT_TOKEN_FILE *lct;
01699   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01700   GWEN_CRYPT_KEY *k;
01701   int keyNum;
01702   GWEN_BUFFER *tbuf;
01703   int i;
01704   int rv;
01705   uint32_t l;
01706 
01707   assert(ct);
01708   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01709   assert(lct);
01710 
01711   DBG_INFO(GWEN_LOGDOMAIN, "Deciphering with key %d", keyId);
01712 
01713   /* reload if needed */
01714   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01715   if (rv) {
01716     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01717     return rv;
01718   }
01719 
01720   /* get context */
01721   i=(keyId>>16);
01722   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01723   while(ctx) {
01724     if (i==0)
01725       break;
01726     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01727     i--;
01728   }
01729 
01730   if (ctx==NULL) {
01731     DBG_INFO(GWEN_LOGDOMAIN, "No context by id [%x] known", (keyId>>16) & 0xffff);
01732     return GWEN_ERROR_NOT_FOUND;
01733   }
01734 
01735   /* get key */
01736   keyNum=keyId & 0xffff;
01737   if (keyNum!=2 && keyNum!=4) {
01738     /* not localCryptKey */
01739     DBG_INFO(GWEN_LOGDOMAIN, "Bad key for decrypting (%x)", keyId);
01740     return GWEN_ERROR_INVALID;
01741   }
01742 
01743   k=GWEN_Crypt_TokenFile__GetKey(ct, keyId, gid);
01744   if (k==NULL) {
01745     DBG_INFO(GWEN_LOGDOMAIN, "Key not found");
01746     return GWEN_ERROR_NOT_FOUND;
01747   }
01748 
01749   /* decipher with key */
01750   tbuf=GWEN_Buffer_new(0, inLen+16, 0, 1);
01751   l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
01752   rv=GWEN_Crypt_Key_Decipher(k,
01753                              pInData, inLen,
01754                              (uint8_t*)GWEN_Buffer_GetStart(tbuf), &l);
01755   if (rv<0) {
01756     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01757     GWEN_Buffer_free(tbuf);
01758     return rv;
01759   }
01760   GWEN_Buffer_IncrementPos(tbuf, l);
01761   GWEN_Buffer_AdjustUsedBytes(tbuf);
01762 
01763   /* unpadd according to given algo */
01764   rv=GWEN_Padd_UnapplyPaddAlgo(a, tbuf);
01765   if (rv) {
01766     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01767     GWEN_Buffer_free(tbuf);
01768     return rv;
01769   }
01770 
01771   /* copy resulting data to given buffer */
01772   l=GWEN_Buffer_GetUsedBytes(tbuf);
01773   if (l>*pOutLen) {
01774     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01775     GWEN_Buffer_free(tbuf);
01776     return GWEN_ERROR_BUFFER_OVERFLOW;
01777   }
01778   memmove(pOutData, GWEN_Buffer_GetStart(tbuf), l);
01779   *pOutLen=l;
01780   GWEN_Buffer_free(tbuf);
01781 
01782   return 0;
01783 }
01784 
01785 
01786 
01787 int GWENHYWFAR_CB
01788 GWEN_Crypt_TokenFile__GenerateKey(GWEN_CRYPT_TOKEN *ct,
01789                                   uint32_t keyId,
01790                                   const GWEN_CRYPT_CRYPTALGO *a,
01791                                   uint32_t gid) {
01792   GWEN_CRYPT_TOKEN_FILE *lct;
01793   GWEN_CRYPT_KEY *pubKey;
01794   GWEN_CRYPT_KEY *secKey;
01795   int rv;
01796   uint32_t keyNum;
01797   GWEN_CRYPT_TOKEN_CONTEXT *ctx;
01798   int i;
01799   uint8_t kbuf[256];
01800   uint32_t klen;
01801   GWEN_CRYPT_TOKEN_KEYINFO *cki;
01802   GWEN_CRYPT_TOKEN_KEYINFO *ki;
01803   int sizeInBits;
01804 
01805   assert(ct);
01806   lct=GWEN_INHERIT_GETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct);
01807   assert(lct);
01808 
01809   /* reload if needed */
01810   rv=GWEN_Crypt_TokenFile__ReloadIfNeeded(ct, gid);
01811   if (rv) {
01812     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01813     return rv;
01814   }
01815 
01816   keyNum=keyId & 0xffff;
01817 
01818   /* check key id */
01819   if (keyNum!=1 && keyNum!=2 && keyNum!=5) {
01820     DBG_INFO(GWEN_LOGDOMAIN, "Can only generate local keys.");
01821     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01822                          I18N("Can only generate local keys."));
01823     return GWEN_ERROR_NOT_SUPPORTED;
01824   }
01825 
01826   /* check for algo */
01827   if (GWEN_Crypt_CryptAlgo_GetId(a)!=GWEN_Crypt_CryptAlgoId_Rsa) {
01828     DBG_INFO(GWEN_LOGDOMAIN, "Only RSA keys supported.");
01829     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01830                          I18N("Only RSA keys supported."));
01831     return GWEN_ERROR_NOT_SUPPORTED;
01832   }
01833 
01834   /* get context */
01835   i=(keyId>>16);
01836   ctx=GWEN_Crypt_Token_Context_List_First(lct->contextList);
01837   while(ctx) {
01838     if (i==0)
01839       break;
01840     ctx=GWEN_Crypt_Token_Context_List_Next(ctx);
01841     i--;
01842   }
01843 
01844   sizeInBits=GWEN_Crypt_CryptAlgo_GetKeySizeInBits(a);
01845   if (sizeInBits>0) {
01846     /* generate key pair with precise number of bits */
01847     DBG_DEBUG(GWEN_LOGDOMAIN, "Creating key pair using %d bits", sizeInBits);
01848     rv=GWEN_Crypt_KeyRsa_GeneratePair2(sizeInBits,
01849                                        (GWEN_Crypt_Token_GetModes(ct) &
01850                                         GWEN_CRYPT_TOKEN_MODE_EXP_65537)?1:0,
01851                                        &pubKey,
01852                                        &secKey);
01853   }
01854   else {
01855     /* generate key pair the old way, just using the chunksize */
01856     DBG_INFO(GWEN_LOGDOMAIN, "Creating key pair using %d bytes", GWEN_Crypt_CryptAlgo_GetChunkSize(a));
01857     rv=GWEN_Crypt_KeyRsa_GeneratePair(GWEN_Crypt_CryptAlgo_GetChunkSize(a),
01858                                       (GWEN_Crypt_Token_GetModes(ct) &
01859                                        GWEN_CRYPT_TOKEN_MODE_EXP_65537)?1:0,
01860                                       &pubKey,
01861                                       &secKey);
01862   }
01863   if (rv) {
01864     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01865     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01866                          I18N("Could not generate key"));
01867     return rv;
01868   }
01869 
01870   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
01871                        I18N("Key generated"));
01872 
01873   /* set key */
01874   if (keyNum==1)
01875     cki=GWEN_CTF_Context_GetLocalSignKeyInfo(ctx);
01876   else if (keyNum==3)
01877     cki=GWEN_CTF_Context_GetLocalCryptKeyInfo(ctx);
01878   else
01879       cki=GWEN_CTF_Context_GetLocalAuthKeyInfo(ctx);
01880   if (cki==NULL) {
01881     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01882                          I18N("No key info found"));
01883     return GWEN_ERROR_NO_DATA;
01884   }
01885 
01886   /* update key info for the key */
01887   ki=GWEN_Crypt_Token_KeyInfo_dup(cki);
01888   assert(ki);
01889 
01890   /* get modulus */
01891   klen=sizeof(kbuf);
01892   rv=GWEN_Crypt_KeyRsa_GetModulus(pubKey, kbuf, &klen);
01893   if (rv) {
01894     DBG_INFO(GWEN_LOGDOMAIN, "No modulus for key");
01895     GWEN_Crypt_Token_KeyInfo_free(ki);
01896     GWEN_Crypt_Key_free(pubKey);
01897     return rv;
01898   }
01899   GWEN_Crypt_Token_KeyInfo_SetModulus(ki, kbuf, klen);
01900 
01901   /* get exponent */
01902   klen=sizeof(kbuf);
01903   rv=GWEN_Crypt_KeyRsa_GetExponent(pubKey, kbuf, &klen);
01904   if (rv) {
01905     DBG_INFO(GWEN_LOGDOMAIN, "No exponent for key");
01906     GWEN_Crypt_Token_KeyInfo_free(ki);
01907     GWEN_Crypt_Key_free(pubKey);
01908     return rv;
01909   }
01910   GWEN_Crypt_Token_KeyInfo_SetExponent(ki, kbuf, klen);
01911   GWEN_Crypt_Token_KeyInfo_SetKeyNumber(ki, GWEN_Crypt_Key_GetKeyNumber(pubKey));
01912   GWEN_Crypt_Token_KeyInfo_SetKeyVersion(ki, GWEN_Crypt_Key_GetKeyVersion(pubKey));
01913 
01914   if (keyNum==1) {
01915     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN){
01916       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
01917       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
01918     }
01919     GWEN_CTF_Context_SetLocalSignKey(ctx, secKey);
01920     GWEN_CTF_Context_SetLocalSignKeyInfo(ctx, ki);
01921     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
01922                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
01923                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
01924                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
01925                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
01926                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
01927                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
01928                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
01929                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
01930   }
01931   else if (keyNum==2) {
01932     GWEN_CTF_Context_SetLocalCryptKey(ctx, secKey);
01933     GWEN_CTF_Context_SetLocalCryptKeyInfo(ctx, ki);
01934     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
01935                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
01936                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
01937                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
01938                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
01939                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
01940                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
01941                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANENCIPHER |
01942                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANDECIPHER);
01943   }
01944   else {
01945     if (GWEN_Crypt_Token_GetModes(ct) & GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN){
01946       DBG_DEBUG(GWEN_LOGDOMAIN, "Adding mode \"direct sign\" to key");
01947       GWEN_Crypt_KeyRsa_AddFlags(secKey, GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN);
01948     }
01949     GWEN_CTF_Context_SetLocalAuthKey(ctx, secKey);
01950     GWEN_CTF_Context_SetLocalAuthKeyInfo(ctx, ki);
01951     GWEN_Crypt_Token_KeyInfo_AddFlags(ki,
01952                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
01953                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
01954                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER |
01955                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
01956                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASSIGNCOUNTER |
01957                                       GWEN_CRYPT_TOKEN_KEYFLAGS_HASACTIONFLAGS |
01958                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANVERIFY |
01959                                       GWEN_CRYPT_TOKEN_KEYFLAGS_CANSIGN);
01960   }
01961 
01962   /* the public key is not used */
01963   GWEN_Crypt_Key_free(pubKey);
01964 
01965   rv=GWEN_Crypt_TokenFile__WriteFile(ct, 0, gid);
01966   if (rv) {
01967     DBG_INFO(GWEN_LOGDOMAIN, "Unable to write file");
01968     GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error,
01969                          I18N("Unable to write key file"));
01970     return rv;
01971   }
01972 
01973   GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Notice,
01974                        I18N("Key generated and set"));
01975 
01976   return 0;
01977 }
01978 
01979 
01980 
01981 
01982 
01983 
01984 GWENHYWFAR_CB
01985 void GWEN_Crypt_TokenFile_freeData(GWEN_UNUSED void *bp, void *p) {
01986   GWEN_CRYPT_TOKEN_FILE *lct;
01987 
01988   lct=(GWEN_CRYPT_TOKEN_FILE*) p;
01989   GWEN_Crypt_Token_Context_List_free(lct->contextList);
01990 
01991   GWEN_FREE_OBJECT(lct);
01992 }
01993 
01994 
01995 
01996 GWEN_CRYPT_TOKEN *GWEN_Crypt_TokenFile_new(const char *typeName,
01997                                            const char *tokenName) {
01998   GWEN_CRYPT_TOKEN *ct;
01999   GWEN_CRYPT_TOKEN_FILE *lct;
02000 
02001   ct=GWEN_Crypt_Token_new(GWEN_Crypt_Token_Device_File, typeName, tokenName);
02002   assert(ct);
02003 
02004   GWEN_NEW_OBJECT(GWEN_CRYPT_TOKEN_FILE, lct);
02005   lct->contextList=GWEN_Crypt_Token_Context_List_new();
02006   GWEN_INHERIT_SETDATA(GWEN_CRYPT_TOKEN, GWEN_CRYPT_TOKEN_FILE, ct, lct,
02007                        GWEN_Crypt_TokenFile_freeData);
02008   GWEN_Crypt_Token_SetOpenFn(ct, GWEN_Crypt_TokenFile_Open);
02009   GWEN_Crypt_Token_SetCreateFn(ct, GWEN_Crypt_TokenFile_Create);
02010   GWEN_Crypt_Token_SetCloseFn(ct, GWEN_Crypt_TokenFile_Close);
02011   GWEN_Crypt_Token_SetGetKeyIdListFn(ct, GWEN_Crypt_TokenFile__GetKeyIdList);
02012   GWEN_Crypt_Token_SetGetKeyInfoFn(ct, GWEN_Crypt_TokenFile__GetKeyInfo);
02013   GWEN_Crypt_Token_SetSetKeyInfoFn(ct, GWEN_Crypt_TokenFile__SetKeyInfo);
02014   GWEN_Crypt_Token_SetGetContextIdListFn(ct, GWEN_Crypt_TokenFile__GetContextIdList);
02015   GWEN_Crypt_Token_SetGetContextFn(ct, GWEN_Crypt_TokenFile__GetContext);
02016   GWEN_Crypt_Token_SetSetContextFn(ct, GWEN_Crypt_TokenFile__SetContext);
02017   GWEN_Crypt_Token_SetSignFn(ct, GWEN_Crypt_TokenFile__Sign);
02018   GWEN_Crypt_Token_SetVerifyFn(ct, GWEN_Crypt_TokenFile__Verify);
02019   GWEN_Crypt_Token_SetEncipherFn(ct, GWEN_Crypt_TokenFile__Encipher);
02020   GWEN_Crypt_Token_SetDecipherFn(ct, GWEN_Crypt_TokenFile__Decipher);
02021   GWEN_Crypt_Token_SetGenerateKeyFn(ct, GWEN_Crypt_TokenFile__GenerateKey);
02022 
02023   return ct;
02024 }
02025 
02026 
02027 
02028 
02029 

Generated on Thu Aug 20 13:54:37 2009 for gwenhywfar by  doxygen 1.5.9