2 This file is part of GNUnet
3 Copyright (C) 2014 GNUnet e.V.
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.
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.
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/>
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
25 #include "gnunet_crypto_lib.h"
27 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
31 * The private information of an RSA key pair.
33 struct GNUNET_CRYPTO_rsa_PrivateKey
36 * Libgcrypt S-expression for the RSA private key.
43 * The public information of an RSA key pair.
45 struct GNUNET_CRYPTO_rsa_PublicKey
48 * Libgcrypt S-expression for the RSA public key.
55 * @brief an RSA signature
57 struct GNUNET_CRYPTO_rsa_Signature
60 * Libgcrypt S-expression for the RSA signature.
67 * @brief RSA blinding key
69 struct GNUNET_CRYPTO_rsa_BlindingKey
72 * Random value used for blinding.
79 * Extract values from an S-expression.
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
88 key_from_sexp (gcry_mpi_t *array,
99 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
101 l2 = gcry_sexp_cadr (list);
102 gcry_sexp_release (list);
107 for (s = elems; *s; s++, idx++)
109 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
111 for (i = 0; i < idx; i++)
113 gcry_free (array[i]);
116 gcry_sexp_release (list);
117 return 3; /* required parameter not found */
119 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
120 gcry_sexp_release (l2);
123 for (i = 0; i < idx; i++)
125 gcry_free (array[i]);
128 gcry_sexp_release (list);
129 return 4; /* required parameter is invalid */
132 gcry_sexp_release (list);
138 * Create a new private key. Caller must free return value.
140 * @param len length of the key in bits (i.e. 2048)
141 * @return fresh private key
143 struct GNUNET_CRYPTO_rsa_PrivateKey *
144 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
146 struct GNUNET_CRYPTO_rsa_PrivateKey *ret;
148 gcry_sexp_t s_keyparam;
151 gcry_sexp_build (&s_keyparam,
153 "(genkey(rsa(nbits %d)))",
156 gcry_pk_genkey (&s_key,
158 gcry_sexp_release (s_keyparam);
161 gcry_pk_testkey (s_key));
163 ret = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
170 * Free memory occupied by the private key.
172 * @param key pointer to the memory to free
175 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_rsa_PrivateKey *key)
177 gcry_sexp_release (key->sexp);
183 * Encode the private key in a format suitable for
184 * storing it into a file.
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
191 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
197 n = gcry_sexp_sprint (key->sexp,
198 GCRYSEXP_FMT_DEFAULT,
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,
213 * Decode the private key from the data-format back
214 * to the "normal", internal format.
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
220 struct GNUNET_CRYPTO_rsa_PrivateKey *
221 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
224 struct GNUNET_CRYPTO_rsa_PrivateKey *key;
225 key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
227 gcry_sexp_new (&key->sexp,
232 LOG (GNUNET_ERROR_TYPE_WARNING,
233 "Decoded private key is not valid\n");
237 if (0 != gcry_pk_testkey (key->sexp))
239 LOG (GNUNET_ERROR_TYPE_WARNING,
240 "Decoded private key is not valid\n");
241 GNUNET_CRYPTO_rsa_private_key_free (key);
249 * Extract the public key of the given private key.
251 * @param priv the private key
252 * @retur NULL on error, otherwise the public key
254 struct GNUNET_CRYPTO_rsa_PublicKey *
255 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_rsa_PrivateKey *priv)
257 struct GNUNET_CRYPTO_rsa_PublicKey *pub;
262 rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
264 rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
266 rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
272 rc = gcry_sexp_build (&result,
274 "(public-key(rsa(n %m)(e %m)))",
277 gcry_mpi_release (ne[0]);
278 gcry_mpi_release (ne[1]);
279 pub = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
286 * Free memory occupied by the public key.
288 * @param key pointer to the memory to free
291 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_rsa_PublicKey *key)
293 gcry_sexp_release (key->sexp);
299 * Encode the public key in a format suitable for
300 * storing it into a file.
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
307 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
313 n = gcry_sexp_sprint (key->sexp,
314 GCRYSEXP_FMT_ADVANCED,
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,
329 * Compute hash over the public key.
331 * @param key public key to hash
332 * @param hc where to store the hash code
335 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_rsa_PublicKey *key,
336 struct GNUNET_HashCode *hc)
341 buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
343 GNUNET_CRYPTO_hash (buf,
351 * Decode the public key from the data-format back
352 * to the "normal", internal format.
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
358 struct GNUNET_CRYPTO_rsa_PublicKey *
359 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
362 struct GNUNET_CRYPTO_rsa_PublicKey *key;
366 key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
368 gcry_sexp_new (&key->sexp,
377 /* verify that this is an RSA public key */
378 ret = key_from_sexp (&n, key->sexp, "public-key", "n");
380 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
383 /* this is no public RSA key */
385 gcry_sexp_release (key->sexp);
389 gcry_mpi_release (n);
395 * Create a blinding key
397 * @param len length of the key in bits (i.e. 2048)
398 * @return the newly created blinding key
400 struct GNUNET_CRYPTO_rsa_BlindingKey *
401 GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
403 struct GNUNET_CRYPTO_rsa_BlindingKey *blind;
405 blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
406 blind->r = gcry_mpi_new (len);
407 gcry_mpi_randomize (blind->r,
415 * Compare the values of two blinding keys.
418 * @param b2 the other key
419 * @return 0 if the two are equal
422 GNUNET_CRYPTO_rsa_blinding_key_cmp (struct GNUNET_CRYPTO_rsa_BlindingKey *b1,
423 struct GNUNET_CRYPTO_rsa_BlindingKey *b2)
425 return gcry_mpi_cmp (b1->r,
431 * Compare the values of two signatures.
433 * @param s1 one signature
434 * @param s2 the other signature
435 * @return 0 if the two are equal
438 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_rsa_Signature *s1,
439 struct GNUNET_CRYPTO_rsa_Signature *s2)
447 z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
449 z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
464 * Compare the values of two public keys.
466 * @param p1 one public key
467 * @param p2 the other public key
468 * @return 0 if the two are equal
471 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_rsa_PublicKey *p1,
472 struct GNUNET_CRYPTO_rsa_PublicKey *p2)
480 z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
482 z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
497 * Compare the values of two private keys.
499 * @param p1 one private key
500 * @param p2 the other private key
501 * @return 0 if the two are equal
504 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_rsa_PrivateKey *p1,
505 struct GNUNET_CRYPTO_rsa_PrivateKey *p2)
513 z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
515 z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
530 * Obtain the length of the RSA key in bits.
532 * @param key the public key to introspect
533 * @return length of the key in bits
536 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_rsa_PublicKey *key)
542 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
545 /* this is no public RSA key */
549 rval = gcry_mpi_get_nbits (n);
550 gcry_mpi_release (n);
556 * Destroy a blinding key
558 * @param bkey the blinding key to destroy
561 GNUNET_CRYPTO_rsa_blinding_key_free (struct GNUNET_CRYPTO_rsa_BlindingKey *bkey)
563 gcry_mpi_release (bkey->r);
569 * Print an MPI to a newly created buffer
571 * @param v MPI to print.
572 * @param[out] buffer set to a buffer with the result
573 * @return number of bytes stored in @a buffer
576 GNUNET_CRYPTO_mpi_print (gcry_mpi_t v,
583 gcry_mpi_print (GCRYMPI_FMT_USG,
588 b = GNUNET_malloc (n);
590 gcry_mpi_print (GCRYMPI_FMT_USG,
601 * Encode the blinding key in a format suitable for
602 * storing it into a file.
604 * @param bkey the blinding key
605 * @param[out] buffer set to a buffer with the encoded key
606 * @return size of memory allocated in @a buffer
609 GNUNET_CRYPTO_rsa_blinding_key_encode (const struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
612 return GNUNET_CRYPTO_mpi_print (bkey->r, buffer);
617 * Decode the blinding key from the data-format back
618 * to the "normal", internal format.
620 * @param buf the buffer where the public key data is stored
621 * @param len the length of the data in @a buf
622 * @return NULL on error
624 struct GNUNET_CRYPTO_rsa_BlindingKey *
625 GNUNET_CRYPTO_rsa_blinding_key_decode (const char *buf,
628 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
631 bkey = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
633 gcry_mpi_scan (&bkey->r,
635 (const unsigned char *) buf,
648 * Computes a full domain hash seeded by the given public key.
649 * This gives a measure of provable security to the Taler exchange
650 * against one-more forgery attacks. See:
651 * https://eprint.iacr.org/2001/002.pdf
652 * http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
654 * @param hash initial hash of the message to sign
655 * @param pkey the public key of the signer
656 * @return libgcrypt error that to represent an allocation failure
659 rsa_full_domain_hash (gcry_mpi_t *r,
660 const struct GNUNET_HashCode *hash,
661 const struct GNUNET_CRYPTO_rsa_PublicKey *pkey,
669 struct GNUNET_HashCode *hs;
671 /* Uncomment the following to debug without using the full domain hash */
673 rc = gcry_mpi_scan (r,
675 (const unsigned char *)hash,
676 sizeof(struct GNUNET_HashCode),
681 nbits = GNUNET_CRYPTO_rsa_public_key_len (pkey);
682 // calls gcry_mpi_get_nbits(.. pkey->sexp ..)
686 // Already almost an HMAC since we consume a hash, so no GCRY_MD_FLAG_HMAC.
687 rc = gcry_md_open (&h,GCRY_MD_SHA512,0);
688 if (0 != rc) return rc;
690 // We seed with the public denomination key as a homage to RSA-PSS by
691 // Mihir Bellare and Phillip Rogaway. Doing this lowers the degree
692 // of the hypothetical polyomial-time attack on RSA-KTI created by a
693 // polynomial-time one-more forgary attack. Yey seeding!
694 buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &buf);
695 gcry_md_write (h, buf,buf_len);
698 nhashes = (nbits-1) / (8 * sizeof(struct GNUNET_HashCode)) + 1;
699 hs = (struct GNUNET_HashCode *)GNUNET_malloc (nhashes * sizeof(struct GNUNET_HashCode));
700 for (i=0; i<nhashes; i++)
702 gcry_md_write (h, hash, sizeof(struct GNUNET_HashCode));
703 rc = gcry_md_copy (&h0, h);
705 gcry_md_putc (h0, i % 256);
706 // gcry_md_final (&h0);
708 gcry_md_read (h0,GCRY_MD_SHA512),
709 sizeof(struct GNUNET_HashCode));
718 rc = gcry_mpi_scan (r,
720 (const unsigned char *)hs,
721 nhashes * sizeof(struct GNUNET_HashCode),
724 if (0 != rc) return rc;
726 // Do not allow *r to exceed n or signatures fail to verify unpredictably.
727 // This happening with gcry_mpi_clear_highbit (*r, nbits-1) so maybe
728 // gcry_mpi_clear_highbit is broken, but setting the highbit sounds good.
729 // (void) fprintf (stderr, "%d %d %d",nbits,nhashes, gcry_mpi_get_nbits(*r));
730 gcry_mpi_set_highbit (*r, nbits-2);
731 // (void) fprintf (stderr, " %d\n",gcry_mpi_get_nbits(*r));
737 * Blinds the given message with the given blinding key
739 * @param hash hash of the message to sign
740 * @param bkey the blinding key
741 * @param pkey the public key of the signer
742 * @param[out] buffer set to a buffer with the blinded message to be signed
743 * @return number of bytes stored in @a buffer
746 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
747 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
748 struct GNUNET_CRYPTO_rsa_PublicKey *pkey,
760 ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
762 ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
770 rc = rsa_full_domain_hash(&data, hash, pkey, &rsize);
771 if (0 != rc) // Allocation error in libgcrypt
774 gcry_mpi_release (ne[0]);
775 gcry_mpi_release (ne[1]);
779 r_e = gcry_mpi_new (0);
784 data_r_e = gcry_mpi_new (0);
785 gcry_mpi_mulm (data_r_e,
789 gcry_mpi_release (data);
790 gcry_mpi_release (ne[0]);
791 gcry_mpi_release (ne[1]);
792 gcry_mpi_release (r_e);
794 n = GNUNET_CRYPTO_mpi_print (data_r_e, buffer);
795 gcry_mpi_release (data_r_e);
801 * Convert an MPI to an S-expression suitable for signature operations.
803 * @param value pointer to the data to convert
804 * @return converted s-expression
807 mpi_to_sexp (gcry_mpi_t value)
809 gcry_sexp_t data = NULL;
812 gcry_sexp_build (&data,
814 "(data (flags raw) (value %M))",
821 * Sign and release the given MPI.
823 * @param key private key to use for the signing
824 * @param value the MPI to sign
825 * @return NULL on error, signature on success
827 struct GNUNET_CRYPTO_rsa_Signature *
828 rsa_sign_mpi (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
831 struct GNUNET_CRYPTO_rsa_Signature *sig;
832 struct GNUNET_CRYPTO_rsa_PublicKey *public_key;
833 gcry_sexp_t data,result;
835 data = mpi_to_sexp (value);
836 gcry_mpi_release (value);
839 gcry_pk_sign (&result,
847 /* verify signature (guards against Lenstra's attack with fault injection...) */
848 public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
850 gcry_pk_verify (result,
855 GNUNET_CRYPTO_rsa_public_key_free (public_key);
856 gcry_sexp_release (data);
857 gcry_sexp_release (result);
860 GNUNET_CRYPTO_rsa_public_key_free (public_key);
862 /* return signature */
863 gcry_sexp_release (data);
864 sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
871 * Sign a blinded value, which must be a full domain hash of a message.
873 * @param key private key to use for the signing
874 * @param msg the message to sign
875 * @param msg_len number of bytes in @a msg to sign
876 * @return NULL on error, signature on success
878 struct GNUNET_CRYPTO_rsa_Signature *
879 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
892 return rsa_sign_mpi (key,v);
897 * Create and sign a full domain hash of a message.
899 * @param key private key to use for the signing
900 * @param hash the hash of the message to sign
901 * @return NULL on error, signature on success
903 struct GNUNET_CRYPTO_rsa_Signature *
904 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_rsa_PrivateKey *key,
905 const struct GNUNET_HashCode *hash)
907 struct GNUNET_CRYPTO_rsa_PublicKey *pkey;
911 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
912 rc = rsa_full_domain_hash (&v, hash, pkey, NULL);
913 GNUNET_CRYPTO_rsa_public_key_free (pkey);
914 GNUNET_assert (0 == rc);
916 return rsa_sign_mpi (key,v);
921 * Free memory occupied by signature.
923 * @param sig memory to freee
926 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_rsa_Signature *sig)
928 gcry_sexp_release (sig->sexp);
934 * Encode the given signature in a format suitable for storing it into a file.
936 * @param sig the signature
937 * @param[out] buffer set to a buffer with the encoded key
938 * @return size of memory allocated in @a buffer
941 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_rsa_Signature *sig,
947 n = gcry_sexp_sprint (sig->sexp,
948 GCRYSEXP_FMT_ADVANCED,
951 b = GNUNET_malloc (n);
952 GNUNET_assert ((n - 1) == /* since the last byte is \0 */
953 gcry_sexp_sprint (sig->sexp,
954 GCRYSEXP_FMT_ADVANCED,
963 * Decode the signature from the data-format back to the "normal", internal
966 * @param buf the buffer where the public key data is stored
967 * @param len the length of the data in @a buf
968 * @return NULL on error
970 struct GNUNET_CRYPTO_rsa_Signature *
971 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
974 struct GNUNET_CRYPTO_rsa_Signature *sig;
978 sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
980 gcry_sexp_new (&sig->sexp,
989 /* verify that this is an RSA signature */
990 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
992 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
995 /* this is no RSA Signature */
997 gcry_sexp_release (sig->sexp);
1001 gcry_mpi_release (s);
1007 * Duplicate the given public key
1009 * @param key the public key to duplicate
1010 * @return the duplicate key; NULL upon error
1012 struct GNUNET_CRYPTO_rsa_PublicKey *
1013 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_rsa_PublicKey *key)
1015 struct GNUNET_CRYPTO_rsa_PublicKey *dup;
1016 gcry_sexp_t dup_sexp;
1019 /* check if we really are exporting a public key */
1020 dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1021 GNUNET_assert (NULL != dup_sexp);
1022 gcry_sexp_release (dup_sexp);
1024 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1025 dup = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
1026 dup->sexp = dup_sexp;
1032 * Unblind a blind-signed signature. The signature should have been generated
1033 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1034 * #GNUNET_CRYPTO_rsa_blind().
1036 * @param sig the signature made on the blinded signature purpose
1037 * @param bkey the blinding key used to blind the signature purpose
1038 * @param pkey the public key of the signer
1039 * @return unblinded signature on success, NULL on error
1041 struct GNUNET_CRYPTO_rsa_Signature *
1042 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig,
1043 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
1044 struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
1051 struct GNUNET_CRYPTO_rsa_Signature *sret;
1053 ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1055 ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1058 GNUNET_break_op (0);
1061 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1063 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1066 gcry_mpi_release (n);
1067 GNUNET_break_op (0);
1070 r_inv = gcry_mpi_new (0);
1072 gcry_mpi_invm (r_inv,
1076 GNUNET_break_op (0);
1077 gcry_mpi_release (n);
1078 gcry_mpi_release (r_inv);
1079 gcry_mpi_release (s);
1082 ubsig = gcry_mpi_new (0);
1083 gcry_mpi_mulm (ubsig, s, r_inv, n);
1084 gcry_mpi_release (n);
1085 gcry_mpi_release (r_inv);
1086 gcry_mpi_release (s);
1088 sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
1090 gcry_sexp_build (&sret->sexp,
1092 "(sig-val (rsa (s %M)))",
1094 gcry_mpi_release (ubsig);
1100 * Verify whether the given hash corresponds to the given signature and the
1101 * signature is valid with respect to the given public key.
1103 * @param hash hash of the message to verify to match the @a sig
1104 * @param sig signature that is being validated
1105 * @param pkey public key of the signer
1106 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1109 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1110 const struct GNUNET_CRYPTO_rsa_Signature *sig,
1111 const struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
1117 rc = rsa_full_domain_hash (&r, hash, pkey, NULL);
1118 GNUNET_assert (0 == rc); // Allocation error in libgcrypt
1119 data = mpi_to_sexp(r);
1120 gcry_mpi_release (r);
1122 rc = gcry_pk_verify (sig->sexp,
1125 gcry_sexp_release (data);
1128 LOG (GNUNET_ERROR_TYPE_WARNING,
1129 _("RSA signature verification failed at %s:%d: %s\n"),
1132 gcry_strerror (rc));
1133 return GNUNET_SYSERR;
1140 * Duplicate the given private key
1142 * @param key the private key to duplicate
1143 * @return the duplicate key; NULL upon error
1145 struct GNUNET_CRYPTO_rsa_PrivateKey *
1146 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_rsa_PrivateKey *key)
1148 struct GNUNET_CRYPTO_rsa_PrivateKey *dup;
1149 gcry_sexp_t dup_sexp;
1152 /* check if we really are exporting a private key */
1153 dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1154 GNUNET_assert (NULL != dup_sexp);
1155 gcry_sexp_release (dup_sexp);
1157 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1158 dup = GNUNET_new (struct GNUNET_CRYPTO_rsa_PrivateKey);
1159 dup->sexp = dup_sexp;
1165 * Duplicate the given private key
1167 * @param key the private key to duplicate
1168 * @return the duplicate key; NULL upon error
1170 struct GNUNET_CRYPTO_rsa_Signature *
1171 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_rsa_Signature *sig)
1173 struct GNUNET_CRYPTO_rsa_Signature *dup;
1174 gcry_sexp_t dup_sexp;
1179 /* verify that this is an RSA signature */
1180 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1182 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1183 GNUNET_assert (0 == ret);
1184 gcry_mpi_release (s);
1186 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1187 dup = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
1188 dup->sexp = dup_sexp;
1193 /* end of util/rsa.c */