fixing #4483: optimize blinding key storage/transmission
[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 RsaBlindingKey
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  * @param bks pre-secret to use to derive the blinding key
400  * @return the newly created blinding key
401  */
402 static struct RsaBlindingKey *
403 rsa_blinding_key_derive (unsigned int len,
404                          const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
405 {
406   struct RsaBlindingKey *blind;
407   uint8_t buf[len / 8];
408   int rc;
409   size_t rsize;
410
411   blind = GNUNET_new (struct RsaBlindingKey);
412   /* FIXME: #4483: actually derive key from bks! - Jeff,
413      check that you're happy with this!*/
414   GNUNET_assert (GNUNET_YES ==
415                  GNUNET_CRYPTO_kdf (buf,
416                                     sizeof (buf),
417                                     "blinding-kdf",
418                                     strlen ("blinding-kdf"),
419                                     bks,
420                                     sizeof (*bks),
421                                     NULL, 0));
422   rc = gcry_mpi_scan (&blind->r,
423                       GCRYMPI_FMT_USG,
424                       (const unsigned char *) buf,
425                       sizeof (buf),
426                       &rsize);
427   GNUNET_assert (0 == rc);
428   return blind;
429 }
430
431
432 /**
433  * Compare the values of two signatures.
434  *
435  * @param s1 one signature
436  * @param s2 the other signature
437  * @return 0 if the two are equal
438  */
439 int
440 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
441                                  struct GNUNET_CRYPTO_RsaSignature *s2)
442 {
443   char *b1;
444   char *b2;
445   size_t z1;
446   size_t z2;
447   int ret;
448
449   z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
450                                            &b1);
451   z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
452                                            &b2);
453   if (z1 != z2)
454     ret = 1;
455   else
456     ret = memcmp (b1,
457                   b2,
458                   z1);
459   GNUNET_free (b1);
460   GNUNET_free (b2);
461   return ret;
462 }
463
464
465 /**
466  * Compare the values of two public keys.
467  *
468  * @param p1 one public key
469  * @param p2 the other public key
470  * @return 0 if the two are equal
471  */
472 int
473 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
474                                   struct GNUNET_CRYPTO_RsaPublicKey *p2)
475 {
476   char *b1;
477   char *b2;
478   size_t z1;
479   size_t z2;
480   int ret;
481
482   z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
483                                             &b1);
484   z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
485                                             &b2);
486   if (z1 != z2)
487     ret = 1;
488   else
489     ret = memcmp (b1,
490                   b2,
491                   z1);
492   GNUNET_free (b1);
493   GNUNET_free (b2);
494   return ret;
495 }
496
497
498 /**
499  * Compare the values of two private keys.
500  *
501  * @param p1 one private key
502  * @param p2 the other private key
503  * @return 0 if the two are equal
504  */
505 int
506 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
507                                    struct GNUNET_CRYPTO_RsaPrivateKey *p2)
508 {
509   char *b1;
510   char *b2;
511   size_t z1;
512   size_t z2;
513   int ret;
514
515   z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
516                                             &b1);
517   z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
518                                             &b2);
519   if (z1 != z2)
520     ret = 1;
521   else
522     ret = memcmp (b1,
523                   b2,
524                   z1);
525   GNUNET_free (b1);
526   GNUNET_free (b2);
527   return ret;
528 }
529
530
531 /**
532  * Obtain the length of the RSA key in bits.
533  *
534  * @param key the public key to introspect
535  * @return length of the key in bits
536  */
537 unsigned int
538 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
539 {
540   gcry_mpi_t n;
541   int ret;
542   unsigned int rval;
543
544   ret = key_from_sexp (&n, key->sexp, "rsa", "n");
545   if (0 != ret)
546   {
547     /* this is no public RSA key */
548     GNUNET_break (0);
549     return 0;
550   }
551   rval = gcry_mpi_get_nbits (n);
552   gcry_mpi_release (n);
553   return rval;
554 }
555
556
557 /**
558  * Destroy a blinding key
559  *
560  * @param bkey the blinding key to destroy
561  */
562 static void
563 rsa_blinding_key_free (struct RsaBlindingKey *bkey)
564 {
565   gcry_mpi_release (bkey->r);
566   GNUNET_free (bkey);
567 }
568
569
570 /**
571  * Print an MPI to a newly created buffer
572  *
573  * @param v MPI to print.
574  * @param[out] newly allocated buffer containing the result
575  * @return number of bytes stored in @a buffer
576  */
577 static size_t
578 numeric_mpi_alloc_n_print (gcry_mpi_t v,
579                            char **buffer)
580 {
581   size_t n;
582   char *b;
583   size_t rsize;
584
585   gcry_mpi_print (GCRYMPI_FMT_USG,
586                   NULL,
587                   0,
588                   &n,
589                   v);
590   b = GNUNET_malloc (n);
591   GNUNET_assert (0 ==
592                  gcry_mpi_print (GCRYMPI_FMT_USG,
593                                  (unsigned char *) b,
594                                  n,
595                                  &rsize,
596                                  v));
597   *buffer = b;
598   return n;
599 }
600
601
602 /**
603  * Computes a full domain hash seeded by the given public key.
604  * This gives a measure of provable security to the Taler exchange
605  * against one-more forgery attacks.  See:
606  *   https://eprint.iacr.org/2001/002.pdf
607  *   http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
608  *
609  * @param[out] r MPI value set to the FDH
610  * @param hash initial hash of the message to sign
611  * @param pkey the public key of the signer
612  * @param rsize If not NULL, the number of bytes actually stored in buffer
613  * @return libgcrypt error that to represent an allocation failure
614  */
615 /* FIXME: exported symbol without proper prefix... */
616 gcry_error_t
617 rsa_full_domain_hash (gcry_mpi_t *r,
618                       const struct GNUNET_HashCode *hash,
619                       const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
620                       size_t *rsize)
621 {
622   unsigned int i;
623   unsigned int nbits;
624   unsigned int nhashes;
625   gcry_error_t rc;
626   char *buf;
627   size_t buf_len;
628   gcry_md_hd_t h;
629   gcry_md_hd_t h0;
630   struct GNUNET_HashCode *hs;
631
632   /* Uncomment the following to debug without using the full domain hash */
633   /*
634   rc = gcry_mpi_scan (r,
635                       GCRYMPI_FMT_USG,
636                       (const unsigned char *)hash,
637                       sizeof(struct GNUNET_HashCode),
638                       rsize);
639   return rc;
640   */
641
642   nbits = GNUNET_CRYPTO_rsa_public_key_len (pkey);
643   if (nbits < 512)
644     nbits = 512;
645
646   /* Already almost an HMAC since we consume a hash, so no GCRY_MD_FLAG_HMAC. */
647   rc = gcry_md_open (&h, GCRY_MD_SHA512, 0);
648   if (0 != rc)
649     return rc;
650
651   /* We seed with the public denomination key as a homage to RSA-PSS by  *
652    * Mihir Bellare and Phillip Rogaway.  Doing this lowers the degree    *
653    * of the hypothetical polyomial-time attack on RSA-KTI created by a   *
654    * polynomial-time one-more forgary attack.  Yey seeding!              */
655   buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &buf);
656   gcry_md_write (h, buf, buf_len);
657   GNUNET_free (buf);
658
659   nhashes = (nbits-1) / (8 * sizeof(struct GNUNET_HashCode)) + 1;
660   hs = GNUNET_new_array (nhashes,
661                          struct GNUNET_HashCode);
662   for (i=0; i<nhashes; i++)
663   {
664     gcry_md_write (h, hash, sizeof(struct GNUNET_HashCode));
665     rc = gcry_md_copy (&h0, h);
666     if (0 != rc)
667     {
668       gcry_md_close (h0);
669       break;
670     }
671     gcry_md_putc (h0, i % 256);
672     memcpy (&hs[i],
673             gcry_md_read (h0, GCRY_MD_SHA512),
674             sizeof(struct GNUNET_HashCode));
675     gcry_md_close (h0);
676   }
677   gcry_md_close (h);
678   if (0 != rc)
679   {
680     GNUNET_free (hs);
681     return rc;
682   }
683
684   rc = gcry_mpi_scan (r,
685                       GCRYMPI_FMT_USG,
686                       (const unsigned char *) hs,
687                       nhashes * sizeof(struct GNUNET_HashCode),
688                       rsize);
689   GNUNET_free (hs);
690   if (0 != rc)
691     return rc;
692
693   /* Do not allow *r to exceed n or signatures fail to verify unpredictably. *
694    * This happening with  gcry_mpi_clear_highbit (*r, nbits-1) so maybe      *
695    * gcry_mpi_clear_highbit is broken, but setting the highbit sounds good.  */
696   gcry_mpi_set_highbit (*r, nbits-2);
697   return rc;
698 }
699
700
701 /**
702  * Blinds the given message with the given blinding key
703  *
704  * @param hash hash of the message to sign
705  * @param bkey the blinding key
706  * @param pkey the public key of the signer
707  * @param[out] buffer set to a buffer with the blinded message to be signed
708  * @return number of bytes stored in @a buffer
709  */
710 size_t
711 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
712                          const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
713                          struct GNUNET_CRYPTO_RsaPublicKey *pkey,
714                          char **buffer)
715 {
716   struct RsaBlindingKey *bkey;
717   gcry_mpi_t data;
718   gcry_mpi_t ne[2];
719   gcry_mpi_t r_e;
720   gcry_mpi_t data_r_e;
721   size_t rsize;
722   size_t n;
723   gcry_error_t rc;
724   int ret;
725   unsigned int len;
726
727   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
728   if (0 != ret)
729     ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
730   if (0 != ret)
731   {
732     GNUNET_break (0);
733     *buffer = NULL;
734     return 0;
735   }
736
737   rc = rsa_full_domain_hash (&data, hash, pkey, &rsize);
738   if (0 != rc)  /* Allocation error in libgcrypt */
739   {
740     GNUNET_break (0);
741     gcry_mpi_release (ne[0]);
742     gcry_mpi_release (ne[1]);
743     *buffer = NULL;
744     return 0;
745   }
746   len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
747   bkey = rsa_blinding_key_derive (len,
748                                   bks);
749   r_e = gcry_mpi_new (0);
750   gcry_mpi_powm (r_e,
751                  bkey->r,
752                  ne[1],
753                  ne[0]);
754   data_r_e = gcry_mpi_new (0);
755   gcry_mpi_mulm (data_r_e,
756                  data,
757                  r_e,
758                  ne[0]);
759   gcry_mpi_release (data);
760   gcry_mpi_release (ne[0]);
761   gcry_mpi_release (ne[1]);
762   gcry_mpi_release (r_e);
763   rsa_blinding_key_free (bkey);  
764
765   n = numeric_mpi_alloc_n_print (data_r_e, buffer);
766   gcry_mpi_release (data_r_e);
767   return n;
768 }
769
770
771 /**
772  * Convert an MPI to an S-expression suitable for signature operations.
773  *
774  * @param value pointer to the data to convert
775  * @return converted s-expression
776  */
777 static gcry_sexp_t
778 mpi_to_sexp (gcry_mpi_t value)
779 {
780   gcry_sexp_t data = NULL;
781
782   GNUNET_assert (0 ==
783                  gcry_sexp_build (&data,
784                                   NULL,
785                                   "(data (flags raw) (value %M))",
786                                   value));
787   return data;
788 }
789
790
791 /**
792  * Sign the given MPI.
793  *
794  * @param key private key to use for the signing
795  * @param value the MPI to sign
796  * @return NULL on error, signature on success
797  */
798 static struct GNUNET_CRYPTO_RsaSignature *
799 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
800               gcry_mpi_t value)
801 {
802   struct GNUNET_CRYPTO_RsaSignature *sig;
803   struct GNUNET_CRYPTO_RsaPublicKey *public_key;
804   gcry_sexp_t data;
805   gcry_sexp_t result;
806
807   data = mpi_to_sexp (value);
808
809   if (0 !=
810       gcry_pk_sign (&result,
811                     data,
812                     key->sexp))
813   {
814     GNUNET_break (0);
815     return NULL;
816   }
817
818   /* verify signature (guards against Lenstra's attack with fault injection...) */
819   public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
820   if (0 !=
821       gcry_pk_verify (result,
822                       data,
823                       public_key->sexp))
824   {
825     GNUNET_break (0);
826     GNUNET_CRYPTO_rsa_public_key_free (public_key);
827     gcry_sexp_release (data);
828     gcry_sexp_release (result);
829     return NULL;
830   }
831   GNUNET_CRYPTO_rsa_public_key_free (public_key);
832
833   /* return signature */
834   gcry_sexp_release (data);
835   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
836   sig->sexp = result;
837   return sig;
838 }
839
840
841 /**
842  * Sign a blinded value, which must be a full domain hash of a message.
843  *
844  * @param key private key to use for the signing
845  * @param msg the message to sign
846  * @param msg_len number of bytes in @a msg to sign
847  * @return NULL on error, signature on success
848  */
849 struct GNUNET_CRYPTO_RsaSignature *
850 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
851                                 const void *msg,
852                                 size_t msg_len)
853 {
854   gcry_mpi_t v = NULL;
855   struct GNUNET_CRYPTO_RsaSignature *sig;
856
857   GNUNET_assert (0 ==
858                  gcry_mpi_scan (&v,
859                                 GCRYMPI_FMT_USG,
860                                 msg,
861                                 msg_len,
862                                 NULL));
863
864   sig = rsa_sign_mpi (key, v);
865   gcry_mpi_release (v);
866   return sig; 
867 }
868
869
870 /**
871  * Create and sign a full domain hash of a message.
872  *
873  * @param key private key to use for the signing
874  * @param hash the hash of the message to sign
875  * @return NULL on error, signature on success
876  */
877 struct GNUNET_CRYPTO_RsaSignature *
878 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
879                             const struct GNUNET_HashCode *hash)
880 {
881   struct GNUNET_CRYPTO_RsaPublicKey *pkey;
882   gcry_mpi_t v = NULL;
883   gcry_error_t rc;
884   struct GNUNET_CRYPTO_RsaSignature *sig;
885
886   pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
887   rc = rsa_full_domain_hash (&v, hash, pkey, NULL);
888   GNUNET_CRYPTO_rsa_public_key_free (pkey);
889   GNUNET_assert (0 == rc);
890
891   sig = rsa_sign_mpi (key, v);
892   gcry_mpi_release (v);
893   return sig; 
894
895 }
896
897
898 /**
899  * Free memory occupied by signature.
900  *
901  * @param sig memory to freee
902  */
903 void
904 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
905 {
906   gcry_sexp_release (sig->sexp);
907   GNUNET_free (sig);
908 }
909
910
911 /**
912  * Encode the given signature in a format suitable for storing it into a file.
913  *
914  * @param sig the signature
915  * @param[out] buffer set to a buffer with the encoded key
916  * @return size of memory allocated in @a buffer
917  */
918 size_t
919 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
920                                     char **buffer)
921 {
922   size_t n;
923   char *b;
924
925   n = gcry_sexp_sprint (sig->sexp,
926                         GCRYSEXP_FMT_ADVANCED,
927                         NULL,
928                         0);
929   b = GNUNET_malloc (n);
930   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
931                  gcry_sexp_sprint (sig->sexp,
932                                    GCRYSEXP_FMT_ADVANCED,
933                                    b,
934                                    n));
935   *buffer = b;
936   return n;
937 }
938
939
940 /**
941  * Decode the signature from the data-format back to the "normal", internal
942  * format.
943  *
944  * @param buf the buffer where the public key data is stored
945  * @param len the length of the data in @a buf
946  * @return NULL on error
947  */
948 struct GNUNET_CRYPTO_RsaSignature *
949 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
950                                     size_t len)
951 {
952   struct GNUNET_CRYPTO_RsaSignature *sig;
953   int ret;
954   gcry_mpi_t s;
955
956   sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
957   if (0 !=
958       gcry_sexp_new (&sig->sexp,
959                      buf,
960                      len,
961                      0))
962   {
963     GNUNET_break_op (0);
964     GNUNET_free (sig);
965     return NULL;
966   }
967   /* verify that this is an RSA signature */
968   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
969   if (0 != ret)
970     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
971   if (0 != ret)
972   {
973     /* this is no RSA Signature */
974     GNUNET_break_op (0);
975     gcry_sexp_release (sig->sexp);
976     GNUNET_free (sig);
977     return NULL;
978   }
979   gcry_mpi_release (s);
980   return sig;
981 }
982
983
984 /**
985  * Duplicate the given public key
986  *
987  * @param key the public key to duplicate
988  * @return the duplicate key; NULL upon error
989  */
990 struct GNUNET_CRYPTO_RsaPublicKey *
991 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
992 {
993   struct GNUNET_CRYPTO_RsaPublicKey *dup;
994   gcry_sexp_t dup_sexp;
995   size_t erroff;
996
997   /* check if we really are exporting a public key */
998   dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
999   GNUNET_assert (NULL != dup_sexp);
1000   gcry_sexp_release (dup_sexp);
1001   /* copy the sexp */
1002   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1003   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1004   dup->sexp = dup_sexp;
1005   return dup;
1006 }
1007
1008
1009 /**
1010  * Unblind a blind-signed signature.  The signature should have been generated
1011  * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1012  * #GNUNET_CRYPTO_rsa_blind().
1013  *
1014  * @param sig the signature made on the blinded signature purpose
1015  * @param bks the blinding key secret used to blind the signature purpose
1016  * @param pkey the public key of the signer
1017  * @return unblinded signature on success, NULL on error
1018  */
1019 struct GNUNET_CRYPTO_RsaSignature *
1020 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
1021                            const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1022                            struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1023 {
1024   struct RsaBlindingKey *bkey;
1025   gcry_mpi_t n;
1026   gcry_mpi_t s;
1027   gcry_mpi_t r_inv;
1028   gcry_mpi_t ubsig;
1029   int ret;
1030   struct GNUNET_CRYPTO_RsaSignature *sret;
1031   unsigned int len;
1032
1033   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1034   if (0 != ret)
1035     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1036   if (0 != ret)
1037   {
1038     GNUNET_break_op (0);
1039     return NULL;
1040   }
1041   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1042   if (0 != ret)
1043     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1044   if (0 != ret)
1045   {
1046     gcry_mpi_release (n);
1047     GNUNET_break_op (0);
1048     return NULL;
1049   }
1050   len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
1051   bkey = rsa_blinding_key_derive (len,
1052                                   bks);
1053
1054   r_inv = gcry_mpi_new (0);
1055   if (1 !=
1056       gcry_mpi_invm (r_inv,
1057                      bkey->r,
1058                      n))
1059   {
1060     GNUNET_break_op (0);
1061     gcry_mpi_release (n);
1062     gcry_mpi_release (r_inv);
1063     gcry_mpi_release (s);
1064     rsa_blinding_key_free (bkey);  
1065     return NULL;
1066   }
1067   ubsig = gcry_mpi_new (0);
1068   gcry_mpi_mulm (ubsig, s, r_inv, n);
1069   gcry_mpi_release (n);
1070   gcry_mpi_release (r_inv);
1071   gcry_mpi_release (s);
1072   rsa_blinding_key_free (bkey);
1073
1074   sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1075   GNUNET_assert (0 ==
1076                  gcry_sexp_build (&sret->sexp,
1077                                   NULL,
1078                                   "(sig-val (rsa (s %M)))",
1079                                   ubsig));
1080   gcry_mpi_release (ubsig);
1081   return sret;
1082 }
1083
1084
1085 /**
1086  * Verify whether the given hash corresponds to the given signature and the
1087  * signature is valid with respect to the given public key.
1088  *
1089  * @param hash hash of the message to verify to match the @a sig
1090  * @param sig signature that is being validated
1091  * @param pkey public key of the signer
1092  * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1093  */
1094 int
1095 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1096                           const struct GNUNET_CRYPTO_RsaSignature *sig,
1097                           const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1098 {
1099   gcry_sexp_t data;
1100   gcry_mpi_t r;
1101   int rc;
1102
1103   rc = rsa_full_domain_hash (&r, hash, pkey, NULL);
1104   GNUNET_assert (0 == rc);  /* Allocation error in libgcrypt */
1105   data = mpi_to_sexp(r);
1106   gcry_mpi_release (r);
1107
1108   rc = gcry_pk_verify (sig->sexp,
1109                        data,
1110                        pkey->sexp);
1111   gcry_sexp_release (data);
1112   if (0 != rc)
1113   {
1114     LOG (GNUNET_ERROR_TYPE_WARNING,
1115          _("RSA signature verification failed at %s:%d: %s\n"),
1116          __FILE__,
1117          __LINE__,
1118          gcry_strerror (rc));
1119     return GNUNET_SYSERR;
1120   }
1121   return GNUNET_OK;
1122 }
1123
1124
1125 /**
1126  * Duplicate the given private key
1127  *
1128  * @param key the private key to duplicate
1129  * @return the duplicate key; NULL upon error
1130  */
1131 struct GNUNET_CRYPTO_RsaPrivateKey *
1132 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1133 {
1134   struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1135   gcry_sexp_t dup_sexp;
1136   size_t erroff;
1137
1138   /* check if we really are exporting a private key */
1139   dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1140   GNUNET_assert (NULL != dup_sexp);
1141   gcry_sexp_release (dup_sexp);
1142   /* copy the sexp */
1143   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1144   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1145   dup->sexp = dup_sexp;
1146   return dup;
1147 }
1148
1149
1150 /**
1151  * Duplicate the given private key
1152  *
1153  * @param key the private key to duplicate
1154  * @return the duplicate key; NULL upon error
1155  */
1156 struct GNUNET_CRYPTO_RsaSignature *
1157 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1158 {
1159   struct GNUNET_CRYPTO_RsaSignature *dup;
1160   gcry_sexp_t dup_sexp;
1161   size_t erroff;
1162   gcry_mpi_t s;
1163   int ret;
1164
1165   /* verify that this is an RSA signature */
1166   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1167   if (0 != ret)
1168     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1169   GNUNET_assert (0 == ret);
1170   gcry_mpi_release (s);
1171   /* copy the sexp */
1172   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1173   dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1174   dup->sexp = dup_sexp;
1175   return dup;
1176 }
1177
1178
1179 /* end of util/rsa.c */