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
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 * @param bks pre-secret to use to derive the blinding key
400 * @return the newly created blinding key
402 static struct RsaBlindingKey *
403 rsa_blinding_key_derive (unsigned int len,
404 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
406 struct RsaBlindingKey *blind;
407 uint8_t buf[len / 8];
411 blind = GNUNET_new (struct RsaBlindingKey);
412 /* FIXME: #4483: actually derive key from bks! - Jeff,
413 check that you're happy with this!*/
414 GNUNET_assert (GNUNET_YES ==
415 GNUNET_CRYPTO_kdf (buf,
418 strlen ("blinding-kdf"),
422 rc = gcry_mpi_scan (&blind->r,
424 (const unsigned char *) buf,
427 GNUNET_assert (0 == rc);
433 * Compare the values of two signatures.
435 * @param s1 one signature
436 * @param s2 the other signature
437 * @return 0 if the two are equal
440 GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
441 struct GNUNET_CRYPTO_RsaSignature *s2)
449 z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
451 z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
466 * Compare the values of two public keys.
468 * @param p1 one public key
469 * @param p2 the other public key
470 * @return 0 if the two are equal
473 GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
474 struct GNUNET_CRYPTO_RsaPublicKey *p2)
482 z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
484 z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
499 * Compare the values of two private keys.
501 * @param p1 one private key
502 * @param p2 the other private key
503 * @return 0 if the two are equal
506 GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
507 struct GNUNET_CRYPTO_RsaPrivateKey *p2)
515 z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
517 z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
532 * Obtain the length of the RSA key in bits.
534 * @param key the public key to introspect
535 * @return length of the key in bits
538 GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
544 ret = key_from_sexp (&n, key->sexp, "rsa", "n");
547 /* this is no public RSA key */
551 rval = gcry_mpi_get_nbits (n);
552 gcry_mpi_release (n);
558 * Destroy a blinding key
560 * @param bkey the blinding key to destroy
563 rsa_blinding_key_free (struct RsaBlindingKey *bkey)
565 gcry_mpi_release (bkey->r);
571 * Print an MPI to a newly created buffer
573 * @param v MPI to print.
574 * @param[out] newly allocated buffer containing the result
575 * @return number of bytes stored in @a buffer
578 numeric_mpi_alloc_n_print (gcry_mpi_t v,
585 gcry_mpi_print (GCRYMPI_FMT_USG,
590 b = GNUNET_malloc (n);
592 gcry_mpi_print (GCRYMPI_FMT_USG,
603 * Computes a full domain hash seeded by the given public key.
604 * This gives a measure of provable security to the Taler exchange
605 * against one-more forgery attacks. See:
606 * https://eprint.iacr.org/2001/002.pdf
607 * http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
609 * @param[out] r MPI value set to the FDH
610 * @param hash initial hash of the message to sign
611 * @param pkey the public key of the signer
612 * @param rsize If not NULL, the number of bytes actually stored in buffer
613 * @return libgcrypt error that to represent an allocation failure
615 /* FIXME: exported symbol without proper prefix... */
617 rsa_full_domain_hash (gcry_mpi_t *r,
618 const struct GNUNET_HashCode *hash,
619 const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
624 unsigned int nhashes;
630 struct GNUNET_HashCode *hs;
632 /* Uncomment the following to debug without using the full domain hash */
634 rc = gcry_mpi_scan (r,
636 (const unsigned char *)hash,
637 sizeof(struct GNUNET_HashCode),
642 nbits = GNUNET_CRYPTO_rsa_public_key_len (pkey);
646 /* Already almost an HMAC since we consume a hash, so no GCRY_MD_FLAG_HMAC. */
647 rc = gcry_md_open (&h, GCRY_MD_SHA512, 0);
651 /* We seed with the public denomination key as a homage to RSA-PSS by *
652 * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
653 * of the hypothetical polyomial-time attack on RSA-KTI created by a *
654 * polynomial-time one-more forgary attack. Yey seeding! */
655 buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &buf);
656 gcry_md_write (h, buf, buf_len);
659 nhashes = (nbits-1) / (8 * sizeof(struct GNUNET_HashCode)) + 1;
660 hs = GNUNET_new_array (nhashes,
661 struct GNUNET_HashCode);
662 for (i=0; i<nhashes; i++)
664 gcry_md_write (h, hash, sizeof(struct GNUNET_HashCode));
665 rc = gcry_md_copy (&h0, h);
671 gcry_md_putc (h0, i % 256);
673 gcry_md_read (h0, GCRY_MD_SHA512),
674 sizeof(struct GNUNET_HashCode));
684 rc = gcry_mpi_scan (r,
686 (const unsigned char *) hs,
687 nhashes * sizeof(struct GNUNET_HashCode),
693 /* Do not allow *r to exceed n or signatures fail to verify unpredictably. *
694 * This happening with gcry_mpi_clear_highbit (*r, nbits-1) so maybe *
695 * gcry_mpi_clear_highbit is broken, but setting the highbit sounds good. */
696 gcry_mpi_set_highbit (*r, nbits-2);
702 * Blinds the given message with the given blinding key
704 * @param hash hash of the message to sign
705 * @param bkey the blinding key
706 * @param pkey the public key of the signer
707 * @param[out] buffer set to a buffer with the blinded message to be signed
708 * @return number of bytes stored in @a buffer
711 GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
712 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
713 struct GNUNET_CRYPTO_RsaPublicKey *pkey,
716 struct RsaBlindingKey *bkey;
727 ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
729 ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
737 rc = rsa_full_domain_hash (&data, hash, pkey, &rsize);
738 if (0 != rc) /* Allocation error in libgcrypt */
741 gcry_mpi_release (ne[0]);
742 gcry_mpi_release (ne[1]);
746 len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
747 bkey = rsa_blinding_key_derive (len,
749 r_e = gcry_mpi_new (0);
754 data_r_e = gcry_mpi_new (0);
755 gcry_mpi_mulm (data_r_e,
759 gcry_mpi_release (data);
760 gcry_mpi_release (ne[0]);
761 gcry_mpi_release (ne[1]);
762 gcry_mpi_release (r_e);
763 rsa_blinding_key_free (bkey);
765 n = numeric_mpi_alloc_n_print (data_r_e, buffer);
766 gcry_mpi_release (data_r_e);
772 * Convert an MPI to an S-expression suitable for signature operations.
774 * @param value pointer to the data to convert
775 * @return converted s-expression
778 mpi_to_sexp (gcry_mpi_t value)
780 gcry_sexp_t data = NULL;
783 gcry_sexp_build (&data,
785 "(data (flags raw) (value %M))",
792 * Sign the given MPI.
794 * @param key private key to use for the signing
795 * @param value the MPI to sign
796 * @return NULL on error, signature on success
798 static struct GNUNET_CRYPTO_RsaSignature *
799 rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
802 struct GNUNET_CRYPTO_RsaSignature *sig;
803 struct GNUNET_CRYPTO_RsaPublicKey *public_key;
807 data = mpi_to_sexp (value);
810 gcry_pk_sign (&result,
818 /* verify signature (guards against Lenstra's attack with fault injection...) */
819 public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
821 gcry_pk_verify (result,
826 GNUNET_CRYPTO_rsa_public_key_free (public_key);
827 gcry_sexp_release (data);
828 gcry_sexp_release (result);
831 GNUNET_CRYPTO_rsa_public_key_free (public_key);
833 /* return signature */
834 gcry_sexp_release (data);
835 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
842 * Sign a blinded value, which must be a full domain hash of a message.
844 * @param key private key to use for the signing
845 * @param msg the message to sign
846 * @param msg_len number of bytes in @a msg to sign
847 * @return NULL on error, signature on success
849 struct GNUNET_CRYPTO_RsaSignature *
850 GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
855 struct GNUNET_CRYPTO_RsaSignature *sig;
864 sig = rsa_sign_mpi (key, v);
865 gcry_mpi_release (v);
871 * Create and sign a full domain hash of a message.
873 * @param key private key to use for the signing
874 * @param hash the hash of the message to sign
875 * @return NULL on error, signature on success
877 struct GNUNET_CRYPTO_RsaSignature *
878 GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
879 const struct GNUNET_HashCode *hash)
881 struct GNUNET_CRYPTO_RsaPublicKey *pkey;
884 struct GNUNET_CRYPTO_RsaSignature *sig;
886 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
887 rc = rsa_full_domain_hash (&v, hash, pkey, NULL);
888 GNUNET_CRYPTO_rsa_public_key_free (pkey);
889 GNUNET_assert (0 == rc);
891 sig = rsa_sign_mpi (key, v);
892 gcry_mpi_release (v);
899 * Free memory occupied by signature.
901 * @param sig memory to freee
904 GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
906 gcry_sexp_release (sig->sexp);
912 * Encode the given signature in a format suitable for storing it into a file.
914 * @param sig the signature
915 * @param[out] buffer set to a buffer with the encoded key
916 * @return size of memory allocated in @a buffer
919 GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
925 n = gcry_sexp_sprint (sig->sexp,
926 GCRYSEXP_FMT_ADVANCED,
929 b = GNUNET_malloc (n);
930 GNUNET_assert ((n - 1) == /* since the last byte is \0 */
931 gcry_sexp_sprint (sig->sexp,
932 GCRYSEXP_FMT_ADVANCED,
941 * Decode the signature from the data-format back to the "normal", internal
944 * @param buf the buffer where the public key data is stored
945 * @param len the length of the data in @a buf
946 * @return NULL on error
948 struct GNUNET_CRYPTO_RsaSignature *
949 GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
952 struct GNUNET_CRYPTO_RsaSignature *sig;
956 sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
958 gcry_sexp_new (&sig->sexp,
967 /* verify that this is an RSA signature */
968 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
970 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
973 /* this is no RSA Signature */
975 gcry_sexp_release (sig->sexp);
979 gcry_mpi_release (s);
985 * Duplicate the given public key
987 * @param key the public key to duplicate
988 * @return the duplicate key; NULL upon error
990 struct GNUNET_CRYPTO_RsaPublicKey *
991 GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
993 struct GNUNET_CRYPTO_RsaPublicKey *dup;
994 gcry_sexp_t dup_sexp;
997 /* check if we really are exporting a public key */
998 dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
999 GNUNET_assert (NULL != dup_sexp);
1000 gcry_sexp_release (dup_sexp);
1002 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1003 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1004 dup->sexp = dup_sexp;
1010 * Unblind a blind-signed signature. The signature should have been generated
1011 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
1012 * #GNUNET_CRYPTO_rsa_blind().
1014 * @param sig the signature made on the blinded signature purpose
1015 * @param bks the blinding key secret used to blind the signature purpose
1016 * @param pkey the public key of the signer
1017 * @return unblinded signature on success, NULL on error
1019 struct GNUNET_CRYPTO_RsaSignature *
1020 GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig,
1021 const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
1022 struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1024 struct RsaBlindingKey *bkey;
1030 struct GNUNET_CRYPTO_RsaSignature *sret;
1033 ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1035 ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1038 GNUNET_break_op (0);
1041 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1043 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1046 gcry_mpi_release (n);
1047 GNUNET_break_op (0);
1050 len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
1051 bkey = rsa_blinding_key_derive (len,
1054 r_inv = gcry_mpi_new (0);
1056 gcry_mpi_invm (r_inv,
1060 GNUNET_break_op (0);
1061 gcry_mpi_release (n);
1062 gcry_mpi_release (r_inv);
1063 gcry_mpi_release (s);
1064 rsa_blinding_key_free (bkey);
1067 ubsig = gcry_mpi_new (0);
1068 gcry_mpi_mulm (ubsig, s, r_inv, n);
1069 gcry_mpi_release (n);
1070 gcry_mpi_release (r_inv);
1071 gcry_mpi_release (s);
1072 rsa_blinding_key_free (bkey);
1074 sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1076 gcry_sexp_build (&sret->sexp,
1078 "(sig-val (rsa (s %M)))",
1080 gcry_mpi_release (ubsig);
1086 * Verify whether the given hash corresponds to the given signature and the
1087 * signature is valid with respect to the given public key.
1089 * @param hash hash of the message to verify to match the @a sig
1090 * @param sig signature that is being validated
1091 * @param pkey public key of the signer
1092 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1095 GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
1096 const struct GNUNET_CRYPTO_RsaSignature *sig,
1097 const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
1103 rc = rsa_full_domain_hash (&r, hash, pkey, NULL);
1104 GNUNET_assert (0 == rc); /* Allocation error in libgcrypt */
1105 data = mpi_to_sexp(r);
1106 gcry_mpi_release (r);
1108 rc = gcry_pk_verify (sig->sexp,
1111 gcry_sexp_release (data);
1114 LOG (GNUNET_ERROR_TYPE_WARNING,
1115 _("RSA signature verification failed at %s:%d: %s\n"),
1118 gcry_strerror (rc));
1119 return GNUNET_SYSERR;
1126 * Duplicate the given private key
1128 * @param key the private key to duplicate
1129 * @return the duplicate key; NULL upon error
1131 struct GNUNET_CRYPTO_RsaPrivateKey *
1132 GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
1134 struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1135 gcry_sexp_t dup_sexp;
1138 /* check if we really are exporting a private key */
1139 dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1140 GNUNET_assert (NULL != dup_sexp);
1141 gcry_sexp_release (dup_sexp);
1143 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1144 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1145 dup->sexp = dup_sexp;
1151 * Duplicate the given private key
1153 * @param key the private key to duplicate
1154 * @return the duplicate key; NULL upon error
1156 struct GNUNET_CRYPTO_RsaSignature *
1157 GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
1159 struct GNUNET_CRYPTO_RsaSignature *dup;
1160 gcry_sexp_t dup_sexp;
1165 /* verify that this is an RSA signature */
1166 ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1168 ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1169 GNUNET_assert (0 == ret);
1170 gcry_mpi_release (s);
1172 GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1173 dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1174 dup->sexp = dup_sexp;
1179 /* end of util/rsa.c */