cryptkeyrsa.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 "cryptkeyrsa_p.h"
00019 #include <gwenhywfar/misc.h>
00020 #include <gwenhywfar/debug.h>
00021 #include <gwenhywfar/text.h>
00022 
00023 
00024 
00025 
00026 GWEN_INHERIT(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA)
00027 
00028 
00029 
00030 
00031 #if 0
00032 static void dumpKeyData(gcry_ac_data_t data) {
00033   int i;
00034   unsigned int l;
00035 
00036   l=gcry_ac_data_length(data);
00037   for (i=0; i<l; i++) {
00038     const char *dname;
00039     gcry_mpi_t mpi;
00040     gcry_error_t err;
00041     unsigned char *buf;
00042     size_t nbytes;
00043 
00044     gcry_ac_data_get_index(data, 0, i, &dname, &mpi);
00045     fprintf(stderr, "%3d: [%s]\n", i, dname);
00046 
00047     /* write mpi as bin into a buffer which will be allocates by this function */
00048     err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
00049     if (err) {
00050       DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(): %d", err);
00051     }
00052     else {
00053       GWEN_Text_DumpString((const char*)buf, nbytes, stderr, 6);
00054       gcry_free(buf);
00055     }
00056   }
00057 }
00058 #endif
00059 
00060 
00061 
00062 
00063 int GWEN_Crypt_KeyRsa_Sign(GWEN_CRYPT_KEY *k,
00064                            const uint8_t *pInData,
00065                            uint32_t inLen,
00066                            uint8_t *pSignatureData,
00067                            uint32_t *pSignatureLen) {
00068   GWEN_CRYPT_KEY_RSA *xk;
00069   gcry_error_t err;
00070   size_t nscanned;
00071   gcry_ac_data_t dsKey;
00072   gcry_mpi_t mpi_d;
00073   gcry_mpi_t mpi_n;
00074   gcry_mpi_t mpi_in;
00075   gcry_mpi_t mpi_sigout1;
00076   gcry_mpi_t mpi_sigout2=NULL;
00077   size_t nwritten;
00078 
00079   assert(k);
00080   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00081   assert(xk);
00082 
00083   dsKey=gcry_ac_key_data_get(xk->key);
00084 
00085   /* get modulus */
00086   err=gcry_ac_data_get_name(dsKey, 0, "n", &mpi_n);
00087   if (err) {
00088     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00089              gcry_strerror(err));
00090     return GWEN_ERROR_BAD_DATA;
00091   }
00092 
00093   /* get private exponent */
00094   err=gcry_ac_data_get_name(dsKey, 0, "d", &mpi_d);
00095   if (err) {
00096     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00097              gcry_strerror(err));
00098     return GWEN_ERROR_BAD_DATA;
00099   }
00100 
00101   /* convert input to MPI */
00102   mpi_in=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00103   err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
00104   if (err) {
00105     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
00106     gcry_mpi_release(mpi_in);
00107     return GWEN_ERROR_BAD_DATA;
00108   }
00109 
00110   /* create first signature */
00111   mpi_sigout1=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00112   gcry_mpi_powm(mpi_sigout1, mpi_in, mpi_d, mpi_n);
00113 
00114   if (!(xk->flags & GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN)) {
00115     /* create second signature */
00116     mpi_sigout2=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00117     gcry_mpi_sub(mpi_sigout2, mpi_n, mpi_sigout1);
00118 
00119     if (gcry_mpi_cmp(mpi_sigout2, mpi_sigout1)<0) {
00120       DBG_ERROR(GWEN_LOGDOMAIN, "Choosing 2nd variant");
00121       gcry_mpi_set(mpi_sigout1, mpi_sigout2);
00122     }
00123   }
00124 
00125   /* release unneeded objects */
00126   gcry_mpi_release(mpi_sigout2);
00127   gcry_mpi_release(mpi_in);
00128 
00129   /* convert signature MPI */
00130   err=gcry_mpi_print(GCRYMPI_FMT_USG,
00131                      pSignatureData, *pSignatureLen,
00132                      &nwritten, mpi_sigout1);
00133   gcry_mpi_release(mpi_sigout1);
00134   if (err) {
00135     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
00136     return GWEN_ERROR_BAD_DATA;
00137   }
00138   *pSignatureLen=nwritten;
00139 
00140   return 0;
00141 }
00142 
00143 
00144 
00145 int GWEN_Crypt_KeyRsa_Verify(GWEN_CRYPT_KEY *k,
00146                              const uint8_t *pInData,
00147                              uint32_t inLen,
00148                              const uint8_t *pSignatureData,
00149                              uint32_t signatureLen) {
00150   GWEN_CRYPT_KEY_RSA *xk;
00151   gcry_error_t err;
00152   size_t nscanned;
00153   gcry_ac_data_t dsKey;
00154   gcry_mpi_t mpi_e;
00155   gcry_mpi_t mpi_n;
00156   gcry_mpi_t mpi_in;
00157   gcry_mpi_t mpi_sigin1;
00158   gcry_mpi_t mpi_sigout;
00159 
00160   assert(k);
00161   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00162   assert(xk);
00163 
00164   dsKey=gcry_ac_key_data_get(xk->key);
00165 
00166   /* get modulus */
00167   err=gcry_ac_data_get_name(dsKey, 0, "n", &mpi_n);
00168   if (err) {
00169     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00170              gcry_strerror(err));
00171     return GWEN_ERROR_BAD_DATA;
00172   }
00173 
00174   /* get public exponent */
00175   err=gcry_ac_data_get_name(dsKey, 0, "e", &mpi_e);
00176   if (err) {
00177     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00178              gcry_strerror(err));
00179     return GWEN_ERROR_BAD_DATA;
00180   }
00181 
00182   /* convert input to MPI */
00183   mpi_in=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00184   err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
00185   if (err) {
00186     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
00187     gcry_mpi_release(mpi_in);
00188     return GWEN_ERROR_BAD_DATA;
00189   }
00190 
00191   /* convert signature to MPI */
00192   mpi_sigin1=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00193   err=gcry_mpi_scan(&mpi_sigin1, GCRYMPI_FMT_USG,
00194                     pSignatureData, signatureLen,
00195                     &nscanned);
00196   if (err) {
00197     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
00198     gcry_mpi_release(mpi_sigin1);
00199     gcry_mpi_release(mpi_in);
00200     return GWEN_ERROR_BAD_DATA;
00201   }
00202 
00203   /* create signature */
00204   mpi_sigout=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00205   gcry_mpi_powm(mpi_sigout, mpi_sigin1, mpi_e, mpi_n);
00206   /* compare */
00207   if (gcry_mpi_cmp(mpi_sigout, mpi_in)) {
00208     gcry_mpi_t mpi_sigin2;
00209 
00210     mpi_sigin2=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00211 
00212     DBG_ERROR(GWEN_LOGDOMAIN, "Trying 2nd variant");
00213     gcry_mpi_sub(mpi_sigin2, mpi_n, mpi_sigin1);
00214     gcry_mpi_powm(mpi_sigout, mpi_sigin2, mpi_e, mpi_n);
00215     if (gcry_mpi_cmp(mpi_sigout, mpi_in)) {
00216       DBG_ERROR(GWEN_LOGDOMAIN, "Bad signature");
00217       gcry_mpi_release(mpi_sigin2);
00218       gcry_mpi_release(mpi_sigout);
00219       gcry_mpi_release(mpi_sigin1);
00220       gcry_mpi_release(mpi_in);
00221       return GWEN_ERROR_VERIFY;
00222     }
00223     gcry_mpi_release(mpi_sigin2);
00224   }
00225 
00226   gcry_mpi_release(mpi_sigout);
00227   gcry_mpi_release(mpi_sigin1);
00228   gcry_mpi_release(mpi_in);
00229 
00230   return 0;
00231 }
00232 
00233 
00234 
00235 int GWEN_Crypt_KeyRsa_Encipher(GWEN_CRYPT_KEY *k,
00236                                const uint8_t *pInData,
00237                                uint32_t inLen,
00238                                uint8_t *pOutData,
00239                                uint32_t *pOutLen) {
00240   GWEN_CRYPT_KEY_RSA *xk;
00241   gcry_error_t err;
00242   size_t nscanned;
00243   gcry_ac_data_t dsKey;
00244   gcry_mpi_t mpi_e;
00245   gcry_mpi_t mpi_n;
00246   gcry_mpi_t mpi_in;
00247   gcry_mpi_t mpi_out;
00248   size_t nwritten;
00249 
00250   assert(k);
00251   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00252   assert(xk);
00253 
00254   dsKey=gcry_ac_key_data_get(xk->key);
00255 
00256   /* get modulus */
00257   err=gcry_ac_data_get_name(dsKey, 0, "n", &mpi_n);
00258   if (err) {
00259     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00260              gcry_strerror(err));
00261     return GWEN_ERROR_BAD_DATA;
00262   }
00263 
00264   /* get private exponent */
00265   err=gcry_ac_data_get_name(dsKey, 0, "e", &mpi_e);
00266   if (err) {
00267     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00268              gcry_strerror(err));
00269     return GWEN_ERROR_BAD_DATA;
00270   }
00271 
00272   /* convert input to MPI */
00273   mpi_in=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00274   err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
00275   if (err) {
00276     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
00277     gcry_mpi_release(mpi_in);
00278     return GWEN_ERROR_BAD_DATA;
00279   }
00280 
00281   /* encrypt */
00282   mpi_out=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00283   gcry_mpi_powm(mpi_out, mpi_in, mpi_e, mpi_n);
00284 
00285   /* release unneeded objects */
00286   gcry_mpi_release(mpi_in);
00287 
00288   /* convert result MPI */
00289   err=gcry_mpi_print(GCRYMPI_FMT_USG,
00290                      pOutData, *pOutLen,
00291                      &nwritten, mpi_out);
00292   gcry_mpi_release(mpi_out);
00293   if (err) {
00294     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
00295     return GWEN_ERROR_BAD_DATA;
00296   }
00297   *pOutLen=nwritten;
00298 
00299   return 0;
00300 }
00301 
00302 
00303 
00304 int GWEN_Crypt_KeyRsa_Decipher(GWEN_CRYPT_KEY *k,
00305                                const uint8_t *pInData,
00306                                uint32_t inLen,
00307                                uint8_t *pOutData,
00308                                uint32_t *pOutLen) {
00309   GWEN_CRYPT_KEY_RSA *xk;
00310   gcry_error_t err;
00311   size_t nscanned;
00312   gcry_ac_data_t dsKey;
00313   gcry_mpi_t mpi_d;
00314   gcry_mpi_t mpi_n;
00315   gcry_mpi_t mpi_in;
00316   gcry_mpi_t mpi_out;
00317   size_t nwritten;
00318 
00319   assert(k);
00320   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00321   assert(xk);
00322 
00323   dsKey=gcry_ac_key_data_get(xk->key);
00324 
00325   /* get modulus */
00326   err=gcry_ac_data_get_name(dsKey, 0, "n", &mpi_n);
00327   if (err) {
00328     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00329              gcry_strerror(err));
00330     return GWEN_ERROR_BAD_DATA;
00331   }
00332 
00333   /* get private exponent */
00334   err=gcry_ac_data_get_name(dsKey, 0, "d", &mpi_d);
00335   if (err) {
00336     DBG_INFO(GWEN_LOGDOMAIN, "gcry_data_get_name(): %s",
00337              gcry_strerror(err));
00338     return GWEN_ERROR_BAD_DATA;
00339   }
00340 
00341   /* convert input to MPI */
00342   mpi_in=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00343   err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
00344   if (err) {
00345     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
00346     gcry_mpi_release(mpi_in);
00347     return GWEN_ERROR_BAD_DATA;
00348   }
00349 
00350   /* decrypt */
00351   mpi_out=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00352   gcry_mpi_powm(mpi_out, mpi_in, mpi_d, mpi_n);
00353 
00354   /* release unneeded objects */
00355   gcry_mpi_release(mpi_in);
00356 
00357   /* convert result MPI */
00358   err=gcry_mpi_print(GCRYMPI_FMT_USG,
00359                      pOutData, *pOutLen,
00360                      &nwritten, mpi_out);
00361   gcry_mpi_release(mpi_out);
00362   if (err) {
00363     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
00364     return GWEN_ERROR_BAD_DATA;
00365   }
00366   *pOutLen=nwritten;
00367 
00368   return 0;
00369 }
00370 
00371 
00372 
00373 int GWEN_Crypt_KeyRsa__ReadMpi(GWEN_DB_NODE *db,
00374                                const char *dbName,
00375                                gcry_ac_data_t ds,
00376                                const char *dsName) {
00377   gcry_error_t err;
00378   const void *p;
00379   unsigned int len;
00380   gcry_mpi_t mpi=NULL;
00381   size_t nscanned;
00382 
00383   /* read n */
00384   p=GWEN_DB_GetBinValue(db, dbName, 0, NULL, 0, &len);
00385   if (p==NULL || len<1) {
00386     DBG_INFO(GWEN_LOGDOMAIN, "Missing %s", dbName);
00387     return GWEN_ERROR_NO_DATA;
00388   }
00389 
00390   err=gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, p, len, &nscanned);
00391   if (err) {
00392     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
00393     if (mpi)
00394       gcry_mpi_release(mpi);
00395     return GWEN_ERROR_GENERIC;
00396   }
00397   if (nscanned<1) {
00398     DBG_INFO(GWEN_LOGDOMAIN, "Empty %s", dbName);
00399     if (mpi)
00400       gcry_mpi_release(mpi);
00401     return GWEN_ERROR_BAD_DATA;
00402   }
00403   err=gcry_ac_data_set(ds, GCRY_AC_FLAG_COPY, (char*)dsName, mpi);
00404   if (err) {
00405     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_set(): %s", gcry_strerror(err));
00406     gcry_mpi_release(mpi);
00407     return GWEN_ERROR_GENERIC;
00408   }
00409   gcry_mpi_release(mpi);
00410 
00411   return 0;
00412 }
00413 
00414 
00415 
00416 
00417 int GWEN_Crypt_KeyRsa__WriteMpi(GWEN_DB_NODE *db,
00418                                 const char *dbName,
00419                                 gcry_ac_data_t ds,
00420                                 const char *dsName) {
00421   gcry_mpi_t mpi;
00422   gcry_error_t err;
00423   unsigned char *buf;
00424   size_t nbytes;
00425 
00426   /* read n (don't copy) */
00427   err=gcry_ac_data_get_name(ds, 0, dsName, &mpi);
00428   if (err) {
00429     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_get_name(%s): %s",
00430              dsName, gcry_strerror(err));
00431     if (err==GPG_ERR_INV_ARG)
00432       return GWEN_ERROR_NO_DATA;
00433     else
00434       return GWEN_ERROR_GENERIC;
00435   }
00436 
00437   /* write mpi as bin into a buffer which will be allocates by this function */
00438   err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
00439   if (err) {
00440     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(%s): %s", dsName, gcry_strerror(err));
00441     return GWEN_ERROR_GENERIC;
00442   }
00443   GWEN_DB_SetBinValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00444                       dbName,
00445                       buf, nbytes);
00446   gcry_free(buf);
00447 
00448   return 0;
00449 }
00450 
00451 
00452 
00453 int GWEN_Crypt_KeyRsa__DataFromDb(GWEN_DB_NODE *db, gcry_ac_data_t *pData,
00454                                   int pub, unsigned int nbits) {
00455   gcry_ac_data_t ds;
00456   gcry_error_t err;
00457   int rv;
00458 
00459   /* allocate key data */
00460   err=gcry_ac_data_new(&ds);
00461   if (err) {
00462     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_new(): %d", err);
00463     return GWEN_ERROR_GENERIC;
00464   }
00465 
00466   /* read n */
00467   rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "n", ds, "n");
00468   if (rv) {
00469     gcry_ac_data_destroy(ds);
00470     return rv;
00471   }
00472 
00473   /* read e */
00474   rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "e", ds, "e");
00475   if (rv) {
00476     gcry_ac_data_destroy(ds);
00477     return rv;
00478   }
00479 
00480   if (!pub) {
00481     /* read d */
00482     rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "d", ds, "d");
00483     if (rv) {
00484       gcry_ac_data_destroy(ds);
00485       return rv;
00486     }
00487 
00488     /* read p */
00489     rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "p", ds, "p");
00490     if (rv) {
00491       gcry_ac_data_destroy(ds);
00492       return rv;
00493     }
00494 
00495     /* read q */
00496     rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "q", ds, "q");
00497     if (rv) {
00498       gcry_ac_data_destroy(ds);
00499       return rv;
00500     }
00501   }
00502 
00503   *pData=ds;
00504   return 0;
00505 }
00506 
00507 
00508 
00509 GWENHYWFAR_CB
00510 void GWEN_Crypt_KeyRsa_freeData(void *bp, void *p) {
00511   GWEN_CRYPT_KEY_RSA *xk;
00512 
00513   xk=(GWEN_CRYPT_KEY_RSA*) p;
00514   if (xk->keyValid)
00515     gcry_ac_key_destroy(xk->key);
00516   if (xk->algoValid)
00517     gcry_ac_close(xk->algoHandle);
00518   GWEN_FREE_OBJECT(xk);
00519 }
00520 
00521 
00522 
00523 GWEN_CRYPT_KEY *GWEN_Crypt_KeyRsa_fromDb(GWEN_DB_NODE *db) {
00524   gcry_error_t err;
00525   gcry_ac_data_t data;
00526   int rv;
00527   int isPublic;
00528   GWEN_CRYPT_KEY *k;
00529   GWEN_CRYPT_KEY_RSA *xk;
00530   unsigned int nbits;
00531   GWEN_DB_NODE *dbR;
00532 
00533   dbR=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "rsa");
00534   if (dbR==NULL) {
00535     DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key (no RSA group)");
00536     return NULL;
00537   }
00538   k=GWEN_Crypt_Key_fromDb(db);
00539   if (k==NULL) {
00540     DBG_INFO(GWEN_LOGDOMAIN, "here");
00541     return NULL;
00542   }
00543   if (GWEN_Crypt_Key_GetCryptAlgoId(k)!=GWEN_Crypt_CryptAlgoId_Rsa) {
00544     DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key");
00545     GWEN_Crypt_Key_free(k);
00546     return NULL;
00547   }
00548   nbits=GWEN_Crypt_Key_GetKeySize(k)*8;
00549 
00550   /* extend key */
00551   GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
00552   GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
00553                        GWEN_Crypt_KeyRsa_freeData);
00554   GWEN_Crypt_Key_SetSignFn(k, GWEN_Crypt_KeyRsa_Sign);
00555   GWEN_Crypt_Key_SetVerifyFn(k, GWEN_Crypt_KeyRsa_Verify);
00556   GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeyRsa_Encipher);
00557   GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeyRsa_Decipher);
00558 
00559   isPublic=GWEN_DB_GetIntValue(dbR, "isPublic", 0, 1);
00560   xk->pub=isPublic;
00561 
00562   xk->flags=GWEN_DB_GetIntValue(dbR, "flags", 0, 0);
00563 
00564   /* prepare data */
00565   rv=GWEN_Crypt_KeyRsa__DataFromDb(dbR, &data, isPublic, nbits);
00566   if (rv) {
00567     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00568     GWEN_Crypt_Key_free(k);
00569     return NULL;
00570   }
00571 
00572   err=gcry_ac_open(&xk->algoHandle, GCRY_AC_RSA, 0); /* TODO: lookup flags to use */
00573   if (err) {
00574     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %d", err);
00575     gcry_ac_data_destroy(data);
00576     GWEN_Crypt_Key_free(k);
00577     return NULL;
00578   }
00579   xk->algoValid=1;
00580 
00581   err=gcry_ac_key_init(&xk->key, xk->algoHandle,
00582                        isPublic?GCRY_AC_KEY_PUBLIC:GCRY_AC_KEY_SECRET,
00583                        data);
00584   if (err) {
00585     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_key_init(): %d", err);
00586     gcry_ac_data_destroy(data);
00587     GWEN_Crypt_Key_free(k);
00588     return NULL;
00589   }
00590   xk->keyValid=1;
00591 
00592 #if 0
00593   DBG_ERROR(0, "fromDb:");
00594   dumpKeyData(data);
00595 #endif
00596 
00597   gcry_ac_data_destroy(data);
00598   return k;
00599 }
00600 
00601 
00602 
00603 int GWEN_Crypt_KeyRsa_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db, int pub) {
00604   GWEN_CRYPT_KEY_RSA *xk;
00605   GWEN_DB_NODE *dbR;
00606   int rv;
00607   gcry_ac_data_t ds;
00608 
00609   assert(k);
00610   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00611   assert(xk);
00612 
00613   if (xk->algoValid==0 || xk->keyValid==0) {
00614     /* should not happen */
00615     DBG_ERROR(GWEN_LOGDOMAIN, "Key is not open");
00616     return GWEN_ERROR_NOT_OPEN;
00617   }
00618 
00619   if (xk->pub && !pub) {
00620     DBG_ERROR(GWEN_LOGDOMAIN, "Can't write public key as secret key");
00621     return GWEN_ERROR_INVALID;
00622   }
00623 
00624   ds=gcry_ac_key_data_get(xk->key);
00625 
00626 #if 0
00627   DBG_ERROR(0, "toDb (%s):", pub?"public":"private");
00628   dumpKeyData(ds);
00629 #endif
00630 
00631   /* let key module write basic key info */
00632   rv=GWEN_Crypt_Key_toDb(k, db);
00633   if (rv)
00634     return rv;
00635 
00636   /* write RSA stuff into our own group */
00637   dbR=GWEN_DB_GetGroup(db, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "rsa");
00638   assert(dbR);
00639 
00640   GWEN_DB_SetIntValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
00641                       "isPublic", pub);
00642   GWEN_DB_SetIntValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
00643                       "flags", xk->flags);
00644 
00645   /* store n */
00646   rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "n", ds, "n");
00647   if (rv) {
00648     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00649     return rv;
00650   }
00651 
00652   /* store e */
00653   rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "e", ds, "e");
00654   if (rv) {
00655     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00656     return rv;
00657   }
00658   if (!pub) {
00659     /* store d */
00660     rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "d", ds, "d");
00661     if (rv) {
00662       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00663       return rv;
00664     }
00665     /* store p */
00666     rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "p", ds, "p");
00667     if (rv) {
00668       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00669       return rv;
00670     }
00671     /* store q */
00672     rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "q", ds, "q");
00673     if (rv) {
00674       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00675       return rv;
00676     }
00677   }
00678 
00679   return 0;
00680 }
00681 
00682 
00683 
00684 
00685 int GWEN_Crypt_KeyRsa__sKeyElementToData(gcry_ac_data_t data, gcry_sexp_t sx, const char *name) {
00686   int rc;
00687   gcry_sexp_t list;
00688   gcry_mpi_t mpi=NULL;
00689 
00690   list=gcry_sexp_find_token(sx, name, 0);
00691   if (!list || !(mpi=gcry_sexp_nth_mpi(list, 1, 0)) ) {
00692     DBG_ERROR(GWEN_LOGDOMAIN, "Entry \"%s\" not found", name);
00693     return GWEN_ERROR_GENERIC;
00694   }
00695 
00696   rc=gcry_ac_data_set(data, GCRY_AC_FLAG_COPY, (char*)name, mpi);
00697   if (rc) {
00698     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_set(): %s", gcry_strerror(rc));
00699     gcry_mpi_release(mpi);
00700     return GWEN_ERROR_GENERIC;
00701   }
00702   gcry_mpi_release(mpi);
00703   gcry_sexp_release(list);
00704 
00705   return 0;
00706 }
00707 
00708 
00709 
00710 int GWEN_Crypt_KeyRsa__sKeyToDataPubKey(gcry_ac_data_t data, gcry_sexp_t sx) {
00711   int rv;
00712 
00713   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "n");
00714   if (rv)
00715     return rv;
00716   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "e");
00717   if (rv)
00718     return rv;
00719   return 0;
00720 }
00721 
00722 
00723 
00724 int GWEN_Crypt_KeyRsa__sKeyToDataPrivKey(gcry_ac_data_t data, gcry_sexp_t sx) {
00725   int rv;
00726 
00727   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "n");
00728   if (rv)
00729     return rv;
00730   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "e");
00731   if (rv)
00732     return rv;
00733   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "d");
00734   if (rv)
00735     return rv;
00736   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "p");
00737   if (rv)
00738     return rv;
00739   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "q");
00740   if (rv)
00741     return rv;
00742   return 0;
00743 }
00744 
00745 
00746 
00747 int GWEN_Crypt_KeyRsa_GeneratePair(unsigned int nbytes, int use65537e,
00748                                    GWEN_CRYPT_KEY **pPubKey,
00749                                    GWEN_CRYPT_KEY **pSecretKey) {
00750   gcry_sexp_t keyparm, key;
00751   int rc;
00752   char buffer[256];
00753   char numbuf[32];
00754   gcry_sexp_t skey, pkey;
00755 
00756   snprintf(numbuf, sizeof(numbuf)-1, "%d", nbytes*8);
00757   if (use65537e) {
00758     snprintf(buffer, sizeof(buffer)-1,
00759              "(genkey\n"
00760              " (rsa\n"
00761              "  (nbits %zd:%d)\n"
00762              "  (rsa-use-e 5:65537)\n"
00763              " ))",
00764              strlen(numbuf),
00765              nbytes*8);
00766   }
00767   else
00768     snprintf(buffer, sizeof(buffer)-1,
00769              "(genkey\n"
00770              " (rsa\n"
00771              "  (nbits %zd:%d)\n"
00772              "  (rsa-use-e 1:0)\n"
00773              " ))",
00774              strlen(numbuf),
00775              nbytes*8);
00776 
00777   rc=gcry_sexp_new(&keyparm, buffer, 0, 1);
00778   if (rc) {
00779     DBG_ERROR(GWEN_LOGDOMAIN,
00780               "Error creating S-expression: %s", gpg_strerror (rc));
00781     return GWEN_ERROR_GENERIC;
00782   }
00783 
00784   rc=gcry_pk_genkey(&key, keyparm);
00785   gcry_sexp_release(keyparm);
00786   if (rc) {
00787     DBG_ERROR(GWEN_LOGDOMAIN, "Error generating RSA key: %s", gpg_strerror (rc));
00788     return GWEN_ERROR_GENERIC;
00789   }
00790 
00791   pkey=gcry_sexp_find_token(key, "public-key", 0);
00792   if (!pkey) {
00793     DBG_ERROR(GWEN_LOGDOMAIN, "Public part missing in return value");
00794     gcry_sexp_release(key);
00795     return GWEN_ERROR_GENERIC;
00796   }
00797   else {
00798     gcry_ac_data_t data;
00799     GWEN_CRYPT_KEY *k;
00800     GWEN_CRYPT_KEY_RSA *xk;
00801 
00802     /* allocate key data */
00803     rc=gcry_ac_data_new(&data);
00804     if (rc) {
00805       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_new(): %s", gcry_strerror(rc));
00806       gcry_sexp_release(key);
00807       return GWEN_ERROR_GENERIC;
00808     }
00809 
00810     rc=GWEN_Crypt_KeyRsa__sKeyToDataPubKey(data, pkey);
00811     if (rc) {
00812       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rc);
00813       gcry_ac_data_destroy(data);
00814       gcry_sexp_release(key);
00815       return rc;
00816     }
00817     gcry_sexp_release(pkey);
00818 
00819     /* create public key */
00820     k=GWEN_Crypt_Key_new(GWEN_Crypt_CryptAlgoId_Rsa, nbytes);
00821     assert(k);
00822     GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
00823     GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
00824                          GWEN_Crypt_KeyRsa_freeData);
00825     GWEN_Crypt_Key_SetSignFn(k, GWEN_Crypt_KeyRsa_Sign);
00826     GWEN_Crypt_Key_SetVerifyFn(k, GWEN_Crypt_KeyRsa_Verify);
00827     GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeyRsa_Encipher);
00828     GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeyRsa_Decipher);
00829   
00830     /* open algo for key */
00831     rc=gcry_ac_open(&xk->algoHandle, GCRY_AC_RSA, 0);
00832     if (rc) {
00833       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %s", gcry_strerror(rc));
00834       GWEN_Crypt_Key_free(k);
00835       gcry_ac_data_destroy(data);
00836       gcry_sexp_release(key);
00837       return GWEN_ERROR_GENERIC;
00838     }
00839     xk->algoValid=1;
00840     /* copy key */
00841     rc=gcry_ac_key_init(&xk->key, xk->algoHandle, GCRY_AC_KEY_PUBLIC, data);
00842     xk->pub=1;
00843     if (rc) {
00844       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_key_init(): %s", gcry_strerror(rc));
00845       GWEN_Crypt_Key_free(k);
00846       gcry_ac_data_destroy(data);
00847       gcry_sexp_release(key);
00848       return GWEN_ERROR_GENERIC;
00849     }
00850     xk->keyValid=1;
00851     *pPubKey=k;
00852     gcry_ac_data_destroy(data);
00853   }
00854 
00855   skey=gcry_sexp_find_token(key, "private-key", 0);
00856   if (!skey) {
00857     DBG_ERROR(GWEN_LOGDOMAIN, "Private part missing in return value");
00858     return GWEN_ERROR_GENERIC;
00859   }
00860   else {
00861     gcry_ac_data_t data;
00862     GWEN_CRYPT_KEY *k;
00863     GWEN_CRYPT_KEY_RSA *xk;
00864 
00865     /* allocate key data */
00866     rc=gcry_ac_data_new(&data);
00867     if (rc) {
00868       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_new(): %s", gcry_strerror(rc));
00869       gcry_sexp_release(key);
00870       return GWEN_ERROR_GENERIC;
00871     }
00872 
00873     rc=GWEN_Crypt_KeyRsa__sKeyToDataPrivKey(data, skey);
00874     if (rc) {
00875       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rc);
00876       gcry_ac_data_destroy(data);
00877       gcry_sexp_release(key);
00878       return rc;
00879     }
00880     gcry_sexp_release(skey);
00881 
00882     /* create public key */
00883     k=GWEN_Crypt_Key_new(GWEN_Crypt_CryptAlgoId_Rsa, nbytes);
00884     assert(k);
00885     GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
00886     GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
00887                          GWEN_Crypt_KeyRsa_freeData);
00888     GWEN_Crypt_Key_SetSignFn(k, GWEN_Crypt_KeyRsa_Sign);
00889     GWEN_Crypt_Key_SetVerifyFn(k, GWEN_Crypt_KeyRsa_Verify);
00890     GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeyRsa_Encipher);
00891     GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeyRsa_Decipher);
00892   
00893     /* open algo for key */
00894     rc=gcry_ac_open(&xk->algoHandle, GCRY_AC_RSA, 0);
00895     if (rc) {
00896       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %s", gcry_strerror(rc));
00897       GWEN_Crypt_Key_free(k);
00898       gcry_ac_data_destroy(data);
00899       gcry_sexp_release(key);
00900       return GWEN_ERROR_GENERIC;
00901     }
00902     xk->algoValid=1;
00903     /* copy key */
00904     rc=gcry_ac_key_init(&xk->key, xk->algoHandle, GCRY_AC_KEY_SECRET, data);
00905     xk->pub=0;
00906     if (rc) {
00907       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %s", gcry_strerror(rc));
00908       GWEN_Crypt_Key_free(k);
00909       gcry_ac_data_destroy(data);
00910       gcry_sexp_release(key);
00911       return GWEN_ERROR_GENERIC;
00912     }
00913     xk->keyValid=1;
00914     *pSecretKey=k;
00915     gcry_ac_data_destroy(data);
00916   }
00917 
00918   gcry_sexp_release(key);
00919   return 0;
00920 }
00921 
00922 
00923 
00924 int GWEN_Crypt_KeyRsa__GetNamedElement(const GWEN_CRYPT_KEY *k,
00925                                        const char *name,
00926                                        uint8_t *buffer,
00927                                        uint32_t *pBufLen) {
00928   gcry_ac_data_t ds;
00929   GWEN_CRYPT_KEY_RSA *xk;
00930   gcry_mpi_t mpi;
00931   gcry_error_t err;
00932   unsigned char *buf;
00933   size_t nbytes;
00934 
00935   assert(k);
00936   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00937   assert(xk);
00938 
00939   if (xk->algoValid==0 || xk->keyValid==0) {
00940     DBG_INFO(GWEN_LOGDOMAIN, "Invalid key data");
00941     return GWEN_ERROR_GENERIC;
00942   }
00943 
00944   ds=gcry_ac_key_data_get(xk->key);
00945 
00946   /* read n (don't copy) */
00947   err=gcry_ac_data_get_name(ds, 0, name, &mpi);
00948   if (err) {
00949     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_get_name(): %d", err);
00950     if (err==GPG_ERR_INV_ARG)
00951       return GWEN_ERROR_NO_DATA;
00952     else
00953       return GWEN_ERROR_GENERIC;
00954   }
00955 
00956   /* write mpi as bin into a buffer which will be allocated by this function */
00957   err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
00958   if (err) {
00959     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(): %d", err);
00960     return GWEN_ERROR_GENERIC;
00961   }
00962   if (nbytes>*pBufLen) {
00963     DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00964     gcry_free(buf);
00965     return GWEN_ERROR_BUFFER_OVERFLOW;
00966   }
00967 
00968   memmove(buffer, buf, nbytes);
00969   *pBufLen=nbytes;
00970   gcry_free(buf);
00971 
00972   return 0;
00973 }
00974 
00975 
00976 
00977 int GWEN_Crypt_KeyRsa_GetModulus(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen) {
00978   return GWEN_Crypt_KeyRsa__GetNamedElement(k, "n", buffer, pBufLen);
00979 }
00980 
00981 
00982 
00983 int GWEN_Crypt_KeyRsa_GetExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen) {
00984   return GWEN_Crypt_KeyRsa__GetNamedElement(k, "e", buffer, pBufLen);
00985 }
00986 
00987 
00988 
00989 GWEN_CRYPT_KEY *GWEN_Crypt_KeyRsa_fromModExp(unsigned int nbytes,
00990                                              const uint8_t *pModulus,
00991                                              uint32_t lModulus,
00992                                              const uint8_t *pExponent,
00993                                              uint32_t lExponent) {
00994   GWEN_DB_NODE *dbKey;
00995   GWEN_DB_NODE *dbR;
00996   GWEN_CRYPT_KEY *key;
00997 
00998   assert(nbytes);
00999   assert(pModulus);
01000   assert(lModulus);
01001   assert(pExponent);
01002   assert(lExponent);
01003 
01004   dbKey=GWEN_DB_Group_new("key");
01005   dbR=GWEN_DB_GetGroup(dbKey, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "rsa");
01006 
01007   /* basic key stuff */
01008   GWEN_DB_SetCharValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
01009                        "cryptAlgoId",
01010                        GWEN_Crypt_CryptAlgoId_toString(GWEN_Crypt_CryptAlgoId_Rsa));
01011   GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
01012                       "keySize", nbytes);
01013 
01014   /* RSA stuff */
01015   GWEN_DB_SetIntValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
01016                       "isPublic", 1);
01017   GWEN_DB_SetBinValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
01018                       "n",
01019                       pModulus, lModulus);
01020   GWEN_DB_SetBinValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
01021                       "e",
01022                       pExponent, lExponent);
01023 
01024   /* create key from DB */
01025   key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
01026   if (key==NULL) {
01027     DBG_INFO(GWEN_LOGDOMAIN,
01028              "Internal error: Bad RSA key group");
01029     GWEN_DB_Dump(dbKey, stderr, 2);
01030     GWEN_DB_Group_free(dbKey);
01031     return NULL;
01032   }
01033 
01034   GWEN_DB_Group_free(dbKey);
01035   return key;
01036 }
01037 
01038 
01039 
01040 GWEN_CRYPT_KEY *GWEN_Crypt_KeyRsa_dup(const GWEN_CRYPT_KEY *k) {
01041   GWEN_CRYPT_KEY_RSA *xk;
01042   GWEN_DB_NODE *dbKey;
01043   GWEN_CRYPT_KEY *nk;
01044   int rv;
01045 
01046   assert(k);
01047   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01048   assert(xk);
01049 
01050   dbKey=GWEN_DB_Group_new("dbKey");
01051   rv=GWEN_Crypt_KeyRsa_toDb(k, dbKey, xk->pub);
01052   if (rv<0) {
01053     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01054     GWEN_DB_Group_free(dbKey);
01055     return NULL;
01056   }
01057 
01058   nk=GWEN_Crypt_KeyRsa_fromDb(dbKey);
01059   GWEN_DB_Group_free(dbKey);
01060   if (nk==NULL) {
01061     DBG_INFO(GWEN_LOGDOMAIN, "Could not create key");
01062   }
01063 
01064   GWEN_Crypt_KeyRsa_SetFlags(nk, xk->flags);
01065 
01066   return nk;
01067 }
01068 
01069 
01070 
01071 uint32_t GWEN_Crypt_KeyRsa_GetFlags(const GWEN_CRYPT_KEY *k) {
01072   GWEN_CRYPT_KEY_RSA *xk;
01073 
01074   assert(k);
01075   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01076   assert(xk);
01077 
01078   return xk->flags;
01079 }
01080 
01081 
01082 
01083 void GWEN_Crypt_KeyRsa_SetFlags(GWEN_CRYPT_KEY *k, uint32_t fl) {
01084   GWEN_CRYPT_KEY_RSA *xk;
01085 
01086   assert(k);
01087   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01088   assert(xk);
01089 
01090   xk->flags=fl;
01091 }
01092 
01093 
01094 
01095 void GWEN_Crypt_KeyRsa_AddFlags(GWEN_CRYPT_KEY *k, uint32_t fl) {
01096   GWEN_CRYPT_KEY_RSA *xk;
01097 
01098   assert(k);
01099   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01100   assert(xk);
01101 
01102   xk->flags|=fl;
01103 }
01104 
01105 
01106 
01107 void GWEN_Crypt_KeyRsa_SubFlags(GWEN_CRYPT_KEY *k, uint32_t fl) {
01108   GWEN_CRYPT_KEY_RSA *xk;
01109 
01110   assert(k);
01111   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01112   assert(xk);
01113 
01114   xk->flags&=~fl;
01115 }
01116 
01117 
01118 
01119 
01120 
01121 
01122 
01123 

Generated on Fri Apr 11 01:53:46 2008 for gwenhywfar by  doxygen 1.5.5