-allow 'years' in time units, indentation and doxygen fixes
[oweals/gnunet.git] / src / util / crypto_rsa.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2014 Christian Grothoff (and other contributing authors)
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  */
23 #include "platform.h"
24 #include <gcrypt.h>
25 #include "gnunet_crypto_lib.h"
26
27 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
28
29
30 /**
31  * The private information of an RSA key pair.
32  */
33 struct GNUNET_CRYPTO_rsa_PrivateKey
34 {
35   /**
36    * Libgcrypt S-expression for the RSA private key.
37    */
38   gcry_sexp_t sexp;
39 };
40
41
42 /**
43  * The public information of an RSA key pair.
44  */
45 struct GNUNET_CRYPTO_rsa_PublicKey
46 {
47   /**
48    * Libgcrypt S-expression for the RSA public key.
49    */
50   gcry_sexp_t sexp;
51 };
52
53
54 /**
55  * @brief an RSA signature
56  */
57 struct GNUNET_CRYPTO_rsa_Signature
58 {
59   /**
60    * Libgcrypt S-expression for the RSA signature.
61    */
62   gcry_sexp_t sexp;
63 };
64
65
66 /**
67  * @brief RSA blinding key
68  */
69 struct GNUNET_CRYPTO_rsa_BlindingKey
70 {
71   /**
72    * Random value used for blinding.
73    */
74   gcry_mpi_t r;
75 };
76
77
78 /**
79  * Extract values from an S-expression.
80  *
81  * @param array where to store the result(s)
82  * @param sexp S-expression to parse
83  * @param topname top-level name in the S-expression that is of interest
84  * @param elems names of the elements to extract
85  * @return 0 on success
86  */
87 static int
88 key_from_sexp (gcry_mpi_t *array,
89                gcry_sexp_t sexp,
90                const char *topname,
91                const char *elems)
92 {
93   gcry_sexp_t list;
94   gcry_sexp_t l2;
95   const char *s;
96   unsigned int i;
97   unsigned int idx;
98
99   if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
100     return 1;
101   l2 = gcry_sexp_cadr (list);
102   gcry_sexp_release (list);
103   list = l2;
104   if (! list)
105     return 2;
106   idx = 0;
107   for (s = elems; *s; s++, idx++)
108   {
109     if (! (l2 = gcry_sexp_find_token (list, s, 1)))
110     {
111       for (i = 0; i < idx; i++)
112       {
113         gcry_free (array[i]);
114         array[i] = NULL;
115       }
116       gcry_sexp_release (list);
117       return 3;                 /* required parameter not found */
118     }
119     array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
120     gcry_sexp_release (l2);
121     if (! array[idx])
122     {
123       for (i = 0; i < idx; i++)
124       {
125         gcry_free (array[i]);
126         array[i] = NULL;
127       }
128       gcry_sexp_release (list);
129       return 4;                 /* required parameter is invalid */
130     }
131   }
132   gcry_sexp_release (list);
133   return 0;
134 }
135
136
137 /**
138  * Create a new private key. Caller must free return value.
139  *
140  * @param len length of the key in bits (i.e. 2048)
141  * @return fresh private key
142  */
143 struct GNUNET_CRYPTO_rsa_PrivateKey *
144 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
145 {
146   struct GNUNET_CRYPTO_rsa_PrivateKey *ret;
147   gcry_sexp_t s_key;
148   gcry_sexp_t s_keyparam;
149
150   GNUNET_assert (0 ==
151                  gcry_sexp_build (&s_keyparam,
152                                   NULL,
153                                   "(genkey(rsa(nbits %d)))",
154                                   len));
155   GNUNET_assert (0 ==
156                  gcry_pk_genkey (&s_key,
157                                  s_keyparam));
158   gcry_sexp_release (s_keyparam);
159 #if EXTRA_CHECKS
160   GNUNET_assert (0 ==
161                  gcry_pk_testkey (s_key));
162 #endif
163   ret = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
164   ret->sexp = s_key;
165   return ret;
166 }
167
168
169 /**
170  * Free memory occupied by the private key.
171  *
172  * @param key pointer to the memory to free
173  */
174 void
175 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_rsa_PrivateKey *key)
176 {
177   gcry_sexp_release (key->sexp);
178   GNUNET_free (key);
179 }
180
181
182 /**
183  * Encode the private key in a format suitable for
184  * storing it into a file.
185  *
186  * @param key the private key
187  * @param[out] buffer set to a buffer with the encoded key
188  * @return size of memory allocated in @a buffer
189  */
190 size_t
191 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
192                               char **buffer)
193 {
194   size_t n;
195   char *b;
196
197   n = gcry_sexp_sprint (key->sexp,
198                         GCRYSEXP_FMT_DEFAULT,
199                         NULL,
200                         0);
201   b = GNUNET_malloc (n);
202   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
203                  gcry_sexp_sprint (key->sexp,
204                                    GCRYSEXP_FMT_DEFAULT,
205                                    b,
206                                    n));
207   *buffer = b;
208   return n;
209 }
210
211
212 /**
213  * Decode the private key from the data-format back
214  * to the "normal", internal format.
215  *
216  * @param buf the buffer where the private key data is stored
217  * @param len the length of the data in @a buf
218  * @return NULL on error
219  */
220 struct GNUNET_CRYPTO_rsa_PrivateKey *
221 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
222                               size_t len)
223 {
224   struct GNUNET_CRYPTO_rsa_PrivateKey *key;
225   key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
226   if (0 !=
227       gcry_sexp_new (&key->sexp,
228                      buf,
229                      len,
230                      0))
231   {
232     LOG (GNUNET_ERROR_TYPE_WARNING,
233          "Decoded private key is not valid\n");
234     GNUNET_free (key);
235     return NULL;
236   }
237   if (0 != gcry_pk_testkey (key->sexp))
238   {
239     LOG (GNUNET_ERROR_TYPE_WARNING,
240          "Decoded private key is not valid\n");
241     GNUNET_CRYPTO_rsa_private_key_free (key);
242     return NULL;
243   }
244   return key;
245 }
246
247
248 /**
249  * Extract the public key of the given private key.
250  *
251  * @param priv the private key
252  * @retur NULL on error, otherwise the public key
253  */
254 struct GNUNET_CRYPTO_rsa_PublicKey *
255 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_rsa_PrivateKey *priv)
256 {
257   struct GNUNET_CRYPTO_rsa_PublicKey *pub;
258   gcry_mpi_t ne[2];
259   int rc;
260   gcry_sexp_t result;
261
262   rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
263   if (0 != rc)
264     rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
265   if (0 != rc)
266     rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
267   if (0 != rc)
268   {
269     GNUNET_break_op (0);
270     return NULL;
271   }
272   rc = gcry_sexp_build (&result,
273                         NULL,
274                         "(public-key(rsa(n %m)(e %m)))",
275                         ne[0],
276                         ne[1]);
277   gcry_mpi_release (ne[0]);
278   gcry_mpi_release (ne[1]);
279   pub = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
280   pub->sexp = result;
281   return pub;
282 }
283
284
285 /**
286  * Free memory occupied by the public key.
287  *
288  * @param key pointer to the memory to free
289  */
290 void
291 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_rsa_PublicKey *key)
292 {
293   gcry_sexp_release (key->sexp);
294   GNUNET_free (key);
295 }
296
297
298 /**
299  * Encode the public key in a format suitable for
300  * storing it into a file.
301  *
302  * @param key the private key
303  * @param[out] buffer set to a buffer with the encoded key
304  * @return size of memory allocated in @a buffer
305  */
306 size_t
307 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
308                                      char **buffer)
309 {
310   size_t n;
311   char *b;
312
313   n = gcry_sexp_sprint (key->sexp,
314                         GCRYSEXP_FMT_ADVANCED,
315                         NULL,
316                         0);
317   b = GNUNET_malloc (n);
318   GNUNET_assert ((n -1) ==      /* since the last byte is \0 */
319                  gcry_sexp_sprint (key->sexp,
320                                    GCRYSEXP_FMT_ADVANCED,
321                                    b,
322                                    n));
323   *buffer = b;
324   return n;
325 }
326
327
328 /**
329  * Compute hash over the public key.
330  *
331  * @param key public key to hash
332  * @param hc where to store the hash code
333  */
334 void
335 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
336                                    struct GNUNET_HashCode *hc)
337 {
338   char *buf;
339   size_t buf_size;
340
341   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
342                                                   &buf);
343   GNUNET_CRYPTO_hash (buf,
344                       buf_size,
345                       hc);
346   GNUNET_free (buf);
347 }
348
349
350 /**
351  * Decode the public key from the data-format back
352  * to the "normal", internal format.
353  *
354  * @param buf the buffer where the public key data is stored
355  * @param len the length of the data in @a buf
356  * @return NULL on error
357  */
358 struct GNUNET_CRYPTO_rsa_PublicKey *
359 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
360                                      size_t len)
361 {
362   struct GNUNET_CRYPTO_rsa_PublicKey *key;
363   gcry_mpi_t n;
364   int ret;
365
366   key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
367   if (0 !=
368       gcry_sexp_new (&key->sexp,
369                      buf,
370                      len,
371                      0))
372   {
373     GNUNET_break_op (0);
374     GNUNET_free (key);
375     return NULL;
376   }
377   /* verify that this is an RSA public key */
378   ret = key_from_sexp (&n, key->sexp, "public-key", "n");
379   if (0 != ret)
380     ret = key_from_sexp (&n, key->sexp, "rsa", "n");
381   if (0 != ret)
382   {
383     /* this is no public RSA key */
384     GNUNET_break (0);
385     gcry_sexp_release (key->sexp);
386     GNUNET_free (key);
387     return NULL;
388   }
389   gcry_mpi_release (n);
390   return key;
391 }
392
393
394 /**
395  * Create a blinding key
396  *
397  * @param len length of the key in bits (i.e. 2048)
398  * @return the newly created blinding key
399  */
400 struct GNUNET_CRYPTO_rsa_BlindingKey *
401 GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
402 {
403   struct GNUNET_CRYPTO_rsa_BlindingKey *blind;
404
405   blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
406   blind->r = gcry_mpi_new (len);
407   gcry_mpi_randomize (blind->r,
408                       len,
409                       GCRY_STRONG_RANDOM);
410   return blind;
411 }
412
413
414 /**
415  * Compare the values of two blinding keys.
416  *
417  * @param b1 one key
418  * @param b2 the other key
419  * @return 0 if the two are equal
420  */
421 int
422 GNUNET_CRYPTO_rsa_blinding_key_cmp (struct GNUNET_CRYPTO_rsa_BlindingKey *b1,
423                                     struct GNUNET_CRYPTO_rsa_BlindingKey *b2)
424 {
425   return gcry_mpi_cmp (b1->r,
426                        b2->r);
427 }
428
429
430 /**
431  * Compare the values of two signatures.
432  *
433  * @param s1 one signature
434  * @param s2 the other signature
435  * @return 0 if the two are equal
436  */
437 int
438 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_rsa_Signature *s1,
439                                  struct GNUNET_CRYPTO_rsa_Signature *s2)
440 {
441   char *b1;
442   char *b2;
443   size_t z1;
444   size_t z2;
445   int ret;
446
447   z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
448                                            &b1);
449   z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
450                                            &b2);
451   if (z1 != z2)
452     ret = 1;
453   else
454     ret = memcmp (b1,
455                   b2,
456                   z1);
457   GNUNET_free (b1);
458   GNUNET_free (b2);
459   return ret;
460 }
461
462
463 /**
464  * Compare the values of two public keys.
465  *
466  * @param p1 one public key
467  * @param p2 the other public key
468  * @return 0 if the two are equal
469  */
470 int
471 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_rsa_PublicKey *p1,
472                                   struct GNUNET_CRYPTO_rsa_PublicKey *p2)
473 {
474   char *b1;
475   char *b2;
476   size_t z1;
477   size_t z2;
478   int ret;
479
480   z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
481                                             &b1);
482   z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
483                                             &b2);
484   if (z1 != z2)
485     ret = 1;
486   else
487     ret = memcmp (b1,
488                   b2,
489                   z1);
490   GNUNET_free (b1);
491   GNUNET_free (b2);
492   return ret;
493 }
494
495
496 /**
497  * Destroy a blinding key
498  *
499  * @param bkey the blinding key to destroy
500  */
501 void
502 GNUNET_CRYPTO_rsa_blinding_key_free (struct GNUNET_CRYPTO_rsa_BlindingKey *bkey)
503 {
504   gcry_mpi_release (bkey->r);
505   GNUNET_free (bkey);
506 }
507
508
509 /**
510  * Encode the blinding key in a format suitable for
511  * storing it into a file.
512  *
513  * @param bkey the blinding key
514  * @param[out] buffer set to a buffer with the encoded key
515  * @return size of memory allocated in @a buffer
516  */
517 size_t
518 GNUNET_CRYPTO_rsa_blinding_key_encode (const struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
519                                char **buffer)
520 {
521   size_t n;
522   char *b;
523   size_t rsize;
524
525   gcry_mpi_print (GCRYMPI_FMT_USG,
526                   NULL,
527                   0,
528                   &n,
529                   bkey->r);
530   b = GNUNET_malloc (n);
531   GNUNET_assert (0 ==
532                  gcry_mpi_print (GCRYMPI_FMT_USG,
533                                  (unsigned char *) b,
534                                  n,
535                                  &rsize,
536                                  bkey->r));
537   *buffer = b;
538   return n;
539 }
540
541
542 /**
543  * Decode the blinding key from the data-format back
544  * to the "normal", internal format.
545  *
546  * @param buf the buffer where the public key data is stored
547  * @param len the length of the data in @a buf
548  * @return NULL on error
549  */
550 struct GNUNET_CRYPTO_rsa_BlindingKey *
551 GNUNET_CRYPTO_rsa_blinding_key_decode (const char *buf,
552                                size_t len)
553 {
554   struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
555   size_t rsize;
556
557   bkey = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
558   if (0 !=
559       gcry_mpi_scan (&bkey->r,
560                      GCRYMPI_FMT_USG,
561                      (const unsigned char *) buf,
562                      len,
563                      &rsize))
564   {
565     GNUNET_break_op (0);
566     GNUNET_free (bkey);
567     return NULL;
568   }
569   return bkey;
570 }
571
572
573 /**
574  * Blinds the given message with the given blinding key
575  *
576  * @param hash hash of the message to sign
577  * @param bkey the blinding key
578  * @param pkey the public key of the signer
579  * @param[out] buffer set to a buffer with the blinded message to be signed
580  * @return number of bytes stored in @a buffer
581  */
582 size_t
583 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
584                  struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
585                  struct GNUNET_CRYPTO_rsa_PublicKey *pkey,
586                  char **buffer)
587 {
588   gcry_mpi_t data;
589   gcry_mpi_t ne[2];
590   gcry_mpi_t r_e;
591   gcry_mpi_t data_r_e;
592   size_t rsize;
593   size_t n;
594   gcry_error_t rc;
595   char *b;
596   int ret;
597
598   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
599   if (0 != ret)
600     ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
601   if (0 != ret)
602   {
603     GNUNET_break (0);
604     *buffer = NULL;
605     return 0;
606   }
607   if (0 != (rc = gcry_mpi_scan (&data,
608                                 GCRYMPI_FMT_USG,
609                                 (const unsigned char *) hash,
610                                 sizeof (struct GNUNET_HashCode),
611                                 &rsize)))
612   {
613     GNUNET_break (0);
614     gcry_mpi_release (ne[0]);
615     gcry_mpi_release (ne[1]);
616     *buffer = NULL;
617     return 0;
618   }
619   r_e = gcry_mpi_new (0);
620   gcry_mpi_powm (r_e,
621                  bkey->r,
622                  ne[1],
623                  ne[0]);
624   data_r_e = gcry_mpi_new (0);
625   gcry_mpi_mulm (data_r_e,
626                  data,
627                  r_e,
628                  ne[0]);
629   gcry_mpi_release (data);
630   gcry_mpi_release (ne[0]);
631   gcry_mpi_release (ne[1]);
632   gcry_mpi_release (r_e);
633
634   gcry_mpi_print (GCRYMPI_FMT_USG,
635                   NULL,
636                   0,
637                   &n,
638                   data_r_e);
639   b = GNUNET_malloc (n);
640   rc = gcry_mpi_print (GCRYMPI_FMT_USG,
641                        (unsigned char *) b,
642                        n,
643                        &rsize,
644                        data_r_e);
645   gcry_mpi_release (data_r_e);
646   *buffer = b;
647   return n;
648 }
649
650
651 /**
652  * Convert the data specified in the given purpose argument to an
653  * S-expression suitable for signature operations.
654  *
655  * @param ptr pointer to the data to convert
656  * @param size the size of the data
657  * @return converted s-expression
658  */
659 static gcry_sexp_t
660 data_to_sexp (const void *ptr, size_t size)
661 {
662   gcry_mpi_t value;
663   gcry_sexp_t data;
664
665   value = NULL;
666   data = NULL;
667   GNUNET_assert (0 ==
668                  gcry_mpi_scan (&value,
669                                 GCRYMPI_FMT_USG,
670                                 ptr,
671                                 size,
672                                 NULL));
673   GNUNET_assert (0 ==
674                  gcry_sexp_build (&data,
675                                   NULL,
676                                   "(data (flags raw) (value %M))",
677                                   value));
678   gcry_mpi_release (value);
679   return data;
680 }
681
682
683 /**
684  * Sign the given message.
685  *
686  * @param key private key to use for the signing
687  * @param msg the message to sign
688  * @param msg_len number of bytes in @a msg to sign
689  * @return NULL on error, signature on success
690  */
691 struct GNUNET_CRYPTO_rsa_Signature *
692 GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
693                         const void *msg,
694                         size_t msg_len)
695 {
696   struct GNUNET_CRYPTO_rsa_Signature *sig;
697   gcry_sexp_t result;
698   gcry_sexp_t data;
699
700   data = data_to_sexp (msg,
701                        msg_len);
702   if (0 !=
703       gcry_pk_sign (&result,
704                     data,
705                     key->sexp))
706   {
707     GNUNET_break (0);
708     return NULL;
709   }
710   gcry_sexp_release (data);
711   sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
712   sig->sexp = result;
713   return sig;
714 }
715
716
717 /**
718  * Free memory occupied by signature.
719  *
720  * @param sig memory to freee
721  */
722 void
723 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_rsa_Signature *sig)
724 {
725   gcry_sexp_release (sig->sexp);
726   GNUNET_free (sig);
727 }
728
729
730 /**
731  * Encode the given signature in a format suitable for storing it into a file.
732  *
733  * @param sig the signature
734  * @param[out] buffer set to a buffer with the encoded key
735  * @return size of memory allocated in @a buffer
736  */
737 size_t
738 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_rsa_Signature *sig,
739                                     char **buffer)
740 {
741   size_t n;
742   char *b;
743
744   n = gcry_sexp_sprint (sig->sexp,
745                         GCRYSEXP_FMT_ADVANCED,
746                         NULL,
747                         0);
748   b = GNUNET_malloc (n);
749   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
750                  gcry_sexp_sprint (sig->sexp,
751                                    GCRYSEXP_FMT_ADVANCED,
752                                    b,
753                                    n));
754   *buffer = b;
755   return n;
756 }
757
758
759 /**
760  * Decode the signature from the data-format back to the "normal", internal
761  * format.
762  *
763  * @param buf the buffer where the public key data is stored
764  * @param len the length of the data in @a buf
765  * @return NULL on error
766  */
767 struct GNUNET_CRYPTO_rsa_Signature *
768 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
769                             size_t len)
770 {
771   struct GNUNET_CRYPTO_rsa_Signature *sig;
772   int ret;
773   gcry_mpi_t s;
774
775   sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
776   if (0 !=
777       gcry_sexp_new (&sig->sexp,
778                      buf,
779                      len,
780                      0))
781   {
782     GNUNET_break_op (0);
783     GNUNET_free (sig);
784     return NULL;
785   }
786   /* verify that this is an RSA signature */
787   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
788   if (0 != ret)
789     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
790   if (0 != ret)
791   {
792     /* this is no RSA Signature */
793     GNUNET_break_op (0);
794     gcry_sexp_release (sig->sexp);
795     GNUNET_free (sig);
796     return NULL;
797   }
798   gcry_mpi_release (s);
799   return sig;
800 }
801
802
803 /**
804  * Duplicate the given public key
805  *
806  * @param key the public key to duplicate
807  * @return the duplicate key; NULL upon error
808  */
809 struct GNUNET_CRYPTO_rsa_PublicKey *
810 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_rsa_PublicKey *key)
811 {
812   struct GNUNET_CRYPTO_rsa_PublicKey *dup;
813   gcry_sexp_t dup_sexp;
814   size_t erroff;
815
816   /* check if we really are exporting a public key */
817   dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
818   GNUNET_assert (NULL != dup_sexp);
819   gcry_sexp_release (dup_sexp);
820   /* copy the sexp */
821   GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
822   dup = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
823   dup->sexp = dup_sexp;
824   return dup;
825 }
826
827
828 /**
829  * Unblind a blind-signed signature.  The signature should have been generated
830  * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
831  * #GNUNET_CRYPTO_rsa_blind().
832  *
833  * @param sig the signature made on the blinded signature purpose
834  * @param bkey the blinding key used to blind the signature purpose
835  * @param pkey the public key of the signer
836  * @return unblinded signature on success, NULL on error
837  */
838 struct GNUNET_CRYPTO_rsa_Signature *
839 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig,
840                    struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
841                    struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
842 {
843   gcry_mpi_t n;
844   gcry_mpi_t s;
845   gcry_mpi_t r_inv;
846   gcry_mpi_t ubsig;
847   int ret;
848   struct GNUNET_CRYPTO_rsa_Signature *sret;
849
850   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
851   if (0 != ret)
852     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
853   if (0 != ret)
854   {
855     GNUNET_break_op (0);
856     return NULL;
857   }
858   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
859   if (0 != ret)
860     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
861   if (0 != ret)
862   {
863     gcry_mpi_release (n);
864     GNUNET_break_op (0);
865     return NULL;
866   }
867   r_inv = gcry_mpi_new (0);
868   if (1 !=
869       gcry_mpi_invm (r_inv,
870                      bkey->r,
871                      n))
872   {
873     GNUNET_break_op (0);
874     gcry_mpi_release (n);
875     gcry_mpi_release (r_inv);
876     gcry_mpi_release (s);
877     return NULL;
878   }
879   ubsig = gcry_mpi_new (0);
880   gcry_mpi_mulm (ubsig, s, r_inv, n);
881   gcry_mpi_release (n);
882   gcry_mpi_release (r_inv);
883   gcry_mpi_release (s);
884
885   sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
886   GNUNET_assert (0 ==
887                  gcry_sexp_build (&sret->sexp,
888                                   NULL,
889                                   "(sig-val (rsa (s %M)))",
890                                   ubsig));
891   gcry_mpi_release (ubsig);
892   return sret;
893 }
894
895
896 /**
897  * Verify whether the given hash corresponds to the given signature and the
898  * signature is valid with respect to the given public key.
899  *
900  * @param hash hash of the message to verify to match the @a sig
901  * @param sig signature that is being validated
902  * @param public_key public key of the signer
903  * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
904  */
905 int
906 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
907                   const struct GNUNET_CRYPTO_rsa_Signature *sig,
908                   const struct GNUNET_CRYPTO_rsa_PublicKey *public_key)
909 {
910   gcry_sexp_t data;
911   int rc;
912
913   data = data_to_sexp (hash,
914                        sizeof (struct GNUNET_HashCode));
915   rc = gcry_pk_verify (sig->sexp,
916                        data,
917                        public_key->sexp);
918   gcry_sexp_release (data);
919   if (0 != rc)
920   {
921     LOG (GNUNET_ERROR_TYPE_WARNING,
922          _("RSA signature verification failed at %s:%d: %s\n"),
923          __FILE__,
924          __LINE__,
925          gcry_strerror (rc));
926     return GNUNET_SYSERR;
927   }
928   return GNUNET_OK;
929 }
930
931
932 /* end of util/rsa.c */