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