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_DEBUG(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_DEBUG(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 (%d)", dbName, (int)nscanned);
00399 #if 0
00400     if (mpi)
00401       gcry_mpi_release(mpi);
00402     return GWEN_ERROR_BAD_DATA;
00403 #endif
00404   }
00405   err=gcry_ac_data_set(ds, GCRY_AC_FLAG_COPY, (char*)dsName, mpi);
00406   if (err) {
00407     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_set(): %s", gcry_strerror(err));
00408     gcry_mpi_release(mpi);
00409     return GWEN_ERROR_GENERIC;
00410   }
00411   gcry_mpi_release(mpi);
00412 
00413   return 0;
00414 }
00415 
00416 
00417 
00418 
00419 int GWEN_Crypt_KeyRsa__WriteMpi(GWEN_DB_NODE *db,
00420                                 const char *dbName,
00421                                 gcry_ac_data_t ds,
00422                                 const char *dsName) {
00423   gcry_mpi_t mpi;
00424   gcry_error_t err;
00425   unsigned char *buf;
00426   size_t nbytes;
00427 
00428   /* read n (don't copy) */
00429   err=gcry_ac_data_get_name(ds, 0, dsName, &mpi);
00430   if (err) {
00431     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_get_name(%s): %s",
00432              dsName, gcry_strerror(err));
00433     if (err==GPG_ERR_INV_ARG)
00434       return GWEN_ERROR_NO_DATA;
00435     else
00436       return GWEN_ERROR_GENERIC;
00437   }
00438 
00439   /* write mpi as bin into a buffer which will be allocates by this function */
00440   err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
00441   if (err) {
00442     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(%s): %s", dsName, gcry_strerror(err));
00443     return GWEN_ERROR_GENERIC;
00444   }
00445   GWEN_DB_SetBinValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00446                       dbName,
00447                       buf, nbytes);
00448   gcry_free(buf);
00449 
00450   return 0;
00451 }
00452 
00453 
00454 
00455 int GWEN_Crypt_KeyRsa__DataFromDb(GWEN_DB_NODE *db, gcry_ac_data_t *pData,
00456                                   int pub, unsigned int nbits) {
00457   gcry_ac_data_t ds;
00458   gcry_error_t err;
00459   int rv;
00460 
00461   /* allocate key data */
00462   err=gcry_ac_data_new(&ds);
00463   if (err) {
00464     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_new(): %d", err);
00465     return GWEN_ERROR_GENERIC;
00466   }
00467 
00468   /* read n */
00469   rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "n", ds, "n");
00470   if (rv) {
00471     gcry_ac_data_destroy(ds);
00472     return rv;
00473   }
00474 
00475   /* read e */
00476   rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "e", ds, "e");
00477   if (rv) {
00478     gcry_ac_data_destroy(ds);
00479     return rv;
00480   }
00481 
00482   if (!pub) {
00483     /* read d */
00484     rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "d", ds, "d");
00485     if (rv) {
00486       gcry_ac_data_destroy(ds);
00487       return rv;
00488     }
00489 
00490     /* read p */
00491     rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "p", ds, "p");
00492     if (rv) {
00493       gcry_ac_data_destroy(ds);
00494       return rv;
00495     }
00496 
00497     /* read q */
00498     rv=GWEN_Crypt_KeyRsa__ReadMpi(db, "q", ds, "q");
00499     if (rv) {
00500       gcry_ac_data_destroy(ds);
00501       return rv;
00502     }
00503   }
00504 
00505   *pData=ds;
00506   return 0;
00507 }
00508 
00509 
00510 
00511 GWENHYWFAR_CB
00512 void GWEN_Crypt_KeyRsa_freeData(void *bp, void *p) {
00513   GWEN_CRYPT_KEY_RSA *xk;
00514 
00515   xk=(GWEN_CRYPT_KEY_RSA*) p;
00516   if (xk->keyValid)
00517     gcry_ac_key_destroy(xk->key);
00518   if (xk->algoValid)
00519     gcry_ac_close(xk->algoHandle);
00520   GWEN_FREE_OBJECT(xk);
00521 }
00522 
00523 
00524 
00525 GWEN_CRYPT_KEY *GWEN_Crypt_KeyRsa_fromDb(GWEN_DB_NODE *db) {
00526   gcry_error_t err;
00527   gcry_ac_data_t data;
00528   int rv;
00529   int isPublic;
00530   GWEN_CRYPT_KEY *k;
00531   GWEN_CRYPT_KEY_RSA *xk;
00532   unsigned int nbits;
00533   GWEN_DB_NODE *dbR;
00534 
00535   dbR=GWEN_DB_GetGroup(db, GWEN_PATH_FLAGS_NAMEMUSTEXIST, "rsa");
00536   if (dbR==NULL) {
00537     DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key (no RSA group)");
00538     return NULL;
00539   }
00540   k=GWEN_Crypt_Key_fromDb(db);
00541   if (k==NULL) {
00542     DBG_INFO(GWEN_LOGDOMAIN, "here");
00543     return NULL;
00544   }
00545   if (GWEN_Crypt_Key_GetCryptAlgoId(k)!=GWEN_Crypt_CryptAlgoId_Rsa) {
00546     DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key");
00547     GWEN_Crypt_Key_free(k);
00548     return NULL;
00549   }
00550   nbits=GWEN_Crypt_Key_GetKeySize(k)*8;
00551 
00552   /* extend key */
00553   GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
00554   GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
00555                        GWEN_Crypt_KeyRsa_freeData);
00556   GWEN_Crypt_Key_SetSignFn(k, GWEN_Crypt_KeyRsa_Sign);
00557   GWEN_Crypt_Key_SetVerifyFn(k, GWEN_Crypt_KeyRsa_Verify);
00558   GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeyRsa_Encipher);
00559   GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeyRsa_Decipher);
00560 
00561   isPublic=GWEN_DB_GetIntValue(dbR, "isPublic", 0, 1);
00562   xk->pub=isPublic;
00563 
00564   xk->flags=GWEN_DB_GetIntValue(dbR, "flags", 0, 0);
00565 
00566   /* prepare data */
00567   rv=GWEN_Crypt_KeyRsa__DataFromDb(dbR, &data, isPublic, nbits);
00568   if (rv) {
00569     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00570     GWEN_Crypt_Key_free(k);
00571     return NULL;
00572   }
00573 
00574   err=gcry_ac_open(&xk->algoHandle, GCRY_AC_RSA, 0); /* TODO: lookup flags to use */
00575   if (err) {
00576     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %d", err);
00577     gcry_ac_data_destroy(data);
00578     GWEN_Crypt_Key_free(k);
00579     return NULL;
00580   }
00581   xk->algoValid=1;
00582 
00583   err=gcry_ac_key_init(&xk->key, xk->algoHandle,
00584                        isPublic?GCRY_AC_KEY_PUBLIC:GCRY_AC_KEY_SECRET,
00585                        data);
00586   if (err) {
00587     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_key_init(): %d", err);
00588     gcry_ac_data_destroy(data);
00589     GWEN_Crypt_Key_free(k);
00590     return NULL;
00591   }
00592   xk->keyValid=1;
00593 
00594 #if 0
00595   DBG_ERROR(0, "fromDb:");
00596   dumpKeyData(data);
00597 #endif
00598 
00599   gcry_ac_data_destroy(data);
00600   return k;
00601 }
00602 
00603 
00604 
00605 int GWEN_Crypt_KeyRsa_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db, int pub) {
00606   GWEN_CRYPT_KEY_RSA *xk;
00607   GWEN_DB_NODE *dbR;
00608   int rv;
00609   gcry_ac_data_t ds;
00610 
00611   assert(k);
00612   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00613   assert(xk);
00614 
00615   if (xk->algoValid==0 || xk->keyValid==0) {
00616     /* should not happen */
00617     DBG_ERROR(GWEN_LOGDOMAIN, "Key is not open");
00618     return GWEN_ERROR_NOT_OPEN;
00619   }
00620 
00621   if (xk->pub && !pub) {
00622     DBG_ERROR(GWEN_LOGDOMAIN, "Can't write public key as secret key");
00623     return GWEN_ERROR_INVALID;
00624   }
00625 
00626   ds=gcry_ac_key_data_get(xk->key);
00627 
00628 #if 0
00629   DBG_ERROR(0, "toDb (%s):", pub?"public":"private");
00630   dumpKeyData(ds);
00631 #endif
00632 
00633   /* let key module write basic key info */
00634   rv=GWEN_Crypt_Key_toDb(k, db);
00635   if (rv)
00636     return rv;
00637 
00638   /* write RSA stuff into our own group */
00639   dbR=GWEN_DB_GetGroup(db, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "rsa");
00640   assert(dbR);
00641 
00642   GWEN_DB_SetIntValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
00643                       "isPublic", pub);
00644   GWEN_DB_SetIntValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
00645                       "flags", xk->flags);
00646 
00647   /* store n */
00648   rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "n", ds, "n");
00649   if (rv) {
00650     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00651     return rv;
00652   }
00653 
00654   /* store e */
00655   rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "e", ds, "e");
00656   if (rv) {
00657     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00658     return rv;
00659   }
00660   if (!pub) {
00661     /* store d */
00662     rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "d", ds, "d");
00663     if (rv) {
00664       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00665       return rv;
00666     }
00667     /* store p */
00668     rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "p", ds, "p");
00669     if (rv) {
00670       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00671       return rv;
00672     }
00673     /* store q */
00674     rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "q", ds, "q");
00675     if (rv) {
00676       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00677       return rv;
00678     }
00679   }
00680 
00681   return 0;
00682 }
00683 
00684 
00685 
00686 
00687 int GWEN_Crypt_KeyRsa__sKeyElementToData(gcry_ac_data_t data, gcry_sexp_t sx, const char *name) {
00688   int rc;
00689   gcry_sexp_t list;
00690   gcry_mpi_t mpi=NULL;
00691 
00692   list=gcry_sexp_find_token(sx, name, 0);
00693   if (!list || !(mpi=gcry_sexp_nth_mpi(list, 1, 0)) ) {
00694     DBG_ERROR(GWEN_LOGDOMAIN, "Entry \"%s\" not found", name);
00695     return GWEN_ERROR_GENERIC;
00696   }
00697 
00698   rc=gcry_ac_data_set(data, GCRY_AC_FLAG_COPY, (char*)name, mpi);
00699   if (rc) {
00700     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_set(): %s", gcry_strerror(rc));
00701     gcry_mpi_release(mpi);
00702     return GWEN_ERROR_GENERIC;
00703   }
00704   gcry_mpi_release(mpi);
00705   gcry_sexp_release(list);
00706 
00707   return 0;
00708 }
00709 
00710 
00711 
00712 int GWEN_Crypt_KeyRsa__sKeyToDataPubKey(gcry_ac_data_t data, gcry_sexp_t sx) {
00713   int rv;
00714 
00715   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "n");
00716   if (rv)
00717     return rv;
00718   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "e");
00719   if (rv)
00720     return rv;
00721   return 0;
00722 }
00723 
00724 
00725 
00726 int GWEN_Crypt_KeyRsa__sKeyToDataPrivKey(gcry_ac_data_t data, gcry_sexp_t sx) {
00727   int rv;
00728 
00729   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "n");
00730   if (rv)
00731     return rv;
00732   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "e");
00733   if (rv)
00734     return rv;
00735   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "d");
00736   if (rv)
00737     return rv;
00738   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "p");
00739   if (rv)
00740     return rv;
00741   rv=GWEN_Crypt_KeyRsa__sKeyElementToData(data, sx, "q");
00742   if (rv)
00743     return rv;
00744   return 0;
00745 }
00746 
00747 
00748 
00749 int GWEN_Crypt_KeyRsa_GeneratePair(unsigned int nbytes, int use65537e,
00750                                    GWEN_CRYPT_KEY **pPubKey,
00751                                    GWEN_CRYPT_KEY **pSecretKey) {
00752   gcry_sexp_t keyparm, key;
00753   int rc;
00754   char buffer[256];
00755   char numbuf[32];
00756   gcry_sexp_t skey, pkey;
00757 
00758   snprintf(numbuf, sizeof(numbuf)-1, "%d", nbytes*8);
00759   if (use65537e) {
00760     snprintf(buffer, sizeof(buffer)-1,
00761              "(genkey\n"
00762              " (rsa\n"
00763              "  (nbits %zd:%d)\n"
00764              "  (rsa-use-e 5:65537)\n"
00765              " ))",
00766              strlen(numbuf),
00767              nbytes*8);
00768   }
00769   else
00770     snprintf(buffer, sizeof(buffer)-1,
00771              "(genkey\n"
00772              " (rsa\n"
00773              "  (nbits %zd:%d)\n"
00774              "  (rsa-use-e 1:0)\n"
00775              " ))",
00776              strlen(numbuf),
00777              nbytes*8);
00778 
00779   rc=gcry_sexp_new(&keyparm, buffer, 0, 1);
00780   if (rc) {
00781     DBG_ERROR(GWEN_LOGDOMAIN,
00782               "Error creating S-expression: %s", gpg_strerror (rc));
00783     return GWEN_ERROR_GENERIC;
00784   }
00785 
00786   rc=gcry_pk_genkey(&key, keyparm);
00787   gcry_sexp_release(keyparm);
00788   if (rc) {
00789     DBG_ERROR(GWEN_LOGDOMAIN, "Error generating RSA key: %s", gpg_strerror (rc));
00790     return GWEN_ERROR_GENERIC;
00791   }
00792 
00793   pkey=gcry_sexp_find_token(key, "public-key", 0);
00794   if (!pkey) {
00795     DBG_ERROR(GWEN_LOGDOMAIN, "Public part missing in return value");
00796     gcry_sexp_release(key);
00797     return GWEN_ERROR_GENERIC;
00798   }
00799   else {
00800     gcry_ac_data_t data;
00801     GWEN_CRYPT_KEY *k;
00802     GWEN_CRYPT_KEY_RSA *xk;
00803 
00804     /* allocate key data */
00805     rc=gcry_ac_data_new(&data);
00806     if (rc) {
00807       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_new(): %s", gcry_strerror(rc));
00808       gcry_sexp_release(key);
00809       return GWEN_ERROR_GENERIC;
00810     }
00811 
00812     rc=GWEN_Crypt_KeyRsa__sKeyToDataPubKey(data, pkey);
00813     if (rc) {
00814       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rc);
00815       gcry_ac_data_destroy(data);
00816       gcry_sexp_release(key);
00817       return rc;
00818     }
00819     gcry_sexp_release(pkey);
00820 
00821     /* create public key */
00822     k=GWEN_Crypt_Key_new(GWEN_Crypt_CryptAlgoId_Rsa, nbytes);
00823     assert(k);
00824     GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
00825     GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
00826                          GWEN_Crypt_KeyRsa_freeData);
00827     GWEN_Crypt_Key_SetSignFn(k, GWEN_Crypt_KeyRsa_Sign);
00828     GWEN_Crypt_Key_SetVerifyFn(k, GWEN_Crypt_KeyRsa_Verify);
00829     GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeyRsa_Encipher);
00830     GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeyRsa_Decipher);
00831   
00832     /* open algo for key */
00833     rc=gcry_ac_open(&xk->algoHandle, GCRY_AC_RSA, 0);
00834     if (rc) {
00835       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %s", gcry_strerror(rc));
00836       GWEN_Crypt_Key_free(k);
00837       gcry_ac_data_destroy(data);
00838       gcry_sexp_release(key);
00839       return GWEN_ERROR_GENERIC;
00840     }
00841     xk->algoValid=1;
00842     /* copy key */
00843     rc=gcry_ac_key_init(&xk->key, xk->algoHandle, GCRY_AC_KEY_PUBLIC, data);
00844     xk->pub=1;
00845     if (rc) {
00846       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_key_init(): %s", gcry_strerror(rc));
00847       GWEN_Crypt_Key_free(k);
00848       gcry_ac_data_destroy(data);
00849       gcry_sexp_release(key);
00850       return GWEN_ERROR_GENERIC;
00851     }
00852     xk->keyValid=1;
00853     *pPubKey=k;
00854     gcry_ac_data_destroy(data);
00855   }
00856 
00857   skey=gcry_sexp_find_token(key, "private-key", 0);
00858   if (!skey) {
00859     DBG_ERROR(GWEN_LOGDOMAIN, "Private part missing in return value");
00860     return GWEN_ERROR_GENERIC;
00861   }
00862   else {
00863     gcry_ac_data_t data;
00864     GWEN_CRYPT_KEY *k;
00865     GWEN_CRYPT_KEY_RSA *xk;
00866 
00867     /* allocate key data */
00868     rc=gcry_ac_data_new(&data);
00869     if (rc) {
00870       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_new(): %s", gcry_strerror(rc));
00871       gcry_sexp_release(key);
00872       return GWEN_ERROR_GENERIC;
00873     }
00874 
00875     rc=GWEN_Crypt_KeyRsa__sKeyToDataPrivKey(data, skey);
00876     if (rc) {
00877       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rc);
00878       gcry_ac_data_destroy(data);
00879       gcry_sexp_release(key);
00880       return rc;
00881     }
00882     gcry_sexp_release(skey);
00883 
00884     /* create public key */
00885     k=GWEN_Crypt_Key_new(GWEN_Crypt_CryptAlgoId_Rsa, nbytes);
00886     assert(k);
00887     GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
00888     GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
00889                          GWEN_Crypt_KeyRsa_freeData);
00890     GWEN_Crypt_Key_SetSignFn(k, GWEN_Crypt_KeyRsa_Sign);
00891     GWEN_Crypt_Key_SetVerifyFn(k, GWEN_Crypt_KeyRsa_Verify);
00892     GWEN_Crypt_Key_SetEncipherFn(k, GWEN_Crypt_KeyRsa_Encipher);
00893     GWEN_Crypt_Key_SetDecipherFn(k, GWEN_Crypt_KeyRsa_Decipher);
00894   
00895     /* open algo for key */
00896     rc=gcry_ac_open(&xk->algoHandle, GCRY_AC_RSA, 0);
00897     if (rc) {
00898       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %s", gcry_strerror(rc));
00899       GWEN_Crypt_Key_free(k);
00900       gcry_ac_data_destroy(data);
00901       gcry_sexp_release(key);
00902       return GWEN_ERROR_GENERIC;
00903     }
00904     xk->algoValid=1;
00905     /* copy key */
00906     rc=gcry_ac_key_init(&xk->key, xk->algoHandle, GCRY_AC_KEY_SECRET, data);
00907     xk->pub=0;
00908     if (rc) {
00909       DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_open(): %s", gcry_strerror(rc));
00910       GWEN_Crypt_Key_free(k);
00911       gcry_ac_data_destroy(data);
00912       gcry_sexp_release(key);
00913       return GWEN_ERROR_GENERIC;
00914     }
00915     xk->keyValid=1;
00916     *pSecretKey=k;
00917     gcry_ac_data_destroy(data);
00918   }
00919 
00920   gcry_sexp_release(key);
00921   return 0;
00922 }
00923 
00924 
00925 
00926 int GWEN_Crypt_KeyRsa__GetNamedElement(const GWEN_CRYPT_KEY *k,
00927                                        const char *name,
00928                                        uint8_t *buffer,
00929                                        uint32_t *pBufLen) {
00930   gcry_ac_data_t ds;
00931   GWEN_CRYPT_KEY_RSA *xk;
00932   gcry_mpi_t mpi;
00933   gcry_error_t err;
00934   unsigned char *buf;
00935   size_t nbytes;
00936 
00937   assert(k);
00938   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
00939   assert(xk);
00940 
00941   if (xk->algoValid==0 || xk->keyValid==0) {
00942     DBG_INFO(GWEN_LOGDOMAIN, "Invalid key data");
00943     return GWEN_ERROR_GENERIC;
00944   }
00945 
00946   ds=gcry_ac_key_data_get(xk->key);
00947 
00948   /* read n (don't copy) */
00949   err=gcry_ac_data_get_name(ds, 0, name, &mpi);
00950   if (err) {
00951     DBG_INFO(GWEN_LOGDOMAIN, "gcry_ac_data_get_name(): %d", err);
00952     if (err==GPG_ERR_INV_ARG)
00953       return GWEN_ERROR_NO_DATA;
00954     else
00955       return GWEN_ERROR_GENERIC;
00956   }
00957 
00958   /* write mpi as bin into a buffer which will be allocated by this function */
00959   err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
00960   if (err) {
00961     DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(): %d", err);
00962     return GWEN_ERROR_GENERIC;
00963   }
00964   if (nbytes>*pBufLen) {
00965     DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00966     gcry_free(buf);
00967     return GWEN_ERROR_BUFFER_OVERFLOW;
00968   }
00969 
00970   memmove(buffer, buf, nbytes);
00971   *pBufLen=nbytes;
00972   gcry_free(buf);
00973 
00974   return 0;
00975 }
00976 
00977 
00978 
00979 int GWEN_Crypt_KeyRsa_GetModulus(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen) {
00980   return GWEN_Crypt_KeyRsa__GetNamedElement(k, "n", buffer, pBufLen);
00981 }
00982 
00983 
00984 
00985 int GWEN_Crypt_KeyRsa_GetExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen) {
00986   return GWEN_Crypt_KeyRsa__GetNamedElement(k, "e", buffer, pBufLen);
00987 }
00988 
00989 
00990 
00991 int GWEN_Crypt_KeyRsa_GetSecretExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen) {
00992   return GWEN_Crypt_KeyRsa__GetNamedElement(k, "d", buffer, pBufLen);
00993 }
00994 
00995 
00996 
00997 GWEN_CRYPT_KEY *GWEN_Crypt_KeyRsa_fromModExp(unsigned int nbytes,
00998                                              const uint8_t *pModulus,
00999                                              uint32_t lModulus,
01000                                              const uint8_t *pExponent,
01001                                              uint32_t lExponent) {
01002   GWEN_DB_NODE *dbKey;
01003   GWEN_DB_NODE *dbR;
01004   GWEN_CRYPT_KEY *key;
01005 
01006   assert(nbytes);
01007   assert(pModulus);
01008   assert(lModulus);
01009   assert(pExponent);
01010   assert(lExponent);
01011 
01012   dbKey=GWEN_DB_Group_new("key");
01013   dbR=GWEN_DB_GetGroup(dbKey, GWEN_DB_FLAGS_OVERWRITE_GROUPS, "rsa");
01014 
01015   /* basic key stuff */
01016   GWEN_DB_SetCharValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
01017                        "cryptAlgoId",
01018                        GWEN_Crypt_CryptAlgoId_toString(GWEN_Crypt_CryptAlgoId_Rsa));
01019   GWEN_DB_SetIntValue(dbKey, GWEN_DB_FLAGS_OVERWRITE_VARS,
01020                       "keySize", nbytes);
01021 
01022   /* RSA stuff */
01023   GWEN_DB_SetIntValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
01024                       "isPublic", 1);
01025   GWEN_DB_SetBinValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
01026                       "n",
01027                       pModulus, lModulus);
01028   GWEN_DB_SetBinValue(dbR, GWEN_DB_FLAGS_OVERWRITE_VARS,
01029                       "e",
01030                       pExponent, lExponent);
01031 
01032   /* create key from DB */
01033   key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
01034   if (key==NULL) {
01035     DBG_INFO(GWEN_LOGDOMAIN,
01036              "Internal error: Bad RSA key group");
01037     GWEN_DB_Dump(dbKey, stderr, 2);
01038     GWEN_DB_Group_free(dbKey);
01039     return NULL;
01040   }
01041 
01042   GWEN_DB_Group_free(dbKey);
01043   return key;
01044 }
01045 
01046 
01047 
01048 GWEN_CRYPT_KEY *GWEN_Crypt_KeyRsa_dup(const GWEN_CRYPT_KEY *k) {
01049   GWEN_CRYPT_KEY_RSA *xk;
01050   GWEN_DB_NODE *dbKey;
01051   GWEN_CRYPT_KEY *nk;
01052   int rv;
01053 
01054   assert(k);
01055   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01056   assert(xk);
01057 
01058   dbKey=GWEN_DB_Group_new("dbKey");
01059   rv=GWEN_Crypt_KeyRsa_toDb(k, dbKey, xk->pub);
01060   if (rv<0) {
01061     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01062     GWEN_DB_Group_free(dbKey);
01063     return NULL;
01064   }
01065 
01066   nk=GWEN_Crypt_KeyRsa_fromDb(dbKey);
01067   GWEN_DB_Group_free(dbKey);
01068   if (nk==NULL) {
01069     DBG_INFO(GWEN_LOGDOMAIN, "Could not create key");
01070   }
01071 
01072   GWEN_Crypt_KeyRsa_SetFlags(nk, xk->flags);
01073 
01074   return nk;
01075 }
01076 
01077 
01078 
01079 uint32_t GWEN_Crypt_KeyRsa_GetFlags(const GWEN_CRYPT_KEY *k) {
01080   GWEN_CRYPT_KEY_RSA *xk;
01081 
01082   assert(k);
01083   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01084   assert(xk);
01085 
01086   return xk->flags;
01087 }
01088 
01089 
01090 
01091 void GWEN_Crypt_KeyRsa_SetFlags(GWEN_CRYPT_KEY *k, uint32_t fl) {
01092   GWEN_CRYPT_KEY_RSA *xk;
01093 
01094   assert(k);
01095   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01096   assert(xk);
01097 
01098   xk->flags=fl;
01099 }
01100 
01101 
01102 
01103 void GWEN_Crypt_KeyRsa_AddFlags(GWEN_CRYPT_KEY *k, uint32_t fl) {
01104   GWEN_CRYPT_KEY_RSA *xk;
01105 
01106   assert(k);
01107   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01108   assert(xk);
01109 
01110   xk->flags|=fl;
01111 }
01112 
01113 
01114 
01115 void GWEN_Crypt_KeyRsa_SubFlags(GWEN_CRYPT_KEY *k, uint32_t fl) {
01116   GWEN_CRYPT_KEY_RSA *xk;
01117 
01118   assert(k);
01119   xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
01120   assert(xk);
01121 
01122   xk->flags&=~fl;
01123 }
01124 
01125 
01126 
01127 
01128 
01129 
01130 
01131 

Generated on Wed Jul 9 13:12:27 2008 for gwenhywfar by  doxygen 1.5.6