gwenhywfar 5.14.1
cryptkeyrsa.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Wed Mar 16 2005
3 copyright : (C) 2005 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14#define DISABLE_DEBUGLOG
15
16
17#include "cryptkeyrsa_p.h"
18#include <gwenhywfar/misc.h>
19#include <gwenhywfar/debug.h>
20#include <gwenhywfar/text.h>
21
22
23
24
25GWEN_INHERIT(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA)
26
27
28
29
30#if 0
31static void dumpKeyData(gcry_ac_data_t data)
32{
33 int i;
34 unsigned int l;
35
36 l=gcry_ac_data_length(data);
37 for (i=0; i<l; i++) {
38 const char *dname;
39 gcry_mpi_t mpi;
40 gcry_error_t err;
41 unsigned char *buf;
42 size_t nbytes;
43
44 gcry_ac_data_get_index(data, 0, i, &dname, &mpi);
45 fprintf(stderr, "%3d: [%s]\n", i, dname);
46
47 /* write mpi as bin into a buffer which will be allocates by this function */
48 err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
49 if (err) {
50 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(): %d", err);
51 }
52 else {
53 GWEN_Text_DumpString((const char *)buf, nbytes, stderr, 6);
54 gcry_free(buf);
55 }
56 }
57}
58#endif
59
60
61
62static int GWEN_Crypt_KeyRsa__getNamedElement(gcry_sexp_t pkey, const char *name, gcry_mpi_t *pMpi)
63{
64 gcry_sexp_t list;
65 gcry_mpi_t mpi;
66
67 /* get public exponent */
68 list=gcry_sexp_find_token(pkey, name, 0);
69 if (!list) {
70 DBG_ERROR(GWEN_LOGDOMAIN, "Missing element \"%s\" in sexp", name);
71 return GWEN_ERROR_GENERIC;
72 }
73
74 mpi=gcry_sexp_nth_mpi(list, 1, GCRYMPI_FMT_USG);
75 if (!mpi) {
76 DBG_ERROR(GWEN_LOGDOMAIN, "Error getting value for element \"%s\"", name);
77 gcry_sexp_release(list);
78 return GWEN_ERROR_GENERIC;
79 }
80
81 *pMpi=mpi;
82 gcry_sexp_release(list);
83
84 return 0;
85}
86
87/* We need a printf format specifier for "size_t" but <inttypes.h>
88 * does not have one. So in this one single exception we define our
89 * own, inspired from here:
90 * https://stackoverflow.com/questions/44382862/how-to-printf-a-size-t-without-warning-in-mingw-w64-gcc-7-1
91 */
92#ifdef _WIN32
93# ifdef _WIN64
94# define PRI_SIZET PRIu64
95# else
96# define PRI_SIZET PRIu32
97# endif
98#else
99# define PRI_SIZET "zd"
100#endif
101
102
103int GWEN_Crypt_KeyRsa_GeneratePair(unsigned int nbytes, int use65537e,
104 GWEN_CRYPT_KEY **pPubKey,
105 GWEN_CRYPT_KEY **pSecretKey)
106{
107 gcry_sexp_t keyparm, key;
108 int rc;
109 char buffer[256];
110 char numbuf[32];
111 gcry_sexp_t pkey;
112 int nbits;
113 GWEN_CRYPT_KEY *pubKey=NULL;
114 GWEN_CRYPT_KEY *secretKey=NULL;
115
116 nbits=nbytes*8;
117 assert(nbits>0);
118 snprintf(numbuf, sizeof(numbuf)-1, "%d", nbits);
119 if (use65537e) {
120 snprintf(buffer, sizeof(buffer)-1,
121 "(genkey\n"
122 " (rsa\n"
123 " (nbits %" PRI_SIZET ":%d)\n"
124 " (rsa-use-e 5:65537)\n"
125 " ))",
126 strlen(numbuf),
127 nbits);
128 }
129 else
130 snprintf(buffer, sizeof(buffer)-1,
131 "(genkey\n"
132 " (rsa\n"
133 " (nbits %" PRI_SIZET ":%d)\n"
134 " (rsa-use-e 1:0)\n"
135 " ))",
136 strlen(numbuf),
137 nbits);
138 buffer[sizeof(buffer)-1]=0;
139
140 /*DBG_ERROR(0, "Genkey string: [%s]", buffer);*/
141
142 rc=gcry_sexp_new(&keyparm, buffer, 0, 1);
143 if (rc) {
145 "Error creating S-expression: %s", gpg_strerror(rc));
146 return GWEN_ERROR_GENERIC;
147 }
148
149 rc=gcry_pk_genkey(&key, keyparm);
150 gcry_sexp_release(keyparm);
151 if (rc) {
152 DBG_ERROR(GWEN_LOGDOMAIN, "Error generating RSA key: %s", gpg_strerror(rc));
153 return GWEN_ERROR_GENERIC;
154 }
155
156 pkey=gcry_sexp_find_token(key, "public-key", 0);
157 if (!pkey) {
158 DBG_ERROR(GWEN_LOGDOMAIN, "Public part missing in return value");
159 gcry_sexp_release(key);
160 return GWEN_ERROR_GENERIC;
161 }
162 else {
163 int rv;
164 gcry_mpi_t n=NULL;
165 gcry_mpi_t e=NULL;
167 GWEN_CRYPT_KEY_RSA *xk;
168
169 /* get public exponent */
170 rv=GWEN_Crypt_KeyRsa__getNamedElement(pkey, "n", &n);
171 if (rv<0) {
172 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
173 gcry_sexp_release(key);
174 return GWEN_ERROR_GENERIC;
175 }
176
177 rv=GWEN_Crypt_KeyRsa__getNamedElement(pkey, "e", &e);
178 if (rv<0) {
179 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
180 gcry_mpi_release(n);
181 gcry_sexp_release(key);
182 return GWEN_ERROR_GENERIC;
183 }
184
185 /* create public key */
186 k=GWEN_Crypt_Key_new(GWEN_Crypt_CryptAlgoId_Rsa, nbytes);
187 GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
193 xk->modulus=gcry_mpi_copy(n);
194 xk->pubExponent=gcry_mpi_copy(e);
195 xk->pub=1;
196 pubKey=k;
197
198 gcry_mpi_release(e);
199 gcry_mpi_release(n);
200 }
201
202
203 pkey=gcry_sexp_find_token(key, "private-key", 0);
204 if (!pkey) {
205 DBG_ERROR(GWEN_LOGDOMAIN, "Private part missing in return value");
206 gcry_sexp_release(key);
207 return GWEN_ERROR_GENERIC;
208 }
209 else {
210 int rv;
211 gcry_mpi_t n=NULL;
212 gcry_mpi_t e=NULL;
213 gcry_mpi_t d=NULL;
215 GWEN_CRYPT_KEY_RSA *xk;
216
217 /* get public exponent */
218 rv=GWEN_Crypt_KeyRsa__getNamedElement(pkey, "n", &n);
219 if (rv<0) {
220 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
221 gcry_sexp_release(key);
222 return GWEN_ERROR_GENERIC;
223 }
224
225 rv=GWEN_Crypt_KeyRsa__getNamedElement(pkey, "e", &e);
226 if (rv<0) {
227 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
228 gcry_mpi_release(n);
229 gcry_sexp_release(key);
230 return GWEN_ERROR_GENERIC;
231 }
232
233 rv=GWEN_Crypt_KeyRsa__getNamedElement(pkey, "d", &d);
234 if (rv<0) {
235 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
236 gcry_mpi_release(e);
237 gcry_mpi_release(n);
238 gcry_sexp_release(key);
239 return GWEN_ERROR_GENERIC;
240 }
241
242 /* create private key */
243 k=GWEN_Crypt_Key_new(GWEN_Crypt_CryptAlgoId_Rsa, nbytes);
244 GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
250 xk->modulus=gcry_mpi_copy(n);
251 xk->pubExponent=gcry_mpi_copy(e);
252 xk->privExponent=gcry_mpi_copy(d);
253 xk->pub=0;
254 secretKey=k;
255
256 gcry_mpi_release(d);
257 gcry_mpi_release(e);
258 gcry_mpi_release(n);
259 }
260
261 gcry_sexp_release(key);
262
263 *pPubKey=pubKey;
264 *pSecretKey=secretKey;
265
266 return 0;
267}
268
269
270
271#ifndef NO_DEPRECATED_SYMBOLS
272int GWEN_Crypt_KeyRsa_GeneratePair2(unsigned int nbits, int use65537e,
273 GWEN_CRYPT_KEY **pPubKey,
274 GWEN_CRYPT_KEY **pSecretKey)
275{
276 if (nbits%8) {
278 "nbits is required to be a multiple of 8 (%d)", nbits);
279 return GWEN_ERROR_INVALID;
280 }
281 return GWEN_Crypt_KeyRsa_GeneratePair(nbits/8, use65537e, pPubKey, pSecretKey);
282}
283#endif // ifndef NO_DEPRECATED_SYMBOLS
284
285
286
287
289 const uint8_t *pInData,
290 uint32_t inLen,
291 uint8_t *pSignatureData,
292 uint32_t *pSignatureLen)
293{
294 GWEN_CRYPT_KEY_RSA *xk;
295 gcry_error_t err;
296 size_t nscanned;
297 gcry_mpi_t mpi_in=NULL;
298 gcry_mpi_t mpi_sigout1;
299 gcry_mpi_t mpi_sigout2=NULL;
300 size_t nwritten;
301
302 assert(k);
303 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
304 assert(xk);
305
306 if (xk->modulus==NULL) {
307 DBG_ERROR(GWEN_LOGDOMAIN, "No modulus in key data");
308 return GWEN_ERROR_BAD_DATA;
309 }
310
311 if (xk->privExponent==NULL) {
312 DBG_ERROR(GWEN_LOGDOMAIN, "No secret exponent in key data");
313 return GWEN_ERROR_BAD_DATA;
314 }
315
316 /* convert input to MPI */
317 err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
318 if (err) {
319 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
320 gcry_mpi_release(mpi_in);
321 return GWEN_ERROR_BAD_DATA;
322 }
323
324 /* create first signature */
325 mpi_sigout1=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
326 gcry_mpi_powm(mpi_sigout1, mpi_in, xk->privExponent, xk->modulus);
327
328 if (!(xk->flags & GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN)) {
329 /* create second signature */
330 mpi_sigout2=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
331 gcry_mpi_sub(mpi_sigout2, xk->modulus, mpi_sigout1);
332
333 if (gcry_mpi_cmp(mpi_sigout2, mpi_sigout1)<0) {
334 DBG_DEBUG(GWEN_LOGDOMAIN, "Choosing 2nd variant");
335 gcry_mpi_set(mpi_sigout1, mpi_sigout2);
336 }
337 }
338
339 /* release unneeded objects */
340 gcry_mpi_release(mpi_sigout2);
341 gcry_mpi_release(mpi_in);
342
343 /* convert signature MPI */
344 err=gcry_mpi_print(GCRYMPI_FMT_USG,
345 pSignatureData, *pSignatureLen,
346 &nwritten, mpi_sigout1);
347 gcry_mpi_release(mpi_sigout1);
348 if (err) {
349 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
350 return GWEN_ERROR_BAD_DATA;
351 }
352 *pSignatureLen=nwritten;
353
354 return 0;
355}
356
357
358
360 const uint8_t *pInData,
361 uint32_t inLen,
362 const uint8_t *pSignatureData,
363 uint32_t signatureLen)
364{
365 GWEN_CRYPT_KEY_RSA *xk;
366 gcry_error_t err;
367 size_t nscanned;
368 gcry_mpi_t mpi_in=NULL;
369 gcry_mpi_t mpi_sigin1=NULL;
370 gcry_mpi_t mpi_sigout;
371
372 assert(k);
373 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
374 assert(xk);
375
376 if (xk->modulus==NULL) {
377 DBG_ERROR(GWEN_LOGDOMAIN, "No modulus in key data");
378 return GWEN_ERROR_BAD_DATA;
379 }
380
381 if (xk->pubExponent==NULL) {
382 DBG_ERROR(GWEN_LOGDOMAIN, "No public exponent in key data");
383 return GWEN_ERROR_BAD_DATA;
384 }
385
386
387 /* convert input to MPI */
388 err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
389 if (err) {
390 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
391 gcry_mpi_release(mpi_in);
392 return GWEN_ERROR_BAD_DATA;
393 }
394
395 /* convert signature to MPI */
396 err=gcry_mpi_scan(&mpi_sigin1, GCRYMPI_FMT_USG,
397 pSignatureData, signatureLen,
398 &nscanned);
399 if (err) {
400 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
401 gcry_mpi_release(mpi_sigin1);
402 gcry_mpi_release(mpi_in);
403 return GWEN_ERROR_BAD_DATA;
404 }
405
406 /* create signature */
407 mpi_sigout=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
408 gcry_mpi_powm(mpi_sigout, mpi_sigin1, xk->pubExponent, xk->modulus);
409 /* compare */
410 if (gcry_mpi_cmp(mpi_sigout, mpi_in)) {
411 gcry_mpi_t mpi_sigin2;
412
413 mpi_sigin2=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
414
415 DBG_DEBUG(GWEN_LOGDOMAIN, "Trying 2nd variant");
416 gcry_mpi_sub(mpi_sigin2, xk->modulus, mpi_sigin1);
417 gcry_mpi_powm(mpi_sigout, mpi_sigin2, xk->pubExponent, xk->modulus);
418 if (gcry_mpi_cmp(mpi_sigout, mpi_in)) {
419 DBG_ERROR(GWEN_LOGDOMAIN, "Bad signature");
420 gcry_mpi_release(mpi_sigin2);
421 gcry_mpi_release(mpi_sigout);
422 gcry_mpi_release(mpi_sigin1);
423 gcry_mpi_release(mpi_in);
424 return GWEN_ERROR_VERIFY;
425 }
426 gcry_mpi_release(mpi_sigin2);
427 }
428
429 gcry_mpi_release(mpi_sigout);
430 gcry_mpi_release(mpi_sigin1);
431 gcry_mpi_release(mpi_in);
432
433 return 0;
434}
435
436
437
439 const uint8_t *pInData,
440 uint32_t inLen,
441 uint8_t *pOutData,
442 uint32_t *pOutLen)
443{
444 GWEN_CRYPT_KEY_RSA *xk;
445 gcry_error_t err;
446 size_t nscanned;
447 gcry_mpi_t mpi_in=NULL;
448 gcry_mpi_t mpi_out;
449 size_t nwritten;
450
451 assert(k);
452 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
453 assert(xk);
454
455 if (xk->modulus==NULL) {
456 DBG_ERROR(GWEN_LOGDOMAIN, "No modulus in key data");
457 return GWEN_ERROR_BAD_DATA;
458 }
459
460 if (xk->pubExponent==NULL) {
461 DBG_ERROR(GWEN_LOGDOMAIN, "No public exponent in key data");
462 return GWEN_ERROR_BAD_DATA;
463 }
464
465
466 /* convert input to MPI */
467 err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
468 if (err) {
469 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
470 gcry_mpi_release(mpi_in);
471 return GWEN_ERROR_BAD_DATA;
472 }
473
474 /* encrypt */
475 mpi_out=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
476 gcry_mpi_powm(mpi_out, mpi_in, xk->pubExponent, xk->modulus);
477
478 /* release unneeded objects */
479 gcry_mpi_release(mpi_in);
480
481 /* convert result MPI */
482 err=gcry_mpi_print(GCRYMPI_FMT_USG,
483 pOutData, *pOutLen,
484 &nwritten, mpi_out);
485 gcry_mpi_release(mpi_out);
486 if (err) {
487 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
488 return GWEN_ERROR_BAD_DATA;
489 }
490 *pOutLen=nwritten;
491
492 return 0;
493}
494
495
496
498 const uint8_t *pInData,
499 uint32_t inLen,
500 uint8_t *pOutData,
501 uint32_t *pOutLen)
502{
503 GWEN_CRYPT_KEY_RSA *xk;
504 gcry_error_t err;
505 size_t nscanned;
506 gcry_mpi_t mpi_in=NULL;
507 gcry_mpi_t mpi_out;
508 size_t nwritten;
509
510 assert(k);
511 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
512 assert(xk);
513
514 if (xk->modulus==NULL) {
515 DBG_ERROR(GWEN_LOGDOMAIN, "No modulus in key data");
516 return GWEN_ERROR_BAD_DATA;
517 }
518
519 if (xk->privExponent==NULL) {
520 DBG_ERROR(GWEN_LOGDOMAIN, "No secret exponent in key data");
521 return GWEN_ERROR_BAD_DATA;
522 }
523
524
525 /* convert input to MPI */
526 err=gcry_mpi_scan(&mpi_in, GCRYMPI_FMT_USG, pInData, inLen, &nscanned);
527 if (err) {
528 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
529 gcry_mpi_release(mpi_in);
530 return GWEN_ERROR_BAD_DATA;
531 }
532
533 /* decrypt */
534 mpi_out=gcry_mpi_new(GWEN_Crypt_Key_GetKeySize(k));
535 gcry_mpi_powm(mpi_out, mpi_in, xk->privExponent, xk->modulus);
536
537 /* release unneeded objects */
538 gcry_mpi_release(mpi_in);
539
540 /* convert result MPI */
541 err=gcry_mpi_print(GCRYMPI_FMT_USG,
542 pOutData, *pOutLen,
543 &nwritten, mpi_out);
544 gcry_mpi_release(mpi_out);
545 if (err) {
546 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
547 return GWEN_ERROR_BAD_DATA;
548 }
549 *pOutLen=nwritten;
550
551 return 0;
552}
553
554
555
556static int GWEN_Crypt_KeyRsa__ReadMpi(GWEN_DB_NODE *db, const char *dbName, gcry_mpi_t *pMpi)
557{
558 gcry_error_t err;
559 const void *p;
560 unsigned int len;
561 gcry_mpi_t mpi=NULL;
562 size_t nscanned=0;
563
564 /* read n */
565 p=GWEN_DB_GetBinValue(db, dbName, 0, NULL, 0, &len);
566 if (p==NULL || len<1) {
567 DBG_INFO(GWEN_LOGDOMAIN, "Missing %s", dbName);
568 return GWEN_ERROR_NO_DATA;
569 }
570
571 err=gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, p, len, &nscanned);
572 if (err) {
573 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_scan(): %s", gcry_strerror(err));
574 gcry_mpi_release(mpi);
575 return GWEN_ERROR_GENERIC;
576 }
577 if (nscanned<1) {
578 if (mpi==NULL) {
579 DBG_INFO(GWEN_LOGDOMAIN, "Empty %s (%d)", dbName, (int)nscanned);
580 return GWEN_ERROR_BAD_DATA;
581 }
582 }
583 *pMpi=mpi;
584
585 return 0;
586}
587
588
589
590
591static int GWEN_Crypt_KeyRsa__WriteMpi(GWEN_DB_NODE *db, const char *dbName, const gcry_mpi_t mpi)
592{
593 gcry_error_t err;
594 unsigned char *buf;
595 size_t nbytes;
596
597 /* write mpi as bin into a buffer which will be allocates by this function */
598 err=gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &nbytes, mpi);
599 if (err) {
600 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_aprint(%s): %s", dbName, gcry_strerror(err));
601 return GWEN_ERROR_GENERIC;
602 }
604 dbName,
605 buf, nbytes);
606 gcry_free(buf);
607
608 return 0;
609}
610
611
612
613static int GWEN_Crypt_KeyRsa__MpiToBuffer(const gcry_mpi_t mpi, unsigned char *buf, size_t nbytes)
614{
615 gcry_error_t err;
616 size_t nwritten=0;
617
618 /* write mpi as bin into the given buffer */
619 err=gcry_mpi_print(GCRYMPI_FMT_USG, buf, nbytes, &nwritten, mpi);
620 if (err) {
621 DBG_INFO(GWEN_LOGDOMAIN, "gcry_mpi_print(): %s", gcry_strerror(err));
622 return GWEN_ERROR_GENERIC;
623 }
624
625 return nwritten;
626}
627
628
629
630static GWENHYWFAR_CB
632{
633 GWEN_CRYPT_KEY_RSA *xk;
634
635 xk=(GWEN_CRYPT_KEY_RSA *) p;
636 if (xk->modulus)
637 gcry_mpi_release(xk->modulus);
638 if (xk->pubExponent)
639 gcry_mpi_release(xk->pubExponent);
640 if (xk->privExponent)
641 gcry_mpi_release(xk->privExponent);
642
644}
645
646
647
649{
650 int rv;
651 int isPublic;
653 GWEN_CRYPT_KEY_RSA *xk;
654 GWEN_DB_NODE *dbR;
655
657 if (dbR==NULL) {
658 DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key (no RSA group)");
659 return NULL;
660 }
662 if (k==NULL) {
663 DBG_INFO(GWEN_LOGDOMAIN, "here");
664 return NULL;
665 }
666 if (GWEN_Crypt_Key_GetCryptAlgoId(k)!=GWEN_Crypt_CryptAlgoId_Rsa) {
667 DBG_ERROR(GWEN_LOGDOMAIN, "DB does not contain an RSA key");
669 return NULL;
670 }
671
672 /* extend key */
673 GWEN_NEW_OBJECT(GWEN_CRYPT_KEY_RSA, xk);
674 GWEN_INHERIT_SETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k, xk,
680
681 isPublic=GWEN_DB_GetIntValue(dbR, "isPublic", 0, 1);
682 xk->pub=isPublic;
683
684 xk->flags=GWEN_DB_GetIntValue(dbR, "flags", 0, 0);
685
686 /* read data */
687 rv=GWEN_Crypt_KeyRsa__ReadMpi(dbR, "n", &(xk->modulus));
688 if (rv<0) {
689 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
691 return NULL;
692 }
693
694 rv=GWEN_Crypt_KeyRsa__ReadMpi(dbR, "e", &(xk->pubExponent));
695 if (rv<0) {
696 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
698 return NULL;
699 }
700
701 if (!isPublic) {
702 rv=GWEN_Crypt_KeyRsa__ReadMpi(dbR, "d", &(xk->privExponent));
703 if (rv<0) {
704 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
706 return NULL;
707 }
708 }
709
710
711 return k;
712}
713
714
715
717{
718 GWEN_CRYPT_KEY_RSA *xk;
719 GWEN_DB_NODE *dbR;
720 int rv;
721
722 assert(k);
723 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
724 assert(xk);
725
726 if (xk->pub && !pub) {
727 DBG_ERROR(GWEN_LOGDOMAIN, "Can't write public key as secret key");
728 return GWEN_ERROR_INVALID;
729 }
730
731#if 0
732 DBG_ERROR(0, "toDb (%s):", pub?"public":"private");
733 dumpKeyData(ds);
734#endif
735
736 /* let key module write basic key info */
737 rv=GWEN_Crypt_Key_toDb(k, db);
738 if (rv)
739 return rv;
740
741 /* write RSA stuff into our own group */
743 assert(dbR);
744
746 "isPublic", pub);
748 "flags", xk->flags);
749
750 /* store n */
751 rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "n", xk->modulus);
752 if (rv) {
753 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
754 return rv;
755 }
756
757 /* store e */
758 rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "e", xk->pubExponent);
759 if (rv) {
760 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
761 return rv;
762 }
763
764
765 if (!pub) {
766 /* store d */
767 rv=GWEN_Crypt_KeyRsa__WriteMpi(dbR, "d", xk->privExponent);
768 if (rv) {
769 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
770 return rv;
771 }
772 }
773
774 return 0;
775}
776
777
778
779
780int GWEN_Crypt_KeyRsa_GetModulus(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen)
781{
782 GWEN_CRYPT_KEY_RSA *xk;
783 int rv;
784
785 assert(k);
786 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
787 assert(xk);
788
789 rv=GWEN_Crypt_KeyRsa__MpiToBuffer(xk->modulus, buffer, *pBufLen);
790 if (rv<1) {
791 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
792 if (rv<0)
793 return rv;
794 return GWEN_ERROR_GENERIC;
795 }
796
797 *pBufLen=rv;
798 return 0;
799}
800
801
802
803int GWEN_Crypt_KeyRsa_GetExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen)
804{
805 GWEN_CRYPT_KEY_RSA *xk;
806 int rv;
807
808 assert(k);
809 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
810 assert(xk);
811
812 rv=GWEN_Crypt_KeyRsa__MpiToBuffer(xk->pubExponent, buffer, *pBufLen);
813 if (rv<1) {
814 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
815 if (rv<0)
816 return rv;
817 return GWEN_ERROR_GENERIC;
818 }
819
820 *pBufLen=rv;
821 return 0;
822}
823
824
825
826int GWEN_Crypt_KeyRsa_GetSecretExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen)
827{
828 GWEN_CRYPT_KEY_RSA *xk;
829 int rv;
830
831 assert(k);
832 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
833 assert(xk);
834
835 rv=GWEN_Crypt_KeyRsa__MpiToBuffer(xk->privExponent, buffer, *pBufLen);
836 if (rv<1) {
837 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
838 if (rv<0)
839 return rv;
840 return GWEN_ERROR_GENERIC;
841 }
842
843 *pBufLen=rv;
844 return 0;
845}
846
847
848
850 const uint8_t *pModulus,
851 uint32_t lModulus,
852 const uint8_t *pExponent,
853 uint32_t lExponent)
854{
855 GWEN_DB_NODE *dbKey;
856 GWEN_DB_NODE *dbR;
857 GWEN_CRYPT_KEY *key;
858
859 assert(nbytes);
860 assert(pModulus);
861 assert(lModulus);
862 assert(pExponent);
863 assert(lExponent);
864
865 dbKey=GWEN_DB_Group_new("key");
867
868 /* basic key stuff */
870 "cryptAlgoId",
871 GWEN_Crypt_CryptAlgoId_toString(GWEN_Crypt_CryptAlgoId_Rsa));
873 "keySize", nbytes);
874
875 /* RSA stuff */
877 "isPublic", 1);
879 "n",
880 pModulus, lModulus);
882 "e",
883 pExponent, lExponent);
884
885 /* create key from DB */
886 key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
887 if (key==NULL) {
889 "Internal error: Bad RSA key group");
890 GWEN_DB_Dump(dbKey, 2);
891 GWEN_DB_Group_free(dbKey);
892 return NULL;
893 }
894
895 GWEN_DB_Group_free(dbKey);
896 return key;
897}
898
899
900
902 const uint8_t *pModulus,
903 uint32_t lModulus,
904 const uint8_t *pExponent,
905 uint32_t lExponent,
906 const uint8_t *pPrivExponent,
907 uint32_t lPrivExponent)
908{
909 GWEN_DB_NODE *dbKey;
910 GWEN_DB_NODE *dbR;
911 GWEN_CRYPT_KEY *key;
912
913 assert(nbytes);
914 assert(pModulus);
915 assert(lModulus);
916 assert(pExponent);
917 assert(lExponent);
918 assert(pPrivExponent);
919 assert(lPrivExponent);
920
921 dbKey=GWEN_DB_Group_new("key");
923
924 /* basic key stuff */
926 "cryptAlgoId",
927 GWEN_Crypt_CryptAlgoId_toString(GWEN_Crypt_CryptAlgoId_Rsa));
929 "keySize", nbytes);
930
931 /* RSA stuff */
933 "isPublic", 0);
935 "n",
936 pModulus, lModulus);
938 "e",
939 pExponent, lExponent);
941 "d",
942 pPrivExponent, lPrivExponent);
943
944 /* create key from DB */
945 key=GWEN_Crypt_KeyRsa_fromDb(dbKey);
946 if (key==NULL) {
948 "Internal error: Bad RSA key group");
949 GWEN_DB_Dump(dbKey, 2);
950 GWEN_DB_Group_free(dbKey);
951 return NULL;
952 }
953
954 GWEN_DB_Group_free(dbKey);
955 return key;
956}
957
958
959
961{
962 GWEN_CRYPT_KEY_RSA *xk;
963 GWEN_DB_NODE *dbKey;
964 GWEN_CRYPT_KEY *nk;
965 int rv;
966
967 assert(k);
968 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
969 assert(xk);
970
971 dbKey=GWEN_DB_Group_new("dbKey");
972 rv=GWEN_Crypt_KeyRsa_toDb(k, dbKey, xk->pub);
973 if (rv<0) {
974 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
975 GWEN_DB_Group_free(dbKey);
976 return NULL;
977 }
978
979 nk=GWEN_Crypt_KeyRsa_fromDb(dbKey);
980 GWEN_DB_Group_free(dbKey);
981 if (nk==NULL) {
982 DBG_INFO(GWEN_LOGDOMAIN, "Could not create key");
983 }
984
985 GWEN_Crypt_KeyRsa_SetFlags(nk, xk->flags);
986
987 return nk;
988}
989
990
991
993{
994 GWEN_CRYPT_KEY_RSA *xk;
995
996 assert(k);
997 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
998 assert(xk);
999
1000 return xk->flags;
1001}
1002
1003
1004
1006{
1007 GWEN_CRYPT_KEY_RSA *xk;
1008
1009 assert(k);
1010 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
1011 assert(xk);
1012
1013 xk->flags=fl;
1014}
1015
1016
1017
1019{
1020 GWEN_CRYPT_KEY_RSA *xk;
1021
1022 assert(k);
1023 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
1024 assert(xk);
1025
1026 xk->flags|=fl;
1027}
1028
1029
1030
1032{
1033 GWEN_CRYPT_KEY_RSA *xk;
1034
1035 assert(k);
1036 xk=GWEN_INHERIT_GETDATA(GWEN_CRYPT_KEY, GWEN_CRYPT_KEY_RSA, k);
1037 assert(xk);
1038
1039 xk->flags&=~fl;
1040}
1041
1042
1043
1044
1045
1046
1047
1048
#define NULL
Definition binreloc.c:300
const char * GWEN_Crypt_CryptAlgoId_toString(GWEN_CRYPT_CRYPTALGOID a)
Definition cryptalgo.c:53
GWEN_CRYPT_KEY * GWEN_Crypt_Key_new(GWEN_CRYPT_CRYPTALGOID cryptAlgoId, int keySize)
Definition cryptkey.c:63
void GWEN_Crypt_Key_free(GWEN_CRYPT_KEY *k)
Definition cryptkey.c:154
GWEN_CRYPT_KEY * GWEN_Crypt_Key_fromDb(GWEN_DB_NODE *db)
Definition cryptkey.c:80
GWEN_CRYPT_CRYPTALGOID GWEN_Crypt_Key_GetCryptAlgoId(const GWEN_CRYPT_KEY *k)
Definition cryptkey.c:171
int GWEN_Crypt_Key_GetKeySize(const GWEN_CRYPT_KEY *k)
Definition cryptkey.c:179
GWEN_CRYPT_KEY_SIGN_FN GWEN_Crypt_Key_SetSignFn(GWEN_CRYPT_KEY *k, GWEN_CRYPT_KEY_SIGN_FN f)
Definition cryptkey.c:219
GWEN_CRYPT_KEY_VERIFY_FN GWEN_Crypt_Key_SetVerifyFn(GWEN_CRYPT_KEY *k, GWEN_CRYPT_KEY_VERIFY_FN f)
Definition cryptkey.c:232
GWEN_CRYPT_KEY_ENCIPHER_FN GWEN_Crypt_Key_SetEncipherFn(GWEN_CRYPT_KEY *k, GWEN_CRYPT_KEY_ENCIPHER_FN f)
Definition cryptkey.c:245
int GWEN_Crypt_Key_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db)
Definition cryptkey.c:117
GWEN_CRYPT_KEY_DECIPHER_FN GWEN_Crypt_Key_SetDecipherFn(GWEN_CRYPT_KEY *k, GWEN_CRYPT_KEY_DECIPHER_FN f)
Definition cryptkey.c:259
struct GWEN_CRYPT_KEY GWEN_CRYPT_KEY
Definition cryptkey.h:26
void GWEN_Crypt_KeyRsa_SubFlags(GWEN_CRYPT_KEY *k, uint32_t fl)
static int GWEN_Crypt_KeyRsa__MpiToBuffer(const gcry_mpi_t mpi, unsigned char *buf, size_t nbytes)
static int GWEN_Crypt_KeyRsa__getNamedElement(gcry_sexp_t pkey, const char *name, gcry_mpi_t *pMpi)
Definition cryptkeyrsa.c:62
GWEN_CRYPT_KEY * GWEN_Crypt_KeyRsa_dup(const GWEN_CRYPT_KEY *k)
int GWEN_Crypt_KeyRsa_GeneratePair2(unsigned int nbits, int use65537e, GWEN_CRYPT_KEY **pPubKey, GWEN_CRYPT_KEY **pSecretKey)
static GWENHYWFAR_CB int GWEN_Crypt_KeyRsa_Decipher(GWEN_CRYPT_KEY *k, const uint8_t *pInData, uint32_t inLen, uint8_t *pOutData, uint32_t *pOutLen)
GWEN_CRYPT_KEY * GWEN_Crypt_KeyRsa_fromDb(GWEN_DB_NODE *db)
int GWEN_Crypt_KeyRsa_GeneratePair(unsigned int nbytes, int use65537e, GWEN_CRYPT_KEY **pPubKey, GWEN_CRYPT_KEY **pSecretKey)
GWEN_CRYPT_KEY * GWEN_Crypt_KeyRsa_fromModExp(unsigned int nbytes, const uint8_t *pModulus, uint32_t lModulus, const uint8_t *pExponent, uint32_t lExponent)
int GWEN_Crypt_KeyRsa_toDb(const GWEN_CRYPT_KEY *k, GWEN_DB_NODE *db, int pub)
static GWENHYWFAR_CB int GWEN_Crypt_KeyRsa_Encipher(GWEN_CRYPT_KEY *k, const uint8_t *pInData, uint32_t inLen, uint8_t *pOutData, uint32_t *pOutLen)
int GWEN_Crypt_KeyRsa_GetExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen)
static GWENHYWFAR_CB int GWEN_Crypt_KeyRsa_Verify(GWEN_CRYPT_KEY *k, const uint8_t *pInData, uint32_t inLen, const uint8_t *pSignatureData, uint32_t signatureLen)
GWEN_CRYPT_KEY * GWEN_Crypt_KeyRsa_fromModPrivExp(unsigned int nbytes, const uint8_t *pModulus, uint32_t lModulus, const uint8_t *pExponent, uint32_t lExponent, const uint8_t *pPrivExponent, uint32_t lPrivExponent)
static GWENHYWFAR_CB void GWEN_Crypt_KeyRsa_freeData(GWEN_UNUSED void *bp, void *p)
int GWEN_Crypt_KeyRsa_GetSecretExponent(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen)
void GWEN_Crypt_KeyRsa_AddFlags(GWEN_CRYPT_KEY *k, uint32_t fl)
void GWEN_Crypt_KeyRsa_SetFlags(GWEN_CRYPT_KEY *k, uint32_t fl)
GWENHYWFAR_CB int GWEN_Crypt_KeyRsa_Sign(GWEN_CRYPT_KEY *k, const uint8_t *pInData, uint32_t inLen, uint8_t *pSignatureData, uint32_t *pSignatureLen)
#define PRI_SIZET
Definition cryptkeyrsa.c:99
static int GWEN_Crypt_KeyRsa__WriteMpi(GWEN_DB_NODE *db, const char *dbName, const gcry_mpi_t mpi)
int GWEN_Crypt_KeyRsa_GetModulus(const GWEN_CRYPT_KEY *k, uint8_t *buffer, uint32_t *pBufLen)
static int GWEN_Crypt_KeyRsa__ReadMpi(GWEN_DB_NODE *db, const char *dbName, gcry_mpi_t *pMpi)
uint32_t GWEN_Crypt_KeyRsa_GetFlags(const GWEN_CRYPT_KEY *k)
#define GWEN_CRYPT_KEYRSA_FLAGS_DIRECTSIGN
Definition cryptkeyrsa.h:22
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition db.c:173
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition db.c:1202
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition db.c:1381
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const void *val, unsigned int valSize)
Definition db.c:1269
const void * GWEN_DB_GetBinValue(GWEN_DB_NODE *n, const char *path, int idx, const void *defVal, unsigned int defValSize, unsigned int *returnValueSize)
Definition db.c:1237
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
Definition db.c:1420
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition db.c:1163
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition db.c:421
#define GWEN_DB_FLAGS_OVERWRITE_GROUPS
Definition db.h:123
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
#define GWEN_ERROR_VERIFY
Definition error.h:104
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_BAD_DATA
Definition error.h:121
#define GWEN_ERROR_GENERIC
Definition error.h:62
#define GWEN_ERROR_NO_DATA
Definition error.h:94
#define GWEN_UNUSED
#define GWENHYWFAR_CB
#define GWEN_INHERIT_SETDATA(bt, t, element, data, fn)
Definition inherit.h:300
#define GWEN_INHERIT(bt, t)
Definition inherit.h:264
#define GWEN_INHERIT_GETDATA(bt, t, element)
Definition inherit.h:279
#define GWEN_LOGDOMAIN
Definition logger.h:32
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
Definition path.h:84
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition text.c:1283