GNUnet  0.16.x
gnsrecord_crypto.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013, 2018 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
28 #include "gnsrecord_crypto.h"
29 
30 #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
31 
32 ssize_t
34  const void *block,
35  size_t size,
36  const unsigned char *key,
37  const unsigned char *ctr,
38  void *result)
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 }
57 
58 
59 ssize_t
61  const void *block,
62  size_t size,
63  const unsigned char *key,
64  const unsigned char *ctr,
65  void *result)
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 }
84 
85 
88  const void *block,
89  size_t size,
90  const unsigned char *key,
91  const unsigned char *nonce,
92  void *result)
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 }
107 
108 
111  const void *block,
112  size_t size,
113  const unsigned char *key,
114  const unsigned char *nonce,
115  void *result)
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 }
124 
125 
126 void
127 GNR_derive_block_aes_key (unsigned char *ctr,
128  unsigned char *key,
129  const char *label,
130  uint64_t exp,
131  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
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 }
153 
154 
155 void
156 GNR_derive_block_xsalsa_key (unsigned char *nonce,
157  unsigned char *key,
158  const char *label,
159  uint64_t exp,
160  const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
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 }
181 
182 
183 static ssize_t
185  unsigned int rd_count)
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 }
195 
196 
209 static enum GNUNET_GenericReturnValue
211  const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
213  const char *label,
214  const struct GNUNET_GNSRECORD_Data *rd,
215  unsigned int rd_count,
216  struct GNUNET_GNSRECORD_Block **block)
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 }
304 
305 static ssize_t
307  unsigned int rd_count)
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 }
318 
319 
334  const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
336  const char *label,
337  const struct GNUNET_GNSRECORD_Data *rd,
338  unsigned int rd_count,
339  struct GNUNET_GNSRECORD_Block **block)
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 }
428 
429 ssize_t
432  const struct GNUNET_GNSRECORD_Data *rd,
433  unsigned int rd_count)
434 {
436  ssize_t res = -1;
437 
439  &pkey);
440  switch (ntohl (key->type))
441  {
443  res = block_get_size_ecdsa (rd, rd_count);
444  break;
446  res = block_get_size_eddsa (rd, rd_count);
447  break;
448  default:
449  GNUNET_assert (0);
450  }
451  return res;
452 
453 }
454 
458  const char *label,
459  const struct GNUNET_GNSRECORD_Data *rd,
460  unsigned int rd_count,
462 {
465  char *norm_label;
466 
468  &pkey);
469  norm_label = GNUNET_GNSRECORD_string_normalize (label);
470 
471  switch (ntohl (key->type))
472  {
474  res = block_create_ecdsa (&key->ecdsa_key,
475  &pkey.ecdsa_key,
476  expire,
477  norm_label,
478  rd,
479  rd_count,
480  result);
481  break;
483  res = block_create_eddsa (&key->eddsa_key,
484  &pkey.eddsa_key,
485  expire,
486  norm_label,
487  rd,
488  rd_count,
489  result);
490  break;
491  default:
492  GNUNET_assert (0);
493  }
494  GNUNET_free (norm_label);
495  return res;
496 }
497 
498 
503 {
508 
513 };
514 
515 
519  const char *label,
520  const struct GNUNET_GNSRECORD_Data *rd,
521  unsigned int rd_count,
523 {
524  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
525  struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
527  char *norm_label;
528 
529  norm_label = GNUNET_GNSRECORD_string_normalize (label);
530 
531  if (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pkey->type))
532  {
533  key = &pkey->ecdsa_key;
534 #define CSIZE 64
535  static struct KeyCacheLine cache[CSIZE];
536  struct KeyCacheLine *line;
537 
538  line = &cache[(*(unsigned int *) key) % CSIZE];
539  if (0 != memcmp (&line->key,
540  key,
541  sizeof(*key)))
542  {
543  /* cache miss, recompute */
544  line->key = *key;
546  &line->pkey);
547  }
548 #undef CSIZE
550  &line->pkey,
551  expire,
552  norm_label,
553  rd,
554  rd_count,
555  result);
556  }
557  else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
558  {
560  &edpubkey);
561  res = block_create_eddsa (&pkey->eddsa_key,
562  &edpubkey,
563  expire,
564  norm_label,
565  rd,
566  rd_count,
567  result);
568  }
569  GNUNET_free (norm_label);
570  return res;
571 }
572 
573 
583 {
584  struct GNRBlockPS *purp;
585  size_t payload_len = ntohl (block->size)
586  - sizeof (struct GNUNET_GNSRECORD_Block);
588  purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
589  purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
591  GNUNET_memcpy (&purp[1],
592  &block[1],
593  payload_len);
594  switch (ntohl (block->type))
595  {
600  &purp->purpose,
601  &block->ecdsa_block.signature,
602  &block->ecdsa_block.derived_key);
603  break;
608  &purp->purpose,
609  &block->eddsa_block.signature,
610  &block->eddsa_block.derived_key);
611  break;
612  default:
613  res = GNUNET_NO;
614  }
615  GNUNET_free (purp);
616  return res;
617 }
618 
619 
621 block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
622  const struct
624  const char *label,
626  void *proc_cls)
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 }
743 
744 
746 block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
747  const struct
749  const char *label,
751  void *proc_cls)
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 }
869 
870 
884  const struct
886  const char *label,
888  void *proc_cls)
889 {
891  char *norm_label;
892 
893  norm_label = GNUNET_GNSRECORD_string_normalize (label);
894  switch (ntohl (zone_key->type))
895  {
897  res = block_decrypt_ecdsa (block,
898  &zone_key->ecdsa_key, norm_label, proc,
899  proc_cls);
900  break;
902  res = block_decrypt_eddsa (block,
903  &zone_key->eddsa_key, norm_label, proc,
904  proc_cls);
905  break;
906  default:
907  res = GNUNET_SYSERR;
908  }
909  GNUNET_free (norm_label);
910  return res;
911 }
912 
913 
921 void
924  const char *label,
925  struct GNUNET_HashCode *query)
926 {
927  char *norm_label;
929 
930  norm_label = GNUNET_GNSRECORD_string_normalize (label);
931  switch (ntohl (zone->type))
932  {
935 
937  &pub);
939  norm_label,
940  query);
941  break;
942  default:
943  GNUNET_assert (0);
944  }
945  GNUNET_free (norm_label);
946 }
947 
948 
957 void
960  const char *label,
961  struct GNUNET_HashCode *query)
962 {
963  char *norm_label;
964  struct GNUNET_IDENTITY_PublicKey pd;
965 
966  norm_label = GNUNET_GNSRECORD_string_normalize (label);
967 
968  switch (ntohl (pub->type))
969  {
971  pd.type = pub->type;
973  norm_label,
974  "gns",
975  &pd.ecdsa_key);
977  sizeof (pd.ecdsa_key),
978  query);
979  break;
981  pd.type = pub->type;
983  norm_label,
984  "gns",
985  &(pd.eddsa_key));
987  sizeof (pd.eddsa_key),
988  query);
989  break;
990  default:
991  GNUNET_assert (0);
992  }
993  GNUNET_free (norm_label);
994 }
995 
996 
997 /* end of gnsrecord_crypto.c */
static ssize_t block_get_size_eddsa(const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
ssize_t ecdsa_symmetric_encrypt(const void *block, size_t size, const unsigned char *key, const unsigned char *ctr, void *result)
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)
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)
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)
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 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)
ssize_t ecdsa_symmetric_decrypt(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 CSIZE
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.
API for GNS record-related crypto.
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
#define GNUNET_GNSRECORD_TYPE_EDKEY
Record type for EDKEY zone delegations.
static int res
static char * line
Desired phone line (string to be converted to a hash).
struct GNUNET_HashCode key
The key used in the DHT.
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:99
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * pkey
Public key of the zone to look in, in ASCII.
static char * zone
Name of the zone being managed.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CONTAINER_MultiHashMap32 * cache
Hashmap to maintain cache.
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_log(kind,...)
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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...
#define GNUNET_CRYPTO_AES_KEY_LENGTH
length of the sessionkey in bytes (256 BIT sessionkey)
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_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.
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:197
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Verify ECDSA signature.
Definition: crypto_ecc.c:623
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.
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:186
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:682
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
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.
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.
#define GNUNET_GNSRECORD_MAX_BLOCK_SIZE
Maximum size of a value that can be stored in a GNS block.
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,...
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.
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.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_verify(const struct GNUNET_GNSRECORD_Block *block)
Check if a signature is valid.
unsigned int GNUNET_GNSRECORD_records_deserialize_get_size(size_t len, const char *src)
void(* GNUNET_GNSRECORD_RecordCallback)(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a records that were decrypted from a block.
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.
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.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SHADOW_RECORD
This record should not be used unless all (other) records with an absolute expiration time have expir...
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
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
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:175
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_INFO
#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
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
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
static unsigned int size
Size of the "table".
Definition: peer.c:67
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.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
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...
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
Private ECC key encoded for transmission.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
uint32_t type
The zone type (GNUNET_GNSRECORD_TYPE_PKEY)
struct GNUNET_GNSRECORD_EcdsaBlock ecdsa_block
struct GNUNET_GNSRECORD_EddsaBlock eddsa_block
uint32_t size
Size of the block.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
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.
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.
A 512-bit hashcode.
A private key for an identity as per LSD0001.
uint32_t type
Type of public key.
struct GNUNET_CRYPTO_EcdsaPrivateKey ecdsa_key
An ECDSA identity key.
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_key
AN EdDSA identtiy key.
An identity key as per LSD0001.
uint32_t type
Type of public key.
struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_key
An ECDSA identity key.
struct GNUNET_CRYPTO_EddsaPublicKey eddsa_key
AN EdDSA identtiy key.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
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.
Line in cache mapping private keys to public keys.
struct GNUNET_CRYPTO_EcdsaPublicKey pkey
Associated public key.
struct GNUNET_CRYPTO_EcdsaPrivateKey key
A private key.