GNUnet  0.17.6
gnunet-gnsrecord-tvg.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020 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 
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_signatures.h"
29 #include "gnunet_gns_service.h"
30 #include "gnunet_gnsrecord_lib.h"
31 #include "gnunet_dnsparser_lib.h"
32 #include "gnunet_testing_lib.h"
33 #include <inttypes.h>
34 #include "gnsrecord_crypto.h"
35 
36 
37 static char *d_pkey =
38  "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
39 
40 static char *d_edkey =
41  "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
42 
43 
44 static int
45 parsehex (char *src, char *dst, size_t dstlen, int invert)
46 {
47  char *line = src;
48  char *data = line;
49  int off;
50  int read_byte;
51  int data_len = 0;
52 
53  while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
54  {
55  if (invert)
56  dst[dstlen - 1 - data_len++] = read_byte;
57  else
58  dst[data_len++] = read_byte;
59  data += off;
60  }
61  return data_len;
62 }
63 
64 
65 static void
67  size_t buf_len,
68  int fold,
69  int in_be)
70 {
71  int i;
72 
73  for (i = 0; i < buf_len; i++)
74  {
75  if ((0 != i) && (0 != fold) && (i % fold == 0))
76  printf ("\n");
77  if (in_be)
78  printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
79  else
80  printf ("%02x", ((unsigned char*) buf)[i]);
81  }
82  printf ("\n");
83 }
84 
85 
86 static void
88  size_t buf_len,
89  int fold)
90 {
91  print_bytes_ (buf, buf_len, fold, 0);
92 }
93 
94 
95 static void
97 {
98  uint16_t flags = htons (rd->flags);
99  uint64_t abs_nbo = GNUNET_htonll (rd->expiration_time);
100  uint16_t size_nbo = htons (rd->data_size);
101  uint32_t type_nbo = htonl (rd->record_type);
102  printf ("EXPIRATION:\n");
103  print_bytes (&abs_nbo, sizeof (abs_nbo), 8);
104  printf ("\nDATA_SIZE:\n");
105  print_bytes (&size_nbo, sizeof (size_nbo), 8);
106  printf ("\nTYPE:\n");
107  print_bytes (&type_nbo, sizeof (type_nbo), 8);
108  printf ("\nFLAGS: ");
109  print_bytes ((void*) &flags, sizeof (flags), 8);
110  printf ("\n");
111  fprintf (stdout,
112  "DATA:\n");
113  print_bytes ((char*) rd->data, rd->data_size, 8);
114  printf ("\n");
115 }
116 
117 
126 static void
127 run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label)
128 {
130  struct GNUNET_GNSRECORD_Block *rrblock;
131  char *bdata;
132  struct GNUNET_IDENTITY_PrivateKey id_priv;
133  struct GNUNET_IDENTITY_PublicKey id_pub;
134  struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
135  struct GNUNET_IDENTITY_PublicKey pkey_data;
136  struct GNUNET_HashCode query;
137  char *rdata;
138  char *conv_lbl;
139  size_t rdata_size;
140  char ztld[128];
141  unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
142  unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
143 
144  id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
146  parsehex (d_pkey,
147  (char*) &id_priv.ecdsa_key,
148  sizeof (id_priv.ecdsa_key), 1);
149 
151  &id_pub);
152  printf ("Zone private key (d, big-endian):\n");
153  print_bytes_ (&id_priv.ecdsa_key,
154  sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1);
155  printf ("\n");
156  printf ("Zone identifier (ztype|zkey):\n");
158  print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
161  ztld,
162  sizeof (ztld));
163  printf ("\n");
164  printf ("zTLD:\n");
165  printf ("%s\n", ztld);
166  printf ("\n");
167 
168  pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
170  GNUNET_IDENTITY_key_get_public (&pkey_data_p,
171  &pkey_data);
172  conv_lbl = GNUNET_GNSRECORD_string_normalize (label);
173  printf ("Label:\n");
174  print_bytes (conv_lbl, strlen (conv_lbl), 8);
175  GNUNET_free (conv_lbl);
176  printf ("\nNumber of records (integer): %d\n\n", rd_count);
177 
178  for (int i = 0; i < rd_count; i++)
179  {
180  printf ("Record #%d := (\n", i);
181  print_record (&rd[i]);
182  printf (")\n\n");
183  }
184 
185  rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count,
186  rd);
187  rdata = GNUNET_malloc (rdata_size);
189  rd,
190  (size_t) rdata_size,
191  rdata);
192  printf ("RDATA:\n");
193  print_bytes (rdata,
194  (size_t) rdata_size,
195  8);
196  printf ("\n");
200  skey,
201  label,
203  expire).abs_value_us__,
204  &id_pub.ecdsa_key);
205 
206  printf ("Encryption NONCE|EXPIRATION|BLOCK COUNTER:\n");
207  print_bytes (ctr, sizeof (ctr), 8);
208  printf ("\n");
209  printf ("Encryption key (K):\n");
210  print_bytes (skey, sizeof (skey), 8);
211  printf ("\n");
213  label,
214  &query);
215  printf ("Storage key (q):\n");
216  print_bytes (&query, sizeof (query), 8);
217  printf ("\n");
219  expire,
220  label,
221  rd,
222  rd_count,
223  &rrblock));
224  size_t bdata_size = ntohl (rrblock->size) - sizeof (struct
226 
227  bdata = (char*) &(&rrblock->ecdsa_block)[1];
228  printf ("BDATA:\n");
229  print_bytes (bdata, bdata_size, 8);
230  printf ("\n");
231  printf ("RRBLOCK:\n");
232  print_bytes (rrblock, ntohl (rrblock->size), 8);
233  printf ("\n");
234  GNUNET_free (rdata);
235 }
236 
237 
246 static void
247 run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label)
248 {
250  struct GNUNET_GNSRECORD_Block *rrblock;
251  char *bdata;
252  struct GNUNET_IDENTITY_PrivateKey id_priv;
253  struct GNUNET_IDENTITY_PublicKey id_pub;
254  struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
255  struct GNUNET_IDENTITY_PublicKey pkey_data;
256  struct GNUNET_HashCode query;
257  char *rdata;
258  char *conv_lbl;
259  size_t rdata_size;
260 
261  char ztld[128];
262  unsigned char nonce[crypto_secretbox_NONCEBYTES];
263  unsigned char skey[crypto_secretbox_KEYBYTES];
264 
265  id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
268  &id_pub);
269 
270  id_priv.type = htonl (GNUNET_IDENTITY_TYPE_EDDSA);
272  parsehex (d_edkey,
273  (char*) &id_priv.eddsa_key,
274  sizeof (id_priv.eddsa_key), 0);
276  &id_pub);
277  fprintf (stdout,
278  "Zone private key (d):\n");
279  print_bytes (&id_priv.eddsa_key, sizeof (struct
281  printf ("\n");
282  printf ("Zone identifier (ztype|zkey):\n");
284  print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
287  ztld,
288  sizeof (ztld));
289  printf ("\n");
290  printf ("zTLD:\n");
291  printf ("%s\n", ztld);
292  printf ("\n");
293 
294  pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
296  GNUNET_IDENTITY_key_get_public (&pkey_data_p,
297  &pkey_data);
298  conv_lbl = GNUNET_GNSRECORD_string_normalize (label);
299  printf ("Label:\n");
300  print_bytes (conv_lbl, strlen (conv_lbl), 8);
301  GNUNET_free (conv_lbl);
302  fprintf (stdout,
303  "\nNumber of records (integer): %d\n\n", rd_count);
304 
305  for (int i = 0; i < rd_count; i++)
306  {
307  printf ("Record #%d := (\n", i);
308  print_record (&rd[i]);
309  printf (")\n\n");
310  }
311 
312  rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count,
313  rd);
315  rd,
317  GNUNET_assert (0 < rdata_size);
318  rdata = GNUNET_malloc ((size_t) rdata_size);
320  rd,
321  (size_t) rdata_size,
322  rdata);
323  printf ("RDATA:\n");
324  print_bytes (rdata,
325  (size_t) rdata_size,
326  8);
327  printf ("\n");
329  skey,
330  label,
332  expire).abs_value_us__,
333  &id_pub.eddsa_key);
334  printf ("Encryption NONCE|EXPIRATION:\n");
335  print_bytes (nonce, sizeof (nonce), 8);
336  printf ("\n");
337  printf ("Encryption key (K):\n");
338  print_bytes (skey, sizeof (skey), 8);
339  printf ("\n");
341  label,
342  &query);
343  printf ("Storage key (q):\n");
344  print_bytes (&query, sizeof (query), 8);
345  printf ("\n");
346 
348  expire,
349  label,
350  rd,
351  rd_count,
352  &rrblock));
353  size_t bdata_size = ntohl (rrblock->size) - sizeof (struct
355 
356  bdata = (char*) &(&rrblock->eddsa_block)[1];
357  printf ("BDATA:\n");
358  print_bytes (bdata, bdata_size, 8);
359  printf ("\n");
360  printf ("RRBLOCK:\n");
361  print_bytes (rrblock, ntohl (rrblock->size), 8);
362  printf ("\n");
363  GNUNET_free (rdata);
364 }
365 
366 
375 static void
376 run (void *cls,
377  char *const *args,
378  const char *cfgfile,
379  const struct GNUNET_CONFIGURATION_Handle *cfg)
380 {
381  struct GNUNET_GNSRECORD_Data rd_pkey;
382  struct GNUNET_GNSRECORD_Data rd[3];
383  struct GNUNET_TIME_Absolute exp1;
384  struct GNUNET_TIME_Absolute exp2;
385  struct GNUNET_TIME_Relative exp3;
386  size_t pkey_data_size;
387  size_t ip_data_size;
388  char *pkey_data;
389  char *ip_data;
390 
391  /*
392  * Make different expiration times
393  */
394  GNUNET_STRINGS_fancy_time_to_absolute ("2048-01-23 10:51:34",
395  &exp1);
396  GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01",
397  &exp2);
399  &exp3);
400 
401 
402  memset (&rd_pkey, 0, sizeof (struct GNUNET_GNSRECORD_Data));
405  "000G0011WESGZY9VRV9NNJ66W3GKNZFZF56BFD2BQF3MHMJST2G2GKDYGG",
406  (void**) &pkey_data,
407  &pkey_data_size));
408  rd_pkey.data = pkey_data;
409  rd_pkey.data_size = pkey_data_size;
410  rd_pkey.expiration_time = exp1.abs_value_us;
415  "::dead:beef",
416  (void**) &ip_data,
417  &ip_data_size));
418 
419  rd[0].data = ip_data;
420  rd[0].data_size = ip_data_size;
421  rd[0].expiration_time = exp1.abs_value_us;
424 
425  rd[1].data = "\u611b\u79f0";
426  rd[1].data_size = strlen (rd[1].data);
427  rd[1].expiration_time = exp2.abs_value_us;
430 
431  rd[2].data = "Hello World";
432  rd[2].data_size = strlen (rd[2].data);
433  rd[2].expiration_time = exp3.rel_value_us;
437 
438  run_pkey (&rd_pkey, 1, "testdelegation");
439  run_pkey (rd, 3, "\u5929\u4e0b\u7121\u6575");
440  run_edkey (&rd_pkey, 1, "testdelegation");
441  run_edkey (rd, 3, "\u5929\u4e0b\u7121\u6575");
442 }
443 
444 
452 int
453 main (int argc,
454  char *const *argv)
455 {
456  const struct GNUNET_GETOPT_CommandLineOption options[] = {
458  };
459 
461  GNUNET_log_setup ("gnunet-gns-tvg",
462  "INFO",
463  NULL));
464  if (GNUNET_OK !=
465  GNUNET_PROGRAM_run (argc, argv,
466  "gnunet-gns-tvg",
467  "Generate test vectors for GNS",
468  options,
469  &run, NULL))
470  return 1;
471  return 0;
472 }
473 
474 
475 /* end of gnunet-gns-tvg.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define GNUNET_GNSRECORD_TYPE_NICK
GNS nick names.
#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.
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.
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.
API for GNS record-related crypto.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static char * line
Desired phone line (string to be converted to a hash).
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:101
static void print_bytes_(void *buf, size_t buf_len, int fold, int in_be)
static int parsehex(char *src, char *dst, size_t dstlen, int invert)
static void print_bytes(void *buf, size_t buf_len, int fold)
static char * d_edkey
static void print_record(const struct GNUNET_GNSRECORD_Data *rd)
static char * d_pkey
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run.
int main(int argc, char *const *argv)
The main function of the test vector generation tool.
static void run_pkey(struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label)
Main function that will be run.
static void run_edkey(struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label)
Main function that will be run.
uint32_t data
The data value.
static char buf[2048]
API for helper library to parse DNS packets.
API to the GNS service.
API that can be used to manipulate GNS record data.
Convenience API for writing testcases for GNUnet.
void GNUNET_CRYPTO_eddsa_key_create(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:461
void GNUNET_CRYPTO_ecdsa_key_create(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:446
#define GNUNET_DNSPARSER_TYPE_AAAA
#define GNUNET_DNSPARSER_TYPE_TXT
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
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.
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.
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.
int GNUNET_GNSRECORD_string_to_value(uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of a 'value' of a record to the binary representation.
Definition: gnsrecord.c:188
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_record_get_expiration_time(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute min)
Returns the expiration time of the given block of records.
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_CRITICAL
This record is critical.
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be handed out to other peers.
@ GNUNET_GNSRECORD_RF_NONE
No special options.
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
ssize_t GNUNET_IDENTITY_key_get_length(const struct GNUNET_IDENTITY_PublicKey *key)
Get the compacted length of a GNUNET_IDENTITY_PublicKey.
Definition: identity_api.c:991
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
#define GNUNET_CRYPTO_AES_KEY_LENGTH
length of the sessionkey in bytes (256 BIT sessionkey)
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
@ GNUNET_OK
Definition: gnunet_common.h:99
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:399
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:709
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:261
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_absolute(const char *fancy_time, struct GNUNET_TIME_Absolute *atime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:303
Private ECC key encoded for transmission.
Private ECC key encoded for transmission.
Definition of a command line option.
struct GNUNET_GNSRECORD_EcdsaBlock ecdsa_block
struct GNUNET_GNSRECORD_EddsaBlock eddsa_block
uint32_t size
Size of the block.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
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.
struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_key
An ECDSA identity key.
struct GNUNET_CRYPTO_EddsaPublicKey eddsa_key
AN EdDSA identtiy key.
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.
uint64_t rel_value_us
The actual value.