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