GNUnet  0.19.2
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 "platform.h"
29 #include "gnsrecord_crypto.h"
30 
31 #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
32 
33 ssize_t
35  const void *block,
36  size_t size,
37  const unsigned char *key,
38  const unsigned char *ctr,
39  void *result)
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 }
58 
59 
60 ssize_t
62  const void *block,
63  size_t size,
64  const unsigned char *key,
65  const unsigned char *ctr,
66  void *result)
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 }
85 
86 
89  const void *block,
90  size_t size,
91  const unsigned char *key,
92  const unsigned char *nonce,
93  void *result)
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 }
109 
110 
113  const void *block,
114  size_t size,
115  const unsigned char *key,
116  const unsigned char *nonce,
117  void *result)
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 }
126 
127 
128 void
129 GNR_derive_block_aes_key (unsigned char *ctr,
130  unsigned char *key,
131  const char *label,
132  uint64_t exp,
133  const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
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 }
155 
156 
157 void
158 GNR_derive_block_xsalsa_key (unsigned char *nonce,
159  unsigned char *key,
160  const char *label,
161  uint64_t exp,
162  const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
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 }
183 
184 
185 static ssize_t
187  unsigned int rd_count)
188 {
189  ssize_t len;
190 
192  if (len < 0)
193  return -1;
194  len += sizeof(struct GNUNET_GNSRECORD_Block);
195  return len;
196 }
197 
199 block_sign_ecdsa (const struct
201  const struct
203  const char *label,
204  struct GNUNET_GNSRECORD_Block *block)
205 {
206  struct GNRBlockPS *gnr_block;
207  struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
208  size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block);
209 
210  gnr_block = GNUNET_malloc (size);
211  ecblock = &(block)->ecdsa_block;
212  gnr_block->purpose.size = htonl (size);
213  gnr_block->purpose.purpose =
215  gnr_block->expiration_time = ecblock->expiration_time;
216  /* encrypt and sign */
217  GNUNET_memcpy (&gnr_block[1], &ecblock[1],
218  size - sizeof (*gnr_block));
220  label,
221  "gns",
222  &ecblock->derived_key);
223  if (GNUNET_OK !=
225  label,
226  "gns",
227  &gnr_block->purpose,
228  &ecblock->signature))
229  {
230  GNUNET_break (0);
231  GNUNET_free (gnr_block);
232  return GNUNET_SYSERR;
233  }
234  GNUNET_free (gnr_block);
235  return GNUNET_OK;
236 }
237 
238 
240 block_sign_eddsa (const struct
242  const struct
244  const char *label,
245  struct GNUNET_GNSRECORD_Block *block)
246 {
247  struct GNRBlockPS *gnr_block;
248  struct GNUNET_GNSRECORD_EddsaBlock *edblock;
249  size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block);
250  gnr_block = GNUNET_malloc (size);
251  edblock = &(block)->eddsa_block;
252  gnr_block->purpose.size = htonl (size);
253  gnr_block->purpose.purpose =
255  gnr_block->expiration_time = edblock->expiration_time;
256  GNUNET_memcpy (&gnr_block[1], &edblock[1],
257  size - sizeof (*gnr_block));
258  /* encrypt and sign */
260  label,
261  "gns",
262  &edblock->derived_key);
264  label,
265  "gns",
266  &gnr_block->purpose,
267  &edblock->signature);
268  GNUNET_free (gnr_block);
269  return GNUNET_OK;
270 }
271 
272 
274 GNUNET_GNSRECORD_block_sign (const struct
276  const char *label,
277  struct GNUNET_GNSRECORD_Block *block)
278 {
281  char *norm_label;
282 
284  &pkey);
285  norm_label = GNUNET_GNSRECORD_string_normalize (label);
286 
287  switch (ntohl (key->type))
288  {
290  res = block_sign_ecdsa (&key->ecdsa_key,
291  &pkey.ecdsa_key,
292  norm_label,
293  block);
294  break;
296  res = block_sign_eddsa (&key->eddsa_key,
297  &pkey.eddsa_key,
298  norm_label,
299  block);
300  break;
301  default:
302  GNUNET_assert (0);
303  }
304  GNUNET_free (norm_label);
305  return res;
306 }
307 
308 
322 static enum GNUNET_GenericReturnValue
324  const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
326  const char *label,
327  const struct GNUNET_GNSRECORD_Data *rd,
328  unsigned int rd_count,
329  struct GNUNET_GNSRECORD_Block **block,
330  int sign)
331 {
332  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
333  rd);
334  struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
335  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
336  unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
338  struct GNUNET_TIME_Absolute now;
339 
340  if (payload_len < 0)
341  {
342  GNUNET_break (0);
343  return GNUNET_SYSERR;
344  }
345  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
346  {
347  GNUNET_break (0);
348  return GNUNET_SYSERR;
349  }
350  /* convert relative to absolute times */
351  now = GNUNET_TIME_absolute_get ();
352  for (unsigned int i = 0; i < rd_count; i++)
353  {
354  rdc[i] = rd[i];
355  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
356  {
357  struct GNUNET_TIME_Relative t;
358 
359  /* encrypted blocks must never have relative expiration times, convert! */
361  t.rel_value_us = rdc[i].expiration_time;
362  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
363  }
364  }
365  /* serialize */
366  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
367  (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
368  {
369  char payload[payload_len];
370 
371  GNUNET_assert (payload_len ==
373  rdc,
374  payload_len,
375  payload));
376  ecblock = &(*block)->ecdsa_block;
377  (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
380  skey,
381  label,
383  pkey);
384  GNUNET_assert (payload_len ==
386  payload_len,
387  skey,
388  ctr,
389  &ecblock[1]));
390  }
391  if (GNUNET_YES != sign)
392  return GNUNET_OK;
393  if (GNUNET_OK !=
394  block_sign_ecdsa (key, pkey, label, *block))
395  {
396  GNUNET_break (0);
397  GNUNET_free (*block);
398  return GNUNET_SYSERR;
399  }
400  return GNUNET_OK;
401 }
402 
403 static ssize_t
405  unsigned int rd_count)
406 {
407  ssize_t len;
408 
410  if (len < 0)
411  return -1;
412  len += sizeof(struct GNUNET_GNSRECORD_Block);
413  len += crypto_secretbox_MACBYTES;
414  return len;
415 }
416 
417 
433  const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
435  const char *label,
436  const struct GNUNET_GNSRECORD_Data *rd,
437  unsigned int rd_count,
438  struct GNUNET_GNSRECORD_Block **block,
439  int sign)
440 {
441  ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
442  rd);
443  struct GNUNET_GNSRECORD_EddsaBlock *edblock;
444  unsigned char nonce[crypto_secretbox_NONCEBYTES];
445  unsigned char skey[crypto_secretbox_KEYBYTES];
447  struct GNUNET_TIME_Absolute now;
448 
449  if (payload_len < 0)
450  {
451  GNUNET_break (0);
452  return GNUNET_SYSERR;
453  }
454  if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
455  {
456  GNUNET_break (0);
457  return GNUNET_SYSERR;
458  }
459  /* convert relative to absolute times */
460  now = GNUNET_TIME_absolute_get ();
461  for (unsigned int i = 0; i < rd_count; i++)
462  {
463  rdc[i] = rd[i];
464  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
465  {
466  struct GNUNET_TIME_Relative t;
467 
468  /* encrypted blocks must never have relative expiration times, convert! */
470  t.rel_value_us = rdc[i].expiration_time;
471  rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
472  }
473  }
474  /* serialize */
475  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
476  + payload_len + crypto_secretbox_MACBYTES);
477  (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block)
478  + payload_len + crypto_secretbox_MACBYTES);
479  {
480  char payload[payload_len];
481 
482  GNUNET_assert (payload_len ==
484  rdc,
485  payload_len,
486  payload));
487  edblock = &(*block)->eddsa_block;
488  (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
491  skey,
492  label,
494  pkey);
497  payload_len,
498  skey,
499  nonce,
500  &edblock[1]));
501  if (GNUNET_YES != sign)
502  return GNUNET_OK;
503  block_sign_eddsa (key, pkey, label, *block);
504  }
505  return GNUNET_OK;
506 }
507 
508 ssize_t
511  const struct GNUNET_GNSRECORD_Data *rd,
512  unsigned int rd_count)
513 {
515  ssize_t res = -1;
516 
518  &pkey);
519  switch (ntohl (key->type))
520  {
523  break;
526  break;
527  default:
528  GNUNET_assert (0);
529  }
530  return res;
531 
532 }
533 
537  const char *label,
538  const struct GNUNET_GNSRECORD_Data *rd,
539  unsigned int rd_count,
541 {
544  char *norm_label;
545 
547  &pkey);
548  norm_label = GNUNET_GNSRECORD_string_normalize (label);
549 
550  switch (ntohl (key->type))
551  {
553  res = block_create_ecdsa (&key->ecdsa_key,
554  &pkey.ecdsa_key,
555  expire,
556  norm_label,
557  rd,
558  rd_count,
559  result,
560  GNUNET_YES);
561  break;
563  res = block_create_eddsa (&key->eddsa_key,
564  &pkey.eddsa_key,
565  expire,
566  norm_label,
567  rd,
568  rd_count,
569  result,
570  GNUNET_YES);
571  break;
572  default:
573  GNUNET_assert (0);
574  }
575  GNUNET_free (norm_label);
576  return res;
577 }
578 
579 
584 {
589 
594 };
595 
596 
597 static enum GNUNET_GenericReturnValue
600  const char *label,
601  const struct GNUNET_GNSRECORD_Data *rd,
602  unsigned int rd_count,
604  int sign)
605 {
606  const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
607  struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
609  char *norm_label;
610 
611  norm_label = GNUNET_GNSRECORD_string_normalize (label);
612 
613  if (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pkey->type))
614  {
615  key = &pkey->ecdsa_key;
616 #define CSIZE 64
617  static struct KeyCacheLine cache[CSIZE];
618  struct KeyCacheLine *line;
619 
620  line = &cache[(*(unsigned int *) key) % CSIZE];
621  if (0 != memcmp (&line->key,
622  key,
623  sizeof(*key)))
624  {
625  /* cache miss, recompute */
626  line->key = *key;
628  &line->pkey);
629  }
630 #undef CSIZE
632  &line->pkey,
633  expire,
634  norm_label,
635  rd,
636  rd_count,
637  result,
638  sign);
639  }
640  else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
641  {
643  &edpubkey);
644  res = block_create_eddsa (&pkey->eddsa_key,
645  &edpubkey,
646  expire,
647  norm_label,
648  rd,
649  rd_count,
650  result,
651  sign);
652  }
653  GNUNET_free (norm_label);
654  return res;
655 }
656 
657 
658 
663  const char *label,
664  const struct GNUNET_GNSRECORD_Data *rd,
665  unsigned int rd_count,
667 {
668  return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_NO);
669 }
670 
671 
672 
676  const char *label,
677  const struct GNUNET_GNSRECORD_Data *rd,
678  unsigned int rd_count,
680 {
681  return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_YES);
682 }
683 
693 {
694  struct GNRBlockPS *purp;
695  size_t payload_len = ntohl (block->size)
696  - sizeof (struct GNUNET_GNSRECORD_Block);
698  purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
699  purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
701  GNUNET_memcpy (&purp[1],
702  &block[1],
703  payload_len);
704  switch (ntohl (block->type))
705  {
710  &purp->purpose,
711  &block->ecdsa_block.signature,
712  &block->ecdsa_block.derived_key);
713  break;
718  &purp->purpose,
719  &block->eddsa_block.signature,
720  &block->eddsa_block.derived_key);
721  break;
722  default:
723  res = GNUNET_NO;
724  }
725  GNUNET_free (purp);
726  return res;
727 }
728 
729 
731 block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
732  const struct
734  const char *label,
736  void *proc_cls)
737 {
738  size_t payload_len = ntohl (block->size) - sizeof (struct
740  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
741  unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
742 
743  if (ntohl (block->size) <
744  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
745  + sizeof(struct GNUNET_TIME_AbsoluteNBO))
746  {
747  GNUNET_break_op (0);
748  return GNUNET_SYSERR;
749  }
751  key,
752  label,
754  zone_key);
755  {
756  char payload[payload_len];
757  unsigned int rd_count;
758 
759  GNUNET_assert (payload_len ==
760  ecdsa_symmetric_decrypt (&block[1], payload_len,
761  key, ctr,
762  payload));
764  payload);
765  if (rd_count > 2048)
766  {
767  /* limit to sane value */
768  GNUNET_break_op (0);
769  return GNUNET_SYSERR;
770  }
771  {
773  unsigned int j;
774  struct GNUNET_TIME_Absolute now;
775 
776  if (GNUNET_OK !=
778  payload,
779  rd_count,
780  rd))
781  {
782  GNUNET_break_op (0);
783  return GNUNET_SYSERR;
784  }
785  /* hide expired records */
786  now = GNUNET_TIME_absolute_get ();
787  j = 0;
788  for (unsigned int i = 0; i < rd_count; i++)
789  {
790  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
791  {
792  /* encrypted blocks must never have relative expiration times, skip! */
793  GNUNET_break_op (0);
794  continue;
795  }
796 
797  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW))
798  {
799  int include_record = GNUNET_YES;
800  /* Shadow record, figure out if we have a not expired active record */
801  for (unsigned int k = 0; k < rd_count; k++)
802  {
803  if (k == i)
804  continue;
805  if (rd[i].expiration_time < now.abs_value_us)
806  include_record = GNUNET_NO; /* Shadow record is expired */
807  if ((rd[k].record_type == rd[i].record_type) &&
808  (rd[k].expiration_time >= now.abs_value_us) &&
809  (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW)))
810  {
811  include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
813  "Ignoring shadow record\n");
814  break;
815  }
816  }
817  if (GNUNET_YES == include_record)
818  {
819  rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW; /* Remove Flag */
820  if (j != i)
821  rd[j] = rd[i];
822  j++;
823  }
824  }
825  else if (rd[i].expiration_time >= now.abs_value_us)
826  {
827  /* Include this record */
828  if (j != i)
829  rd[j] = rd[i];
830  j++;
831  }
832  else
833  {
834  struct GNUNET_TIME_Absolute at;
835 
838  "Excluding record that expired %s (%llu ago)\n",
840  (unsigned long long) rd[i].expiration_time
841  - now.abs_value_us);
842  }
843  }
844  rd_count = j;
845  if (NULL != proc)
846  proc (proc_cls,
847  rd_count,
848  (0 != rd_count) ? rd : NULL);
849  }
850  }
851  return GNUNET_OK;
852 }
853 
854 
856 block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
857  const struct
859  const char *label,
861  void *proc_cls)
862 {
863  size_t payload_len = ntohl (block->size) - sizeof (struct
865  unsigned char nonce[crypto_secretbox_NONCEBYTES];
866  unsigned char key[crypto_secretbox_KEYBYTES];
867 
868  if (ntohl (block->size) <
869  sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
870  + sizeof(struct GNUNET_TIME_AbsoluteNBO))
871  {
872  GNUNET_break_op (0);
873  return GNUNET_SYSERR;
874  }
876  key,
877  label,
879  zone_key);
880  {
881  char payload[payload_len];
882  unsigned int rd_count;
883 
885  eddsa_symmetric_decrypt (&block[1], payload_len,
886  key, nonce,
887  payload));
888  payload_len -= crypto_secretbox_MACBYTES;
890  payload);
891  if (rd_count > 2048)
892  {
893  /* limit to sane value */
894  GNUNET_break_op (0);
895  return GNUNET_SYSERR;
896  }
897  {
899  unsigned int j;
900  struct GNUNET_TIME_Absolute now;
901 
902  if (GNUNET_OK !=
904  payload,
905  rd_count,
906  rd))
907  {
908  GNUNET_break_op (0);
909  return GNUNET_SYSERR;
910  }
911  /* hide expired records */
912  now = GNUNET_TIME_absolute_get ();
913  j = 0;
914  for (unsigned int i = 0; i < rd_count; i++)
915  {
916  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
917  {
918  /* encrypted blocks must never have relative expiration times, skip! */
919  GNUNET_break_op (0);
920  continue;
921  }
922 
923  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW))
924  {
925  int include_record = GNUNET_YES;
926  /* Shadow record, figure out if we have a not expired active record */
927  for (unsigned int k = 0; k < rd_count; k++)
928  {
929  if (k == i)
930  continue;
931  if (rd[i].expiration_time < now.abs_value_us)
932  include_record = GNUNET_NO; /* Shadow record is expired */
933  if ((rd[k].record_type == rd[i].record_type) &&
934  (rd[k].expiration_time >= now.abs_value_us) &&
935  (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW)))
936  {
937  include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
939  "Ignoring shadow record\n");
940  break;
941  }
942  }
943  if (GNUNET_YES == include_record)
944  {
945  rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW; /* Remove Flag */
946  if (j != i)
947  rd[j] = rd[i];
948  j++;
949  }
950  }
951  else if (rd[i].expiration_time >= now.abs_value_us)
952  {
953  /* Include this record */
954  if (j != i)
955  rd[j] = rd[i];
956  j++;
957  }
958  else
959  {
960  struct GNUNET_TIME_Absolute at;
961 
964  "Excluding record that expired %s (%llu ago)\n",
966  (unsigned long long) rd[i].expiration_time
967  - now.abs_value_us);
968  }
969  }
970  rd_count = j;
971  if (NULL != proc)
972  proc (proc_cls,
973  rd_count,
974  (0 != rd_count) ? rd : NULL);
975  }
976  }
977  return GNUNET_OK;
978 }
979 
980 
983  const struct
985  const char *label,
987  void *proc_cls)
988 {
990  char *norm_label;
991 
992  norm_label = GNUNET_GNSRECORD_string_normalize (label);
993  switch (ntohl (zone_key->type))
994  {
996  res = block_decrypt_ecdsa (block,
997  &zone_key->ecdsa_key, norm_label, proc,
998  proc_cls);
999  break;
1001  res = block_decrypt_eddsa (block,
1002  &zone_key->eddsa_key, norm_label, proc,
1003  proc_cls);
1004  break;
1005  default:
1006  res = GNUNET_SYSERR;
1007  }
1008  GNUNET_free (norm_label);
1009  return res;
1010 }
1011 
1012 
1020 void
1023  const char *label,
1024  struct GNUNET_HashCode *query)
1025 {
1026  char *norm_label;
1028 
1029  norm_label = GNUNET_GNSRECORD_string_normalize (label);
1030  switch (ntohl (zone->type))
1031  {
1034 
1036  &pub);
1038  norm_label,
1039  query);
1040  break;
1041  default:
1042  GNUNET_assert (0);
1043  }
1044  GNUNET_free (norm_label);
1045 }
1046 
1047 
1048 void
1051  const char *label,
1052  struct GNUNET_HashCode *query)
1053 {
1054  char *norm_label;
1055  struct GNUNET_IDENTITY_PublicKey pd;
1056 
1057  norm_label = GNUNET_GNSRECORD_string_normalize (label);
1058 
1059  switch (ntohl (pub->type))
1060  {
1062  pd.type = pub->type;
1064  norm_label,
1065  "gns",
1066  &pd.ecdsa_key);
1068  sizeof (pd.ecdsa_key),
1069  query);
1070  break;
1072  pd.type = pub->type;
1074  norm_label,
1075  "gns",
1076  &(pd.eddsa_key));
1078  sizeof (pd.eddsa_key),
1079  query);
1080  break;
1081  default:
1082  GNUNET_assert (0);
1083  }
1084  GNUNET_free (norm_label);
1085 }
1086 
1087 
1088 /* end of gnsrecord_crypto.c */
#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.
#define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN
Signature of a gnunet naming system record block (GNUnet-GNSRECORD)
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)
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)
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)
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)
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 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.
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)
API for GNS record-related crypto.
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:101
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 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.
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
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.
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:643
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:702
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.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SHADOW
This record should not be used unless all (other) records in the set with an absolute expiration time...
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.
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.
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.
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().
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:70
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:179
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
#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).
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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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:111
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
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
static unsigned int size
Size of the "table".
Definition: peer.c:68
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.