aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gnsrecord/gnunet-gnsrecord-tvg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gnsrecord/gnunet-gnsrecord-tvg.c')
-rw-r--r--src/lib/gnsrecord/gnunet-gnsrecord-tvg.c539
1 files changed, 539 insertions, 0 deletions
diff --git a/src/lib/gnsrecord/gnunet-gnsrecord-tvg.c b/src/lib/gnsrecord/gnunet-gnsrecord-tvg.c
new file mode 100644
index 000000000..746e95c32
--- /dev/null
+++ b/src/lib/gnsrecord/gnunet-gnsrecord-tvg.c
@@ -0,0 +1,539 @@
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
21/**
22 * @file util/gnunet-gns-tvg.c
23 * @brief Generate test vectors for GNS.
24 * @author Martin Schanzenbach
25 */
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_testing_lib.h"
32#include "gnsrecord_crypto.h"
33#include <inttypes.h>
34
35
36static char *d_pkey =
37 "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
38
39static char *d_edkey =
40 "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
41
42
43static int
44parsehex (char *src, char *dst, size_t dstlen, int invert)
45{
46 char *line = src;
47 char *data = line;
48 int off;
49 int read_byte;
50 int data_len = 0;
51
52 while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
53 {
54 if (invert)
55 dst[dstlen - 1 - data_len++] = read_byte;
56 else
57 dst[data_len++] = read_byte;
58 data += off;
59 }
60 return data_len;
61}
62
63
64static void
65print_bytes_ (void *buf,
66 size_t buf_len,
67 int fold,
68 int in_be)
69{
70 int i;
71
72 for (i = 0; i < buf_len; i++)
73 {
74 if (0 != i)
75 {
76 if ((0 != fold) && (i % fold == 0))
77 printf ("\n ");
78 else
79 printf (" ");
80 }
81 else
82 {
83 printf (" ");
84 }
85 if (in_be)
86 printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
87 else
88 printf ("%02x", ((unsigned char*) buf)[i]);
89 }
90 printf ("\n");
91}
92
93
94static void
95print_bytes (void *buf,
96 size_t buf_len,
97 int fold)
98{
99 print_bytes_ (buf, buf_len, fold, 0);
100}
101
102
103static void
104print_record (const struct GNUNET_GNSRECORD_Data *rd)
105{
106 struct GNUNET_TIME_Relative rt;
107 struct GNUNET_TIME_Absolute at;
108 uint16_t flags = htons (rd->flags);
109 uint64_t abs_nbo = GNUNET_htonll (rd->expiration_time);
110 uint16_t size_nbo = htons (rd->data_size);
111 uint32_t type_nbo = htonl (rd->record_type);
112 at.abs_value_us = GNUNET_ntohll (abs_nbo);
113 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
114 {
115 rt.rel_value_us = rd->expiration_time;
116 at = GNUNET_TIME_relative_to_absolute (rt);
117 abs_nbo = GNUNET_htonll (at.abs_value_us);
118 }
119 printf (" EXPIRATION: %" PRIu64 " us\n", rd->expiration_time);
120 print_bytes (&abs_nbo, sizeof (abs_nbo), 8);
121 printf ("\n DATA_SIZE:\n");
122 print_bytes (&size_nbo, sizeof (size_nbo), 8);
123 printf ("\n TYPE:\n");
124 print_bytes (&type_nbo, sizeof (type_nbo), 8);
125 printf ("\n FLAGS: ");
126 print_bytes ((void*) &flags, sizeof (flags), 8);
127 printf ("\n");
128 fprintf (stdout,
129 " DATA:\n");
130 print_bytes ((char*) rd->data, rd->data_size, 8);
131 printf ("\n");
132}
133
134
135/**
136 * Main function that will be run.
137 *
138 * @param cls closure
139 * @param args remaining command-line arguments
140 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
141 * @param cfg configuration
142 */
143static void
144run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label)
145{
146 struct GNUNET_TIME_Absolute expire;
147 struct GNUNET_GNSRECORD_Block *rrblock;
148 char *bdata;
149 struct GNUNET_CRYPTO_PrivateKey id_priv;
150 struct GNUNET_CRYPTO_PublicKey id_pub;
151 struct GNUNET_CRYPTO_PrivateKey pkey_data_p;
152 struct GNUNET_CRYPTO_PublicKey pkey_data;
153 struct GNUNET_HashCode query;
154 char *rdata;
155 char *conv_lbl;
156 size_t rdata_size;
157 char ztld[128];
158 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
159 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
160
161 id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
162 GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
163 parsehex (d_pkey,
164 (char*) &id_priv.ecdsa_key,
165 sizeof (id_priv.ecdsa_key), 1);
166
167 GNUNET_CRYPTO_key_get_public (&id_priv,
168 &id_pub);
169 printf ("Zone private key (d, big-endian):\n");
170 print_bytes_ (&id_priv.ecdsa_key,
171 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1);
172 printf ("\n");
173 printf ("Zone identifier (ztype|zkey):\n");
174 GNUNET_assert (0 < GNUNET_CRYPTO_public_key_get_length (&id_pub));
175 print_bytes (&id_pub, GNUNET_CRYPTO_public_key_get_length (&id_pub), 8);
176 GNUNET_STRINGS_data_to_string (&id_pub,
177 GNUNET_CRYPTO_public_key_get_length (
178 &id_pub),
179 ztld,
180 sizeof (ztld));
181 printf ("\n");
182 printf ("zTLD:\n");
183 printf ("%s\n", ztld);
184 printf ("\n");
185
186 pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
187 GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key);
188 GNUNET_CRYPTO_key_get_public (&pkey_data_p,
189 &pkey_data);
190 conv_lbl = GNUNET_GNSRECORD_string_normalize (label);
191 printf ("Label:\n");
192 print_bytes (conv_lbl, strlen (conv_lbl), 8);
193 GNUNET_free (conv_lbl);
194 printf ("\nNumber of records (integer): %d\n\n", rd_count);
195
196 for (int i = 0; i < rd_count; i++)
197 {
198 printf ("Record #%d := (\n", i);
199 print_record (&rd[i]);
200 printf (")\n\n");
201 }
202
203 rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count,
204 rd);
205 rdata = GNUNET_malloc (rdata_size);
206 GNUNET_GNSRECORD_records_serialize (rd_count,
207 rd,
208 (size_t) rdata_size,
209 rdata);
210 printf ("RDATA:\n");
211 print_bytes (rdata,
212 (size_t) rdata_size,
213 8);
214 printf ("\n");
215 expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count, rd,
216 GNUNET_TIME_UNIT_ZERO_ABS);
217 GNR_derive_block_aes_key (ctr,
218 skey,
219 label,
220 GNUNET_TIME_absolute_hton (
221 expire).abs_value_us__,
222 &id_pub.ecdsa_key);
223
224 printf ("Encryption NONCE|EXPIRATION|BLOCK COUNTER:\n");
225 print_bytes (ctr, sizeof (ctr), 8);
226 printf ("\n");
227 printf ("Encryption key (K):\n");
228 print_bytes (skey, sizeof (skey), 8);
229 printf ("\n");
230 GNUNET_GNSRECORD_query_from_public_key (&id_pub,
231 label,
232 &query);
233 printf ("Storage key (q):\n");
234 print_bytes (&query, sizeof (query), 8);
235 printf ("\n");
236 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
237 expire,
238 label,
239 rd,
240 rd_count,
241 &rrblock));
242 struct GNUNET_CRYPTO_EcdsaPublicKey derived_key;
243 struct GNUNET_CRYPTO_EcdsaPrivateKey *derived_privkey;
244
245 GNUNET_CRYPTO_ecdsa_public_key_derive (&id_pub.ecdsa_key,
246 label,
247 "gns",
248 &derived_key);
249 derived_privkey = GNUNET_CRYPTO_ecdsa_private_key_derive (&id_priv.ecdsa_key,
250 label,
251 "gns");
252 printf ("ZKDF(zkey):\n");
253 print_bytes (&derived_key, sizeof (derived_key), 8);
254 printf ("\n");
255 printf ("Derived private key (d', big-endian):\n");
256 print_bytes_ (derived_privkey, sizeof (*derived_privkey), 8, 1);
257 printf ("\n");
258 size_t bdata_size = ntohl (rrblock->size) - sizeof (struct
259 GNUNET_GNSRECORD_Block);
260
261 GNUNET_free (derived_privkey);
262
263 bdata = (char*) &(&rrblock->ecdsa_block)[1];
264 printf ("BDATA:\n");
265 print_bytes (bdata, bdata_size, 8);
266 printf ("\n");
267 printf ("RRBLOCK:\n");
268 print_bytes (rrblock, ntohl (rrblock->size), 8);
269 printf ("\n");
270 GNUNET_free (rdata);
271}
272
273
274/**
275 * Main function that will be run.
276 *
277 * @param cls closure
278 * @param args remaining command-line arguments
279 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
280 * @param cfg configuration
281 */
282static void
283run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label)
284{
285 struct GNUNET_TIME_Absolute expire;
286 struct GNUNET_GNSRECORD_Block *rrblock;
287 char *bdata;
288 struct GNUNET_CRYPTO_PrivateKey id_priv;
289 struct GNUNET_CRYPTO_PublicKey id_pub;
290 struct GNUNET_CRYPTO_PrivateKey pkey_data_p;
291 struct GNUNET_CRYPTO_PublicKey pkey_data;
292 struct GNUNET_HashCode query;
293 char *rdata;
294 char *conv_lbl;
295 size_t rdata_size;
296
297 char ztld[128];
298 unsigned char nonce[crypto_secretbox_NONCEBYTES];
299 unsigned char skey[crypto_secretbox_KEYBYTES];
300
301 id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
302 GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
303 GNUNET_CRYPTO_key_get_public (&id_priv,
304 &id_pub);
305
306 id_priv.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA);
307 GNUNET_CRYPTO_eddsa_key_create (&id_priv.eddsa_key);
308 parsehex (d_edkey,
309 (char*) &id_priv.eddsa_key,
310 sizeof (id_priv.eddsa_key), 0);
311 GNUNET_CRYPTO_key_get_public (&id_priv,
312 &id_pub);
313 fprintf (stdout,
314 "Zone private key (d):\n");
315 print_bytes (&id_priv.eddsa_key, sizeof (struct
316 GNUNET_CRYPTO_EddsaPrivateKey), 8);
317 printf ("\n");
318 printf ("Zone identifier (ztype|zkey):\n");
319 GNUNET_assert (0 < GNUNET_CRYPTO_public_key_get_length (&id_pub));
320 print_bytes (&id_pub, GNUNET_CRYPTO_public_key_get_length (&id_pub), 8);
321 GNUNET_STRINGS_data_to_string (&id_pub,
322 GNUNET_CRYPTO_public_key_get_length (
323 &id_pub),
324 ztld,
325 sizeof (ztld));
326 printf ("\n");
327 printf ("zTLD:\n");
328 printf ("%s\n", ztld);
329 printf ("\n");
330
331 pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
332 GNUNET_CRYPTO_eddsa_key_create (&pkey_data_p.eddsa_key);
333 GNUNET_CRYPTO_key_get_public (&pkey_data_p,
334 &pkey_data);
335 conv_lbl = GNUNET_GNSRECORD_string_normalize (label);
336 printf ("Label:\n");
337 print_bytes (conv_lbl, strlen (conv_lbl), 8);
338 GNUNET_free (conv_lbl);
339 fprintf (stdout,
340 "\nNumber of records (integer): %d\n\n", rd_count);
341
342 for (int i = 0; i < rd_count; i++)
343 {
344 printf ("Record #%d := (\n", i);
345 print_record (&rd[i]);
346 printf (")\n\n");
347 }
348
349 rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count,
350 rd);
351 expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count,
352 rd,
353 GNUNET_TIME_UNIT_ZERO_ABS);
354 GNUNET_assert (0 < rdata_size);
355 rdata = GNUNET_malloc ((size_t) rdata_size);
356 GNUNET_GNSRECORD_records_serialize (rd_count,
357 rd,
358 (size_t) rdata_size,
359 rdata);
360 printf ("RDATA:\n");
361 print_bytes (rdata,
362 (size_t) rdata_size,
363 8);
364 printf ("\n");
365 GNR_derive_block_xsalsa_key (nonce,
366 skey,
367 label,
368 GNUNET_TIME_absolute_hton (
369 expire).abs_value_us__,
370 &id_pub.eddsa_key);
371 printf ("Encryption NONCE|EXPIRATION:\n");
372 print_bytes (nonce, sizeof (nonce), 8);
373 printf ("\n");
374 printf ("Encryption key (K):\n");
375 print_bytes (skey, sizeof (skey), 8);
376 printf ("\n");
377 GNUNET_GNSRECORD_query_from_public_key (&id_pub,
378 label,
379 &query);
380 printf ("Storage key (q):\n");
381 print_bytes (&query, sizeof (query), 8);
382 printf ("\n");
383
384 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
385 expire,
386 label,
387 rd,
388 rd_count,
389 &rrblock));
390
391 struct GNUNET_CRYPTO_EddsaPublicKey derived_key;
392 struct GNUNET_CRYPTO_EddsaPrivateScalar derived_privkey;
393 GNUNET_CRYPTO_eddsa_public_key_derive (&id_pub.eddsa_key,
394 label,
395 "gns",
396 &derived_key);
397 GNUNET_CRYPTO_eddsa_private_key_derive (&id_priv.eddsa_key,
398 label,
399 "gns", &derived_privkey);
400 printf ("ZKDF(zkey):\n");
401 print_bytes (&derived_key, sizeof (derived_key), 8);
402 printf ("\n");
403 printf ("nonce := SHA-256 (dh[32..63] || h):\n");
404 print_bytes (derived_privkey.s + 32, 32, 8);
405 printf ("\n");
406 char derived_privkeyNBO[32];
407 /* Convert from little endian */
408 for (size_t i = 0; i < 32; i++)
409 derived_privkeyNBO[i] = derived_privkey.s[31 - i];
410 printf ("Derived private key (d', big-endian):\n");
411 print_bytes (derived_privkeyNBO, sizeof (derived_privkeyNBO), 8);
412 printf ("\n");
413 size_t bdata_size = ntohl (rrblock->size) - sizeof (struct
414 GNUNET_GNSRECORD_Block);
415
416
417 bdata = (char*) &(&rrblock->eddsa_block)[1];
418 printf ("BDATA:\n");
419 print_bytes (bdata, bdata_size, 8);
420 printf ("\n");
421 printf ("RRBLOCK:\n");
422 print_bytes (rrblock, ntohl (rrblock->size), 8);
423 printf ("\n");
424 GNUNET_free (rdata);
425}
426
427
428/**
429 * Main function that will be run.
430 *
431 * @param cls closure
432 * @param args remaining command-line arguments
433 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
434 * @param cfg configuration
435 */
436static void
437run (void *cls,
438 char *const *args,
439 const char *cfgfile,
440 const struct GNUNET_CONFIGURATION_Handle *cfg)
441{
442 struct GNUNET_GNSRECORD_Data rd_pkey;
443 struct GNUNET_GNSRECORD_Data rd[3];
444 struct GNUNET_TIME_Absolute exp1;
445 struct GNUNET_TIME_Absolute exp2;
446 struct GNUNET_TIME_Absolute exp3;
447 struct GNUNET_TIME_AbsoluteNBO exp1nbo;
448 struct GNUNET_TIME_AbsoluteNBO exp2nbo;
449 struct GNUNET_TIME_AbsoluteNBO exp3nbo;
450 size_t pkey_data_size;
451 size_t ip_data_size;
452 char *pkey_data;
453 char *ip_data;
454
455 /*
456 * Make different expiration times
457 */
458 parsehex ("001cee8c10e25980", (char*) &exp1nbo, sizeof (exp1nbo), 0);
459 parsehex ("003ff2aa5408db40", (char*) &exp2nbo, sizeof (exp2nbo), 0);
460 parsehex ("0028bb13ff371940", (char*) &exp3nbo, sizeof (exp3nbo), 0);
461 exp1 = GNUNET_TIME_absolute_ntoh (exp1nbo);
462 exp2 = GNUNET_TIME_absolute_ntoh (exp2nbo);
463 exp3 = GNUNET_TIME_absolute_ntoh (exp3nbo);
464
465 memset (&rd_pkey, 0, sizeof (struct GNUNET_GNSRECORD_Data));
466 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (
467 GNUNET_GNSRECORD_TYPE_PKEY,
468 "000G0011WESGZY9VRV9NNJ66W3GKNZFZF56BFD2BQF3MHMJST2G2GKDYGG",
469 (void**) &pkey_data,
470 &pkey_data_size));
471 rd_pkey.data = pkey_data;
472 rd_pkey.data_size = pkey_data_size;
473 rd_pkey.expiration_time = exp1.abs_value_us;
474 rd_pkey.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
475 rd_pkey.flags = GNUNET_GNSRECORD_RF_CRITICAL;
476 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (
477 GNUNET_DNSPARSER_TYPE_AAAA,
478 "::dead:beef",
479 (void**) &ip_data,
480 &ip_data_size));
481
482 rd[0].data = ip_data;
483 rd[0].data_size = ip_data_size;
484 rd[0].expiration_time = exp1.abs_value_us;
485 rd[0].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
486 rd[0].flags = GNUNET_GNSRECORD_RF_NONE;
487
488 rd[1].data = "\u611b\u79f0";
489 rd[1].data_size = strlen (rd[1].data);
490 rd[1].expiration_time = exp2.abs_value_us;
491 rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK;
492 rd[1].flags = GNUNET_GNSRECORD_RF_NONE;
493
494 rd[2].data = "Hello World";
495 rd[2].data_size = strlen (rd[2].data);
496 rd[2].expiration_time = exp3.abs_value_us;
497 rd[2].record_type = GNUNET_DNSPARSER_TYPE_TXT;
498 rd[2].flags = GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
499
500 run_pkey (&rd_pkey, 1, "testdelegation");
501 run_pkey (rd, 3, "\u5929\u4e0b\u7121\u6575");
502 run_edkey (&rd_pkey, 1, "testdelegation");
503 run_edkey (rd, 3, "\u5929\u4e0b\u7121\u6575");
504}
505
506
507/**
508 * The main function of the test vector generation tool.
509 *
510 * @param argc number of arguments from the command line
511 * @param argv command line arguments
512 * @return 0 ok, 1 on error
513 */
514int
515main (int argc,
516 char *const *argv)
517{
518 const struct GNUNET_GETOPT_CommandLineOption options[] = {
519 GNUNET_GETOPT_OPTION_END
520 };
521
522 GNUNET_assert (GNUNET_OK ==
523 GNUNET_log_setup ("gnunet-gns-tvg",
524 "INFO",
525 NULL));
526 // gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
527 // gcry_control (GCRYCTL_SET_VERBOSITY, 99);
528 if (GNUNET_OK !=
529 GNUNET_PROGRAM_run (argc, argv,
530 "gnunet-gns-tvg",
531 "Generate test vectors for GNS",
532 options,
533 &run, NULL))
534 return 1;
535 return 0;
536}
537
538
539/* end of gnunet-gns-tvg.c */