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