expand GNUNET_OS_ProjectData API to also enable de-duplcation of logic for --help
[oweals/gnunet.git] / src / util / crypto_rsa.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2014,2016 GNUnet e.V.
4
5   GNUnet is free software; you can redistribute it and/or modify it under the
6   terms of the GNU General Public License as published by the Free Software
7   Foundation; either version 3, or (at your option) any later version.
8
9   GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License along with
14   GNUnet; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
15 */
16
17 /**
18  * @file util/crypto_rsa.c
19  * @brief Chaum-style Blind signatures based on RSA
20  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
21  * @author Christian Grothoff
22  * @author Jeffrey Burdges <burdges@gnunet.org>
23  */
24 #include "platform.h"
25 #include <gcrypt.h>
26 #include "gnunet_crypto_lib.h"
27
28 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
29
30
31 /**
32  * The private information of an RSA key pair.
33  */
34 struct GNUNET_CRYPTO_RsaPrivateKey
35 {
36   /**
37    * Libgcrypt S-expression for the RSA private key.
38    */
39   gcry_sexp_t sexp;
40 };
41
42
43 /**
44  * The public information of an RSA key pair.
45  */
46 struct GNUNET_CRYPTO_RsaPublicKey
47 {
48   /**
49    * Libgcrypt S-expression for the RSA public key.
50    */
51   gcry_sexp_t sexp;
52 };
53
54
55 /**
56  * @brief an RSA signature
57  */
58 struct GNUNET_CRYPTO_RsaSignature
59 {
60   /**
61    * Libgcrypt S-expression for the RSA signature.
62    */
63   gcry_sexp_t sexp;
64 };
65
66
67 /**
68  * @brief RSA blinding key
69  */
70 struct GNUNET_CRYPTO_rsa_BlindingKey
71 {
72   /**
73    * Random value used for blinding.
74    */
75   gcry_mpi_t r;
76 };
77
78
79 /**
80  * Extract values from an S-expression.
81  *
82  * @param array where to store the result(s)
83  * @param sexp S-expression to parse
84  * @param topname top-level name in the S-expression that is of interest
85  * @param elems names of the elements to extract
86  * @return 0 on success
87  */
88 static int
89 key_from_sexp (gcry_mpi_t *array,
90                gcry_sexp_t sexp,
91                const char *topname,
92                const char *elems)
93 {
94   gcry_sexp_t list;
95   gcry_sexp_t l2;
96   const char *s;
97   unsigned int i;
98   unsigned int idx;
99
100   if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
101     return 1;
102   l2 = gcry_sexp_cadr (list);
103   gcry_sexp_release (list);
104   list = l2;
105   if (! list)
106     return 2;
107   idx = 0;
108   for (s = elems; *s; s++, idx++)
109   {
110     if (! (l2 = gcry_sexp_find_token (list, s, 1)))
111     {
112       for (i = 0; i < idx; i++)
113       {
114         gcry_free (array[i]);
115         array[i] = NULL;
116       }
117       gcry_sexp_release (list);
118       return 3;                 /* required parameter not found */
119     }
120     array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
121     gcry_sexp_release (l2);
122     if (! array[idx])
123     {
124       for (i = 0; i < idx; i++)
125       {
126         gcry_free (array[i]);
127         array[i] = NULL;
128       }
129       gcry_sexp_release (list);
130       return 4;                 /* required parameter is invalid */
131     }
132   }
133   gcry_sexp_release (list);
134   return 0;
135 }
136
137
138 /**
139  * Create a new private key. Caller must free return value.
140  *
141  * @param len length of the key in bits (i.e. 2048)
142  * @return fresh private key
143  */
144 struct GNUNET_CRYPTO_RsaPrivateKey *
145 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
146 {
147   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
148   gcry_sexp_t s_key;
149   gcry_sexp_t s_keyparam;
150
151   GNUNET_assert (0 ==
152                  gcry_sexp_build (&s_keyparam,
153                                   NULL,
154                                   "(genkey(rsa(nbits %d)))",
155                                   len));
156   GNUNET_assert (0 ==
157                  gcry_pk_genkey (&s_key,
158                                  s_keyparam));
159   gcry_sexp_release (s_keyparam);
160 #if EXTRA_CHECKS
161   GNUNET_assert (0 ==
162                  gcry_pk_testkey (s_key));
163 #endif
164   ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
165   ret->sexp = s_key;
166   return ret;
167 }
168
169
170 /**
171  * Free memory occupied by the private key.
172  *
173  * @param key pointer to the memory to free
174  */
175 void
176 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
177 {
178   gcry_sexp_release (key->sexp);
179   GNUNET_free (key);
180 }
181
182
183 /**
184  * Encode the private key in a format suitable for
185  * storing it into a file.
186  *
187  * @param key the private key
188  * @param[out] buffer set to a buffer with the encoded key
189  * @return size of memory allocated in @a buffer
190  */
191 size_t
192 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
193                                       char **buffer)
194 {
195   size_t n;
196   char *b;
197
198   n = gcry_sexp_sprint (key->sexp,
199                         GCRYSEXP_FMT_DEFAULT,
200                         NULL,
201                         0);
202   b = GNUNET_malloc (n);
203   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
204                  gcry_sexp_sprint (key->sexp,
205                                    GCRYSEXP_FMT_DEFAULT,
206                                    b,
207                                    n));
208   *buffer = b;
209   return n;
210 }
211
212
213 /**
214  * Decode the private key from the data-format back
215  * to the "normal", internal format.
216  *
217  * @param buf the buffer where the private key data is stored
218  * @param len the length of the data in @a buf
219  * @return NULL on error
220  */
221 struct GNUNET_CRYPTO_RsaPrivateKey *
222 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
223                                       size_t len)
224 {
225   struct GNUNET_CRYPTO_RsaPrivateKey *key;
226   key = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
227   if (0 !=
228       gcry_sexp_new (&key->sexp,
229                      buf,
230                      len,
231                      0))
232   {
233     LOG (GNUNET_ERROR_TYPE_WARNING,
234          "Decoded private key is not valid\n");
235     GNUNET_free (key);
236     return NULL;
237   }
238   if (0 != gcry_pk_testkey (key->sexp))
239   {
240     LOG (GNUNET_ERROR_TYPE_WARNING,
241          "Decoded private key is not valid\n");
242     GNUNET_CRYPTO_rsa_private_key_free (key);
243     return NULL;
244   }
245   return key;
246 }
247
248
249 /**
250  * Extract the public key of the given private key.
251  *
252  * @param priv the private key
253  * @retur NULL on error, otherwise the public key
254  */
255 struct GNUNET_CRYPTO_RsaPublicKey *
256 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
257 {
258   struct GNUNET_CRYPTO_RsaPublicKey *pub;
259   gcry_mpi_t ne[2];
260   int rc;
261   gcry_sexp_t result;
262
263   rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
264   if (0 != rc)
265     rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
266   if (0 != rc)
267     rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
268   if (0 != rc)
269   {
270     GNUNET_break_op (0);
271     return NULL;
272   }
273   rc = gcry_sexp_build (&result,
274                         NULL,
275                         "(public-key(rsa(n %m)(e %m)))",
276                         ne[0],
277                         ne[1]);
278   gcry_mpi_release (ne[0]);
279   gcry_mpi_release (ne[1]);
280   pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
281   pub->sexp = result;
282   return pub;
283 }
284
285
286 /**
287  * Free memory occupied by the public key.
288  *
289  * @param key pointer to the memory to free
290  */
291 void
292 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
293 {
294   gcry_sexp_release (key->sexp);
295   GNUNET_free (key);
296 }
297
298
299 /**
300  * Encode the public key in a format suitable for
301  * storing it into a file.
302  *
303  * @param key the private key
304  * @param[out] buffer set to a buffer with the encoded key
305  * @return size of memory allocated in @a buffer
306  */
307 size_t
308 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key,
309                                      char **buffer)
310 {
311   size_t n;
312   char *b;
313
314   n = gcry_sexp_sprint (key->sexp,
315                         GCRYSEXP_FMT_ADVANCED,
316                         NULL,
317                         0);
318   b = GNUNET_malloc (n);
319   GNUNET_assert ((n -1) ==      /* since the last byte is \0 */
320                  gcry_sexp_sprint (key->sexp,
321                                    GCRYSEXP_FMT_ADVANCED,
322                                    b,
323                                    n));
324   *buffer = b;
325   return n;
326 }
327
328
329 /**
330  * Compute hash over the public key.
331  *
332  * @param key public key to hash
333  * @param hc where to store the hash code
334  */
335 void
336 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key,
337                                    struct GNUNET_HashCode *hc)
338 {
339   char *buf;
340   size_t buf_size;
341
342   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
343                                                   &buf);
344   GNUNET_CRYPTO_hash (buf,
345                       buf_size,
346                       hc);
347   GNUNET_free (buf);
348 }
349
350
351 /**
352  * Decode the public key from the data-format back
353  * to the "normal", internal format.
354  *
355  * @param buf the buffer where the public key data is stored
356  * @param len the length of the data in @a buf
357  * @return NULL on error
358  */
359 struct GNUNET_CRYPTO_RsaPublicKey *
360 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
361                                      size_t len)
362 {
363   struct GNUNET_CRYPTO_RsaPublicKey *key;
364   gcry_mpi_t n;
365   int ret;
366
367   key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
368   if (0 !=
369       gcry_sexp_new (&key->sexp,
370                      buf,
371                      len,
372                      0))
373   {
374     GNUNET_break_op (0);
375     GNUNET_free (key);
376     return NULL;
377   }
378   /* verify that this is an RSA public key */
379   ret = key_from_sexp (&n, key->sexp, "public-key", "n");
380   if (0 != ret)
381     ret = key_from_sexp (&n, key->sexp, "rsa", "n");
382   if (0 != ret)
383   {
384     /* this is no public RSA key */
385     GNUNET_break (0);
386     gcry_sexp_release (key->sexp);
387     GNUNET_free (key);
388     return NULL;
389   }
390   gcry_mpi_release (n);
391   return key;
392 }
393
394
395 /**
396  * Create a blinding key
397  *
398  * @param len length of the key in bits (i.e. 2048)
399  * @return the newly created blinding key
400  */
401 struct GNUNET_CRYPTO_rsa_BlindingKey *
402 GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
403 {
404   struct GNUNET_CRYPTO_rsa_BlindingKey *blind;
405
406   blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
407   blind->r = gcry_mpi_new (len);
408   gcry_mpi_randomize (blind->r,
409                       len,
410                       GCRY_STRONG_RANDOM);
411   return blind;
412 }
413
414
415 /**
416  * Compare the values of two blinding keys.
417  *
418  * @param b1 one key
419  * @param b2 the other key
420  * @return 0 if the two are equal
421  */
422 int
423 GNUNET_CRYPTO_rsa_blinding_key_cmp (struct GNUNET_CRYPTO_rsa_BlindingKey *b1,
424                                     struct GNUNET_CRYPTO_rsa_BlindingKey *b2)
425 {
426   return gcry_mpi_cmp (b1->r,
427                        b2->r);
428 }
429
430
431 /**
432  * Compare the values of two signatures.
433  *
434  * @param s1 one signature
435  * @param s2 the other signature
436  * @return 0 if the two are equal
437  */
438 int
439 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
440                                  struct GNUNET_CRYPTO_RsaSignature *s2)
441 {
442   char *b1;
443   char *b2;
444   size_t z1;
445   size_t z2;
446   int ret;
447
448   z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
449                                            &b1);
450   z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
451                                            &b2);
452   if (z1 != z2)
453     ret = 1;
454   else
455     ret = memcmp (b1,
456                   b2,
457                   z1);
458   GNUNET_free (b1);
459   GNUNET_free (b2);
460   return ret;
461 }
462
463
464 /**
465  * Compare the values of two public keys.
466  *
467  * @param p1 one public key
468  * @param p2 the other public key
469  * @return 0 if the two are equal
470  */
471 int
472 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
473                                   struct GNUNET_CRYPTO_RsaPublicKey *p2)
474 {
475   char *b1;
476   char *b2;
477   size_t z1;
478   size_t z2;
479   int ret;
480
481   z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
482                                             &b1);
483   z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
484                                             &b2);
485   if (z1 != z2)
486     ret = 1;
487   else
488     ret = memcmp (b1,
489                   b2,
490                   z1);
491   GNUNET_free (b1);
492   GNUNET_free (b2);
493   return ret;
494 }
495
496
497 /**
498  * Compare the values of two private keys.
499  *
500  * @param p1 one private key
501  * @param p2 the other private key
502  * @return 0 if the two are equal
503  */
504 int
505 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
506                                    struct GNUNET_CRYPTO_RsaPrivateKey *p2)
507 {
508   char *b1;
509   char *b2;
510   size_t z1;
511   size_t z2;
512   int ret;
513
514   z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
515                                             &b1);
516   z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
517                                             &b2);
518   if (z1 != z2)
519     ret = 1;
520   else
521     ret = memcmp (b1,
522                   b2,
523                   z1);
524   GNUNET_free (b1);
525   GNUNET_free (b2);
526   return ret;
527 }
528
529
530 /**
531  * Obtain the length of the RSA key in bits.
532  *
533  * @param key the public key to introspect
534  * @return length of the key in bits
535  */
536 unsigned int
537 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
538 {
539   gcry_mpi_t n;
540   int ret;
541   unsigned int rval;
542
543   ret = key_from_sexp (&n, key->sexp, "rsa", "n");
544   if (0 != ret)
545   {
546     /* this is no public RSA key */
547     GNUNET_break (0);
548     return 0;
549   }
550   rval = gcry_mpi_get_nbits (n);
551   gcry_mpi_release (n);
552   return rval;
553 }
554
555
556 /**
557  * Destroy a blinding key
558  *
559  * @param bkey the blinding key to destroy
560  */
561 void
562 GNUNET_CRYPTO_rsa_blinding_key_free (struct GNUNET_CRYPTO_rsa_BlindingKey *bkey)
563 {
564   gcry_mpi_release (bkey->r);
565   GNUNET_free (bkey);
566 }
567
568
569 /**
570  * Print an MPI to a newly created buffer
571  *
572  * @param v MPI to print.
573  * @param[out] newly allocated buffer containing the result
574  * @return number of bytes stored in @a buffer
575  */
576 static size_t
577 numeric_mpi_alloc_n_print (gcry_mpi_t v,
578            char **buffer)
579 {
580   size_t n;
581   char *b;
582   size_t rsize;
583
584   gcry_mpi_print (GCRYMPI_FMT_USG,
585                   NULL,
586                   0,
587                   &n,
588                   v);
589   b = GNUNET_malloc (n);
590   GNUNET_assert (0 ==
591                  gcry_mpi_print (GCRYMPI_FMT_USG,
592                                  (unsigned char *) b,
593                                  n,
594                                  &rsize,
595                                  v));
596   *buffer = b;
597   return n;
598 }
599
600
601 /**
602  * Encode the blinding key in a format suitable for
603  * storing it into a file.
604  *
605  * @param bkey the blinding key
606  * @param[out] buffer set to a buffer with the encoded key
607  * @return size of memory allocated in @a buffer
608  */
609 size_t
610 GNUNET_CRYPTO_rsa_blinding_key_encode (const struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
611                                        char **buffer)
612 {
613   return numeric_mpi_alloc_n_print (bkey->r, buffer);
614 }
615
616
617 /**
618  * Decode the blinding key from the data-format back
619  * to the "normal", internal format.
620  *
621  * @param buf the buffer where the public key data is stored
622  * @param len the length of the data in @a buf
623  * @return NULL on error
624  */
625 struct GNUNET_CRYPTO_rsa_BlindingKey *
626 GNUNET_CRYPTO_rsa_blinding_key_decode (const char *buf,
627                                        size_t len)
628 {
629   struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
630   size_t rsize;
631
632   bkey = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
633   if (0 !=
634       gcry_mpi_scan (&bkey->r,
635                      GCRYMPI_FMT_USG,
636                      (const unsigned char *) buf,
637                      len,
638                      &rsize))
639   {
640     GNUNET_break_op (0);
641     GNUNET_free (bkey);
642     return NULL;
643   }
644   return bkey;
645 }
646
647
648 /**
649  * Computes a full domain hash seeded by the given public key.
650  * This gives a measure of provable security to the Taler exchange
651  * against one-more forgery attacks.  See:
652  *   https://eprint.iacr.org/2001/002.pdf
653  *   http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
654  *
655  * @param[out] r MPI value set to the FDH
656  * @param hash initial hash of the message to sign
657  * @param pkey the public key of the signer
658  * @param rsize If not NULL, the number of bytes actually stored in buffer
659  * @return libgcrypt error that to represent an allocation failure
660  */
661 gcry_error_t
662 rsa_full_domain_hash (gcry_mpi_t *r,
663                       const struct GNUNET_HashCode *hash,
664                       const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
665                       size_t *rsize)
666 {
667   unsigned int i;
668   unsigned int nbits;
669   unsigned int nhashes;
670   gcry_error_t rc;
671   char *buf;
672   size_t buf_len;
673   gcry_md_hd_t h;
674   gcry_md_hd_t h0;
675   struct GNUNET_HashCode *hs;
676
677   /* Uncomment the following to debug without using the full domain hash */
678   /*
679   rc = gcry_mpi_scan (r,
680                       GCRYMPI_FMT_USG,
681                       (const unsigned char *)hash,
682                       sizeof(struct GNUNET_HashCode),
683                       rsize);
684   return rc;
685   */
686
687   nbits = GNUNET_CRYPTO_rsa_public_key_len (pkey);
688   if (nbits < 512)
689     nbits = 512;
690
691   /* Already almost an HMAC since we consume a hash, so no GCRY_MD_FLAG_HMAC. */
692   rc = gcry_md_open (&h, GCRY_MD_SHA512, 0);
693   if (0 != rc)
694     return rc;
695
696   /* We seed with the public denomination key as a homage to RSA-PSS by  *
697    * Mihir Bellare and Phillip Rogaway.  Doing this lowers the degree    *
698    * of the hypothetical polyomial-time attack on RSA-KTI created by a   *
699    * polynomial-time one-more forgary attack.  Yey seeding!              */
700   buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &buf);
701   gcry_md_write (h, buf, buf_len);
702   GNUNET_free (buf);
703
704   nhashes = (nbits-1) / (8 * sizeof(struct GNUNET_HashCode)) + 1;
705   hs = GNUNET_new_array (nhashes,
706                          struct GNUNET_HashCode);
707   for (i=0; i<nhashes; i++)
708   {
709     gcry_md_write (h, hash, sizeof(struct GNUNET_HashCode));
710     rc = gcry_md_copy (&h0, h);
711     if (0 != rc)
712     {
713       gcry_md_close (h0);
714       break;
715     }
716     gcry_md_putc (h0, i % 256);
717     memcpy (&hs[i],
718             gcry_md_read (h0, GCRY_MD_SHA512),
719             sizeof(struct GNUNET_HashCode));
720     gcry_md_close (h0);
721   }
722   gcry_md_close (h);
723   if (0 != rc)
724   {
725     GNUNET_free (hs);
726     return rc;
727   }
728
729   rc = gcry_mpi_scan (r,
730                       GCRYMPI_FMT_USG,
731                       (const unsigned char *) hs,
732                       nhashes * sizeof(struct GNUNET_HashCode),
733                       rsize);
734   GNUNET_free (hs);
735   if (0 != rc)
736     return rc;
737
738   /* Do not allow *r to exceed n or signatures fail to verify unpredictably. *
739    * This happening with  gcry_mpi_clear_highbit (*r, nbits-1) so maybe      *
740    * gcry_mpi_clear_highbit is broken, but setting the highbit sounds good.  */
741   gcry_mpi_set_highbit (*r, nbits-2);
742   return rc;
743 }
744
745
746 /**
747  * Blinds the given message with the given blinding key
748  *
749  * @param hash hash of the message to sign
750  * @param bkey the blinding key
751  * @param pkey the public key of the signer
752  * @param[out] buffer set to a buffer with the blinded message to be signed
753  * @return number of bytes stored in @a buffer
754  */
755 size_t
756 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
757                          struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
758                          struct GNUNET_CRYPTO_RsaPublicKey *pkey,
759                          char **buffer)
760 {
761   gcry_mpi_t data;
762   gcry_mpi_t ne[2];
763   gcry_mpi_t r_e;
764   gcry_mpi_t data_r_e;
765   size_t rsize;
766   size_t n;
767   gcry_error_t rc;
768   int ret;
769
770   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
771   if (0 != ret)
772     ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
773   if (0 != ret)
774   {
775     GNUNET_break (0);
776     *buffer = NULL;
777     return 0;
778   }
779
780   rc = rsa_full_domain_hash (&data, hash, pkey, &rsize);
781   if (0 != rc)  /* Allocation error in libgcrypt */
782   {
783     GNUNET_break (0);
784     gcry_mpi_release (ne[0]);
785     gcry_mpi_release (ne[1]);
786     *buffer = NULL;
787     return 0;
788   }
789   r_e = gcry_mpi_new (0);
790   gcry_mpi_powm (r_e,
791                  bkey->r,
792                  ne[1],
793                  ne[0]);
794   data_r_e = gcry_mpi_new (0);
795   gcry_mpi_mulm (data_r_e,
796                  data,
797                  r_e,
798                  ne[0]);
799   gcry_mpi_release (data);
800   gcry_mpi_release (ne[0]);
801   gcry_mpi_release (ne[1]);
802   gcry_mpi_release (r_e);
803
804   n = numeric_mpi_alloc_n_print (data_r_e, buffer);
805   gcry_mpi_release (data_r_e);
806   return n;
807 }
808
809
810 /**
811  * Convert an MPI to an S-expression suitable for signature operations.
812  *
813  * @param value pointer to the data to convert
814  * @return converted s-expression
815  */
816 static gcry_sexp_t
817 mpi_to_sexp (gcry_mpi_t value)
818 {
819   gcry_sexp_t data = NULL;
820
821   GNUNET_assert (0 ==
822                  gcry_sexp_build (&data,
823                                   NULL,
824                                   "(data (flags raw) (value %M))",
825                                   value));
826   return data;
827 }
828
829
830 /**
831  * Sign the given MPI.
832  *
833  * @param key private key to use for the signing
834  * @param value the MPI to sign
835  * @return NULL on error, signature on success
836  */
837 static struct GNUNET_CRYPTO_RsaSignature *
838 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
839               gcry_mpi_t value)
840 {
841   struct GNUNET_CRYPTO_RsaSignature *sig;
842   struct GNUNET_CRYPTO_RsaPublicKey *public_key;
843   gcry_sexp_t data;
844   gcry_sexp_t result;
845
846   data = mpi_to_sexp (value);
847
848   if (0 !=
849       gcry_pk_sign (&result,
850                     data,
851                     key->sexp))
852   {
853     GNUNET_break (0);
854     return NULL;
855   }
856
857   /* verify signature (guards against Lenstra's attack with fault injection...) */
858   public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
859   if (0 !=
860       gcry_pk_verify (result,
861                       data,
862                       public_key->sexp))
863   {
864     GNUNET_break (0);
865     GNUNET_CRYPTO_rsa_public_key_free (public_key);
866     gcry_sexp_release (data);
867     gcry_sexp_release (result);
868     return NULL;
869   }
870   GNUNET_CRYPTO_rsa_public_key_free (public_key);
871
872   /* return signature */
873   gcry_sexp_release (data);
874   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
875   sig->sexp = result;
876   return sig;
877 }
878
879
880 /**
881  * Sign a blinded value, which must be a full domain hash of a message.
882  *
883  * @param key private key to use for the signing
884  * @param msg the message to sign
885  * @param msg_len number of bytes in @a msg to sign
886  * @return NULL on error, signature on success
887  */
888 struct GNUNET_CRYPTO_RsaSignature *
889 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
890                                 const void *msg,
891                                 size_t msg_len)
892 {
893   gcry_mpi_t v = NULL;
894   struct GNUNET_CRYPTO_RsaSignature *sig;
895
896   GNUNET_assert (0 ==
897                  gcry_mpi_scan (&v,
898                                 GCRYMPI_FMT_USG,
899                                 msg,
900                                 msg_len,
901                                 NULL));
902
903   sig = rsa_sign_mpi (key, v);
904   gcry_mpi_release (v);
905   return sig; 
906 }
907
908
909 /**
910  * Create and sign a full domain hash of a message.
911  *
912  * @param key private key to use for the signing
913  * @param hash the hash of the message to sign
914  * @return NULL on error, signature on success
915  */
916 struct GNUNET_CRYPTO_RsaSignature *
917 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
918                             const struct GNUNET_HashCode *hash)
919 {
920   struct GNUNET_CRYPTO_RsaPublicKey *pkey;
921   gcry_mpi_t v = NULL;
922   gcry_error_t rc;
923   struct GNUNET_CRYPTO_RsaSignature *sig;
924
925   pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
926   rc = rsa_full_domain_hash (&v, hash, pkey, NULL);
927   GNUNET_CRYPTO_rsa_public_key_free (pkey);
928   GNUNET_assert (0 == rc);
929
930   sig = rsa_sign_mpi (key, v);
931   gcry_mpi_release (v);
932   return sig; 
933
934 }
935
936
937 /**
938  * Free memory occupied by signature.
939  *
940  * @param sig memory to freee
941  */
942 void
943 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
944 {
945   gcry_sexp_release (sig->sexp);
946   GNUNET_free (sig);
947 }
948
949
950 /**
951  * Encode the given signature in a format suitable for storing it into a file.
952  *
953  * @param sig the signature
954  * @param[out] buffer set to a buffer with the encoded key
955  * @return size of memory allocated in @a buffer
956  */
957 size_t
958 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
959                                     char **buffer)
960 {
961   size_t n;
962   char *b;
963
964   n = gcry_sexp_sprint (sig->sexp,
965                         GCRYSEXP_FMT_ADVANCED,
966                         NULL,
967                         0);
968   b = GNUNET_malloc (n);
969   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
970                  gcry_sexp_sprint (sig->sexp,
971                                    GCRYSEXP_FMT_ADVANCED,
972                                    b,
973                                    n));
974   *buffer = b;
975   return n;
976 }
977
978
979 /**
980  * Decode the signature from the data-format back to the "normal", internal
981  * format.
982  *
983  * @param buf the buffer where the public key data is stored
984  * @param len the length of the data in @a buf
985  * @return NULL on error
986  */
987 struct GNUNET_CRYPTO_RsaSignature *
988 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
989                                     size_t len)
990 {
991   struct GNUNET_CRYPTO_RsaSignature *sig;
992   int ret;
993   gcry_mpi_t s;
994
995   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
996   if (0 !=
997       gcry_sexp_new (&sig->sexp,
998                      buf,
999                      len,
1000                      0))
1001   {
1002     GNUNET_break_op (0);
1003     GNUNET_free (sig);
1004     return NULL;
1005   }
1006   /* verify that this is an RSA signature */
1007   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1008   if (0 != ret)
1009     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1010   if (0 != ret)
1011   {
1012     /* this is no RSA Signature */
1013     GNUNET_break_op (0);
1014     gcry_sexp_release (sig->sexp);
1015     GNUNET_free (sig);
1016     return NULL;
1017   }
1018   gcry_mpi_release (s);
1019   return sig;
1020 }
1021
1022
1023 /**
1024  * Duplicate the given public key
1025  *
1026  * @param key the public key to duplicate
1027  * @return the duplicate key; NULL upon error
1028  */
1029 struct GNUNET_CRYPTO_RsaPublicKey *
1030 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
1031 {
1032   struct GNUNET_CRYPTO_RsaPublicKey *dup;
1033   gcry_sexp_t dup_sexp;
1034   size_t erroff;
1035
1036   /* check if we really are exporting a public key */
1037   dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1038   GNUNET_assert (NULL != dup_sexp);
1039   gcry_sexp_release (dup_sexp);
1040   /* copy the sexp */
1041   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1042   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1043   dup->sexp = dup_sexp;
1044   return dup;
1045 }
1046
1047
1048 /**
1049  * Unblind a blind-signed signature.  The signature should have been generated
1050  * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1051  * #GNUNET_CRYPTO_rsa_blind().
1052  *
1053  * @param sig the signature made on the blinded signature purpose
1054  * @param bkey the blinding key used to blind the signature purpose
1055  * @param pkey the public key of the signer
1056  * @return unblinded signature on success, NULL on error
1057  */
1058 struct GNUNET_CRYPTO_RsaSignature *
1059 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
1060                            struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
1061                            struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1062 {
1063   gcry_mpi_t n;
1064   gcry_mpi_t s;
1065   gcry_mpi_t r_inv;
1066   gcry_mpi_t ubsig;
1067   int ret;
1068   struct GNUNET_CRYPTO_RsaSignature *sret;
1069
1070   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1071   if (0 != ret)
1072     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1073   if (0 != ret)
1074   {
1075     GNUNET_break_op (0);
1076     return NULL;
1077   }
1078   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1079   if (0 != ret)
1080     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1081   if (0 != ret)
1082   {
1083     gcry_mpi_release (n);
1084     GNUNET_break_op (0);
1085     return NULL;
1086   }
1087   r_inv = gcry_mpi_new (0);
1088   if (1 !=
1089       gcry_mpi_invm (r_inv,
1090                      bkey->r,
1091                      n))
1092   {
1093     GNUNET_break_op (0);
1094     gcry_mpi_release (n);
1095     gcry_mpi_release (r_inv);
1096     gcry_mpi_release (s);
1097     return NULL;
1098   }
1099   ubsig = gcry_mpi_new (0);
1100   gcry_mpi_mulm (ubsig, s, r_inv, n);
1101   gcry_mpi_release (n);
1102   gcry_mpi_release (r_inv);
1103   gcry_mpi_release (s);
1104
1105   sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1106   GNUNET_assert (0 ==
1107                  gcry_sexp_build (&sret->sexp,
1108                                   NULL,
1109                                   "(sig-val (rsa (s %M)))",
1110                                   ubsig));
1111   gcry_mpi_release (ubsig);
1112   return sret;
1113 }
1114
1115
1116 /**
1117  * Verify whether the given hash corresponds to the given signature and the
1118  * signature is valid with respect to the given public key.
1119  *
1120  * @param hash hash of the message to verify to match the @a sig
1121  * @param sig signature that is being validated
1122  * @param pkey public key of the signer
1123  * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1124  */
1125 int
1126 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1127                           const struct GNUNET_CRYPTO_RsaSignature *sig,
1128                           const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1129 {
1130   gcry_sexp_t data;
1131   gcry_mpi_t r;
1132   int rc;
1133
1134   rc = rsa_full_domain_hash (&r, hash, pkey, NULL);
1135   GNUNET_assert (0 == rc);  /* Allocation error in libgcrypt */
1136   data = mpi_to_sexp(r);
1137   gcry_mpi_release (r);
1138
1139   rc = gcry_pk_verify (sig->sexp,
1140                        data,
1141                        pkey->sexp);
1142   gcry_sexp_release (data);
1143   if (0 != rc)
1144   {
1145     LOG (GNUNET_ERROR_TYPE_WARNING,
1146          _("RSA signature verification failed at %s:%d: %s\n"),
1147          __FILE__,
1148          __LINE__,
1149          gcry_strerror (rc));
1150     return GNUNET_SYSERR;
1151   }
1152   return GNUNET_OK;
1153 }
1154
1155
1156 /**
1157  * Duplicate the given private key
1158  *
1159  * @param key the private key to duplicate
1160  * @return the duplicate key; NULL upon error
1161  */
1162 struct GNUNET_CRYPTO_RsaPrivateKey *
1163 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1164 {
1165   struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1166   gcry_sexp_t dup_sexp;
1167   size_t erroff;
1168
1169   /* check if we really are exporting a private key */
1170   dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1171   GNUNET_assert (NULL != dup_sexp);
1172   gcry_sexp_release (dup_sexp);
1173   /* copy the sexp */
1174   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1175   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1176   dup->sexp = dup_sexp;
1177   return dup;
1178 }
1179
1180
1181 /**
1182  * Duplicate the given private key
1183  *
1184  * @param key the private key to duplicate
1185  * @return the duplicate key; NULL upon error
1186  */
1187 struct GNUNET_CRYPTO_RsaSignature *
1188 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1189 {
1190   struct GNUNET_CRYPTO_RsaSignature *dup;
1191   gcry_sexp_t dup_sexp;
1192   size_t erroff;
1193   gcry_mpi_t s;
1194   int ret;
1195
1196   /* verify that this is an RSA signature */
1197   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1198   if (0 != ret)
1199     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1200   GNUNET_assert (0 == ret);
1201   gcry_mpi_release (s);
1202   /* copy the sexp */
1203   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1204   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1205   dup->sexp = dup_sexp;
1206   return dup;
1207 }
1208
1209
1210 /* end of util/rsa.c */