GNUnet  0.20.0
gnsrecord_crypto.c File Reference

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

#include "platform.h"
#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)
 
enum GNUNET_GenericReturnValue block_sign_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, const char *label, struct GNUNET_GNSRECORD_Block *block)
 
enum GNUNET_GenericReturnValue block_sign_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, const char *label, struct GNUNET_GNSRECORD_Block *block)
 
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_sign (const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, struct GNUNET_GNSRECORD_Block *block)
 Sign a block create with GNUNET_GNSRECORD_block_create_unsigned. More...
 
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, int sign)
 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, int sign)
 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...
 
static enum GNUNET_GenericReturnValue 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, int sign)
 
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create_unsigned (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)
 Create name and records but do not sign! Sign later with GNUNET_GNSRECORD_block_sign(). 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 31 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 34 of file gnsrecord_crypto.c.

40 {
41  gcry_cipher_hd_t handle;
42  int rc;
43 
44  GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
45  GCRY_CIPHER_MODE_CTR, 0));
46  rc = gcry_cipher_setkey (handle,
47  key,
49  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
50  rc = gcry_cipher_setctr (handle,
51  ctr,
53  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
54  GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size));
55  gcry_cipher_close (handle);
56  return size;
57 }
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:68

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 61 of file gnsrecord_crypto.c.

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

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 61 of file gnsrecord_crypto.c.

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

◆ 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 61 of file gnsrecord_crypto.c.

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

◆ 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 129 of file gnsrecord_crypto.c.

134 {
135  static const char ctx_key[] = "gns-aes-ctx-key";
136  static const char ctx_iv[] = "gns-aes-ctx-iv";
137 
139  ctx_key, strlen (ctx_key),
140  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
141  label, strlen (label),
142  NULL, 0);
143  memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
145  GNUNET_CRYPTO_kdf (ctr, 4,
146  ctx_iv, strlen (ctx_iv),
147  pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
148  label, strlen (label),
149  NULL, 0);
151  memcpy (ctr + 4, &exp, sizeof (exp));
153  ctr[15] |= 0x01;
154 }
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
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:70
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 158 of file gnsrecord_crypto.c.

163 {
164  static const char ctx_key[] = "gns-xsalsa-ctx-key";
165  static const char ctx_iv[] = "gns-xsalsa-ctx-iv";
166 
167  GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES,
168  ctx_key, strlen (ctx_key),
169  pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
170  label, strlen (label),
171  NULL, 0);
172  memset (nonce, 0, crypto_secretbox_NONCEBYTES);
174  GNUNET_CRYPTO_kdf (nonce, (crypto_secretbox_NONCEBYTES - sizeof (exp)),
175  ctx_iv, strlen (ctx_iv),
176  pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
177  label, strlen (label),
178  NULL, 0);
180  memcpy (nonce + (crypto_secretbox_NONCEBYTES - sizeof (exp)),
181  &exp, sizeof (exp));
182 }
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 186 of file gnsrecord_crypto.c.

188 {
189  ssize_t len;
190 
192  if (len < 0)
193  return -1;
194  len += sizeof(struct GNUNET_GNSRECORD_Block);
195  return len;
196 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
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_create2().

Here is the caller graph for this function:

◆ block_sign_ecdsa()

enum GNUNET_GenericReturnValue block_sign_ecdsa ( const struct GNUNET_CRYPTO_EcdsaPrivateKey key,
const struct GNUNET_CRYPTO_EcdsaPublicKey pkey,
const char *  label,
struct GNUNET_GNSRECORD_Block block 
)

Definition at line 186 of file gnsrecord_crypto.c.

206 {
207  struct GNRBlockPS *gnr_block;
208  struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
209  size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block);
210 
211  gnr_block = GNUNET_malloc (size);
212  ecblock = &(block)->ecdsa_block;
213  gnr_block->purpose.size = htonl (size);
214  gnr_block->purpose.purpose =
216  gnr_block->expiration_time = ecblock->expiration_time;
217  /* encrypt and sign */
218  GNUNET_memcpy (&gnr_block[1], &ecblock[1],
219  size - sizeof (*gnr_block));
221  label,
222  "gns",
223  &ecblock->derived_key);
224  if (GNUNET_OK !=
226  label,
227  "gns",
228  &gnr_block->purpose,
229  &ecblock->signature))
230  {
231  GNUNET_break (0);
232  GNUNET_free (gnr_block);
233  return GNUNET_SYSERR;
234  }
235  GNUNET_free (gnr_block);
236  return GNUNET_OK;
237 }
#define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN
GNS record set signature (GNS)
static char * pkey
Public key of the zone to look in, in ASCII.
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.
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.
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...
uint32_t size
Size of the block.
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.

◆ block_sign_eddsa()

enum GNUNET_GenericReturnValue block_sign_eddsa ( const struct GNUNET_CRYPTO_EddsaPrivateKey key,
const struct GNUNET_CRYPTO_EddsaPublicKey pkey,
const char *  label,
struct GNUNET_GNSRECORD_Block block 
)

Definition at line 186 of file gnsrecord_crypto.c.

247 {
248  struct GNRBlockPS *gnr_block;
249  struct GNUNET_GNSRECORD_EddsaBlock *edblock;
250  size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block);
251  gnr_block = GNUNET_malloc (size);
252  edblock = &(block)->eddsa_block;
253  gnr_block->purpose.size = htonl (size);
254  gnr_block->purpose.purpose =
256  gnr_block->expiration_time = edblock->expiration_time;
257  GNUNET_memcpy (&gnr_block[1], &edblock[1],
258  size - sizeof (*gnr_block));
259  /* encrypt and sign */
261  label,
262  "gns",
263  &edblock->derived_key);
265  label,
266  "gns",
267  &gnr_block->purpose,
268  &edblock->signature);
269  GNUNET_free (gnr_block);
270  return GNUNET_OK;
271 }
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.

◆ 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,
int  sign 
)
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.
signsign the block GNUNET_NO if block will be signed later.
Returns
GNUNET_SYSERR on error (otherwise GNUNET_OK)

Definition at line 186 of file gnsrecord_crypto.c.

332 {
333  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
334  rd);
335  struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
336  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
337  unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
339  struct GNUNET_TIME_Absolute now;
340 
341  if (payload_len < 0)
342  {
343  GNUNET_break (0);
344  return GNUNET_SYSERR;
345  }
346  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
347  {
348  GNUNET_break (0);
349  return GNUNET_SYSERR;
350  }
351  /* convert relative to absolute times */
352  now = GNUNET_TIME_absolute_get ();
353  for (unsigned int i = 0; i < rd_count; i++)
354  {
355  rdc[i] = rd[i];
356  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
357  {
358  struct GNUNET_TIME_Relative t;
359 
360  /* encrypted blocks must never have relative expiration times, convert! */
362  t.rel_value_us = rdc[i].expiration_time;
363  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
364  }
365  }
366  /* serialize */
367  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
368  (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
369  {
370  char payload[payload_len];
371 
372  GNUNET_assert (payload_len ==
374  rdc,
375  payload_len,
376  payload));
377  ecblock = &(*block)->ecdsa_block;
378  (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
381  skey,
382  label,
384  pkey);
385  GNUNET_assert (payload_len ==
387  payload_len,
388  skey,
389  ctr,
390  &ecblock[1]));
391  }
392  if (GNUNET_YES != sign)
393  return GNUNET_OK;
394  if (GNUNET_OK !=
395  block_sign_ecdsa (key, pkey, label, *block))
396  {
397  GNUNET_break (0);
398  GNUNET_free (*block);
399  return GNUNET_SYSERR;
400  }
401  return GNUNET_OK;
402 }
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
enum GNUNET_GenericReturnValue block_sign_ecdsa(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, const char *label, struct GNUNET_GNSRECORD_Block *block)
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.
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:101
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_SCHEDULER_Task * t
Main task.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
#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.
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
@ GNUNET_YES
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
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:450
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
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(), len, rd, and rd_count.

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 406 of file gnsrecord_crypto.c.

408 {
409  ssize_t len;
410 
412  if (len < 0)
413  return -1;
414  len += sizeof(struct GNUNET_GNSRECORD_Block);
415  len += crypto_secretbox_MACBYTES;
416  return len;
417 }

Referenced by block_create2().

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,
int  sign 
)

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.
signGNUNET_YES if block shall be signed as well
Returns
GNUNET_SYSERR on error (otherwise GNUNET_OK)

Definition at line 406 of file gnsrecord_crypto.c.

442 {
443  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
444  rd);
445  struct GNUNET_GNSRECORD_EddsaBlock *edblock;
446  unsigned char nonce[crypto_secretbox_NONCEBYTES];
447  unsigned char skey[crypto_secretbox_KEYBYTES];
449  struct GNUNET_TIME_Absolute now;
450 
451  if (payload_len < 0)
452  {
453  GNUNET_break (0);
454  return GNUNET_SYSERR;
455  }
456  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
457  {
458  GNUNET_break (0);
459  return GNUNET_SYSERR;
460  }
461  /* convert relative to absolute times */
462  now = GNUNET_TIME_absolute_get ();
463  for (unsigned int i = 0; i < rd_count; i++)
464  {
465  rdc[i] = rd[i];
466  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
467  {
468  struct GNUNET_TIME_Relative t;
469 
470  /* encrypted blocks must never have relative expiration times, convert! */
472  t.rel_value_us = rdc[i].expiration_time;
473  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
474  }
475  }
476  /* serialize */
477  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
478  + payload_len + crypto_secretbox_MACBYTES);
479  (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block)
480  + payload_len + crypto_secretbox_MACBYTES);
481  {
482  char payload[payload_len];
483 
484  GNUNET_assert (payload_len ==
486  rdc,
487  payload_len,
488  payload));
489  edblock = &(*block)->eddsa_block;
490  (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
493  skey,
494  label,
496  pkey);
499  payload_len,
500  skey,
501  nonce,
502  &edblock[1]));
503  if (GNUNET_YES != sign)
504  return GNUNET_OK;
505  block_sign_eddsa (key, pkey, label, *block);
506  }
507  return GNUNET_OK;
508 }
#define GNUNET_GNSRECORD_TYPE_EDKEY
GNS zone delegation (EDKEY)
enum GNUNET_GenericReturnValue block_sign_eddsa(const struct GNUNET_CRYPTO_EddsaPrivateKey *key, const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, const char *label, struct GNUNET_GNSRECORD_Block *block)
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)

References GNUNET_GNSRECORD_records_get_size(), len, rd, and rd_count.

Here is the call graph for this function:

◆ block_create2()

static enum GNUNET_GenericReturnValue 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,
int  sign 
)
static

Definition at line 512 of file gnsrecord_crypto.c.

609 {
610  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
611  struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
613  char *norm_label;
614 
615  norm_label = GNUNET_GNSRECORD_string_normalize (label);
616 
617  if (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pkey->type))
618  {
619  key = &pkey->ecdsa_key;
620 #define CSIZE 64
621  static struct KeyCacheLine cache[CSIZE];
622  struct KeyCacheLine *line;
623 
624  line = &cache[(*(unsigned int *) key) % CSIZE];
625  if (0 != memcmp (&line->key,
626  key,
627  sizeof(*key)))
628  {
629  /* cache miss, recompute */
630  line->key = *key;
632  &line->pkey);
633  }
634 #undef CSIZE
636  &line->pkey,
637  expire,
638  norm_label,
639  rd,
640  rd_count,
641  result,
642  sign);
643  }
644  else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
645  {
647  &edpubkey);
648  res = block_create_eddsa (&pkey->eddsa_key,
649  &edpubkey,
650  expire,
651  norm_label,
652  rd,
653  rd_count,
654  result,
655  sign);
656  }
657  GNUNET_free (norm_label);
658  return res;
659 }
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, int sign)
Sign name and records (EDDSA version)
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, int sign)
Sign name and records.
#define CSIZE
static int res
static char * line
Desired phone line (string to be converted to a hash).
static struct GNUNET_CONTAINER_MultiHashMap32 * cache
Hashmap to maintain cache.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:198
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:187
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
GNUNET_GenericReturnValue
Named constants for return values.
Private ECC key encoded for transmission.
Line in cache mapping private keys to public keys.

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, rd, rd_count, and res.

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 512 of file gnsrecord_crypto.c.

740 {
741  size_t payload_len = ntohl (block->size) - sizeof (struct
743  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
744  unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
745 
746  if (ntohl (block->size) <
747  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
748  + sizeof(struct GNUNET_TIME_AbsoluteNBO))
749  {
750  GNUNET_break_op (0);
751  return GNUNET_SYSERR;
752  }
754  key,
755  label,
757  zone_key);
758  {
759  char payload[payload_len];
760  unsigned int rd_count;
761 
762  GNUNET_assert (payload_len ==
763  ecdsa_symmetric_decrypt (&block[1], payload_len,
764  key, ctr,
765  payload));
767  payload);
768  if (rd_count > 2048)
769  {
770  /* limit to sane value */
771  GNUNET_break_op (0);
772  return GNUNET_SYSERR;
773  }
774  {
776  unsigned int j;
777  struct GNUNET_TIME_Absolute now;
778 
779  if (GNUNET_OK !=
781  payload,
782  rd_count,
783  rd))
784  {
785  GNUNET_break_op (0);
786  return GNUNET_SYSERR;
787  }
788  /* hide expired records */
789  now = GNUNET_TIME_absolute_get ();
790  j = 0;
791  for (unsigned int i = 0; i < rd_count; i++)
792  {
793  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
794  {
795  /* encrypted blocks must never have relative expiration times, skip! */
796  GNUNET_break_op (0);
797  continue;
798  }
799 
800  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW))
801  {
802  int include_record = GNUNET_YES;
803  /* Shadow record, figure out if we have a not expired active record */
804  for (unsigned int k = 0; k < rd_count; k++)
805  {
806  if (k == i)
807  continue;
808  if (rd[i].expiration_time < now.abs_value_us)
809  include_record = GNUNET_NO; /* Shadow record is expired */
810  if ((rd[k].record_type == rd[i].record_type) &&
811  (rd[k].expiration_time >= now.abs_value_us) &&
812  (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW)))
813  {
814  include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
816  "Ignoring shadow record\n");
817  break;
818  }
819  }
820  if (GNUNET_YES == include_record)
821  {
822  rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW; /* Remove Flag */
823  if (j != i)
824  rd[j] = rd[i];
825  j++;
826  }
827  }
828  else if (rd[i].expiration_time >= now.abs_value_us)
829  {
830  /* Include this record */
831  if (j != i)
832  rd[j] = rd[i];
833  j++;
834  }
835  else
836  {
837  struct GNUNET_TIME_Absolute at;
838 
841  "Excluding record that expired %s (%llu ago)\n",
843  (unsigned long long) rd[i].expiration_time
844  - now.abs_value_us);
845  }
846  }
847  rd_count = j;
848  if (NULL != proc)
849  proc (proc_cls,
850  rd_count,
851  (0 != rd_count) ? rd : NULL);
852  }
853  }
854  return GNUNET_OK;
855 }
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.
@ GNUNET_GNSRECORD_RF_SHADOW
This record should not be used unless all (other) records in the set with an absolute expiration time...
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)
#define GNUNET_log(kind,...)
@ GNUNET_NO
#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:616
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
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
Time for absolute time used by GNUnet, in microseconds and in network byte order.

◆ 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 512 of file gnsrecord_crypto.c.

865 {
866  size_t payload_len = ntohl (block->size) - sizeof (struct
868  unsigned char nonce[crypto_secretbox_NONCEBYTES];
869  unsigned char key[crypto_secretbox_KEYBYTES];
870 
871  if (ntohl (block->size) <
872  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
873  + sizeof(struct GNUNET_TIME_AbsoluteNBO))
874  {
875  GNUNET_break_op (0);
876  return GNUNET_SYSERR;
877  }
879  key,
880  label,
882  zone_key);
883  {
884  char payload[payload_len];
885  unsigned int rd_count;
886 
888  eddsa_symmetric_decrypt (&block[1], payload_len,
889  key, nonce,
890  payload));
891  payload_len -= crypto_secretbox_MACBYTES;
893  payload);
894  if (rd_count > 2048)
895  {
896  /* limit to sane value */
897  GNUNET_break_op (0);
898  return GNUNET_SYSERR;
899  }
900  {
902  unsigned int j;
903  struct GNUNET_TIME_Absolute now;
904 
905  if (GNUNET_OK !=
907  payload,
908  rd_count,
909  rd))
910  {
911  GNUNET_break_op (0);
912  return GNUNET_SYSERR;
913  }
914  /* hide expired records */
915  now = GNUNET_TIME_absolute_get ();
916  j = 0;
917  for (unsigned int i = 0; i < rd_count; i++)
918  {
919  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
920  {
921  /* encrypted blocks must never have relative expiration times, skip! */
922  GNUNET_break_op (0);
923  continue;
924  }
925 
926  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW))
927  {
928  int include_record = GNUNET_YES;
929  /* Shadow record, figure out if we have a not expired active record */
930  for (unsigned int k = 0; k < rd_count; k++)
931  {
932  if (k == i)
933  continue;
934  if (rd[i].expiration_time < now.abs_value_us)
935  include_record = GNUNET_NO; /* Shadow record is expired */
936  if ((rd[k].record_type == rd[i].record_type) &&
937  (rd[k].expiration_time >= now.abs_value_us) &&
938  (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW)))
939  {
940  include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
942  "Ignoring shadow record\n");
943  break;
944  }
945  }
946  if (GNUNET_YES == include_record)
947  {
948  rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW; /* Remove Flag */
949  if (j != i)
950  rd[j] = rd[i];
951  j++;
952  }
953  }
954  else if (rd[i].expiration_time >= now.abs_value_us)
955  {
956  /* Include this record */
957  if (j != i)
958  rd[j] = rd[i];
959  j++;
960  }
961  else
962  {
963  struct GNUNET_TIME_Absolute at;
964 
967  "Excluding record that expired %s (%llu ago)\n",
969  (unsigned long long) rd[i].expiration_time
970  - now.abs_value_us);
971  }
972  }
973  rd_count = j;
974  if (NULL != proc)
975  proc (proc_cls,
976  rd_count,
977  (0 != rd_count) ? rd : NULL);
978  }
979  }
980  return GNUNET_OK;
981 }
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