2 This file is part of GNUnet
3 Copyright (C) 2014,2016 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
22 * @author Jeffrey Burdges <burdges@gnunet.org>
26 #include "gnunet_crypto_lib.h"
28 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
32 * The private information of an RSA key pair.
34 struct GNUNET_CRYPTO_RsaPrivateKey
37 * Libgcrypt S-expression for the RSA private key.
44 * The public information of an RSA key pair.
46 struct GNUNET_CRYPTO_RsaPublicKey
49 * Libgcrypt S-expression for the RSA public key.
56 * @brief an RSA signature
58 struct GNUNET_CRYPTO_RsaSignature
61 * Libgcrypt S-expression for the RSA signature.
68 * @brief RSA blinding key
70 struct GNUNET_CRYPTO_rsa_BlindingKey
73 * Random value used for blinding.
80 * Extract values from an S-expression.
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
89 key_from_sexp (gcry_mpi_t *array,
100 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
102 l2 = gcry_sexp_cadr (list);
103 gcry_sexp_release (list);
108 for (s = elems; *s; s++, idx++)
110 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
112 for (i = 0; i < idx; i++)
114 gcry_free (array[i]);
117 gcry_sexp_release (list);
118 return 3; /* required parameter not found */
120 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
121 gcry_sexp_release (l2);
124 for (i = 0; i < idx; i++)
126 gcry_free (array[i]);
129 gcry_sexp_release (list);
130 return 4; /* required parameter is invalid */
133 gcry_sexp_release (list);
139 * Create a new private key. Caller must free return value.
141 * @param len length of the key in bits (i.e. 2048)
142 * @return fresh private key
144 struct GNUNET_CRYPTO_RsaPrivateKey *
145 GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
147 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
149 gcry_sexp_t s_keyparam;
152 gcry_sexp_build (&s_keyparam,
154 "(genkey(rsa(nbits %d)))",
157 gcry_pk_genkey (&s_key,
159 gcry_sexp_release (s_keyparam);
162 gcry_pk_testkey (s_key));
164 ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
171 * Free memory occupied by the private key.
173 * @param key pointer to the memory to free
176 GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
178 gcry_sexp_release (key->sexp);
184 * Encode the private key in a format suitable for
185 * storing it into a file.
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
192 GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
198 n = gcry_sexp_sprint (key->sexp,
199 GCRYSEXP_FMT_DEFAULT,
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,
214 * Decode the private key from the data-format back
215 * to the "normal", internal format.
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
221 struct GNUNET_CRYPTO_RsaPrivateKey *
222 GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
225 struct GNUNET_CRYPTO_RsaPrivateKey *key;
226 key = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
228 gcry_sexp_new (&key->sexp,
233 LOG (GNUNET_ERROR_TYPE_WARNING,
234 "Decoded private key is not valid\n");
238 if (0 != gcry_pk_testkey (key->sexp))
240 LOG (GNUNET_ERROR_TYPE_WARNING,
241 "Decoded private key is not valid\n");
242 GNUNET_CRYPTO_rsa_private_key_free (key);
250 * Extract the public key of the given private key.
252 * @param priv the private key
253 * @retur NULL on error, otherwise the public key
255 struct GNUNET_CRYPTO_RsaPublicKey *
256 GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
258 struct GNUNET_CRYPTO_RsaPublicKey *pub;
263 rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
265 rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
267 rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
273 rc = gcry_sexp_build (&result,
275 "(public-key(rsa(n %m)(e %m)))",
278 gcry_mpi_release (ne[0]);
279 gcry_mpi_release (ne[1]);
280 pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
287 * Free memory occupied by the public key.
289 * @param key pointer to the memory to free
292 GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
294 gcry_sexp_release (key->sexp);
300 * Encode the public key in a format suitable for
301 * storing it into a file.
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
308 GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key,
314 n = gcry_sexp_sprint (key->sexp,
315 GCRYSEXP_FMT_ADVANCED,
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,
330 * Compute hash over the public key.
332 * @param key public key to hash
333 * @param hc where to store the hash code
336 GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key,
337 struct GNUNET_HashCode *hc)
342 buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
344 GNUNET_CRYPTO_hash (buf,
352 * Decode the public key from the data-format back
353 * to the "normal", internal format.
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
359 struct GNUNET_CRYPTO_RsaPublicKey *
360 GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
363 struct GNUNET_CRYPTO_RsaPublicKey *key;
367 key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
369 gcry_sexp_new (&key->sexp,
378 /* verify that this is an RSA public key */
379 ret = key_from_sexp (&n, key->sexp, "public-key", "n");
381 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
384 /* this is no public RSA key */
386 gcry_sexp_release (key->sexp);
390 gcry_mpi_release (n);
396 * Create a blinding key
398 * @param len length of the key in bits (i.e. 2048)
399 * @return the newly created blinding key
401 struct GNUNET_CRYPTO_rsa_BlindingKey *
402 GNUNET_CRYPTO_rsa_blinding_key_create (unsigned int len)
404 struct GNUNET_CRYPTO_rsa_BlindingKey *blind;
406 blind = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
407 blind->r = gcry_mpi_new (len);
408 gcry_mpi_randomize (blind->r,
416 * Compare the values of two blinding keys.
419 * @param b2 the other key
420 * @return 0 if the two are equal
423 GNUNET_CRYPTO_rsa_blinding_key_cmp (struct GNUNET_CRYPTO_rsa_BlindingKey *b1,
424 struct GNUNET_CRYPTO_rsa_BlindingKey *b2)
426 return gcry_mpi_cmp (b1->r,
432 * Compare the values of two signatures.
434 * @param s1 one signature
435 * @param s2 the other signature
436 * @return 0 if the two are equal
439 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
440 struct GNUNET_CRYPTO_RsaSignature *s2)
448 z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
450 z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
465 * Compare the values of two public keys.
467 * @param p1 one public key
468 * @param p2 the other public key
469 * @return 0 if the two are equal
472 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
473 struct GNUNET_CRYPTO_RsaPublicKey *p2)
481 z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
483 z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
498 * Compare the values of two private keys.
500 * @param p1 one private key
501 * @param p2 the other private key
502 * @return 0 if the two are equal
505 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
506 struct GNUNET_CRYPTO_RsaPrivateKey *p2)
514 z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
516 z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
531 * Obtain the length of the RSA key in bits.
533 * @param key the public key to introspect
534 * @return length of the key in bits
537 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
543 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
546 /* this is no public RSA key */
550 rval = gcry_mpi_get_nbits (n);
551 gcry_mpi_release (n);
557 * Destroy a blinding key
559 * @param bkey the blinding key to destroy
562 GNUNET_CRYPTO_rsa_blinding_key_free (struct GNUNET_CRYPTO_rsa_BlindingKey *bkey)
564 gcry_mpi_release (bkey->r);
570 * Print an MPI to a newly created buffer
572 * @param v MPI to print.
573 * @param[out] newly allocated buffer containing the result
574 * @return number of bytes stored in @a buffer
577 numeric_mpi_alloc_n_print (gcry_mpi_t v,
584 gcry_mpi_print (GCRYMPI_FMT_USG,
589 b = GNUNET_malloc (n);
591 gcry_mpi_print (GCRYMPI_FMT_USG,
602 * Encode the blinding key in a format suitable for
603 * storing it into a file.
605 * @param bkey the blinding key
606 * @param[out] buffer set to a buffer with the encoded key
607 * @return size of memory allocated in @a buffer
610 GNUNET_CRYPTO_rsa_blinding_key_encode (const struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
613 return numeric_mpi_alloc_n_print (bkey->r, buffer);
618 * Decode the blinding key from the data-format back
619 * to the "normal", internal format.
621 * @param buf the buffer where the public key data is stored
622 * @param len the length of the data in @a buf
623 * @return NULL on error
625 struct GNUNET_CRYPTO_rsa_BlindingKey *
626 GNUNET_CRYPTO_rsa_blinding_key_decode (const char *buf,
629 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
632 bkey = GNUNET_new (struct GNUNET_CRYPTO_rsa_BlindingKey);
634 gcry_mpi_scan (&bkey->r,
636 (const unsigned char *) buf,
649 * Computes a full domain hash seeded by the given public key.
650 * This gives a measure of provable security to the Taler exchange
651 * against one-more forgery attacks. See:
652 * https://eprint.iacr.org/2001/002.pdf
653 * http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
655 * @param[out] r MPI value set to the FDH
656 * @param hash initial hash of the message to sign
657 * @param pkey the public key of the signer
658 * @param rsize If not NULL, the number of bytes actually stored in buffer
659 * @return libgcrypt error that to represent an allocation failure
662 rsa_full_domain_hash (gcry_mpi_t *r,
663 const struct GNUNET_HashCode *hash,
664 const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
669 unsigned int nhashes;
675 struct GNUNET_HashCode *hs;
677 /* Uncomment the following to debug without using the full domain hash */
679 rc = gcry_mpi_scan (r,
681 (const unsigned char *)hash,
682 sizeof(struct GNUNET_HashCode),
687 nbits = GNUNET_CRYPTO_rsa_public_key_len (pkey);
691 /* Already almost an HMAC since we consume a hash, so no GCRY_MD_FLAG_HMAC. */
692 rc = gcry_md_open (&h, GCRY_MD_SHA512, 0);
696 /* We seed with the public denomination key as a homage to RSA-PSS by *
697 * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
698 * of the hypothetical polyomial-time attack on RSA-KTI created by a *
699 * polynomial-time one-more forgary attack. Yey seeding! */
700 buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &buf);
701 gcry_md_write (h, buf, buf_len);
704 nhashes = (nbits-1) / (8 * sizeof(struct GNUNET_HashCode)) + 1;
705 hs = GNUNET_new_array (nhashes,
706 struct GNUNET_HashCode);
707 for (i=0; i<nhashes; i++)
709 gcry_md_write (h, hash, sizeof(struct GNUNET_HashCode));
710 rc = gcry_md_copy (&h0, h);
716 gcry_md_putc (h0, i % 256);
718 gcry_md_read (h0, GCRY_MD_SHA512),
719 sizeof(struct GNUNET_HashCode));
729 rc = gcry_mpi_scan (r,
731 (const unsigned char *) hs,
732 nhashes * sizeof(struct GNUNET_HashCode),
738 /* Do not allow *r to exceed n or signatures fail to verify unpredictably. *
739 * This happening with gcry_mpi_clear_highbit (*r, nbits-1) so maybe *
740 * gcry_mpi_clear_highbit is broken, but setting the highbit sounds good. */
741 gcry_mpi_set_highbit (*r, nbits-2);
747 * Blinds the given message with the given blinding key
749 * @param hash hash of the message to sign
750 * @param bkey the blinding key
751 * @param pkey the public key of the signer
752 * @param[out] buffer set to a buffer with the blinded message to be signed
753 * @return number of bytes stored in @a buffer
756 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
757 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
758 struct GNUNET_CRYPTO_RsaPublicKey *pkey,
770 ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
772 ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
780 rc = rsa_full_domain_hash (&data, hash, pkey, &rsize);
781 if (0 != rc) /* Allocation error in libgcrypt */
784 gcry_mpi_release (ne[0]);
785 gcry_mpi_release (ne[1]);
789 r_e = gcry_mpi_new (0);
794 data_r_e = gcry_mpi_new (0);
795 gcry_mpi_mulm (data_r_e,
799 gcry_mpi_release (data);
800 gcry_mpi_release (ne[0]);
801 gcry_mpi_release (ne[1]);
802 gcry_mpi_release (r_e);
804 n = numeric_mpi_alloc_n_print (data_r_e, buffer);
805 gcry_mpi_release (data_r_e);
811 * Convert an MPI to an S-expression suitable for signature operations.
813 * @param value pointer to the data to convert
814 * @return converted s-expression
817 mpi_to_sexp (gcry_mpi_t value)
819 gcry_sexp_t data = NULL;
822 gcry_sexp_build (&data,
824 "(data (flags raw) (value %M))",
831 * Sign the given MPI.
833 * @param key private key to use for the signing
834 * @param value the MPI to sign
835 * @return NULL on error, signature on success
837 static struct GNUNET_CRYPTO_RsaSignature *
838 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
841 struct GNUNET_CRYPTO_RsaSignature *sig;
842 struct GNUNET_CRYPTO_RsaPublicKey *public_key;
846 data = mpi_to_sexp (value);
849 gcry_pk_sign (&result,
857 /* verify signature (guards against Lenstra's attack with fault injection...) */
858 public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
860 gcry_pk_verify (result,
865 GNUNET_CRYPTO_rsa_public_key_free (public_key);
866 gcry_sexp_release (data);
867 gcry_sexp_release (result);
870 GNUNET_CRYPTO_rsa_public_key_free (public_key);
872 /* return signature */
873 gcry_sexp_release (data);
874 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
881 * Sign a blinded value, which must be a full domain hash of a message.
883 * @param key private key to use for the signing
884 * @param msg the message to sign
885 * @param msg_len number of bytes in @a msg to sign
886 * @return NULL on error, signature on success
888 struct GNUNET_CRYPTO_RsaSignature *
889 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
894 struct GNUNET_CRYPTO_RsaSignature *sig;
903 sig = rsa_sign_mpi (key, v);
904 gcry_mpi_release (v);
910 * Create and sign a full domain hash of a message.
912 * @param key private key to use for the signing
913 * @param hash the hash of the message to sign
914 * @return NULL on error, signature on success
916 struct GNUNET_CRYPTO_RsaSignature *
917 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
918 const struct GNUNET_HashCode *hash)
920 struct GNUNET_CRYPTO_RsaPublicKey *pkey;
923 struct GNUNET_CRYPTO_RsaSignature *sig;
925 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
926 rc = rsa_full_domain_hash (&v, hash, pkey, NULL);
927 GNUNET_CRYPTO_rsa_public_key_free (pkey);
928 GNUNET_assert (0 == rc);
930 sig = rsa_sign_mpi (key, v);
931 gcry_mpi_release (v);
938 * Free memory occupied by signature.
940 * @param sig memory to freee
943 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
945 gcry_sexp_release (sig->sexp);
951 * Encode the given signature in a format suitable for storing it into a file.
953 * @param sig the signature
954 * @param[out] buffer set to a buffer with the encoded key
955 * @return size of memory allocated in @a buffer
958 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
964 n = gcry_sexp_sprint (sig->sexp,
965 GCRYSEXP_FMT_ADVANCED,
968 b = GNUNET_malloc (n);
969 GNUNET_assert ((n - 1) == /* since the last byte is \0 */
970 gcry_sexp_sprint (sig->sexp,
971 GCRYSEXP_FMT_ADVANCED,
980 * Decode the signature from the data-format back to the "normal", internal
983 * @param buf the buffer where the public key data is stored
984 * @param len the length of the data in @a buf
985 * @return NULL on error
987 struct GNUNET_CRYPTO_RsaSignature *
988 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
991 struct GNUNET_CRYPTO_RsaSignature *sig;
995 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
997 gcry_sexp_new (&sig->sexp,
1002 GNUNET_break_op (0);
1006 /* verify that this is an RSA signature */
1007 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1009 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1012 /* this is no RSA Signature */
1013 GNUNET_break_op (0);
1014 gcry_sexp_release (sig->sexp);
1018 gcry_mpi_release (s);
1024 * Duplicate the given public key
1026 * @param key the public key to duplicate
1027 * @return the duplicate key; NULL upon error
1029 struct GNUNET_CRYPTO_RsaPublicKey *
1030 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
1032 struct GNUNET_CRYPTO_RsaPublicKey *dup;
1033 gcry_sexp_t dup_sexp;
1036 /* check if we really are exporting a public key */
1037 dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1038 GNUNET_assert (NULL != dup_sexp);
1039 gcry_sexp_release (dup_sexp);
1041 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1042 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1043 dup->sexp = dup_sexp;
1049 * Unblind a blind-signed signature. The signature should have been generated
1050 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1051 * #GNUNET_CRYPTO_rsa_blind().
1053 * @param sig the signature made on the blinded signature purpose
1054 * @param bkey the blinding key used to blind the signature purpose
1055 * @param pkey the public key of the signer
1056 * @return unblinded signature on success, NULL on error
1058 struct GNUNET_CRYPTO_RsaSignature *
1059 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
1060 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
1061 struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1068 struct GNUNET_CRYPTO_RsaSignature *sret;
1070 ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1072 ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1075 GNUNET_break_op (0);
1078 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1080 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1083 gcry_mpi_release (n);
1084 GNUNET_break_op (0);
1087 r_inv = gcry_mpi_new (0);
1089 gcry_mpi_invm (r_inv,
1093 GNUNET_break_op (0);
1094 gcry_mpi_release (n);
1095 gcry_mpi_release (r_inv);
1096 gcry_mpi_release (s);
1099 ubsig = gcry_mpi_new (0);
1100 gcry_mpi_mulm (ubsig, s, r_inv, n);
1101 gcry_mpi_release (n);
1102 gcry_mpi_release (r_inv);
1103 gcry_mpi_release (s);
1105 sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1107 gcry_sexp_build (&sret->sexp,
1109 "(sig-val (rsa (s %M)))",
1111 gcry_mpi_release (ubsig);
1117 * Verify whether the given hash corresponds to the given signature and the
1118 * signature is valid with respect to the given public key.
1120 * @param hash hash of the message to verify to match the @a sig
1121 * @param sig signature that is being validated
1122 * @param pkey public key of the signer
1123 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1126 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1127 const struct GNUNET_CRYPTO_RsaSignature *sig,
1128 const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1134 rc = rsa_full_domain_hash (&r, hash, pkey, NULL);
1135 GNUNET_assert (0 == rc); /* Allocation error in libgcrypt */
1136 data = mpi_to_sexp(r);
1137 gcry_mpi_release (r);
1139 rc = gcry_pk_verify (sig->sexp,
1142 gcry_sexp_release (data);
1145 LOG (GNUNET_ERROR_TYPE_WARNING,
1146 _("RSA signature verification failed at %s:%d: %s\n"),
1149 gcry_strerror (rc));
1150 return GNUNET_SYSERR;
1157 * Duplicate the given private key
1159 * @param key the private key to duplicate
1160 * @return the duplicate key; NULL upon error
1162 struct GNUNET_CRYPTO_RsaPrivateKey *
1163 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1165 struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1166 gcry_sexp_t dup_sexp;
1169 /* check if we really are exporting a private key */
1170 dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1171 GNUNET_assert (NULL != dup_sexp);
1172 gcry_sexp_release (dup_sexp);
1174 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1175 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1176 dup->sexp = dup_sexp;
1182 * Duplicate the given private key
1184 * @param key the private key to duplicate
1185 * @return the duplicate key; NULL upon error
1187 struct GNUNET_CRYPTO_RsaSignature *
1188 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1190 struct GNUNET_CRYPTO_RsaSignature *dup;
1191 gcry_sexp_t dup_sexp;
1196 /* verify that this is an RSA signature */
1197 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1199 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1200 GNUNET_assert (0 == ret);
1201 gcry_mpi_release (s);
1203 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1204 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1205 dup->sexp = dup_sexp;
1210 /* end of util/rsa.c */