GNUnet  0.20.0
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 
198 
200 block_sign_ecdsa (const struct
202  const struct
204  const char *label,
205  struct GNUNET_GNSRECORD_Block *block)
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 }
238 
239 
241 block_sign_eddsa (const struct
243  const struct
245  const char *label,
246  struct GNUNET_GNSRECORD_Block *block)
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 }
272 
273 
275 GNUNET_GNSRECORD_block_sign (const struct
277  const char *label,
278  struct GNUNET_GNSRECORD_Block *block)
279 {
282  char *norm_label;
283 
285  &pkey);
286  norm_label = GNUNET_GNSRECORD_string_normalize (label);
287 
288  switch (ntohl (key->type))
289  {
291  res = block_sign_ecdsa (&key->ecdsa_key,
292  &pkey.ecdsa_key,
293  norm_label,
294  block);
295  break;
297  res = block_sign_eddsa (&key->eddsa_key,
298  &pkey.eddsa_key,
299  norm_label,
300  block);
301  break;
302  default:
303  GNUNET_assert (0);
304  }
305  GNUNET_free (norm_label);
306  return res;
307 }
308 
309 
323 static enum GNUNET_GenericReturnValue
325  const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
327  const char *label,
328  const struct GNUNET_GNSRECORD_Data *rd,
329  unsigned int rd_count,
330  struct GNUNET_GNSRECORD_Block **block,
331  int sign)
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 }
403 
404 
405 static ssize_t
407  unsigned int rd_count)
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 }
418 
419 
435  const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
437  const char *label,
438  const struct GNUNET_GNSRECORD_Data *rd,
439  unsigned int rd_count,
440  struct GNUNET_GNSRECORD_Block **block,
441  int sign)
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 }
509 
510 
511 ssize_t
514  const struct GNUNET_GNSRECORD_Data *rd,
515  unsigned int rd_count)
516 {
518  ssize_t res = -1;
519 
521  &pkey);
522  switch (ntohl (key->type))
523  {
526  break;
529  break;
530  default:
531  GNUNET_assert (0);
532  }
533  return res;
534 
535 }
536 
537 
541  const char *label,
542  const struct GNUNET_GNSRECORD_Data *rd,
543  unsigned int rd_count,
545 {
548  char *norm_label;
549 
551  &pkey);
552  norm_label = GNUNET_GNSRECORD_string_normalize (label);
553 
554  switch (ntohl (key->type))
555  {
557  res = block_create_ecdsa (&key->ecdsa_key,
558  &pkey.ecdsa_key,
559  expire,
560  norm_label,
561  rd,
562  rd_count,
563  result,
564  GNUNET_YES);
565  break;
567  res = block_create_eddsa (&key->eddsa_key,
568  &pkey.eddsa_key,
569  expire,
570  norm_label,
571  rd,
572  rd_count,
573  result,
574  GNUNET_YES);
575  break;
576  default:
577  GNUNET_assert (0);
578  }
579  GNUNET_free (norm_label);
580  return res;
581 }
582 
583 
588 {
593 
598 };
599 
600 
601 static enum GNUNET_GenericReturnValue
604  const char *label,
605  const struct GNUNET_GNSRECORD_Data *rd,
606  unsigned int rd_count,
608  int sign)
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 }
660 
661 
666  const char *label,
667  const struct GNUNET_GNSRECORD_Data *rd,
668  unsigned int rd_count,
670 {
671  return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_NO);
672 }
673 
674 
678  const char *label,
679  const struct GNUNET_GNSRECORD_Data *rd,
680  unsigned int rd_count,
682 {
683  return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_YES);
684 }
685 
686 
696 {
697  struct GNRBlockPS *purp;
698  size_t payload_len = ntohl (block->size)
699  - sizeof (struct GNUNET_GNSRECORD_Block);
701  purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
702  purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
704  GNUNET_memcpy (&purp[1],
705  &block[1],
706  payload_len);
707  switch (ntohl (block->type))
708  {
713  &purp->purpose,
714  &block->ecdsa_block.signature,
715  &block->ecdsa_block.derived_key);
716  break;
721  &purp->purpose,
722  &block->eddsa_block.signature,
723  &block->eddsa_block.derived_key);
724  break;
725  default:
726  res = GNUNET_NO;
727  }
728  GNUNET_free (purp);
729  return res;
730 }
731 
732 
734 block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
735  const struct
737  const char *label,
739  void *proc_cls)
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 }
856 
857 
859 block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
860  const struct
862  const char *label,
864  void *proc_cls)
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 }
982 
983 
986  const struct
988  const char *label,
990  void *proc_cls)
991 {
993  char *norm_label;
994 
995  norm_label = GNUNET_GNSRECORD_string_normalize (label);
996  switch (ntohl (zone_key->type))
997  {
999  res = block_decrypt_ecdsa (block,
1000  &zone_key->ecdsa_key, norm_label, proc,
1001  proc_cls);
1002  break;
1004  res = block_decrypt_eddsa (block,
1005  &zone_key->eddsa_key, norm_label, proc,
1006  proc_cls);
1007  break;
1008  default:
1009  res = GNUNET_SYSERR;
1010  }
1011  GNUNET_free (norm_label);
1012  return res;
1013 }
1014 
1015 
1023 void
1026  const char *label,
1027  struct GNUNET_HashCode *query)
1028 {
1029  char *norm_label;
1031 
1032  norm_label = GNUNET_GNSRECORD_string_normalize (label);
1033  switch (ntohl (zone->type))
1034  {
1037 
1039  &pub);
1041  norm_label,
1042  query);
1043  break;
1044  default:
1045  GNUNET_assert (0);
1046  }
1047  GNUNET_free (norm_label);
1048 }
1049 
1050 
1051 void
1054  const char *label,
1055  struct GNUNET_HashCode *query)
1056 {
1057  char *norm_label;
1058  struct GNUNET_IDENTITY_PublicKey pd;
1059 
1060  norm_label = GNUNET_GNSRECORD_string_normalize (label);
1061 
1062  switch (ntohl (pub->type))
1063  {
1065  pd.type = pub->type;
1067  norm_label,
1068  "gns",
1069  &pd.ecdsa_key);
1071  sizeof (pd.ecdsa_key),
1072  query);
1073  break;
1075  pd.type = pub->type;
1077  norm_label,
1078  "gns",
1079  &(pd.eddsa_key));
1081  sizeof (pd.eddsa_key),
1082  query);
1083  break;
1084  default:
1085  GNUNET_assert (0);
1086  }
1087  GNUNET_free (norm_label);
1088 }
1089 
1090 
1091 /* 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
GNS zone delegation (EDKEY)
#define GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN
GNS record set signature (GNS)
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:198
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:631
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:187
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:690
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_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.
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.
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.