GNUnet  0.11.x
Data Structures | Macros | Functions
crypto_rsa.c File Reference

Chaum-style Blind signatures based on RSA. More...

#include "platform.h"
#include <gcrypt.h>
#include "gnunet_crypto_lib.h"
#include "benchmark.h"
Include dependency graph for crypto_rsa.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_CRYPTO_RsaPrivateKey
 The private information of an RSA key pair. More...
 
struct  GNUNET_CRYPTO_RsaPublicKey
 The public information of an RSA key pair. More...
 
struct  GNUNET_CRYPTO_RsaSignature
 an RSA signature More...
 
struct  RsaBlindingKey
 RSA blinding key. More...
 
struct  GNUNET_CRYPTO_RsaPublicKeyHeaderP
 Format of the header of a serialized RSA public key. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
 

Functions

static int key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
 Extract values from an S-expression. More...
 
struct GNUNET_CRYPTO_RsaPrivateKeyGNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
 Create a new private key. More...
 
void GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
 Free memory occupied by the private key. More...
 
size_t GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key, void **buffer)
 Encode the private key in a format suitable for storing it into a file. More...
 
struct GNUNET_CRYPTO_RsaPrivateKeyGNUNET_CRYPTO_rsa_private_key_decode (const void *buf, size_t buf_size)
 Decode the private key from the data-format back to the "normal", internal format. More...
 
struct GNUNET_CRYPTO_RsaPublicKeyGNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
 Extract the public key of the given private key. More...
 
void GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
 Free memory occupied by the public key. More...
 
GNUNET_NETWORK_STRUCT_END size_t GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key, void **buffer)
 Encode the public key in a format suitable for storing it into a file. More...
 
void GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key, struct GNUNET_HashCode *hc)
 Compute hash over the public key. More...
 
struct GNUNET_CRYPTO_RsaPublicKeyGNUNET_CRYPTO_rsa_public_key_decode (const char *buf, size_t len)
 Decode the public key from the data-format back to the "normal", internal format. More...
 
static int rsa_gcd_validate (gcry_mpi_t r, gcry_mpi_t n)
 Test for malicious RSA key. More...
 
static struct RsaBlindingKeyrsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
 Create a blinding key. More...
 
int GNUNET_CRYPTO_rsa_signature_cmp (const struct GNUNET_CRYPTO_RsaSignature *s1, const struct GNUNET_CRYPTO_RsaSignature *s2)
 Compare the values of two signatures. More...
 
int GNUNET_CRYPTO_rsa_public_key_cmp (const struct GNUNET_CRYPTO_RsaPublicKey *p1, const struct GNUNET_CRYPTO_RsaPublicKey *p2)
 Compare the values of two public keys. More...
 
int GNUNET_CRYPTO_rsa_private_key_cmp (const struct GNUNET_CRYPTO_RsaPrivateKey *p1, const struct GNUNET_CRYPTO_RsaPrivateKey *p2)
 Compare the values of two private keys. More...
 
unsigned int GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
 Obtain the length of the RSA key in bits. More...
 
static void rsa_blinding_key_free (struct RsaBlindingKey *bkey)
 Destroy a blinding key. More...
 
static size_t numeric_mpi_alloc_n_print (gcry_mpi_t v, char **buffer)
 Print an MPI to a newly created buffer. More...
 
static gcry_mpi_t rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_HashCode *hash)
 Computes a full domain hash seeded by the given public key. More...
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey, void **buf, size_t *buf_size)
 Blinds the given message with the given blinding key. More...
 
static gcry_sexp_t mpi_to_sexp (gcry_mpi_t value)
 Convert an MPI to an S-expression suitable for signature operations. More...
 
static struct GNUNET_CRYPTO_RsaSignaturersa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key, gcry_mpi_t value)
 Sign the given MPI. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const void *msg, size_t msg_len)
 Sign a blinded value, which must be a full domain hash of a message. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_HashCode *hash)
 Create and sign a full domain hash of a message. More...
 
void GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
 Free memory occupied by signature. More...
 
size_t GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig, void **buffer)
 Encode the given signature in a format suitable for storing it into a file. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_signature_decode (const void *buf, size_t buf_size)
 Decode the signature from the data-format back to the "normal", internal format. More...
 
struct GNUNET_CRYPTO_RsaPublicKeyGNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
 Duplicate the given public key. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey)
 Unblind a blind-signed signature. More...
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash, const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
 Verify whether the given hash corresponds to the given signature and the signature is valid with respect to the given public key. More...
 
struct GNUNET_CRYPTO_RsaPrivateKeyGNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
 Duplicate the given private key. More...
 
struct GNUNET_CRYPTO_RsaSignatureGNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
 Duplicate the given rsa signature. More...
 

Detailed Description

Chaum-style Blind signatures based on RSA.

Author
Sree Harsha Totakura sreeh.nosp@m.arsh.nosp@m.a@tot.nosp@m.akur.nosp@m.a.in
Christian Grothoff
Jeffrey Burdges burdg.nosp@m.es@g.nosp@m.nunet.nosp@m..org

Definition in file crypto_rsa.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)

Definition at line 33 of file crypto_rsa.c.

Function Documentation

◆ key_from_sexp()

static int key_from_sexp ( gcry_mpi_t *  array,
gcry_sexp_t  sexp,
const char *  topname,
const char *  elems 
)
static

Extract values from an S-expression.

Parameters
arraywhere to store the result(s)
sexpS-expression to parse
topnametop-level name in the S-expression that is of interest
elemsnames of the elements to extract
Returns
0 on success

Definition at line 94 of file crypto_rsa.c.

98 {
99  gcry_sexp_t list;
100  gcry_sexp_t l2;
101  const char *s;
102  unsigned int idx;
103 
104  if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
105  return 1;
106  l2 = gcry_sexp_cadr (list);
107  gcry_sexp_release (list);
108  list = l2;
109  if (! list)
110  return 2;
111  idx = 0;
112  for (s = elems; *s; s++, idx++)
113  {
114  if (! (l2 = gcry_sexp_find_token (list, s, 1)))
115  {
116  for (unsigned int i = 0; i < idx; i++)
117  {
118  gcry_free (array[i]);
119  array[i] = NULL;
120  }
121  gcry_sexp_release (list);
122  return 3; /* required parameter not found */
123  }
124  array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
125  gcry_sexp_release (l2);
126  if (! array[idx])
127  {
128  for (unsigned int i = 0; i < idx; i++)
129  {
130  gcry_free (array[i]);
131  array[i] = NULL;
132  }
133  gcry_sexp_release (list);
134  return 4; /* required parameter is invalid */
135  }
136  }
137  gcry_sexp_release (list);
138  return 0;
139 }
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69

References list.

Referenced by GNUNET_CRYPTO_rsa_blind(), GNUNET_CRYPTO_rsa_private_key_get_public(), GNUNET_CRYPTO_rsa_public_key_encode(), GNUNET_CRYPTO_rsa_public_key_len(), GNUNET_CRYPTO_rsa_signature_dup(), GNUNET_CRYPTO_rsa_signature_encode(), GNUNET_CRYPTO_rsa_unblind(), and rsa_blinding_key_derive().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_create()

struct GNUNET_CRYPTO_RsaPrivateKey* GNUNET_CRYPTO_rsa_private_key_create ( unsigned int  len)

Create a new private key.

Caller must free return value.

Parameters
lenlength of the key in bits (e.g. 2048)
Returns
fresh private key

Definition at line 143 of file crypto_rsa.c.

144 {
146  gcry_sexp_t s_key;
147  gcry_sexp_t s_keyparam;
148 
149  BENCHMARK_START (rsa_private_key_create);
150 
151  GNUNET_assert (0 ==
152  gcry_sexp_build (&s_keyparam,
153  NULL,
154  "(genkey(rsa(nbits %d)))",
155  len));
156  GNUNET_assert (0 ==
157  gcry_pk_genkey (&s_key,
158  s_keyparam));
159  gcry_sexp_release (s_keyparam);
160 #if EXTRA_CHECKS
161  GNUNET_assert (0 ==
162  gcry_pk_testkey (s_key));
163 #endif
165  ret->sexp = s_key;
166  BENCHMARK_END (rsa_private_key_create);
167  return ret;
168 }
#define BENCHMARK_START(opname)
Definition: benchmark.h:57
#define BENCHMARK_END(opname)
Definition: benchmark.h:58
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
The private information of an RSA key pair.
Definition: crypto_rsa.c:40

References BENCHMARK_END, BENCHMARK_START, GNUNET_assert, GNUNET_new, len, and ret.

Referenced by output_vectors().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_free()

void GNUNET_CRYPTO_rsa_private_key_free ( struct GNUNET_CRYPTO_RsaPrivateKey key)

Free memory occupied by the private key.

Parameters
keypointer to the memory to free

Definition at line 172 of file crypto_rsa.c.

173 {
174  gcry_sexp_release (key->sexp);
175  GNUNET_free (key);
176 }
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_free, and key.

Referenced by GNUNET_CRYPTO_rsa_private_key_decode(), and output_vectors().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_encode()

size_t GNUNET_CRYPTO_rsa_private_key_encode ( const struct GNUNET_CRYPTO_RsaPrivateKey key,
void **  buffer 
)

Encode the private key in a format suitable for storing it into a file.

Parameters
keythe private key
[out]bufferset to a buffer with the encoded key
Returns
size of memory allocatedin buffer

Definition at line 180 of file crypto_rsa.c.

183 {
184  size_t n;
185  char *b;
186 
187  n = gcry_sexp_sprint (key->sexp,
188  GCRYSEXP_FMT_DEFAULT,
189  NULL,
190  0);
191  b = GNUNET_malloc (n);
192  GNUNET_assert ((n - 1) == /* since the last byte is \0 */
193  gcry_sexp_sprint (key->sexp,
194  GCRYSEXP_FMT_DEFAULT,
195  b,
196  n));
197  *buffer = b;
198  return n;
199 }
#define GNUNET_malloc(size)
Wrapper around malloc.

References testconfigure::b, GNUNET_assert, GNUNET_malloc, and key.

Referenced by GNUNET_CRYPTO_rsa_private_key_cmp(), and output_vectors().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_decode()

struct GNUNET_CRYPTO_RsaPrivateKey* GNUNET_CRYPTO_rsa_private_key_decode ( const void *  buf,
size_t  buf_size 
)

Decode the private key from the data-format back to the "normal", internal format.

Parameters
bufthe buffer where the private key data is stored
buf_sizethe size of the data in buf
Returns
NULL on error

Definition at line 203 of file crypto_rsa.c.

205 {
207 
209  if (0 !=
210  gcry_sexp_new (&key->sexp,
211  buf,
212  buf_size,
213  0))
214  {
216  "Decoded private key is not valid\n");
217  GNUNET_free (key);
218  return NULL;
219  }
220  if (0 != gcry_pk_testkey (key->sexp))
221  {
223  "Decoded private key is not valid\n");
225  return NULL;
226  }
227  return key;
228 }
void GNUNET_CRYPTO_rsa_private_key_free(struct GNUNET_CRYPTO_RsaPrivateKey *key)
Free memory occupied by the private key.
Definition: crypto_rsa.c:172
#define LOG(kind,...)
Definition: crypto_rsa.c:33
static char buf[2048]
@ GNUNET_ERROR_TYPE_WARNING

References buf, GNUNET_CRYPTO_rsa_private_key_free(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_new, key, and LOG.

Referenced by checkvec().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_get_public()

struct GNUNET_CRYPTO_RsaPublicKey* GNUNET_CRYPTO_rsa_private_key_get_public ( const struct GNUNET_CRYPTO_RsaPrivateKey priv)

Extract the public key of the given private key.

Parameters
privthe private key
Returns
NULL on error, otherwise the public key

Definition at line 232 of file crypto_rsa.c.

234 {
236  gcry_mpi_t ne[2];
237  int rc;
238  gcry_sexp_t result;
239 
240  BENCHMARK_START (rsa_private_key_get_public);
241 
242  rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
243  if (0 != rc)
244  rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
245  if (0 != rc)
246  rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
247  if (0 != rc)
248  {
249  GNUNET_break_op (0);
250  return NULL;
251  }
252  rc = gcry_sexp_build (&result,
253  NULL,
254  "(public-key(rsa(n %m)(e %m)))",
255  ne[0],
256  ne[1]);
257  gcry_mpi_release (ne[0]);
258  gcry_mpi_release (ne[1]);
260  pub->sexp = result;
261  BENCHMARK_END (rsa_private_key_get_public);
262  return pub;
263 }
static int key_from_sexp(gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
Extract values from an S-expression.
Definition: crypto_rsa.c:94
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA private key.
Definition: crypto_rsa.c:44
The public information of an RSA key pair.
Definition: crypto_rsa.c:52

References BENCHMARK_END, BENCHMARK_START, GNUNET_break_op, GNUNET_new, key_from_sexp(), pub, result, and GNUNET_CRYPTO_RsaPrivateKey::sexp.

Referenced by GNUNET_CRYPTO_rsa_sign_fdh(), output_vectors(), and rsa_sign_mpi().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_free()

void GNUNET_CRYPTO_rsa_public_key_free ( struct GNUNET_CRYPTO_RsaPublicKey key)

Free memory occupied by the public key.

Parameters
keypointer to the memory to free

Definition at line 267 of file crypto_rsa.c.

268 {
269  gcry_sexp_release (key->sexp);
270  GNUNET_free (key);
271 }

References GNUNET_free, and key.

Referenced by clean_rsa_pub(), clean_rsa_public_key(), GNUNET_CRYPTO_rsa_sign_fdh(), output_vectors(), and rsa_sign_mpi().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_encode()

GNUNET_NETWORK_STRUCT_END size_t GNUNET_CRYPTO_rsa_public_key_encode ( const struct GNUNET_CRYPTO_RsaPublicKey key,
void **  buffer 
)

Encode the public key in a format suitable for storing it into a file.

Parameters
keythe private key
[out]bufferset to a buffer with the encoded key
Returns
size of memory allocated in buffer

Definition at line 300 of file crypto_rsa.c.

303 {
304  gcry_mpi_t ne[2];
305  size_t n_size;
306  size_t e_size;
307  size_t rsize;
308  size_t buf_size;
309  char *buf;
311  int ret;
312 
313  ret = key_from_sexp (ne,
314  key->sexp,
315  "public-key",
316  "ne");
317  if (0 != ret)
318  ret = key_from_sexp (ne,
319  key->sexp,
320  "rsa",
321  "ne");
322  if (0 != ret)
323  {
324  GNUNET_break (0);
325  *buffer = NULL;
326  return 0;
327  }
328  gcry_mpi_print (GCRYMPI_FMT_USG,
329  NULL,
330  0,
331  &n_size,
332  ne[0]);
333  gcry_mpi_print (GCRYMPI_FMT_USG,
334  NULL,
335  0,
336  &e_size,
337  ne[1]);
338  if ( (e_size > UINT16_MAX) ||
339  (n_size > UINT16_MAX) )
340  {
341  GNUNET_break (0);
342  if (NULL != buffer)
343  *buffer = NULL;
344  gcry_mpi_release (ne[0]);
345  gcry_mpi_release (ne[1]);
346  return 0;
347  }
348  buf_size = n_size + e_size + sizeof (hdr);
349  if (NULL == buffer)
350  {
351  gcry_mpi_release (ne[0]);
352  gcry_mpi_release (ne[1]);
353  return buf_size;
354  }
355  buf = GNUNET_malloc (buf_size);
356  hdr.modulus_length = htons ((uint16_t) n_size);
357  hdr.public_exponent_length = htons ((uint16_t) e_size);
358  memcpy (buf,
359  &hdr,
360  sizeof (hdr));
361  GNUNET_assert (0 ==
362  gcry_mpi_print (GCRYMPI_FMT_USG,
363  (unsigned char *) &buf[sizeof (hdr)],
364  n_size,
365  &rsize,
366  ne[0]));
367 
368  GNUNET_assert (0 ==
369  gcry_mpi_print (GCRYMPI_FMT_USG,
370  (unsigned char *) &buf[sizeof (hdr) + n_size],
371  e_size,
372  &rsize,
373  ne[1]));
374  *buffer = buf;
375  gcry_mpi_release (ne[0]);
376  gcry_mpi_release (ne[1]);
377  return buf_size;
378 }
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
Format of the header of a serialized RSA public key.
Definition: crypto_rsa.c:280

References buf, GNUNET_assert, GNUNET_break, GNUNET_malloc, key, key_from_sexp(), GNUNET_CRYPTO_RsaPublicKeyHeaderP::modulus_length, GNUNET_CRYPTO_RsaPublicKeyHeaderP::public_exponent_length, and ret.

Referenced by bind_rsa_pub(), checkvec(), GNUNET_CRYPTO_rsa_blind(), GNUNET_CRYPTO_rsa_public_key_cmp(), GNUNET_CRYPTO_rsa_public_key_hash(), GNUNET_JSON_from_rsa_public_key(), GNUNET_PQ_query_param_rsa_public_key(), my_conv_rsa_public_key(), and output_vectors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_hash()

void GNUNET_CRYPTO_rsa_public_key_hash ( const struct GNUNET_CRYPTO_RsaPublicKey key,
struct GNUNET_HashCode hc 
)

Compute hash over the public key.

Parameters
keypublic key to hash
hcwhere to store the hash code

Definition at line 382 of file crypto_rsa.c.

384 {
385  void *buf;
386  size_t buf_size;
387 
389  &buf);
391  buf_size,
392  hc);
393  GNUNET_free (buf);
394 }
GNUNET_NETWORK_STRUCT_END size_t GNUNET_CRYPTO_rsa_public_key_encode(const struct GNUNET_CRYPTO_RsaPublicKey *key, void **buffer)
Encode the public key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:300
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41

References buf, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_rsa_public_key_encode(), GNUNET_free, and key.

Here is the call graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_decode()

struct GNUNET_CRYPTO_RsaPublicKey* GNUNET_CRYPTO_rsa_public_key_decode ( const char *  buf,
size_t  len 
)

Decode the public key from the data-format back to the "normal", internal format.

Parameters
bufthe buffer where the public key data is stored
lenthe length of the data in buf
Returns
NULL on error

Definition at line 398 of file crypto_rsa.c.

400 {
403  size_t e_size;
404  size_t n_size;
405  gcry_mpi_t n;
406  gcry_mpi_t e;
407  gcry_sexp_t data;
408 
409  if (len < sizeof (hdr))
410  {
411  GNUNET_break_op (0);
412  return NULL;
413  }
414  memcpy (&hdr, buf, sizeof (hdr));
415  n_size = ntohs (hdr.modulus_length);
416  e_size = ntohs (hdr.public_exponent_length);
417  if (len != sizeof (hdr) + e_size + n_size)
418  {
419  GNUNET_break_op (0);
420  return NULL;
421  }
422  if (0 !=
423  gcry_mpi_scan (&n,
424  GCRYMPI_FMT_USG,
425  &buf[sizeof (hdr)],
426  n_size,
427  NULL))
428  {
429  GNUNET_break_op (0);
430  return NULL;
431  }
432  if (0 !=
433  gcry_mpi_scan (&e,
434  GCRYMPI_FMT_USG,
435  &buf[sizeof (hdr) + n_size],
436  e_size,
437  NULL))
438  {
439  GNUNET_break_op (0);
440  gcry_mpi_release (n);
441  return NULL;
442  }
443 
444  if (0 !=
445  gcry_sexp_build (&data,
446  NULL,
447  "(public-key(rsa(n %m)(e %m)))",
448  n,
449  e))
450  {
451  GNUNET_break (0);
452  gcry_mpi_release (n);
453  gcry_mpi_release (e);
454  return NULL;
455  }
456  gcry_mpi_release (n);
457  gcry_mpi_release (e);
459  key->sexp = data;
460  return key;
461 }
static struct Experiment * e
uint32_t data
The data value.

References buf, data, e, GNUNET_break, GNUNET_break_op, GNUNET_new, key, len, GNUNET_CRYPTO_RsaPublicKeyHeaderP::modulus_length, and GNUNET_CRYPTO_RsaPublicKeyHeaderP::public_exponent_length.

Referenced by checkvec(), extract_rsa_pub(), parse_rsa_public_key(), and post_extract_rsa_public_key().

Here is the caller graph for this function:

◆ rsa_gcd_validate()

static int rsa_gcd_validate ( gcry_mpi_t  r,
gcry_mpi_t  n 
)
static

Test for malicious RSA key.

Assuming n is an RSA modulous and r is generated using a call to GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a malicious RSA key designed to deanomize the user.

Parameters
rKDF result
nRSA modulus
Returns
True if gcd(r,n) = 1, False means RSA key is malicious

Definition at line 476 of file crypto_rsa.c.

477 {
478  gcry_mpi_t g;
479  int t;
480 
481  g = gcry_mpi_new (0);
482  t = gcry_mpi_gcd (g, r, n);
483  gcry_mpi_release (g);
484  return t;
485 }
static struct GNUNET_SCHEDULER_Task * t
Main task.

References t.

Referenced by GNUNET_CRYPTO_rsa_blind(), and rsa_blinding_key_derive().

Here is the caller graph for this function:

◆ rsa_blinding_key_derive()

static struct RsaBlindingKey* rsa_blinding_key_derive ( const struct GNUNET_CRYPTO_RsaPublicKey pkey,
const struct GNUNET_CRYPTO_RsaBlindingKeySecret bks 
)
static

Create a blinding key.

Parameters
lenlength of the key in bits (e.g. 2048)
bkspre-secret to use to derive the blinding key
Returns
the newly created blinding key, NULL if RSA key is malicious

Definition at line 496 of file crypto_rsa.c.

498 {
499  char *xts = "Blinding KDF extractor HMAC key"; /* Trusts bks' randomness more */
500  struct RsaBlindingKey *blind;
501  gcry_mpi_t n;
502 
503  blind = GNUNET_new (struct RsaBlindingKey);
504  GNUNET_assert (NULL != blind);
505 
506  /* Extract the composite n from the RSA public key */
507  GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
508  /* Assert that it at least looks like an RSA key */
509  GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
510 
511  GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
512  n,
513  xts, strlen (xts),
514  bks, sizeof(*bks),
515  "Blinding KDF");
516  if (0 == rsa_gcd_validate (blind->r, n))
517  {
518  GNUNET_free (blind);
519  blind = NULL;
520  }
521 
522  gcry_mpi_release (n);
523  return blind;
524 }
static int rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
Test for malicious RSA key.
Definition: crypto_rsa.c:476
static char * pkey
Public key of the zone to look in, in ASCII.
void GNUNET_CRYPTO_kdf_mod_mpi(gcry_mpi_t *r, gcry_mpi_t n, const void *xts, size_t xts_len, const void *skm, size_t skm_len, const char *ctx)
Deterministically generate a pseudo-random number uniformly from the integers modulo a libgcrypt mpi.
Definition: crypto_kdf.c:127
RSA blinding key.
Definition: crypto_rsa.c:76
gcry_mpi_t r
Random value used for blinding.
Definition: crypto_rsa.c:80

References GNUNET_assert, GNUNET_CRYPTO_kdf_mod_mpi(), GNUNET_free, GNUNET_new, key_from_sexp(), pkey, RsaBlindingKey::r, and rsa_gcd_validate().

Referenced by GNUNET_CRYPTO_rsa_unblind().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_signature_cmp()

int GNUNET_CRYPTO_rsa_signature_cmp ( const struct GNUNET_CRYPTO_RsaSignature s1,
const struct GNUNET_CRYPTO_RsaSignature s2 
)

Compare the values of two signatures.

Parameters
s1one signature
s2the other signature
Returns
0 if the two are equal

Definition at line 571 of file crypto_rsa.c.

573 {
574  void *b1;
575  void *b2;
576  size_t z1;
577  size_t z2;
578  int ret;
579 
581  &b1);
583  &b2);
584  if (z1 != z2)
585  ret = 1;
586  else
587  ret = memcmp (b1,
588  b2,
589  z1);
590  GNUNET_free (b1);
591  GNUNET_free (b2);
592  return ret;
593 }
size_t GNUNET_CRYPTO_rsa_signature_encode(const struct GNUNET_CRYPTO_RsaSignature *sig, void **buffer)
Encode the given signature in a format suitable for storing it into a file.
Definition: crypto_rsa.c:968

References GNUNET_CRYPTO_rsa_signature_encode(), GNUNET_free, and ret.

Here is the call graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_cmp()

int GNUNET_CRYPTO_rsa_public_key_cmp ( const struct GNUNET_CRYPTO_RsaPublicKey p1,
const struct GNUNET_CRYPTO_RsaPublicKey p2 
)

Compare the values of two public keys.

Parameters
p1one public key
p2the other public key
Returns
0 if the two are equal

Definition at line 597 of file crypto_rsa.c.

599 {
600  void *b1;
601  void *b2;
602  size_t z1;
603  size_t z2;
604  int ret;
605 
607  &b1);
609  &b2);
610  if (z1 != z2)
611  ret = 1;
612  else
613  ret = memcmp (b1,
614  b2,
615  z1);
616  GNUNET_free (b1);
617  GNUNET_free (b2);
618  return ret;
619 }

References GNUNET_CRYPTO_rsa_public_key_encode(), GNUNET_free, and ret.

Here is the call graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_cmp()

int GNUNET_CRYPTO_rsa_private_key_cmp ( const struct GNUNET_CRYPTO_RsaPrivateKey p1,
const struct GNUNET_CRYPTO_RsaPrivateKey p2 
)

Compare the values of two private keys.

Parameters
p1one private key
p2the other private key
Returns
0 if the two are equal

Definition at line 623 of file crypto_rsa.c.

625 {
626  void *b1;
627  void *b2;
628  size_t z1;
629  size_t z2;
630  int ret;
631 
633  &b1);
635  &b2);
636  if (z1 != z2)
637  ret = 1;
638  else
639  ret = memcmp (b1,
640  b2,
641  z1);
642  GNUNET_free (b1);
643  GNUNET_free (b2);
644  return ret;
645 }
size_t GNUNET_CRYPTO_rsa_private_key_encode(const struct GNUNET_CRYPTO_RsaPrivateKey *key, void **buffer)
Encode the private key in a format suitable for storing it into a file.
Definition: crypto_rsa.c:180

References GNUNET_CRYPTO_rsa_private_key_encode(), GNUNET_free, and ret.

Here is the call graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_len()

unsigned int GNUNET_CRYPTO_rsa_public_key_len ( const struct GNUNET_CRYPTO_RsaPublicKey key)

Obtain the length of the RSA key in bits.

Parameters
keythe public key to introspect
Returns
length of the key in bits

Definition at line 649 of file crypto_rsa.c.

650 {
651  gcry_mpi_t n;
652  unsigned int rval;
653 
654  if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
655  { /* Not an RSA public key */
656  GNUNET_break (0);
657  return 0;
658  }
659  rval = gcry_mpi_get_nbits (n);
660  gcry_mpi_release (n);
661  return rval;
662 }

References GNUNET_break, key, and key_from_sexp().

Here is the call graph for this function:

◆ rsa_blinding_key_free()

static void rsa_blinding_key_free ( struct RsaBlindingKey bkey)
static

Destroy a blinding key.

Parameters
bkeythe blinding key to destroy

Definition at line 671 of file crypto_rsa.c.

672 {
673  gcry_mpi_release (bkey->r);
674  GNUNET_free (bkey);
675 }

References GNUNET_free, and RsaBlindingKey::r.

Referenced by GNUNET_CRYPTO_rsa_unblind().

Here is the caller graph for this function:

◆ numeric_mpi_alloc_n_print()

static size_t numeric_mpi_alloc_n_print ( gcry_mpi_t  v,
char **  buffer 
)
static

Print an MPI to a newly created buffer.

Parameters
vMPI to print.
[out]newlyallocated buffer containing the result
Returns
number of bytes stored in buffer

Definition at line 686 of file crypto_rsa.c.

688 {
689  size_t n;
690  char *b;
691  size_t rsize;
692 
693  gcry_mpi_print (GCRYMPI_FMT_USG,
694  NULL,
695  0,
696  &n,
697  v);
698  b = GNUNET_malloc (n);
699  GNUNET_assert (0 ==
700  gcry_mpi_print (GCRYMPI_FMT_USG,
701  (unsigned char *) b,
702  n,
703  &rsize,
704  v));
705  *buffer = b;
706  return n;
707 }

References testconfigure::b, GNUNET_assert, and GNUNET_malloc.

◆ rsa_full_domain_hash()

static gcry_mpi_t rsa_full_domain_hash ( const struct GNUNET_CRYPTO_RsaPublicKey pkey,
const struct GNUNET_HashCode hash 
)
static

Computes a full domain hash seeded by the given public key.

This gives a measure of provable security to the Taler exchange against one-more forgery attacks. See: https://eprint.iacr.org/2001/002.pdf http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf

Parameters
hashinitial hash of the message to sign
pkeythe public key of the signer
rsizeIf not NULL, the number of bytes actually stored in buffer
Returns
MPI value set to the FDH, NULL if RSA key is malicious

Definition at line 723 of file crypto_rsa.c.

725 {
726  gcry_mpi_t r, n;
727  void *xts;
728  size_t xts_len;
729  int ok;
730 
731  /* Extract the composite n from the RSA public key */
732  GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n"));
733  /* Assert that it at least looks like an RSA key */
734  GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE));
735 
736  /* We key with the public denomination key as a homage to RSA-PSS by *
737  * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
738  * of the hypothetical polyomial-time attack on RSA-KTI created by a *
739  * polynomial-time one-more forgary attack. Yey seeding! */
740  xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
741 
743  n,
744  xts, xts_len,
745  hash, sizeof(*hash),
746  "RSA-FDA FTpsW!");
747  GNUNET_free (xts);
748 
749  ok = rsa_gcd_validate (r, n);
750  gcry_mpi_release (n);
751  if (ok)
752  return r;
753  gcry_mpi_release (r);
754  return NULL;
755 }
static int ok
Return value from 'main' (0 == success)

Referenced by GNUNET_CRYPTO_rsa_sign_fdh().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_blind()

enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_blind ( const struct GNUNET_HashCode hash,
const struct GNUNET_CRYPTO_RsaBlindingKeySecret bks,
struct GNUNET_CRYPTO_RsaPublicKey pkey,
void **  buf,
size_t *  buf_size 
)

Blinds the given message with the given blinding key.

Parameters
hashhash of the message to sign
bkeythe blinding key
pkeythe public key of the signer
[out]bufset to a buffer with the blinded message to be signed
[out]buf_sizenumber of bytes stored in buf
Returns
GNUNET_YES if successful, GNUNET_NO if RSA key is malicious

Definition at line 723 of file crypto_rsa.c.

764 {
765  struct RsaBlindingKey *bkey;
766  gcry_mpi_t data;
767  gcry_mpi_t ne[2];
768  gcry_mpi_t r_e;
769  gcry_mpi_t data_r_e;
770  int ret;
771 
772  BENCHMARK_START (rsa_blind);
773 
774  GNUNET_assert (buf != NULL);
775  GNUNET_assert (buf_size != NULL);
776  ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
777  if (0 != ret)
778  ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
779  if (0 != ret)
780  {
781  GNUNET_break (0);
782  *buf = NULL;
783  *buf_size = 0;
784  return GNUNET_NO;
785  }
786 
787  data = rsa_full_domain_hash (pkey, hash);
788  if (NULL == data)
789  goto rsa_gcd_validate_failure;
790 
791  bkey = rsa_blinding_key_derive (pkey, bks);
792  if (NULL == bkey)
793  {
794  gcry_mpi_release (data);
795  goto rsa_gcd_validate_failure;
796  }
797 
798  r_e = gcry_mpi_new (0);
799  gcry_mpi_powm (r_e,
800  bkey->r,
801  ne[1],
802  ne[0]);
803  data_r_e = gcry_mpi_new (0);
804  gcry_mpi_mulm (data_r_e,
805  data,
806  r_e,
807  ne[0]);
808  gcry_mpi_release (data);
809  gcry_mpi_release (ne[0]);
810  gcry_mpi_release (ne[1]);
811  gcry_mpi_release (r_e);
812  rsa_blinding_key_free (bkey);
813 
814  *buf_size = numeric_mpi_alloc_n_print (data_r_e,
815  (char **) buf);
816  gcry_mpi_release (data_r_e);
817 
818  BENCHMARK_END (rsa_blind);
819 
820  return GNUNET_YES;
821 
822 rsa_gcd_validate_failure:
823  /* We know the RSA key is malicious here, so warn the wallet. */
824  /* GNUNET_break_op (0); */
825  gcry_mpi_release (ne[0]);
826  gcry_mpi_release (ne[1]);
827  *buf = NULL;
828  *buf_size = 0;
829  return GNUNET_NO;
830 }
static void rsa_blinding_key_free(struct RsaBlindingKey *bkey)
Destroy a blinding key.
Definition: crypto_rsa.c:671
static gcry_mpi_t rsa_full_domain_hash(const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_HashCode *hash)
Computes a full domain hash seeded by the given public key.
Definition: crypto_rsa.c:723
static struct RsaBlindingKey * rsa_blinding_key_derive(const struct GNUNET_CRYPTO_RsaPublicKey *pkey, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
Create a blinding key.
Definition: crypto_rsa.c:496
static size_t numeric_mpi_alloc_n_print(gcry_mpi_t v, char **buffer)
Print an MPI to a newly created buffer.
Definition: crypto_rsa.c:686
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94

References GNUNET_assert, GNUNET_CRYPTO_kdf_mod_mpi(), GNUNET_CRYPTO_rsa_public_key_encode(), GNUNET_free, key_from_sexp(), ok, pkey, RsaBlindingKey::r, and rsa_gcd_validate().

Referenced by checkvec(), and output_vectors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mpi_to_sexp()

static gcry_sexp_t mpi_to_sexp ( gcry_mpi_t  value)
static

Convert an MPI to an S-expression suitable for signature operations.

Parameters
valuepointer to the data to convert
Returns
converted s-expression

Definition at line 840 of file crypto_rsa.c.

841 {
842  gcry_sexp_t data = NULL;
843 
844  GNUNET_assert (0 ==
845  gcry_sexp_build (&data,
846  NULL,
847  "(data (flags raw) (value %M))",
848  value));
849  return data;
850 }
static char * value
Value of the record to add/remove.

References data, GNUNET_assert, and value.

Referenced by rsa_sign_mpi().

Here is the caller graph for this function:

◆ rsa_sign_mpi()

static struct GNUNET_CRYPTO_RsaSignature* rsa_sign_mpi ( const struct GNUNET_CRYPTO_RsaPrivateKey key,
gcry_mpi_t  value 
)
static

Sign the given MPI.

Parameters
keyprivate key to use for the signing
valuethe MPI to sign
Returns
NULL on error, signature on success

Definition at line 861 of file crypto_rsa.c.

863 {
864  struct GNUNET_CRYPTO_RsaSignature *sig;
865  gcry_sexp_t data;
866  gcry_sexp_t result;
867  int rc;
868 
869  data = mpi_to_sexp (value);
870 
871  if (0 !=
872  (rc = gcry_pk_sign (&result,
873  data,
874  key->sexp)))
875  {
877  _ ("RSA signing failed at %s:%d: %s\n"),
878  __FILE__,
879  __LINE__,
880  gcry_strerror (rc));
881  gcry_sexp_release (data);
882  GNUNET_break (0);
883  return NULL;
884  }
885 
886  /* Lenstra protection was first added to libgcrypt 1.6.4
887  * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
888  */
889 #if GCRYPT_VERSION_NUMBER < 0x010604
890  /* verify signature (guards against Lenstra's attack with fault injection...) */
891  struct GNUNET_CRYPTO_RsaPublicKey *public_key =
893  if (0 !=
894  gcry_pk_verify (result,
895  data,
896  public_key->sexp))
897  {
898  GNUNET_break (0);
900  gcry_sexp_release (data);
901  gcry_sexp_release (result);
902  return NULL;
903  }
905 #endif
906 
907  /* return signature */
908  gcry_sexp_release (data);
909  sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
910  sig->sexp = result;
911  return sig;
912 }
static gcry_sexp_t mpi_to_sexp(gcry_mpi_t value)
Convert an MPI to an S-expression suitable for signature operations.
Definition: crypto_rsa.c:840
void GNUNET_CRYPTO_rsa_public_key_free(struct GNUNET_CRYPTO_RsaPublicKey *key)
Free memory occupied by the public key.
Definition: crypto_rsa.c:267
struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_private_key_get_public(const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
Extract the public key of the given private key.
Definition: crypto_rsa.c:232
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA public key.
Definition: crypto_rsa.c:56
an RSA signature
Definition: crypto_rsa.c:64
gcry_sexp_t sexp
Libgcrypt S-expression for the RSA signature.
Definition: crypto_rsa.c:68

References _, data, GNUNET_break, GNUNET_CRYPTO_rsa_private_key_get_public(), GNUNET_CRYPTO_rsa_public_key_free(), GNUNET_ERROR_TYPE_WARNING, GNUNET_new, key, LOG, mpi_to_sexp(), result, GNUNET_CRYPTO_RsaPublicKey::sexp, GNUNET_CRYPTO_RsaSignature::sexp, and value.

Referenced by GNUNET_CRYPTO_rsa_sign_blinded(), and GNUNET_CRYPTO_rsa_sign_fdh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_sign_blinded()

struct GNUNET_CRYPTO_RsaSignature* GNUNET_CRYPTO_rsa_sign_blinded ( const struct GNUNET_CRYPTO_RsaPrivateKey key,
const void *  msg,
size_t  msg_len 
)

Sign a blinded value, which must be a full domain hash of a message.

Parameters
keyprivate key to use for the signing
msgthe (blinded) message to sign
msg_lennumber of bytes in msg to sign
Returns
NULL on error, signature on success

Definition at line 916 of file crypto_rsa.c.

919 {
920  gcry_mpi_t v = NULL;
921  struct GNUNET_CRYPTO_RsaSignature *sig;
922 
923  BENCHMARK_START (rsa_sign_blinded);
924 
925  GNUNET_assert (0 ==
926  gcry_mpi_scan (&v,
927  GCRYMPI_FMT_USG,
928  msg,
929  msg_len,
930  NULL));
931 
932  sig = rsa_sign_mpi (key, v);
933  gcry_mpi_release (v);
934  BENCHMARK_END (rsa_sign_blinded);
935  return sig;
936 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static struct GNUNET_CRYPTO_RsaSignature * rsa_sign_mpi(const struct GNUNET_CRYPTO_RsaPrivateKey *key, gcry_mpi_t value)
Sign the given MPI.
Definition: crypto_rsa.c:861

References BENCHMARK_END, BENCHMARK_START, GNUNET_assert, key, msg, and rsa_sign_mpi().

Referenced by checkvec(), and output_vectors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_sign_fdh()

struct GNUNET_CRYPTO_RsaSignature* GNUNET_CRYPTO_rsa_sign_fdh ( const struct GNUNET_CRYPTO_RsaPrivateKey key,
const struct GNUNET_HashCode hash 
)

Create and sign a full domain hash of a message.

Parameters
keyprivate key to use for the signing
hashthe hash of the message to sign
Returns
NULL on error, including a malicious RSA key, signature on success

Definition at line 940 of file crypto_rsa.c.

942 {
944  gcry_mpi_t v = NULL;
945  struct GNUNET_CRYPTO_RsaSignature *sig;
946 
948  v = rsa_full_domain_hash (pkey, hash);
950  if (NULL == v) /* rsa_gcd_validate failed meaning */
951  return NULL; /* our *own* RSA key is malicious. */
952 
953  sig = rsa_sign_mpi (key, v);
954  gcry_mpi_release (v);
955  return sig;
956 }

References GNUNET_CRYPTO_rsa_private_key_get_public(), GNUNET_CRYPTO_rsa_public_key_free(), key, pkey, rsa_full_domain_hash(), and rsa_sign_mpi().

Here is the call graph for this function:

◆ GNUNET_CRYPTO_rsa_signature_free()

void GNUNET_CRYPTO_rsa_signature_free ( struct GNUNET_CRYPTO_RsaSignature sig)

Free memory occupied by signature.

Parameters
sigmemory to free

Definition at line 960 of file crypto_rsa.c.

961 {
962  gcry_sexp_release (sig->sexp);
963  GNUNET_free (sig);
964 }

References GNUNET_free, and GNUNET_CRYPTO_RsaSignature::sexp.

Referenced by clean_rsa_sig(), clean_rsa_signature(), and output_vectors().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_signature_encode()

size_t GNUNET_CRYPTO_rsa_signature_encode ( const struct GNUNET_CRYPTO_RsaSignature sig,
void **  buffer 
)

Encode the given signature in a format suitable for storing it into a file.

Parameters
sigthe signature
[out]bufferset to a buffer with the encoded key
Returns
size of memory allocated in buffer

Definition at line 968 of file crypto_rsa.c.

971 {
972  gcry_mpi_t s;
973  size_t buf_size;
974  size_t rsize;
975  unsigned char *buf;
976  int ret;
977 
978  ret = key_from_sexp (&s,
979  sig->sexp,
980  "sig-val",
981  "s");
982  if (0 != ret)
983  ret = key_from_sexp (&s,
984  sig->sexp,
985  "rsa",
986  "s");
987  GNUNET_assert (0 == ret);
988  gcry_mpi_print (GCRYMPI_FMT_USG,
989  NULL,
990  0,
991  &buf_size,
992  s);
993  buf = GNUNET_malloc (buf_size);
994  GNUNET_assert (0 ==
995  gcry_mpi_print (GCRYMPI_FMT_USG,
996  buf,
997  buf_size,
998  &rsize,
999  s));
1000  GNUNET_assert (rsize == buf_size);
1001  *buffer = (void *) buf;
1002  gcry_mpi_release (s);
1003  return buf_size;
1004 }

References buf, GNUNET_assert, GNUNET_malloc, key_from_sexp(), ret, and GNUNET_CRYPTO_RsaSignature::sexp.

Referenced by bind_rsa_sig(), checkvec(), GNUNET_CRYPTO_rsa_signature_cmp(), GNUNET_JSON_from_rsa_signature(), GNUNET_PQ_query_param_rsa_signature(), my_conv_rsa_signature(), and output_vectors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_signature_decode()

struct GNUNET_CRYPTO_RsaSignature* GNUNET_CRYPTO_rsa_signature_decode ( const void *  buf,
size_t  buf_size 
)

Decode the signature from the data-format back to the "normal", internal format.

Parameters
bufthe buffer where the public key data is stored
buf_sizethe number of bytes of the data in buf
Returns
NULL on error

Definition at line 1008 of file crypto_rsa.c.

1010 {
1011  struct GNUNET_CRYPTO_RsaSignature *sig;
1012  gcry_mpi_t s;
1013  gcry_sexp_t data;
1014 
1015  if (0 !=
1016  gcry_mpi_scan (&s,
1017  GCRYMPI_FMT_USG,
1018  buf,
1019  buf_size,
1020  NULL))
1021  {
1022  GNUNET_break_op (0);
1023  return NULL;
1024  }
1025 
1026  if (0 !=
1027  gcry_sexp_build (&data,
1028  NULL,
1029  "(sig-val(rsa(s %M)))",
1030  s))
1031  {
1032  GNUNET_break (0);
1033  gcry_mpi_release (s);
1034  return NULL;
1035  }
1036  gcry_mpi_release (s);
1037  sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1038  sig->sexp = data;
1039  return sig;
1040 }

References buf, data, GNUNET_break, GNUNET_break_op, GNUNET_new, and GNUNET_CRYPTO_RsaSignature::sexp.

Referenced by extract_rsa_sig(), parse_rsa_signature(), and post_extract_rsa_signature().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_public_key_dup()

struct GNUNET_CRYPTO_RsaPublicKey* GNUNET_CRYPTO_rsa_public_key_dup ( const struct GNUNET_CRYPTO_RsaPublicKey key)

Duplicate the given public key.

Parameters
keythe public key to duplicate
Returns
the duplicate key; NULL upon error

Definition at line 1044 of file crypto_rsa.c.

1045 {
1046  struct GNUNET_CRYPTO_RsaPublicKey *dup;
1047  gcry_sexp_t dup_sexp;
1048  size_t erroff;
1049 
1050  /* check if we really are exporting a public key */
1051  dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
1052  GNUNET_assert (NULL != dup_sexp);
1053  gcry_sexp_release (dup_sexp);
1054  /* copy the sexp */
1055  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1056  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
1057  dup->sexp = dup_sexp;
1058  return dup;
1059 }

References GNUNET_assert, GNUNET_new, key, and GNUNET_CRYPTO_RsaPublicKey::sexp.

◆ GNUNET_CRYPTO_rsa_unblind()

struct GNUNET_CRYPTO_RsaSignature* GNUNET_CRYPTO_rsa_unblind ( const struct GNUNET_CRYPTO_RsaSignature sig,
const struct GNUNET_CRYPTO_RsaBlindingKeySecret bks,
struct GNUNET_CRYPTO_RsaPublicKey pkey 
)

Unblind a blind-signed signature.

The signature should have been generated with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with GNUNET_CRYPTO_rsa_blind().

Parameters
sigthe signature made on the blinded signature purpose
bksthe blinding key secret used to blind the signature purpose
pkeythe public key of the signer
Returns
unblinded signature on success, NULL if RSA key is bad or malicious.

Definition at line 1063 of file crypto_rsa.c.

1066 {
1067  struct RsaBlindingKey *bkey;
1068  gcry_mpi_t n;
1069  gcry_mpi_t s;
1070  gcry_mpi_t r_inv;
1071  gcry_mpi_t ubsig;
1072  int ret;
1073  struct GNUNET_CRYPTO_RsaSignature *sret;
1074 
1075  BENCHMARK_START (rsa_unblind);
1076 
1077  ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
1078  if (0 != ret)
1079  ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
1080  if (0 != ret)
1081  {
1082  GNUNET_break_op (0);
1083  return NULL;
1084  }
1085  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1086  if (0 != ret)
1087  ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1088  if (0 != ret)
1089  {
1090  gcry_mpi_release (n);
1091  GNUNET_break_op (0);
1092  return NULL;
1093  }
1094 
1095  bkey = rsa_blinding_key_derive (pkey, bks);
1096  if (NULL == bkey)
1097  {
1098  /* RSA key is malicious since rsa_gcd_validate failed here.
1099  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1100  * so the exchange is being malicious in an unfamilair way, maybe
1101  * just trying to crash us. */
1102  GNUNET_break_op (0);
1103  gcry_mpi_release (n);
1104  gcry_mpi_release (s);
1105  return NULL;
1106  }
1107 
1108  r_inv = gcry_mpi_new (0);
1109  if (1 !=
1110  gcry_mpi_invm (r_inv,
1111  bkey->r,
1112  n))
1113  {
1114  /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
1115  * caught above, but we handle it the same here. */
1116  GNUNET_break_op (0);
1117  gcry_mpi_release (r_inv);
1118  rsa_blinding_key_free (bkey);
1119  gcry_mpi_release (n);
1120  gcry_mpi_release (s);
1121  return NULL;
1122  }
1123 
1124  ubsig = gcry_mpi_new (0);
1125  gcry_mpi_mulm (ubsig, s, r_inv, n);
1126  gcry_mpi_release (n);
1127  gcry_mpi_release (r_inv);
1128  gcry_mpi_release (s);
1129  rsa_blinding_key_free (bkey);
1130 
1131  sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1132  GNUNET_assert (0 ==
1133  gcry_sexp_build (&sret->sexp,
1134  NULL,
1135  "(sig-val (rsa (s %M)))",
1136  ubsig));
1137  gcry_mpi_release (ubsig);
1138  BENCHMARK_END (rsa_unblind);
1139  return sret;
1140 }

References BENCHMARK_END, BENCHMARK_START, GNUNET_assert, GNUNET_break_op, GNUNET_new, key_from_sexp(), pkey, RsaBlindingKey::r, ret, rsa_blinding_key_derive(), rsa_blinding_key_free(), and GNUNET_CRYPTO_RsaSignature::sexp.

Referenced by checkvec(), and output_vectors().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_verify()

enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_verify ( const struct GNUNET_HashCode hash,
const struct GNUNET_CRYPTO_RsaSignature sig,
const struct GNUNET_CRYPTO_RsaPublicKey public_key 
)

Verify whether the given hash corresponds to the given signature and the signature is valid with respect to the given public key.

Parameters
hashthe message to verify to match the sig
sigsignature that is being validated
public_keypublic key of the signer
Returns
GNUNET_YES if ok, GNUNET_NO if RSA key is malicious, GNUNET_SYSERR if signature

Definition at line 1063 of file crypto_rsa.c.

1147 {
1148  gcry_sexp_t data;
1149  gcry_mpi_t r;
1150  int rc;
1151 
1152  BENCHMARK_START (rsa_verify);
1153 
1154  r = rsa_full_domain_hash (pkey, hash);
1155  if (NULL == r)
1156  {
1157  GNUNET_break_op (0);
1158  /* RSA key is malicious since rsa_gcd_validate failed here.
1159  * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
1160  * so the exchange is being malicious in an unfamilair way, maybe
1161  * just trying to crash us. Arguably, we've only an internal error
1162  * though because we should've detected this in our previous call
1163  * to GNUNET_CRYPTO_rsa_unblind. *///
1164  return GNUNET_NO;
1165  }
1166 
1167  data = mpi_to_sexp (r);
1168  gcry_mpi_release (r);
1169 
1170  rc = gcry_pk_verify (sig->sexp,
1171  data,
1172  pkey->sexp);
1173  gcry_sexp_release (data);
1174  if (0 != rc)
1175  {
1177  _ ("RSA signature verification failed at %s:%d: %s\n"),
1178  __FILE__,
1179  __LINE__,
1180  gcry_strerror (rc));
1181  BENCHMARK_END (rsa_verify);
1182  return GNUNET_SYSERR;
1183  }
1184  BENCHMARK_END (rsa_verify);
1185  return GNUNET_OK;
1186 }
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_SYSERR
Definition: gnunet_common.h:93

Referenced by checkvec(), and output_vectors().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_rsa_private_key_dup()

struct GNUNET_CRYPTO_RsaPrivateKey* GNUNET_CRYPTO_rsa_private_key_dup ( const struct GNUNET_CRYPTO_RsaPrivateKey key)

Duplicate the given private key.

Parameters
keythe private key to duplicate
Returns
the duplicate key; NULL upon error

Definition at line 1190 of file crypto_rsa.c.

1192 {
1193  struct GNUNET_CRYPTO_RsaPrivateKey *dup;
1194  gcry_sexp_t dup_sexp;
1195  size_t erroff;
1196 
1197  /* check if we really are exporting a private key */
1198  dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
1199  GNUNET_assert (NULL != dup_sexp);
1200  gcry_sexp_release (dup_sexp);
1201  /* copy the sexp */
1202  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
1203  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
1204  dup->sexp = dup_sexp;
1205  return dup;
1206 }

References GNUNET_assert, GNUNET_new, key, and GNUNET_CRYPTO_RsaPrivateKey::sexp.

◆ GNUNET_CRYPTO_rsa_signature_dup()

struct GNUNET_CRYPTO_RsaSignature* GNUNET_CRYPTO_rsa_signature_dup ( const struct GNUNET_CRYPTO_RsaSignature sig)

Duplicate the given rsa signature.

Parameters
sigthe signature to duplicate
Returns
the duplicate key; NULL upon error

Definition at line 1210 of file crypto_rsa.c.

1211 {
1212  struct GNUNET_CRYPTO_RsaSignature *dup;
1213  gcry_sexp_t dup_sexp;
1214  size_t erroff;
1215  gcry_mpi_t s;
1216  int ret;
1217 
1218  /* verify that this is an RSA signature */
1219  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
1220  if (0 != ret)
1221  ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
1222  GNUNET_assert (0 == ret);
1223  gcry_mpi_release (s);
1224  /* copy the sexp */
1225  GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
1226  dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
1227  dup->sexp = dup_sexp;
1228  return dup;
1229 }

References GNUNET_assert, GNUNET_new, key_from_sexp(), ret, and GNUNET_CRYPTO_RsaSignature::sexp.

Here is the call graph for this function: