GNUnet  0.17.5
Data Structures | Macros | Functions
gnsrecord_crypto.c File Reference

API for GNS record-related crypto. More...

#include "gnsrecord_crypto.h"
Include dependency graph for gnsrecord_crypto.c:

Go to the source code of this file.

Data Structures

struct  KeyCacheLine
 Line in cache mapping private keys to public keys. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
 
#define CSIZE   64
 

Functions

ssize_t ecdsa_symmetric_decrypt (const void *block, size_t size, const unsigned char *key, const unsigned char *ctr, void *result)
 
ssize_t ecdsa_symmetric_encrypt (const void *block, size_t size, const unsigned char *key, const unsigned char *ctr, void *result)
 
enum GNUNET_GenericReturnValue eddsa_symmetric_decrypt (const void *block, size_t size, const unsigned char *key, const unsigned char *nonce, void *result)
 
enum GNUNET_GenericReturnValue eddsa_symmetric_encrypt (const void *block, size_t size, const unsigned char *key, const unsigned char *nonce, void *result)
 
void GNR_derive_block_aes_key (unsigned char *ctr, unsigned char *key, const char *label, uint64_t exp, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 Derive session key and iv from label and public key. More...
 
void GNR_derive_block_xsalsa_key (unsigned char *nonce, unsigned char *key, const char *label, uint64_t exp, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
 Derive session key and iv from label and public key. More...
 
static ssize_t block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 
static enum GNUNET_GenericReturnValue block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **block)
 Sign name and records. More...
 
static ssize_t block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 
enum GNUNET_GenericReturnValue block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **block)
 Sign name and records (EDDSA version) More...
 
ssize_t GNUNET_GNSRECORD_block_calculate_size (const struct GNUNET_IDENTITY_PrivateKey *key, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
 Get size of buffer for block creation. More...
 
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **result)
 Sign name and records. More...
 
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **result)
 Sign name and records, cache derived public key (also keeps the private key in static memory, so do not use this function if keeping the private key in the process'es RAM is a major issue). More...
 
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
 Check if a signature is valid. More...
 
enum GNUNET_GenericReturnValue block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
 
enum GNUNET_GenericReturnValue block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_EddsaPublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
 
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_IDENTITY_PublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
 Decrypt block. More...
 
void GNUNET_GNSRECORD_query_from_private_key (const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, struct GNUNET_HashCode *query)
 Calculate the DHT query for a given label in a given zone. More...
 
void GNUNET_GNSRECORD_query_from_public_key (const struct GNUNET_IDENTITY_PublicKey *pub, const char *label, struct GNUNET_HashCode *query)
 Calculate the DHT query for a given label in a given zone. More...
 

Detailed Description

API for GNS record-related crypto.

Author
Martin Schanzenbach
Matthias Wachs
Christian Grothoff

Definition in file gnsrecord_crypto.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)

Definition at line 30 of file gnsrecord_crypto.c.

◆ CSIZE

#define CSIZE   64

Function Documentation

◆ ecdsa_symmetric_decrypt()

ssize_t ecdsa_symmetric_decrypt ( const void *  block,
size_t  size,
const unsigned char *  key,
const unsigned char *  ctr,
void *  result 
)

Definition at line 33 of file gnsrecord_crypto.c.

39 {
40  gcry_cipher_hd_t handle;
41  int rc;
42 
43  GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
44  GCRY_CIPHER_MODE_CTR, 0));
45  rc = gcry_cipher_setkey (handle,
46  key,
48  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
49  rc = gcry_cipher_setctr (handle,
50  ctr,
52  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
53  GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size));
54  gcry_cipher_close (handle);
55  return size;
56 }
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
#define GNUNET_CRYPTO_AES_KEY_LENGTH
length of the sessionkey in bytes (256 BIT sessionkey)
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static unsigned int size
Size of the "table".
Definition: peer.c:67

References GNUNET_assert, GNUNET_CRYPTO_AES_KEY_LENGTH, handle, key, result, and size.

◆ ecdsa_symmetric_encrypt()

ssize_t ecdsa_symmetric_encrypt ( const void *  block,
size_t  size,
const unsigned char *  key,
const unsigned char *  ctr,
void *  result 
)

Definition at line 60 of file gnsrecord_crypto.c.

66 {
67  gcry_cipher_hd_t handle;
68  int rc;
69 
70  GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
71  GCRY_CIPHER_MODE_CTR, 0));
72  rc = gcry_cipher_setkey (handle,
73  key,
75  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
76  rc = gcry_cipher_setctr (handle,
77  ctr,
79  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
80  GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size));
81  gcry_cipher_close (handle);
82  return size;
83 }

References GNUNET_assert, GNUNET_CRYPTO_AES_KEY_LENGTH, handle, key, result, and size.

◆ eddsa_symmetric_decrypt()

enum GNUNET_GenericReturnValue eddsa_symmetric_decrypt ( const void *  block,
size_t  size,
const unsigned char *  key,
const unsigned char *  nonce,
void *  result 
)

Definition at line 60 of file gnsrecord_crypto.c.

93 {
94  ssize_t ctlen = size - crypto_secretbox_MACBYTES;
95  if (ctlen < 0)
96  return GNUNET_SYSERR;
97  if (0 != crypto_secretbox_open_detached (result,
98  ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext
99  block, // Tag
100  ctlen,
101  nonce, key))
102  {
103  return GNUNET_SYSERR;
104  }
105  return GNUNET_OK;
106 }
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_SYSERR
Definition: gnunet_common.h:97

◆ eddsa_symmetric_encrypt()

enum GNUNET_GenericReturnValue eddsa_symmetric_encrypt ( const void *  block,
size_t  size,
const unsigned char *  key,
const unsigned char *  nonce,
void *  result 
)

Definition at line 60 of file gnsrecord_crypto.c.

116 {
117  if (size > crypto_secretbox_MESSAGEBYTES_MAX)
118  return GNUNET_SYSERR;
119  crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext
120  result, // TAG
121  block, size, nonce, key);
122  return GNUNET_OK;
123 }

◆ GNR_derive_block_aes_key()

void GNR_derive_block_aes_key ( unsigned char *  ctr,
unsigned char *  key,
const char *  label,
uint64_t  exp,
const struct GNUNET_CRYPTO_EcdsaPublicKey pub 
)

Derive session key and iv from label and public key.

Parameters
ivinitialization vector to initialize
skeysession key to initialize
labellabel to use for KDF
pubpublic key to use for KDF

4 byte nonce

Expiration time 64 bit.

Set counter part to 1

Definition at line 127 of file gnsrecord_crypto.c.

132 {
133  static const char ctx_key[] = "gns-aes-ctx-key";
134  static const char ctx_iv[] = "gns-aes-ctx-iv";
135 
137  ctx_key, strlen (ctx_key),
138  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
139  label, strlen (label),
140  NULL, 0);
141  memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
143  GNUNET_CRYPTO_kdf (ctr, 4,
144  ctx_iv, strlen (ctx_iv),
145  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
146  label, strlen (label),
147  NULL, 0);
149  memcpy (ctr + 4, &exp, sizeof (exp));
151  ctr[15] |= 0x01;
152 }
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:69
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...

References GNUNET_CRYPTO_AES_KEY_LENGTH, GNUNET_CRYPTO_kdf(), key, and pub.

Referenced by run_pkey().

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

◆ GNR_derive_block_xsalsa_key()

void GNR_derive_block_xsalsa_key ( unsigned char *  nonce,
unsigned char *  key,
const char *  label,
uint64_t  exp,
const struct GNUNET_CRYPTO_EddsaPublicKey pub 
)

Derive session key and iv from label and public key.

Parameters
nonceinitialization vector to initialize
skeysession key to initialize
labellabel to use for KDF
pubpublic key to use for KDF

16 byte nonce

Expiration time 64 bit.

Definition at line 156 of file gnsrecord_crypto.c.

161 {
162  static const char ctx_key[] = "gns-xsalsa-ctx-key";
163  static const char ctx_iv[] = "gns-xsalsa-ctx-iv";
164 
165  GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES,
166  ctx_key, strlen (ctx_key),
167  pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
168  label, strlen (label),
169  NULL, 0);
170  memset (nonce, 0, crypto_secretbox_NONCEBYTES);
172  GNUNET_CRYPTO_kdf (nonce, (crypto_secretbox_NONCEBYTES - sizeof (exp)),
173  ctx_iv, strlen (ctx_iv),
174  pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
175  label, strlen (label),
176  NULL, 0);
178  memcpy (nonce + (crypto_secretbox_NONCEBYTES - sizeof (exp)),
179  &exp, sizeof (exp));
180 }
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...

References GNUNET_CRYPTO_kdf(), key, and pub.

Referenced by run_edkey().

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

◆ block_get_size_ecdsa()

static ssize_t block_get_size_ecdsa ( const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count 
)
static

Definition at line 184 of file gnsrecord_crypto.c.

186 {
187  ssize_t len;
188 
189  len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
190  if (len < 0)
191  return -1;
192  len += sizeof(struct GNUNET_GNSRECORD_Block);
193  return len;
194 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.

Referenced by block_decrypt_ecdsa().

Here is the caller graph for this function:

◆ block_create_ecdsa()

static enum GNUNET_GenericReturnValue block_create_ecdsa ( const struct GNUNET_CRYPTO_EcdsaPrivateKey key,
const struct GNUNET_CRYPTO_EcdsaPublicKey pkey,
struct GNUNET_TIME_Absolute  expire,
const char *  label,
const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count,
struct GNUNET_GNSRECORD_Block **  block 
)
static

Sign name and records.

Parameters
keythe private key
pkeyassociated public key
expireblock expiration
labelthe name for the records
rdrecord data
rd_countnumber of records
blockthe block result. Must be allocated sufficiently.
Returns
GNUNET_SYSERR on error (otherwise GNUNET_OK)

Definition at line 184 of file gnsrecord_crypto.c.

217 {
218  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
219  rd);
220  struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
221  struct GNRBlockPS *gnr_block;
222  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
223  unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
224  struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
225  struct GNUNET_TIME_Absolute now;
226 
227  if (payload_len < 0)
228  {
229  GNUNET_break (0);
230  return GNUNET_SYSERR;
231  }
232  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
233  {
234  GNUNET_break (0);
235  return GNUNET_SYSERR;
236  }
237  /* convert relative to absolute times */
238  now = GNUNET_TIME_absolute_get ();
239  for (unsigned int i = 0; i < rd_count; i++)
240  {
241  rdc[i] = rd[i];
242  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
243  {
244  struct GNUNET_TIME_Relative t;
245 
246  /* encrypted blocks must never have relative expiration times, convert! */
248  t.rel_value_us = rdc[i].expiration_time;
249  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
250  }
251  }
252  /* serialize */
253  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
254  (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
255  {
256  char payload[payload_len];
257 
258  GNUNET_assert (payload_len ==
260  rdc,
261  payload_len,
262  payload));
263  gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
264  ecblock = &(*block)->ecdsa_block;
265  (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
266  gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len);
267  gnr_block->purpose.purpose =
270  ecblock->expiration_time = gnr_block->expiration_time;
271  /* encrypt and sign */
273  label,
274  "gns",
275  &ecblock->derived_key);
277  skey,
278  label,
280  pkey);
281  GNUNET_assert (payload_len ==
283  payload_len,
284  skey,
285  ctr,
286  &ecblock[1]));
287  GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
288  }
289  if (GNUNET_OK !=
291  label,
292  "gns",
293  &gnr_block->purpose,
294  &ecblock->signature))
295  {
296  GNUNET_break (0);
297  GNUNET_free (*block);
298  GNUNET_free (gnr_block);
299  return GNUNET_SYSERR;
300  }
301  GNUNET_free (gnr_block);
302  return GNUNET_OK;
303 }
ssize_t ecdsa_symmetric_encrypt(const void *block, size_t size, const unsigned char *key, const unsigned char *ctr, void *result)
void GNR_derive_block_aes_key(unsigned char *ctr, unsigned char *key, const char *label, uint64_t exp, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Derive session key and iv from label and public key.
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:101
static char * pkey
Public key of the zone to look in, in ASCII.
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN
Signature of a gnunet naming system record block (GNUnet-GNSRECORD)
void GNUNET_CRYPTO_ecdsa_public_key_derive(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, const char *context, struct GNUNET_CRYPTO_EcdsaPublicKey *result)
Derive a public key from a given public key and a label.
#define GNUNET_GNSRECORD_MAX_BLOCK_SIZE
Maximum size of a value that can be stored in a GNS block.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_derived(const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const char *label, const char *context, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
This is a signature function for ECDSA which takes a private key, derives/blinds it and signs the mes...
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:449
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
Information we have in an encrypted block with record data (i.e.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Number of bytes signed; also specifies the number of bytes of encrypted data that follow.
struct GNUNET_TIME_AbsoluteNBO expiration_time
Expiration time of the block.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Information we have in an encrypted block with record data (i.e.
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature of the block.
struct GNUNET_TIME_AbsoluteNBO expiration_time
Expiration time of the block.
struct GNUNET_CRYPTO_EcdsaPublicKey derived_key
Derived key used for signing; hash of this is the query.
uint64_t abs_value_us__
The actual value (in network byte order).
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.

References GNUNET_GNSRECORD_records_get_size(), and len.

Here is the call graph for this function:

◆ block_get_size_eddsa()

static ssize_t block_get_size_eddsa ( const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count 
)
static

Definition at line 306 of file gnsrecord_crypto.c.

308 {
309  ssize_t len;
310 
311  len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
312  if (len < 0)
313  return -1;
314  len += sizeof(struct GNUNET_GNSRECORD_Block);
315  len += crypto_secretbox_MACBYTES;
316  return len;
317 }

Referenced by block_decrypt_ecdsa().

Here is the caller graph for this function:

◆ block_create_eddsa()

enum GNUNET_GenericReturnValue block_create_eddsa ( const struct GNUNET_CRYPTO_EddsaPrivateKey key,
const struct GNUNET_CRYPTO_EddsaPublicKey pkey,
struct GNUNET_TIME_Absolute  expire,
const char *  label,
const struct GNUNET_GNSRECORD_Data rd,
unsigned int  rd_count,
struct GNUNET_GNSRECORD_Block **  block 
)

Sign name and records (EDDSA version)

Parameters
keythe private key
pkeyassociated public key
expireblock expiration
labelthe name for the records
rdrecord data
rd_countnumber of records
blockwhere to store the block. Must be allocated sufficiently.
Returns
GNUNET_SYSERR on error (otherwise GNUNET_OK)

Definition at line 306 of file gnsrecord_crypto.c.

340 {
341  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
342  rd);
343  struct GNUNET_GNSRECORD_EddsaBlock *edblock;
344  struct GNRBlockPS *gnr_block;
345  unsigned char nonce[crypto_secretbox_NONCEBYTES];
346  unsigned char skey[crypto_secretbox_KEYBYTES];
347  struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
348  struct GNUNET_TIME_Absolute now;
349 
350  if (payload_len < 0)
351  {
352  GNUNET_break (0);
353  return GNUNET_SYSERR;
354  }
355  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
356  {
357  GNUNET_break (0);
358  return GNUNET_SYSERR;
359  }
360  /* convert relative to absolute times */
361  now = GNUNET_TIME_absolute_get ();
362  for (unsigned int i = 0; i < rd_count; i++)
363  {
364  rdc[i] = rd[i];
365  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
366  {
367  struct GNUNET_TIME_Relative t;
368 
369  /* encrypted blocks must never have relative expiration times, convert! */
371  t.rel_value_us = rdc[i].expiration_time;
372  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
373  }
374  }
375  /* serialize */
376  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
377  + payload_len + crypto_secretbox_MACBYTES);
378  (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block)
379  + payload_len + crypto_secretbox_MACBYTES);
380  {
381  char payload[payload_len];
382 
383  GNUNET_assert (payload_len ==
385  rdc,
386  payload_len,
387  payload));
388  gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
389  + payload_len
390  + crypto_secretbox_MACBYTES);
391  edblock = &(*block)->eddsa_block;
392  (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
393  gnr_block->purpose.size =
394  htonl (sizeof(struct GNRBlockPS)
395  + payload_len
396  + crypto_secretbox_MACBYTES);
397  gnr_block->purpose.purpose =
400  edblock->expiration_time = gnr_block->expiration_time;
401  /* encrypt and sign */
403  label,
404  "gns",
405  &edblock->derived_key);
407  skey,
408  label,
410  pkey);
413  payload_len,
414  skey,
415  nonce,
416  &edblock[1]));
417  GNUNET_memcpy (&gnr_block[1], &edblock[1],
418  payload_len + crypto_secretbox_MACBYTES);
419 
421  label,
422  "gns",
423  &gnr_block->purpose,
424  &edblock->signature);
425  }
426  return GNUNET_OK;
427 }
void GNR_derive_block_xsalsa_key(unsigned char *nonce, unsigned char *key, const char *label, uint64_t exp, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Derive session key and iv from label and public key.
enum GNUNET_GenericReturnValue eddsa_symmetric_encrypt(const void *block, size_t size, const unsigned char *key, const unsigned char *nonce, void *result)
#define GNUNET_GNSRECORD_TYPE_EDKEY
Record type for EDKEY zone delegations.
void GNUNET_CRYPTO_eddsa_public_key_derive(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, const char *label, const char *context, struct GNUNET_CRYPTO_EddsaPublicKey *result)
Derive a public key from a given public key and a label.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_derived(const struct GNUNET_CRYPTO_EddsaPrivateKey *pkey, const char *label, const char *context, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
This is a signature function for EdDSA which takes a private key and derives it using the label and c...
Information we have in an encrypted block with record data (i.e.
struct GNUNET_CRYPTO_EddsaPublicKey derived_key
Derived key used for signing; hash of this is the query.
struct GNUNET_TIME_AbsoluteNBO expiration_time
Expiration time of the block.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the block.

References GNUNET_GNSRECORD_records_get_size(), and len.

Here is the call graph for this function:

◆ block_decrypt_ecdsa()

enum GNUNET_GenericReturnValue block_decrypt_ecdsa ( const struct GNUNET_GNSRECORD_Block block,
const struct GNUNET_CRYPTO_EcdsaPublicKey zone_key,
const char *  label,
GNUNET_GNSRECORD_RecordCallback  proc,
void *  proc_cls 
)

Definition at line 430 of file gnsrecord_crypto.c.

627 {
628  size_t payload_len = ntohl (block->size) - sizeof (struct
630  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
631  unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
632 
633  if (ntohl (block->size) <
634  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
635  + sizeof(struct GNUNET_TIME_AbsoluteNBO))
636  {
637  GNUNET_break_op (0);
638  return GNUNET_SYSERR;
639  }
641  key,
642  label,
644  zone_key);
645  {
646  char payload[payload_len];
647  unsigned int rd_count;
648 
649  GNUNET_assert (payload_len ==
650  ecdsa_symmetric_decrypt (&block[1], payload_len,
651  key, ctr,
652  payload));
653  rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
654  payload);
655  if (rd_count > 2048)
656  {
657  /* limit to sane value */
658  GNUNET_break_op (0);
659  return GNUNET_SYSERR;
660  }
661  {
662  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
663  unsigned int j;
664  struct GNUNET_TIME_Absolute now;
665 
666  if (GNUNET_OK !=
668  payload,
669  rd_count,
670  rd))
671  {
672  GNUNET_break_op (0);
673  return GNUNET_SYSERR;
674  }
675  /* hide expired records */
676  now = GNUNET_TIME_absolute_get ();
677  j = 0;
678  for (unsigned int i = 0; i < rd_count; i++)
679  {
680  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
681  {
682  /* encrypted blocks must never have relative expiration times, skip! */
683  GNUNET_break_op (0);
684  continue;
685  }
686 
687  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
688  {
689  int include_record = GNUNET_YES;
690  /* Shadow record, figure out if we have a not expired active record */
691  for (unsigned int k = 0; k < rd_count; k++)
692  {
693  if (k == i)
694  continue;
695  if (rd[i].expiration_time < now.abs_value_us)
696  include_record = GNUNET_NO; /* Shadow record is expired */
697  if ((rd[k].record_type == rd[i].record_type) &&
698  (rd[k].expiration_time >= now.abs_value_us) &&
699  (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
700  {
701  include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
703  "Ignoring shadow record\n");
704  break;
705  }
706  }
707  if (GNUNET_YES == include_record)
708  {
709  rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
710  if (j != i)
711  rd[j] = rd[i];
712  j++;
713  }
714  }
715  else if (rd[i].expiration_time >= now.abs_value_us)
716  {
717  /* Include this record */
718  if (j != i)
719  rd[j] = rd[i];
720  j++;
721  }
722  else
723  {
724  struct GNUNET_TIME_Absolute at;
725 
726  at.abs_value_us = rd[i].expiration_time;
728  "Excluding record that expired %s (%llu ago)\n",
730  (unsigned long long) rd[i].expiration_time
731  - now.abs_value_us);
732  }
733  }
734  rd_count = j;
735  if (NULL != proc)
736  proc (proc_cls,
737  rd_count,
738  (0 != rd_count) ? rd : NULL);
739  }
740  }
741  return GNUNET_OK;
742 }
ssize_t ecdsa_symmetric_decrypt(const void *block, size_t size, const unsigned char *key, const unsigned char *ctr, void *result)
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
unsigned int GNUNET_GNSRECORD_records_deserialize_get_size(size_t len, const char *src)
@ GNUNET_GNSRECORD_RF_SHADOW_RECORD
This record should not be used unless all (other) records with an absolute expiration time have expir...
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
@ GNUNET_ERROR_TYPE_INFO
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
struct GNUNET_GNSRECORD_EcdsaBlock ecdsa_block
uint32_t size
Size of the block.
Time for absolute time used by GNUnet, in microseconds and in network byte order.

References block_get_size_ecdsa(), block_get_size_eddsa(), GNUNET_assert, GNUNET_GNSRECORD_TYPE_EDKEY, GNUNET_GNSRECORD_TYPE_PKEY, GNUNET_IDENTITY_key_get_public(), key, pkey, and res.

Here is the call graph for this function:

◆ block_decrypt_eddsa()

enum GNUNET_GenericReturnValue block_decrypt_eddsa ( const struct GNUNET_GNSRECORD_Block block,
const struct GNUNET_CRYPTO_EddsaPublicKey zone_key,
const char *  label,
GNUNET_GNSRECORD_RecordCallback  proc,
void *  proc_cls 
)

Definition at line 430 of file gnsrecord_crypto.c.

752 {
753  size_t payload_len = ntohl (block->size) - sizeof (struct
755  unsigned char nonce[crypto_secretbox_NONCEBYTES];
756  unsigned char key[crypto_secretbox_KEYBYTES];
757 
758  if (ntohl (block->size) <
759  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
760  + sizeof(struct GNUNET_TIME_AbsoluteNBO))
761  {
762  GNUNET_break_op (0);
763  return GNUNET_SYSERR;
764  }
766  key,
767  label,
769  zone_key);
770  {
771  char payload[payload_len];
772  unsigned int rd_count;
773 
775  eddsa_symmetric_decrypt (&block[1], payload_len,
776  key, nonce,
777  payload));
778  payload_len -= crypto_secretbox_MACBYTES;
779  rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
780  payload);
781  if (rd_count > 2048)
782  {
783  /* limit to sane value */
784  GNUNET_break_op (0);
785  return GNUNET_SYSERR;
786  }
787  {
788  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
789  unsigned int j;
790  struct GNUNET_TIME_Absolute now;
791 
792  if (GNUNET_OK !=
794  payload,
795  rd_count,
796  rd))
797  {
798  GNUNET_break_op (0);
799  return GNUNET_SYSERR;
800  }
801  /* hide expired records */
802  now = GNUNET_TIME_absolute_get ();
803  j = 0;
804  for (unsigned int i = 0; i < rd_count; i++)
805  {
806  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
807  {
808  /* encrypted blocks must never have relative expiration times, skip! */
809  GNUNET_break_op (0);
810  continue;
811  }
812 
813  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
814  {
815  int include_record = GNUNET_YES;
816  /* Shadow record, figure out if we have a not expired active record */
817  for (unsigned int k = 0; k < rd_count; k++)
818  {
819  if (k == i)
820  continue;
821  if (rd[i].expiration_time < now.abs_value_us)
822  include_record = GNUNET_NO; /* Shadow record is expired */
823  if ((rd[k].record_type == rd[i].record_type) &&
824  (rd[k].expiration_time >= now.abs_value_us) &&
825  (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
826  {
827  include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
829  "Ignoring shadow record\n");
830  break;
831  }
832  }
833  if (GNUNET_YES == include_record)
834  {
835  rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
836  if (j != i)
837  rd[j] = rd[i];
838  j++;
839  }
840  }
841  else if (rd[i].expiration_time >= now.abs_value_us)
842  {
843  /* Include this record */
844  if (j != i)
845  rd[j] = rd[i];
846  j++;
847  }
848  else
849  {
850  struct GNUNET_TIME_Absolute at;
851 
852  at.abs_value_us = rd[i].expiration_time;
854  "Excluding record that expired %s (%llu ago)\n",
856  (unsigned long long) rd[i].expiration_time
857  - now.abs_value_us);
858  }
859  }
860  rd_count = j;
861  if (NULL != proc)
862  proc (proc_cls,
863  rd_count,
864  (0 != rd_count) ? rd : NULL);
865  }
866  }
867  return GNUNET_OK;
868 }
enum GNUNET_GenericReturnValue eddsa_symmetric_decrypt(const void *block, size_t size, const unsigned char *key, const unsigned char *nonce, void *result)
struct GNUNET_GNSRECORD_EddsaBlock eddsa_block