00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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
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
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
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
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
00126 gcry_mpi_release(mpi_sigout2);
00127 gcry_mpi_release(mpi_in);
00128
00129
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
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
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
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
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
00204 mpi_sigout=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
00205 gcry_mpi_powm(mpi_sigout, mpi_sigin1, mpi_e, mpi_n);
00206
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
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
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
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
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
00286 gcry_mpi_release(mpi_in);
00287
00288
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
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
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
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
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
00355 gcry_mpi_release(mpi_in);
00356
00357
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
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
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
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
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
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
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
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
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
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
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
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);
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
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
00634 rv=GWEN_Crypt_Key_toDb(k, db);
00635 if (rv)
00636 return rv;
00637
00638
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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