- refactor kx sending, unify under send_kx
[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_util_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
226   key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
227   if (0 !=
228       gcry_sexp_new (&key->sexp,
229                      buf,
230                      len,
231                      0))
232   {
233     GNUNET_break_op (0);
234     GNUNET_free (key);
235     return NULL;
236   }
237   /* FIXME: verify that this is an RSA private key */
238   return key;
239 }
240
241
242 /**
243  * Extract the public key of the given private key.
244  *
245  * @param priv the private key
246  * @retur NULL on error, otherwise the public key
247  */
248 struct GNUNET_CRYPTO_rsa_PublicKey *
249 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_rsa_PrivateKey *priv)
250 {
251   struct GNUNET_CRYPTO_rsa_PublicKey *pub;
252   gcry_mpi_t ne[2];
253   int rc;
254   gcry_sexp_t result;
255
256   rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
257   if (0 != rc)
258     rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
259   if (0 != rc)
260     rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
261   if (0 != rc)
262   {
263     GNUNET_break_op (0);
264     return NULL;
265   }
266   rc = gcry_sexp_build (&result,
267                         NULL,
268                         "(public-key(rsa(n %m)(e %m)))",
269                         ne[0],
270                         ne[1]);
271   gcry_mpi_release (ne[0]);
272   gcry_mpi_release (ne[1]);
273   pub = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
274   pub->sexp = result;
275   return pub;
276 }
277
278
279 /**
280  * Free memory occupied by the public key.
281  *
282  * @param key pointer to the memory to free
283  */
284 void
285 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_rsa_PublicKey *key)
286 {
287   gcry_sexp_release (key->sexp);
288   GNUNET_free (key);
289 }
290
291
292 /**
293  * Encode the public key in a format suitable for
294  * storing it into a file.
295  *
296  * @param key the private key
297  * @param[out] buffer set to a buffer with the encoded key
298  * @return size of memory allocated in @a buffer
299  */
300 size_t
301 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
302                                      char **buffer)
303 {
304   size_t n;
305   char *b;
306
307   n = gcry_sexp_sprint (key->sexp,
308                         GCRYSEXP_FMT_ADVANCED,
309                         NULL,
310                         0);
311   b = GNUNET_malloc (n);
312   GNUNET_assert ((n -1) ==      /* since the last byte is \0 */
313                  gcry_sexp_sprint (key->sexp,
314                                    GCRYSEXP_FMT_ADVANCED,
315                                    b,
316                                    n));
317   *buffer = b;
318   return n;
319 }
320
321
322 /**
323  * Compute hash over the public key.
324  *
325  * @param key public key to hash
326  * @param hc where to store the hash code
327  */
328 void
329 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
330                                    struct GNUNET_HashCode *hc)
331 {
332   char *buf;
333   size_t buf_size;
334
335   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
336                                                   &buf);
337   GNUNET_CRYPTO_hash (buf,
338                       buf_size,
339                       hc);
340   GNUNET_free (buf);
341 }
342
343
344 /**
345  * Decode the public key from the data-format back
346  * to the "normal", internal format.
347  *
348  * @param buf the buffer where the public key data is stored
349  * @param len the length of the data in @a buf
350  * @return NULL on error
351  */
352 struct GNUNET_CRYPTO_rsa_PublicKey *
353 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
354                                      size_t len)
355 {
356   struct GNUNET_CRYPTO_rsa_PublicKey *key;
357   gcry_mpi_t n;
358   int ret;
359
360   key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
361   if (0 !=
362       gcry_sexp_new (&key->sexp,
363                      buf,
364                      len,
365                      0))
366   {
367     GNUNET_break_op (0);
368     GNUNET_free (key);
369     return NULL;
370   }
371   /* verify that this is an RSA public key */
372   ret = key_from_sexp (&n, key->sexp, "public-key", "n");
373   if (0 != ret)
374     ret = key_from_sexp (&n, key->sexp, "rsa", "n");
375   if (0 != ret)
376   {
377     /* this is no public RSA key */
378     GNUNET_break (0);
379     gcry_sexp_release (key->sexp);
380     GNUNET_free (key);
381     return NULL;
382   }
383   gcry_mpi_release (n);
384   return key;
385 }
386
387
388 /**
389  * Create a blinding key
390  *
391  * @param len length of the key in bits (i.e. 2048)
392  * @return the newly created blinding key
393  */
394 struct GNUNET_CRYPTO_rsa_BlindingKey *
395 GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
396 {
397   struct GNUNET_CRYPTO_rsa_BlindingKey *blind;
398
399   blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
400   blind->r = gcry_mpi_new (len);
401   gcry_mpi_randomize (blind->r,
402                       len,
403                       GCRY_STRONG_RANDOM);
404   return blind;
405 }
406
407
408 /**
409  * Compare the values of two blinding keys.
410  * 
411  * @param b1 one key
412  * @param b2 the other key
413  * @return 0 if the two are equal
414  */
415 int
416 GNUNET_CRYPTO_rsa_blinding_key_cmp (struct GNUNET_CRYPTO_rsa_BlindingKey *b1,
417                                     struct GNUNET_CRYPTO_rsa_BlindingKey *b2)
418 {
419   return gcry_mpi_cmp (b1->r,
420                        b2->r);
421 }
422
423
424 /**
425  * Destroy a blinding key
426  *
427  * @param bkey the blinding key to destroy
428  */
429 void
430 GNUNET_CRYPTO_rsa_blinding_key_free (struct GNUNET_CRYPTO_rsa_BlindingKey *bkey)
431 {
432   gcry_mpi_release (bkey->r);
433   GNUNET_free (bkey);
434 }
435
436
437 /**
438  * Encode the blinding key in a format suitable for
439  * storing it into a file.
440  *
441  * @param bkey the blinding key
442  * @param[out] buffer set to a buffer with the encoded key
443  * @return size of memory allocated in @a buffer
444  */
445 size_t
446 GNUNET_CRYPTO_rsa_blinding_key_encode (const struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
447                                char **buffer)
448 {
449   size_t n;
450   char *b;
451   size_t rsize;
452
453   gcry_mpi_print (GCRYMPI_FMT_USG,
454                   NULL,
455                   0,
456                   &n,
457                   bkey->r);
458   b = GNUNET_malloc (n);
459   GNUNET_assert (0 ==
460                  gcry_mpi_print (GCRYMPI_FMT_USG,
461                                  (unsigned char *) b,
462                                  n,
463                                  &rsize,
464                                  bkey->r));
465   *buffer = b;
466   return n;
467 }
468
469
470 /**
471  * Decode the blinding key from the data-format back
472  * to the "normal", internal format.
473  *
474  * @param buf the buffer where the public key data is stored
475  * @param len the length of the data in @a buf
476  * @return NULL on error
477  */
478 struct GNUNET_CRYPTO_rsa_BlindingKey *
479 GNUNET_CRYPTO_rsa_blinding_key_decode (const char *buf,
480                                size_t len)
481 {
482   struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
483   size_t rsize;
484
485   bkey = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
486   if (0 !=
487       gcry_mpi_scan (&bkey->r,
488                      GCRYMPI_FMT_USG,
489                      (const unsigned char *) buf,
490                      len,
491                      &rsize))
492   {
493     GNUNET_break_op (0);
494     GNUNET_free (bkey);
495     return NULL;
496   }
497   return bkey;
498 }
499
500
501 /**
502  * Blinds the given message with the given blinding key
503  *
504  * @param hash hash of the message to sign
505  * @param bkey the blinding key
506  * @param pkey the public key of the signer
507  * @param[out] buffer set to a buffer with the blinded message to be signed
508  * @return number of bytes stored in @a buffer
509  */
510 size_t
511 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
512                  struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
513                  struct GNUNET_CRYPTO_rsa_PublicKey *pkey,
514                  char **buffer)
515 {
516   gcry_mpi_t data;
517   gcry_mpi_t ne[2];
518   gcry_mpi_t r_e;
519   gcry_mpi_t data_r_e;
520   size_t rsize;
521   size_t n;
522   gcry_error_t rc;
523   char *b;
524   int ret;
525
526   ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
527   if (0 != ret)
528     ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
529   if (0 != ret)
530   {
531     GNUNET_break (0);
532     *buffer = NULL;
533     return 0;
534   }
535   if (0 != (rc = gcry_mpi_scan (&data,
536                                 GCRYMPI_FMT_USG,
537                                 (const unsigned char *) hash,
538                                 sizeof (struct GNUNET_HashCode),
539                                 &rsize)))
540   {
541     GNUNET_break (0);
542     gcry_mpi_release (ne[0]);
543     gcry_mpi_release (ne[1]);
544     *buffer = NULL;
545     return 0;
546   }
547   r_e = gcry_mpi_new (0);
548   gcry_mpi_powm (r_e,
549                  bkey->r,
550                  ne[1],
551                  ne[0]);
552   data_r_e = gcry_mpi_new (0);
553   gcry_mpi_mulm (data_r_e,
554                  data,
555                  r_e,
556                  ne[0]);
557   gcry_mpi_release (data);
558   gcry_mpi_release (ne[0]);
559   gcry_mpi_release (ne[1]);
560   gcry_mpi_release (r_e);
561
562   gcry_mpi_print (GCRYMPI_FMT_USG,
563                   NULL,
564                   0,
565                   &n,
566                   data_r_e);
567   b = GNUNET_malloc (n);
568   rc = gcry_mpi_print (GCRYMPI_FMT_USG,
569                        (unsigned char *) b,
570                        n,
571                        &rsize,
572                        data_r_e);
573   gcry_mpi_release (data_r_e);
574   *buffer = b;
575   return n;
576 }
577
578
579 /**
580  * Convert the data specified in the given purpose argument to an
581  * S-expression suitable for signature operations.
582  *
583  * @param ptr pointer to the data to convert
584  * @param size the size of the data
585  * @return converted s-expression
586  */
587 static gcry_sexp_t
588 data_to_sexp (const void *ptr, size_t size)
589 {
590   gcry_mpi_t value;
591   gcry_sexp_t data;
592
593   value = NULL;
594   data = NULL;
595   GNUNET_assert (0 ==
596                  gcry_mpi_scan (&value,
597                                 GCRYMPI_FMT_USG,
598                                 ptr,
599                                 size,
600                                 NULL));
601   GNUNET_assert (0 ==
602                  gcry_sexp_build (&data,
603                                   NULL,
604                                   "(data (flags raw) (value %M))",
605                                   value));
606   gcry_mpi_release (value);
607   return data;
608 }
609
610
611 /**
612  * Sign the given message.
613  *
614  * @param key private key to use for the signing
615  * @param msg the message to sign
616  * @param msg_len number of bytes in @a msg to sign
617  * @return NULL on error, signature on success
618  */
619 struct GNUNET_CRYPTO_rsa_Signature *
620 GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
621                 const void *msg,
622                 size_t msg_len)
623 {
624   struct GNUNET_CRYPTO_rsa_Signature *sig;
625   gcry_sexp_t result;
626   gcry_sexp_t data;
627
628   data = data_to_sexp (msg,
629                        msg_len);
630   if (0 !=
631       gcry_pk_sign (&result,
632                     data,
633                     key->sexp))
634   {
635     GNUNET_break (0);
636     return NULL;
637   }
638   gcry_sexp_release (data);
639   sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
640   sig->sexp = result;
641   return sig;
642 }
643
644
645 /**
646  * Free memory occupied by signature.
647  *
648  * @param sig memory to freee
649  */
650 void
651 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_rsa_Signature *sig)
652 {
653   gcry_sexp_release (sig->sexp);
654   GNUNET_free (sig);
655 }
656
657
658 /**
659  * Encode the given signature in a format suitable for storing it into a file.
660  *
661  * @param sig the signature
662  * @param[out] buffer set to a buffer with the encoded key
663  * @return size of memory allocated in @a buffer
664  */
665 size_t
666 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_rsa_Signature *sig,
667                             char **buffer)
668 {
669   size_t n;
670   char *b;
671
672   n = gcry_sexp_sprint (sig->sexp,
673                         GCRYSEXP_FMT_ADVANCED,
674                         NULL,
675                         0);
676   b = GNUNET_malloc (n);
677   GNUNET_assert ((n - 1) ==     /* since the last byte is \0 */
678                  gcry_sexp_sprint (sig->sexp,
679                                    GCRYSEXP_FMT_ADVANCED,
680                                    b,
681                                    n));
682   *buffer = b;
683   return n;
684 }
685
686
687 /**
688  * Decode the signature from the data-format back to the "normal", internal
689  * format.
690  *
691  * @param buf the buffer where the public key data is stored
692  * @param len the length of the data in @a buf
693  * @return NULL on error
694  */
695 struct GNUNET_CRYPTO_rsa_Signature *
696 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
697                             size_t len)
698 {
699   struct GNUNET_CRYPTO_rsa_Signature *sig;
700   int ret;
701   gcry_mpi_t s;
702
703   sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
704   if (0 !=
705       gcry_sexp_new (&sig->sexp,
706                      buf,
707                      len,
708                      0))
709   {
710     GNUNET_break_op (0);
711     GNUNET_free (sig);
712     return NULL;
713   }
714   /* verify that this is an RSA signature */
715   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
716   if (0 != ret)
717     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
718   if (0 != ret)
719   {
720     /* this is no RSA Signature */
721     GNUNET_break_op (0);
722     gcry_sexp_release (sig->sexp);
723     GNUNET_free (sig);
724     return NULL;
725   }
726   gcry_mpi_release (s);
727   return sig;
728 }
729
730
731 /**
732  * Unblind a blind-signed signature.  The signature should have been generated
733  * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
734  * #GNUNET_CRYPTO_rsa_blind().
735  *
736  * @param sig the signature made on the blinded signature purpose
737  * @param bkey the blinding key used to blind the signature purpose
738  * @param pkey the public key of the signer
739  * @return unblinded signature on success, NULL on error
740  */
741 struct GNUNET_CRYPTO_rsa_Signature *
742 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig,
743                    struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
744                    struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
745 {
746   gcry_mpi_t n;
747   gcry_mpi_t s;
748   gcry_mpi_t r_inv;
749   gcry_mpi_t ubsig;
750   int ret;
751   struct GNUNET_CRYPTO_rsa_Signature *sret;
752
753   ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
754   if (0 != ret)
755     ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
756   if (0 != ret)
757   {
758     GNUNET_break_op (0);
759     return NULL;
760   }
761   ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
762   if (0 != ret)
763     ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
764   if (0 != ret)
765   {
766     gcry_mpi_release (n);
767     GNUNET_break_op (0);
768     return NULL;
769   }
770   r_inv = gcry_mpi_new (0);
771   if (1 !=
772       gcry_mpi_invm (r_inv,
773                      bkey->r,
774                      n))
775   {
776     GNUNET_break_op (0);
777     gcry_mpi_release (n);
778     gcry_mpi_release (r_inv);
779     gcry_mpi_release (s);
780     return NULL;
781   }
782   ubsig = gcry_mpi_new (0);
783   gcry_mpi_mulm (ubsig, s, r_inv, n);
784   gcry_mpi_release (n);
785   gcry_mpi_release (r_inv);
786   gcry_mpi_release (s);
787
788   sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
789   GNUNET_assert (0 ==
790                  gcry_sexp_build (&sret->sexp,
791                                   NULL,
792                                   "(sig-val (rsa (s %M)))",
793                                   ubsig));
794   gcry_mpi_release (ubsig);
795   return sret;
796 }
797
798
799 /**
800  * Verify whether the given hash corresponds to the given signature and the
801  * signature is valid with respect to the given public key.
802  *
803  * @param hash hash of the message to verify to match the @a sig
804  * @param sig signature that is being validated
805  * @param public_key public key of the signer
806  * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
807  */
808 int
809 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
810                   const struct GNUNET_CRYPTO_rsa_Signature *sig,
811                   const struct GNUNET_CRYPTO_rsa_PublicKey *public_key)
812 {
813   gcry_sexp_t data;
814   int rc;
815
816   data = data_to_sexp (hash,
817                        sizeof (struct GNUNET_HashCode));
818   rc = gcry_pk_verify (sig->sexp,
819                        data,
820                        public_key->sexp);
821   gcry_sexp_release (data);
822   if (0 != rc)
823   {
824     LOG (GNUNET_ERROR_TYPE_WARNING,
825          _("RSA signature verification failed at %s:%d: %s\n"),
826          __FILE__,
827          __LINE__,
828          gcry_strerror (rc));
829     return GNUNET_SYSERR;
830   }
831   return GNUNET_OK;
832 }
833
834
835 /* end of util/rsa.c */