aboutsummaryrefslogtreecommitdiff
path: root/src/gnsrecord
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-10-18 13:37:38 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2023-10-18 13:37:38 +0200
commit9ef4abad615bea12d13be542b8ae5fbeb2dfee32 (patch)
tree8875a687e004d331c9ea6a1d511a328c72b88113 /src/gnsrecord
parente95236b3ed78cd597c15f34b89385295702b627f (diff)
downloadgnunet-9ef4abad615bea12d13be542b8ae5fbeb2dfee32.tar.gz
gnunet-9ef4abad615bea12d13be542b8ae5fbeb2dfee32.zip
NEWS: Refactoring components under src/ into lib/, plugin/, cli/ and service/
This also includes a necessary API refactoring of crypto from IDENTITY to UTIL.
Diffstat (limited to 'src/gnsrecord')
-rw-r--r--src/gnsrecord/.gitignore6
-rw-r--r--src/gnsrecord/Makefile.am129
-rw-r--r--src/gnsrecord/gnsrecord.c267
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c1091
-rw-r--r--src/gnsrecord/gnsrecord_crypto.h85
-rw-r--r--src/gnsrecord/gnsrecord_misc.c567
-rw-r--r--src/gnsrecord/gnsrecord_serialization.c302
-rw-r--r--src/gnsrecord/gnunet-gnsrecord-tvg.c539
-rw-r--r--src/gnsrecord/json_gnsrecord.c389
-rw-r--r--src/gnsrecord/meson.build45
-rw-r--r--src/gnsrecord/perf_gnsrecord_crypto.c139
-rw-r--r--src/gnsrecord/plugin_gnsrecord_dns.c818
-rw-r--r--src/gnsrecord/test_gnsrecord_block_expiration.c113
-rw-r--r--src/gnsrecord/test_gnsrecord_crypto.c207
-rw-r--r--src/gnsrecord/test_gnsrecord_serialization.c156
-rw-r--r--src/gnsrecord/test_gnsrecord_testvectors.c711
16 files changed, 0 insertions, 5564 deletions
diff --git a/src/gnsrecord/.gitignore b/src/gnsrecord/.gitignore
deleted file mode 100644
index dca3bd309..000000000
--- a/src/gnsrecord/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
1test_gnsrecord_block_expiration
2test_gnsrecord_crypto
3test_gnsrecord_serialization
4zonefiles
5perf_gnsrecord_crypto
6gnunet-gnsrecord-tvg
diff --git a/src/gnsrecord/Makefile.am b/src/gnsrecord/Makefile.am
deleted file mode 100644
index 7ef7c327e..000000000
--- a/src/gnsrecord/Makefile.am
+++ /dev/null
@@ -1,129 +0,0 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include ${MHD_CFLAGS}
3
4plugindir = $(libdir)/gnunet
5
6pkgcfgdir= $(pkgdatadir)/config.d/
7
8libexecdir= $(pkglibdir)/libexec/
9
10if USE_COVERAGE
11 AM_CFLAGS = --coverage -O0
12 XLIBS = -lgcov
13endif
14
15noinst_PROGRAMS = \
16 gnunet-gnsrecord-tvg
17
18
19check_PROGRAMS = \
20 test_gnsrecord_crypto \
21 test_gnsrecord_serialization \
22 test_gnsrecord_lsd0001testvectors \
23 test_gnsrecord_block_expiration \
24 perf_gnsrecord_crypto
25
26if ENABLE_TEST_RUN
27AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
28TESTS = \
29 $(check_PROGRAMS) \
30 $(check_SCRIPTS)
31endif
32
33lib_LTLIBRARIES = \
34 libgnunetgnsrecord.la \
35 libgnunetgnsrecordjson.la
36
37gnunet_gnsrecord_tvg_SOURCES = \
38 gnunet-gnsrecord-tvg.c \
39 gnsrecord_crypto.h
40gnunet_gnsrecord_tvg_LDADD = \
41 $(top_builddir)/src/util/libgnunetutil.la \
42 $(top_builddir)/src/identity/libgnunetidentity.la \
43 libgnunetgnsrecord.la \
44 $(GN_LIBINTL)
45
46
47libgnunetgnsrecord_la_SOURCES = \
48 gnsrecord.c \
49 gnsrecord_serialization.c \
50 gnsrecord_crypto.c \
51 gnsrecord_misc.c
52libgnunetgnsrecord_la_LIBADD = \
53 $(top_builddir)/src/util/libgnunetutil.la \
54 $(top_builddir)/src/identity/libgnunetidentity.la \
55 $(LIBGCRYPT_LIBS) \
56 -lsodium \
57 $(GN_LIBINTL)
58libgnunetgnsrecord_la_LDFLAGS = \
59 $(GN_LIB_LDFLAGS) \
60 -version-info 0:0:0
61
62libgnunetgnsrecordjson_la_SOURCES = \
63 json_gnsrecord.c
64libgnunetgnsrecordjson_la_LIBADD = \
65 $(top_builddir)/src/util/libgnunetutil.la \
66 $(top_builddir)/src/identity/libgnunetidentity.la \
67 libgnunetgnsrecord.la \
68 -ljansson \
69 $(GN_LIBINTL)
70libgnunetgnsrecordjson_la_LDFLAGS = \
71 $(GN_LIB_LDFLAGS) \
72 -version-info 0:0:0
73
74plugin_LTLIBRARIES = \
75 libgnunet_plugin_gnsrecord_dns.la
76
77
78libgnunet_plugin_gnsrecord_dns_la_SOURCES = \
79 plugin_gnsrecord_dns.c
80libgnunet_plugin_gnsrecord_dns_la_LIBADD = \
81 $(top_builddir)/src/util/libgnunetutil.la \
82 $(LTLIBINTL)
83libgnunet_plugin_gnsrecord_dns_la_LDFLAGS = \
84 $(GN_PLUGIN_LDFLAGS)
85
86
87EXTRA_DIST = \
88 $(check_SCRIPTS)
89
90test_gnsrecord_lsd0001testvectors_SOURCES = \
91 test_gnsrecord_testvectors.c
92test_gnsrecord_lsd0001testvectors_LDADD = \
93 $(top_builddir)/src/testing/libgnunettesting.la \
94 $(top_builddir)/src/identity/libgnunetidentity.la \
95 libgnunetgnsrecord.la \
96 $(top_builddir)/src/util/libgnunetutil.la
97
98
99test_gnsrecord_serialization_SOURCES = \
100 test_gnsrecord_serialization.c
101test_gnsrecord_serialization_LDADD = \
102 $(top_builddir)/src/testing/libgnunettesting.la \
103 libgnunetgnsrecord.la \
104 $(top_builddir)/src/util/libgnunetutil.la
105
106test_gnsrecord_block_expiration_SOURCES = \
107 test_gnsrecord_block_expiration.c
108test_gnsrecord_block_expiration_LDADD = \
109 $(top_builddir)/src/testing/libgnunettesting.la \
110 libgnunetgnsrecord.la \
111 $(top_builddir)/src/util/libgnunetutil.la
112
113
114test_gnsrecord_crypto_SOURCES = \
115 test_gnsrecord_crypto.c
116test_gnsrecord_crypto_LDADD = \
117 $(top_builddir)/src/testing/libgnunettesting.la \
118 $(top_builddir)/src/identity/libgnunetidentity.la \
119 libgnunetgnsrecord.la \
120 $(top_builddir)/src/util/libgnunetutil.la
121
122
123perf_gnsrecord_crypto_SOURCES = \
124 perf_gnsrecord_crypto.c
125perf_gnsrecord_crypto_LDADD = \
126 $(top_builddir)/src/testing/libgnunettesting.la \
127 $(top_builddir)/src/identity/libgnunetidentity.la \
128 libgnunetgnsrecord.la \
129 $(top_builddir)/src/util/libgnunetutil.la
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c
deleted file mode 100644
index c71dc1708..000000000
--- a/src/gnsrecord/gnsrecord.c
+++ /dev/null
@@ -1,267 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 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 gnsrecord/gnsrecord.c
23 * @brief API to access GNS record data
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_gnsrecord_lib.h"
32#include "gnunet_gnsrecord_plugin.h"
33
34#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
35
36
37/**
38 * Handle for a plugin.
39 */
40struct Plugin
41{
42 /**
43 * Name of the shared library.
44 */
45 char *library_name;
46
47 /**
48 * Plugin API.
49 */
50 struct GNUNET_GNSRECORD_PluginFunctions *api;
51};
52
53
54/**
55 * Array of our plugins.
56 */
57static struct Plugin **gns_plugins;
58
59/**
60 * Size of the 'plugins' array.
61 */
62static unsigned int num_plugins;
63
64/**
65 * Global to mark if we've run the initialization.
66 */
67static int once;
68
69
70/**
71 * Add a plugin to the list managed by the block library.
72 *
73 * @param cls NULL
74 * @param library_name name of the plugin
75 * @param lib_ret the plugin API
76 */
77static void
78add_plugin (void *cls,
79 const char *library_name,
80 void *lib_ret)
81{
82 struct GNUNET_GNSRECORD_PluginFunctions *api = lib_ret;
83 struct Plugin *plugin;
84
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Loading block plugin `%s'\n",
87 library_name);
88 plugin = GNUNET_new (struct Plugin);
89 plugin->api = api;
90 plugin->library_name = GNUNET_strdup (library_name);
91 GNUNET_array_append (gns_plugins, num_plugins, plugin);
92}
93
94
95/**
96 * Loads all plugins (lazy initialization).
97 */
98static void
99init ()
100{
101 if (1 == once)
102 return;
103 once = 1;
104
105 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (),
106 "libgnunet_plugin_gnsrecord_",
107 NULL,
108 &add_plugin,
109 NULL);
110}
111
112
113/**
114 * Dual function to #init().
115 */
116void __attribute__ ((destructor))
117GNSRECORD_fini ()
118{
119 struct Plugin *plugin;
120 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
121 const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
122
123 if (pd != dpd)
124 GNUNET_OS_init (dpd);
125
126 for (unsigned int i = 0; i < num_plugins; i++)
127 {
128 plugin = gns_plugins[i];
129 GNUNET_break (NULL ==
130 GNUNET_PLUGIN_unload (plugin->library_name,
131 plugin->api));
132 GNUNET_free (plugin->library_name);
133 GNUNET_free (plugin);
134 }
135 GNUNET_free (gns_plugins);
136
137 if (pd != dpd)
138 GNUNET_OS_init (pd);
139
140 gns_plugins = NULL;
141 once = 0;
142 num_plugins = 0;
143}
144
145
146/**
147 * Convert the 'value' of a record to a string.
148 *
149 * @param type type of the record
150 * @param data value in binary encoding
151 * @param data_size number of bytes in @a data
152 * @return NULL on error, otherwise human-readable representation of the value
153 */
154char *
155GNUNET_GNSRECORD_value_to_string (uint32_t type,
156 const void *data,
157 size_t data_size)
158{
159 struct Plugin *plugin;
160 char *ret;
161
162 init ();
163 for (unsigned int i = 0; i < num_plugins; i++)
164 {
165 plugin = gns_plugins[i];
166 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
167 type,
168 data,
169 data_size)))
170 return ret;
171 }
172 return NULL;
173}
174
175
176int
177GNUNET_GNSRECORD_string_to_value (uint32_t type,
178 const char *s,
179 void **data,
180 size_t *data_size)
181{
182 struct Plugin *plugin;
183
184 init ();
185 for (unsigned int i = 0; i < num_plugins; i++)
186 {
187 plugin = gns_plugins[i];
188 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
189 type,
190 s,
191 data,
192 data_size))
193 return GNUNET_OK;
194 }
195 return GNUNET_SYSERR;
196}
197
198
199uint32_t
200GNUNET_GNSRECORD_typename_to_number (const char *dns_typename)
201{
202 struct Plugin *plugin;
203 uint32_t ret;
204
205 if (0 == strcasecmp (dns_typename,
206 "ANY"))
207 return GNUNET_GNSRECORD_TYPE_ANY;
208 init ();
209 for (unsigned int i = 0; i < num_plugins; i++)
210 {
211 plugin = gns_plugins[i];
212 if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
213 dns_typename)))
214 return ret;
215 }
216 return UINT32_MAX;
217}
218
219
220/**
221 * Convert a type number to the corresponding type string (e.g. 1 to "A")
222 *
223 * @param type number of a type to convert
224 * @return corresponding typestring, NULL on error
225 */
226const char *
227GNUNET_GNSRECORD_number_to_typename (uint32_t type)
228{
229 struct Plugin *plugin;
230 const char *ret;
231
232 if (GNUNET_GNSRECORD_TYPE_ANY == type)
233 return "ANY";
234 init ();
235 for (unsigned int i = 0; i < num_plugins; i++)
236 {
237 plugin = gns_plugins[i];
238 if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
239 type)))
240 return ret;
241 }
242 return NULL;
243}
244
245
246enum GNUNET_GenericReturnValue
247GNUNET_GNSRECORD_is_critical (uint32_t type)
248{
249 struct Plugin *plugin;
250
251 if (GNUNET_GNSRECORD_TYPE_ANY == type)
252 return GNUNET_NO;
253 init ();
254 for (unsigned int i = 0; i < num_plugins; i++)
255 {
256 plugin = gns_plugins[i];
257 if (NULL == plugin->api->is_critical)
258 continue;
259 if (GNUNET_NO == plugin->api->is_critical (plugin->api->cls, type))
260 continue;
261 return GNUNET_YES;
262 }
263 return GNUNET_NO;
264}
265
266
267/* end of gnsrecord.c */
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
deleted file mode 100644
index 384336c97..000000000
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ /dev/null
@@ -1,1091 +0,0 @@
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
21/**
22 * @file gnsrecord/gnsrecord_crypto.c
23 * @brief API for GNS record-related crypto
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "gnsrecord_crypto.h"
30
31#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
32
33ssize_t
34ecdsa_symmetric_decrypt (
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,
48 GNUNET_CRYPTO_AES_KEY_LENGTH);
49 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
50 rc = gcry_cipher_setctr (handle,
51 ctr,
52 GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
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
60ssize_t
61ecdsa_symmetric_encrypt (
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,
75 GNUNET_CRYPTO_AES_KEY_LENGTH);
76 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
77 rc = gcry_cipher_setctr (handle,
78 ctr,
79 GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
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
87enum GNUNET_GenericReturnValue
88eddsa_symmetric_decrypt (
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
111enum GNUNET_GenericReturnValue
112eddsa_symmetric_encrypt (
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
128void
129GNR_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
138 GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH,
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);
144 /** 4 byte nonce **/
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);
150 /** Expiration time 64 bit. **/
151 memcpy (ctr + 4, &exp, sizeof (exp));
152 /** Set counter part to 1 **/
153 ctr[15] |= 0x01;
154}
155
156
157void
158GNR_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);
173 /** 16 byte nonce **/
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);
179 /** Expiration time 64 bit. **/
180 memcpy (nonce + (crypto_secretbox_NONCEBYTES - sizeof (exp)),
181 &exp, sizeof (exp));
182}
183
184
185static ssize_t
186block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
187 unsigned int rd_count)
188{
189 ssize_t len;
190
191 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
192 if (len < 0)
193 return -1;
194 len += sizeof(struct GNUNET_GNSRECORD_Block);
195 return len;
196}
197
198
199enum GNUNET_GenericReturnValue
200block_sign_ecdsa (const struct
201 GNUNET_CRYPTO_EcdsaPrivateKey *key,
202 const struct
203 GNUNET_CRYPTO_EcdsaPublicKey *pkey,
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 =
215 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
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));
220 GNUNET_CRYPTO_ecdsa_public_key_derive (pkey,
221 label,
222 "gns",
223 &ecblock->derived_key);
224 if (GNUNET_OK !=
225 GNUNET_CRYPTO_ecdsa_sign_derived (key,
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
240enum GNUNET_GenericReturnValue
241block_sign_eddsa (const struct
242 GNUNET_CRYPTO_EddsaPrivateKey *key,
243 const struct
244 GNUNET_CRYPTO_EddsaPublicKey *pkey,
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 =
255 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
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 */
260 GNUNET_CRYPTO_eddsa_public_key_derive (pkey,
261 label,
262 "gns",
263 &edblock->derived_key);
264 GNUNET_CRYPTO_eddsa_sign_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
274enum GNUNET_GenericReturnValue
275GNUNET_GNSRECORD_block_sign (const struct
276 GNUNET_IDENTITY_PrivateKey *key,
277 const char *label,
278 struct GNUNET_GNSRECORD_Block *block)
279{
280 struct GNUNET_IDENTITY_PublicKey pkey;
281 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
282 char *norm_label;
283
284 GNUNET_IDENTITY_key_get_public (key,
285 &pkey);
286 norm_label = GNUNET_GNSRECORD_string_normalize (label);
287
288 switch (ntohl (key->type))
289 {
290 case GNUNET_GNSRECORD_TYPE_PKEY:
291 res = block_sign_ecdsa (&key->ecdsa_key,
292 &pkey.ecdsa_key,
293 norm_label,
294 block);
295 break;
296 case GNUNET_GNSRECORD_TYPE_EDKEY:
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
310/**
311 * Sign name and records
312 *
313 * @param key the private key
314 * @param pkey associated public key
315 * @param expire block expiration
316 * @param label the name for the records
317 * @param rd record data
318 * @param rd_count number of records
319 * @param block the block result. Must be allocated sufficiently.
320 * @param sign sign the block GNUNET_NO if block will be signed later.
321 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
322 */
323static enum GNUNET_GenericReturnValue
324block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
325 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
326 struct GNUNET_TIME_Absolute expire,
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];
338 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
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! */
361 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
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 ==
373 GNUNET_GNSRECORD_records_serialize (rd_count,
374 rdc,
375 payload_len,
376 payload));
377 ecblock = &(*block)->ecdsa_block;
378 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
379 ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
380 GNR_derive_block_aes_key (ctr,
381 skey,
382 label,
383 ecblock->expiration_time.abs_value_us__,
384 pkey);
385 GNUNET_assert (payload_len ==
386 ecdsa_symmetric_encrypt (payload,
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
405static ssize_t
406block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd,
407 unsigned int rd_count)
408{
409 ssize_t len;
410
411 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
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
420/**
421 * Sign name and records (EDDSA version)
422 *
423 * @param key the private key
424 * @param pkey associated public key
425 * @param expire block expiration
426 * @param label the name for the records
427 * @param rd record data
428 * @param rd_count number of records
429 * @param block where to store the block. Must be allocated sufficiently.
430 * @param sign GNUNET_YES if block shall be signed as well
431 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
432 */
433enum GNUNET_GenericReturnValue
434block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
435 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
436 struct GNUNET_TIME_Absolute expire,
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];
448 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
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! */
471 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
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 ==
485 GNUNET_GNSRECORD_records_serialize (rd_count,
486 rdc,
487 payload_len,
488 payload));
489 edblock = &(*block)->eddsa_block;
490 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
491 edblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
492 GNR_derive_block_xsalsa_key (nonce,
493 skey,
494 label,
495 edblock->expiration_time.abs_value_us__,
496 pkey);
497 GNUNET_assert (GNUNET_OK ==
498 eddsa_symmetric_encrypt (payload,
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
511ssize_t
512GNUNET_GNSRECORD_block_calculate_size (const struct
513 GNUNET_IDENTITY_PrivateKey *key,
514 const struct GNUNET_GNSRECORD_Data *rd,
515 unsigned int rd_count)
516{
517 struct GNUNET_IDENTITY_PublicKey pkey;
518 ssize_t res = -1;
519
520 GNUNET_IDENTITY_key_get_public (key,
521 &pkey);
522 switch (ntohl (key->type))
523 {
524 case GNUNET_GNSRECORD_TYPE_PKEY:
525 res = block_get_size_ecdsa (rd, rd_count);
526 break;
527 case GNUNET_GNSRECORD_TYPE_EDKEY:
528 res = block_get_size_eddsa (rd, rd_count);
529 break;
530 default:
531 GNUNET_assert (0);
532 }
533 return res;
534
535}
536
537
538enum GNUNET_GenericReturnValue
539GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
540 struct GNUNET_TIME_Absolute expire,
541 const char *label,
542 const struct GNUNET_GNSRECORD_Data *rd,
543 unsigned int rd_count,
544 struct GNUNET_GNSRECORD_Block **result)
545{
546 struct GNUNET_IDENTITY_PublicKey pkey;
547 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
548 char *norm_label;
549
550 GNUNET_IDENTITY_key_get_public (key,
551 &pkey);
552 norm_label = GNUNET_GNSRECORD_string_normalize (label);
553
554 switch (ntohl (key->type))
555 {
556 case GNUNET_GNSRECORD_TYPE_PKEY:
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;
566 case GNUNET_GNSRECORD_TYPE_EDKEY:
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
584/**
585 * Line in cache mapping private keys to public keys.
586 */
587struct KeyCacheLine
588{
589 /**
590 * A private key.
591 */
592 struct GNUNET_CRYPTO_EcdsaPrivateKey key;
593
594 /**
595 * Associated public key.
596 */
597 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
598};
599
600
601static enum GNUNET_GenericReturnValue
602block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
603 struct GNUNET_TIME_Absolute expire,
604 const char *label,
605 const struct GNUNET_GNSRECORD_Data *rd,
606 unsigned int rd_count,
607 struct GNUNET_GNSRECORD_Block **result,
608 int sign)
609{
610 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
611 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
612 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
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;
631 GNUNET_CRYPTO_ecdsa_key_get_public (key,
632 &line->pkey);
633 }
634#undef CSIZE
635 res = block_create_ecdsa (key,
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 {
646 GNUNET_CRYPTO_eddsa_key_get_public (&pkey->eddsa_key,
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
662enum GNUNET_GenericReturnValue
663GNUNET_GNSRECORD_block_create_unsigned (const struct
664 GNUNET_IDENTITY_PrivateKey *pkey,
665 struct GNUNET_TIME_Absolute expire,
666 const char *label,
667 const struct GNUNET_GNSRECORD_Data *rd,
668 unsigned int rd_count,
669 struct GNUNET_GNSRECORD_Block **result)
670{
671 return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_NO);
672}
673
674
675enum GNUNET_GenericReturnValue
676GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
677 struct GNUNET_TIME_Absolute expire,
678 const char *label,
679 const struct GNUNET_GNSRECORD_Data *rd,
680 unsigned int rd_count,
681 struct GNUNET_GNSRECORD_Block **result)
682{
683 return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_YES);
684}
685
686
687/**
688 * Check if a signature is valid. This API is used by the GNS Block
689 * to validate signatures received from the network.
690 *
691 * @param block block to verify
692 * @return #GNUNET_OK if the signature is valid
693 */
694enum GNUNET_GenericReturnValue
695GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
696{
697 struct GNRBlockPS *purp;
698 size_t payload_len = ntohl (block->size)
699 - sizeof (struct GNUNET_GNSRECORD_Block);
700 enum GNUNET_GenericReturnValue res = GNUNET_NO;
701 purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
702 purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
703 purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
704 GNUNET_memcpy (&purp[1],
705 &block[1],
706 payload_len);
707 switch (ntohl (block->type))
708 {
709 case GNUNET_GNSRECORD_TYPE_PKEY:
710 purp->expiration_time = block->ecdsa_block.expiration_time;
711 res = GNUNET_CRYPTO_ecdsa_verify_ (
712 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
713 &purp->purpose,
714 &block->ecdsa_block.signature,
715 &block->ecdsa_block.derived_key);
716 break;
717 case GNUNET_GNSRECORD_TYPE_EDKEY:
718 purp->expiration_time = block->eddsa_block.expiration_time;
719 res = GNUNET_CRYPTO_eddsa_verify_ (
720 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
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
733enum GNUNET_GenericReturnValue
734block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
735 const struct
736 GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
737 const char *label,
738 GNUNET_GNSRECORD_RecordCallback proc,
739 void *proc_cls)
740{
741 size_t payload_len = ntohl (block->size) - sizeof (struct
742 GNUNET_GNSRECORD_Block);
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 }
753 GNR_derive_block_aes_key (ctr,
754 key,
755 label,
756 block->ecdsa_block.expiration_time.abs_value_us__,
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));
766 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
767 payload);
768 if (rd_count > 2048)
769 {
770 /* limit to sane value */
771 GNUNET_break_op (0);
772 return GNUNET_SYSERR;
773 }
774 {
775 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
776 unsigned int j;
777 struct GNUNET_TIME_Absolute now;
778
779 if (GNUNET_OK !=
780 GNUNET_GNSRECORD_records_deserialize (payload_len,
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 */
815 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
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
839 at.abs_value_us = rd[i].expiration_time;
840 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
841 "Excluding record that expired %s (%llu ago)\n",
842 GNUNET_STRINGS_absolute_time_to_string (at),
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
858enum GNUNET_GenericReturnValue
859block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
860 const struct
861 GNUNET_CRYPTO_EddsaPublicKey *zone_key,
862 const char *label,
863 GNUNET_GNSRECORD_RecordCallback proc,
864 void *proc_cls)
865{
866 size_t payload_len = ntohl (block->size) - sizeof (struct
867 GNUNET_GNSRECORD_Block);
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 }
878 GNR_derive_block_xsalsa_key (nonce,
879 key,
880 label,
881 block->eddsa_block.expiration_time.abs_value_us__,
882 zone_key);
883 {
884 char payload[payload_len];
885 unsigned int rd_count;
886
887 GNUNET_assert (GNUNET_OK ==
888 eddsa_symmetric_decrypt (&block[1], payload_len,
889 key, nonce,
890 payload));
891 payload_len -= crypto_secretbox_MACBYTES;
892 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
893 payload);
894 if (rd_count > 2048)
895 {
896 /* limit to sane value */
897 GNUNET_break_op (0);
898 return GNUNET_SYSERR;
899 }
900 {
901 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
902 unsigned int j;
903 struct GNUNET_TIME_Absolute now;
904
905 if (GNUNET_OK !=
906 GNUNET_GNSRECORD_records_deserialize (payload_len,
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 */
941 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
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
965 at.abs_value_us = rd[i].expiration_time;
966 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
967 "Excluding record that expired %s (%llu ago)\n",
968 GNUNET_STRINGS_absolute_time_to_string (at),
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
984enum GNUNET_GenericReturnValue
985GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
986 const struct
987 GNUNET_IDENTITY_PublicKey *zone_key,
988 const char *label,
989 GNUNET_GNSRECORD_RecordCallback proc,
990 void *proc_cls)
991{
992 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
993 char *norm_label;
994
995 norm_label = GNUNET_GNSRECORD_string_normalize (label);
996 switch (ntohl (zone_key->type))
997 {
998 case GNUNET_IDENTITY_TYPE_ECDSA:
999 res = block_decrypt_ecdsa (block,
1000 &zone_key->ecdsa_key, norm_label, proc,
1001 proc_cls);
1002 break;
1003 case GNUNET_IDENTITY_TYPE_EDDSA:
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
1016/**
1017 * Calculate the DHT query for a given @a label in a given @a zone.
1018 *
1019 * @param zone private key of the zone
1020 * @param label label of the record
1021 * @param query hash to use for the query
1022 */
1023void
1024GNUNET_GNSRECORD_query_from_private_key (const struct
1025 GNUNET_IDENTITY_PrivateKey *zone,
1026 const char *label,
1027 struct GNUNET_HashCode *query)
1028{
1029 char *norm_label;
1030 struct GNUNET_IDENTITY_PublicKey pub;
1031
1032 norm_label = GNUNET_GNSRECORD_string_normalize (label);
1033 switch (ntohl (zone->type))
1034 {
1035 case GNUNET_GNSRECORD_TYPE_PKEY:
1036 case GNUNET_GNSRECORD_TYPE_EDKEY:
1037
1038 GNUNET_IDENTITY_key_get_public (zone,
1039 &pub);
1040 GNUNET_GNSRECORD_query_from_public_key (&pub,
1041 norm_label,
1042 query);
1043 break;
1044 default:
1045 GNUNET_assert (0);
1046 }
1047 GNUNET_free (norm_label);
1048}
1049
1050
1051void
1052GNUNET_GNSRECORD_query_from_public_key (const struct
1053 GNUNET_IDENTITY_PublicKey *pub,
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 {
1064 case GNUNET_GNSRECORD_TYPE_PKEY:
1065 pd.type = pub->type;
1066 GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key,
1067 norm_label,
1068 "gns",
1069 &pd.ecdsa_key);
1070 GNUNET_CRYPTO_hash (&pd.ecdsa_key,
1071 sizeof (pd.ecdsa_key),
1072 query);
1073 break;
1074 case GNUNET_GNSRECORD_TYPE_EDKEY:
1075 pd.type = pub->type;
1076 GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key,
1077 norm_label,
1078 "gns",
1079 &(pd.eddsa_key));
1080 GNUNET_CRYPTO_hash (&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 */
diff --git a/src/gnsrecord/gnsrecord_crypto.h b/src/gnsrecord/gnsrecord_crypto.h
deleted file mode 100644
index 4f2e4a5ca..000000000
--- a/src/gnsrecord/gnsrecord_crypto.h
+++ /dev/null
@@ -1,85 +0,0 @@
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
21/**
22 * @file gnsrecord/gnsrecord_crypto.h
23 * @brief API for GNS record-related crypto
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_signatures.h"
32#include "gnunet_arm_service.h"
33#include "gnunet_gnsrecord_lib.h"
34
35/**
36 * Information we have in an encrypted block with record data (i.e. in the DHT).
37 */
38struct GNRBlockPS
39{
40 /**
41 * Number of bytes signed; also specifies the number of bytes
42 * of encrypted data that follow.
43 */
44 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
45
46 /**
47 * Expiration time of the block.
48 */
49 struct GNUNET_TIME_AbsoluteNBO expiration_time;
50
51 /* followed by encrypted data */
52};
53
54
55/**
56 * Derive session key and iv from label and public key.
57 *
58 * @param iv initialization vector to initialize
59 * @param skey session key to initialize
60 * @param label label to use for KDF
61 * @param pub public key to use for KDF
62 */
63void
64GNR_derive_block_aes_key (unsigned char *ctr,
65 unsigned char *key,
66 const char *label,
67 uint64_t exp,
68 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub);
69
70
71/**
72 * Derive session key and iv from label and public key.
73 *
74 * @param nonce initialization vector to initialize
75 * @param skey session key to initialize
76 * @param label label to use for KDF
77 * @param pub public key to use for KDF
78 */
79void
80GNR_derive_block_xsalsa_key (unsigned char *nonce,
81 unsigned char *key,
82 const char *label,
83 uint64_t exp,
84 const struct GNUNET_CRYPTO_EddsaPublicKey *pub);
85
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
deleted file mode 100644
index 931654c49..000000000
--- a/src/gnsrecord/gnsrecord_misc.c
+++ /dev/null
@@ -1,567 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 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 gnsrecord/gnsrecord_misc.c
23 * @brief MISC functions related to GNS records
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_signatures.h"
32#include "gnunet_arm_service.h"
33#include "gnunet_gnsrecord_lib.h"
34
35
36#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
37
38char *
39GNUNET_GNSRECORD_string_normalize (const char *src)
40{
41 /*FIXME: We may want to follow RFC5890/RFC5891 */
42 return GNUNET_STRINGS_utf8_normalize (src);
43}
44
45
46enum GNUNET_GenericReturnValue
47GNUNET_GNSRECORD_label_check (const char*label, char **emsg)
48{
49 if (NULL == label)
50 {
51 *emsg = GNUNET_strdup (_ ("Label is NULL which is not allowed\n"));
52 return GNUNET_NO;
53 }
54 if (0 != strchr (label, '.'))
55 {
56 *emsg = GNUNET_strdup (_ ("Label contains `.' which is not allowed\n"));
57 return GNUNET_NO;
58 }
59 return GNUNET_OK;
60}
61
62
63const char *
64GNUNET_GNSRECORD_z2s (const struct GNUNET_IDENTITY_PublicKey *z)
65{
66 static char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) * 8];
67 char *end;
68
69 end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z,
70 sizeof(struct
71 GNUNET_IDENTITY_PublicKey),
72 buf, sizeof(buf));
73 if (NULL == end)
74 {
75 GNUNET_break (0);
76 return NULL;
77 }
78 *end = '\0';
79 return buf;
80}
81
82
83/**
84 * Compares if two records are equal (ignoring flags such
85 * as authority, private and pending, but not relative vs.
86 * absolute expiration time).
87 *
88 * @param a record
89 * @param b record
90 * @return #GNUNET_YES if the records are equal or #GNUNET_NO if they are not
91 */
92enum GNUNET_GenericReturnValue
93GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a,
94 const struct GNUNET_GNSRECORD_Data *b)
95{
96 LOG (GNUNET_ERROR_TYPE_DEBUG,
97 "Comparing records\n");
98 if (a->record_type != b->record_type)
99 {
100 LOG (GNUNET_ERROR_TYPE_DEBUG,
101 "Record type %u != %u\n", a->record_type, b->record_type);
102 return GNUNET_NO;
103 }
104 if ((a->expiration_time != b->expiration_time) &&
105 ((a->expiration_time != 0) && (b->expiration_time != 0)))
106 {
107 LOG (GNUNET_ERROR_TYPE_DEBUG,
108 "Expiration time %llu != %llu\n",
109 (unsigned long long) a->expiration_time,
110 (unsigned long long) b->expiration_time);
111 return GNUNET_NO;
112 }
113 if ((a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)
114 != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS))
115 {
116 LOG (GNUNET_ERROR_TYPE_DEBUG,
117 "Flags %u (%u) != %u (%u)\n", a->flags,
118 a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags,
119 b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS);
120 return GNUNET_NO;
121 }
122 if (a->data_size != b->data_size)
123 {
124 LOG (GNUNET_ERROR_TYPE_DEBUG,
125 "Data size %lu != %lu\n",
126 a->data_size,
127 b->data_size);
128 return GNUNET_NO;
129 }
130 if (0 != memcmp (a->data, b->data, a->data_size))
131 {
132 LOG (GNUNET_ERROR_TYPE_DEBUG,
133 "Data contents do not match\n");
134 return GNUNET_NO;
135 }
136 LOG (GNUNET_ERROR_TYPE_DEBUG,
137 "Records are equal\n");
138 return GNUNET_YES;
139}
140
141
142struct GNUNET_TIME_Absolute
143GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count,
144 const struct
145 GNUNET_GNSRECORD_Data *rd,
146 struct GNUNET_TIME_Absolute min)
147{
148 struct GNUNET_TIME_Absolute expire;
149 struct GNUNET_TIME_Absolute at;
150 struct GNUNET_TIME_Relative rt;
151 struct GNUNET_TIME_Absolute at_shadow;
152 struct GNUNET_TIME_Relative rt_shadow;
153
154 if (0 == rd_count)
155 return GNUNET_TIME_absolute_max (GNUNET_TIME_UNIT_ZERO_ABS, min);
156 expire = GNUNET_TIME_UNIT_FOREVER_ABS;
157 for (unsigned int c = 0; c < rd_count; c++)
158 {
159 if (0 != (rd[c].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
160 {
161 rt.rel_value_us = rd[c].expiration_time;
162 at = GNUNET_TIME_relative_to_absolute (rt);
163 }
164 else
165 {
166 at.abs_value_us = rd[c].expiration_time;
167 }
168
169 for (unsigned int c2 = 0; c2 < rd_count; c2++)
170 {
171 /* Check for shadow record */
172 if ((c == c2) ||
173 (rd[c].record_type != rd[c2].record_type) ||
174 (0 == (rd[c2].flags & GNUNET_GNSRECORD_RF_SHADOW)))
175 continue;
176 /* We have a shadow record */
177 if (0 != (rd[c2].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
178 {
179 rt_shadow.rel_value_us = rd[c2].expiration_time;
180 at_shadow = GNUNET_TIME_relative_to_absolute (rt_shadow);
181 }
182 else
183 {
184 at_shadow.abs_value_us = rd[c2].expiration_time;
185 }
186 at = GNUNET_TIME_absolute_max (at,
187 at_shadow);
188 }
189 expire = GNUNET_TIME_absolute_min (at,
190 expire);
191 }
192 expire = GNUNET_TIME_absolute_max (expire, min);
193 LOG (GNUNET_ERROR_TYPE_DEBUG,
194 "Determined expiration time for block with %u records to be %s\n",
195 rd_count,
196 GNUNET_STRINGS_absolute_time_to_string (expire));
197 return expire;
198}
199
200
201/**
202 * Test if a given record is expired.
203 *
204 * @return #GNUNET_YES if the record is expired,
205 * #GNUNET_NO if not
206 */
207int
208GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd)
209{
210 struct GNUNET_TIME_Absolute at;
211
212 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
213 return GNUNET_NO;
214 at.abs_value_us = rd->expiration_time;
215 return (0 == GNUNET_TIME_absolute_get_remaining (at).rel_value_us) ?
216 GNUNET_YES : GNUNET_NO;
217}
218
219
220/**
221 * Convert public key to the respective absolute domain name in the
222 * ".zkey" pTLD.
223 * This is one of the very few calls in the entire API that is
224 * NOT reentrant!
225 *
226 * @param pkey a public key with a point on the eliptic curve
227 * @return string "X.zkey" where X is the public
228 * key in an encoding suitable for DNS labels.
229 */
230const char *
231GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_IDENTITY_PublicKey *pkey)
232{
233 static char ret[128];
234 char *pkeys;
235
236 pkeys = GNUNET_IDENTITY_public_key_to_string (pkey);
237 GNUNET_snprintf (ret,
238 sizeof(ret),
239 "%s",
240 pkeys);
241 GNUNET_free (pkeys);
242 return ret;
243}
244
245
246/**
247 * Convert an absolute domain name to the
248 * respective public key.
249 *
250 * @param zkey string encoding the coordinates of the public
251 * key in an encoding suitable for DNS labels.
252 * @param pkey set to a public key on the eliptic curve
253 * @return #GNUNET_SYSERR if @a zkey has the wrong syntax
254 */
255int
256GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey,
257 struct GNUNET_IDENTITY_PublicKey *pkey)
258{
259 if (GNUNET_OK !=
260 GNUNET_IDENTITY_public_key_from_string (zkey,
261 pkey))
262 return GNUNET_SYSERR;
263 return GNUNET_OK;
264}
265
266
267enum GNUNET_GenericReturnValue
268GNUNET_GNSRECORD_identity_from_data (const char *data,
269 size_t data_size,
270 uint32_t type,
271 struct GNUNET_IDENTITY_PublicKey *key)
272{
273 if (GNUNET_NO == GNUNET_GNSRECORD_is_zonekey_type (type))
274 return GNUNET_SYSERR;
275 switch (type)
276 {
277 case GNUNET_GNSRECORD_TYPE_PKEY:
278 if (data_size > sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))
279 return GNUNET_SYSERR;
280 memcpy (&key->ecdsa_key, data, data_size);
281 break;
282 case GNUNET_GNSRECORD_TYPE_EDKEY:
283 if (data_size > sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))
284 return GNUNET_SYSERR;
285 memcpy (&key->eddsa_key, data, data_size);
286 break;
287 default:
288 return GNUNET_NO;
289 }
290 key->type = htonl (type);
291
292 return GNUNET_YES;
293}
294
295
296enum GNUNET_GenericReturnValue
297GNUNET_GNSRECORD_data_from_identity (const struct
298 GNUNET_IDENTITY_PublicKey *key,
299 char **data,
300 size_t *data_size,
301 uint32_t *type)
302{
303 char *tmp;
304 *type = ntohl (key->type);
305 *data_size = GNUNET_IDENTITY_public_key_get_length (key) - sizeof (key->type);
306 if (0 == *data_size)
307 return GNUNET_SYSERR;
308 tmp = GNUNET_malloc (*data_size);
309 memcpy (tmp, ((char*) key) + sizeof (key->type), *data_size);
310 *data = tmp;
311 return GNUNET_OK;
312}
313
314
315enum GNUNET_GenericReturnValue
316GNUNET_GNSRECORD_is_zonekey_type (uint32_t type)
317{
318 switch (type)
319 {
320 case GNUNET_GNSRECORD_TYPE_PKEY:
321 case GNUNET_GNSRECORD_TYPE_EDKEY:
322 return GNUNET_YES;
323 default:
324 return GNUNET_NO;
325 }
326}
327
328
329size_t
330GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block)
331{
332 return ntohl (block->size);
333}
334
335
336struct GNUNET_TIME_Absolute
337GNUNET_GNSRECORD_block_get_expiration (const struct
338 GNUNET_GNSRECORD_Block *block)
339{
340
341 switch (ntohl (block->type))
342 {
343 case GNUNET_GNSRECORD_TYPE_PKEY:
344 return GNUNET_TIME_absolute_ntoh (block->ecdsa_block.expiration_time);
345 case GNUNET_GNSRECORD_TYPE_EDKEY:
346 return GNUNET_TIME_absolute_ntoh (block->eddsa_block.expiration_time);
347 default:
348 GNUNET_break (0); /* Hopefully we never get here, but we might */
349 }
350 return GNUNET_TIME_absolute_get_zero_ ();
351
352}
353
354
355enum GNUNET_GenericReturnValue
356GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block,
357 struct GNUNET_HashCode *query)
358{
359 switch (ntohl (block->type))
360 {
361 case GNUNET_GNSRECORD_TYPE_PKEY:
362 GNUNET_CRYPTO_hash (&(block->ecdsa_block.derived_key),
363 sizeof (block->ecdsa_block.derived_key),
364 query);
365 return GNUNET_OK;
366 case GNUNET_GNSRECORD_TYPE_EDKEY:
367 GNUNET_CRYPTO_hash (&block->eddsa_block.derived_key,
368 sizeof (block->eddsa_block.derived_key),
369 query);
370 return GNUNET_OK;
371 default:
372 return GNUNET_SYSERR;
373 }
374 return GNUNET_SYSERR;
375
376}
377
378
379enum GNUNET_GenericReturnValue
380GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd,
381 struct GNUNET_IDENTITY_PublicKey *key)
382{
383 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
384 "Got record of type %u\n",
385 rd->record_type);
386 switch (rd->record_type)
387 {
388 case GNUNET_GNSRECORD_TYPE_PKEY:
389 key->type = htonl (rd->record_type);
390 memcpy (&key->ecdsa_key, rd->data, sizeof (key->ecdsa_key));
391 return GNUNET_OK;
392 case GNUNET_GNSRECORD_TYPE_EDKEY:
393 key->type = htonl (rd->record_type);
394 memcpy (&key->eddsa_key, rd->data, sizeof (key->eddsa_key));
395 return GNUNET_OK;
396 default:
397 return GNUNET_SYSERR;
398 }
399 return GNUNET_SYSERR;
400
401
402}
403
404
405enum GNUNET_GenericReturnValue
406GNUNET_GNSRECORD_normalize_record_set (const char *label,
407 const struct
408 GNUNET_GNSRECORD_Data *rd,
409 unsigned int rd_count,
410 struct GNUNET_GNSRECORD_Data *
411 rd_public,
412 unsigned int *rd_count_public,
413 struct GNUNET_TIME_Absolute *expiry,
414 enum GNUNET_GNSRECORD_Filter filter,
415 char **emsg)
416{
417 struct GNUNET_TIME_Absolute now;
418 struct GNUNET_TIME_Absolute minimum_expiration;
419 int have_zone_delegation = GNUNET_NO;
420 int have_gns2dns = GNUNET_NO;
421 int have_other = GNUNET_NO;
422 int have_redirect = GNUNET_NO;
423 int have_empty_label = (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, label));
424 unsigned int rd_count_tmp;
425
426 minimum_expiration = GNUNET_TIME_UNIT_ZERO_ABS;
427 now = GNUNET_TIME_absolute_get ();
428 rd_count_tmp = 0;
429 for (unsigned int i = 0; i < rd_count; i++)
430 {
431 /* Ignore private records for public record set */
432 if ((0 != (filter & GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE)) &&
433 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)))
434 {
435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
436 "Filtering private record filter=%u...\n", filter);
437 continue;
438 }
439 /* Skip expired records */
440 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
441 (rd[i].expiration_time < now.abs_value_us))
442 {
443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
444 "Filtering expired record...\n");
445 continue; /* record already expired, skip it */
446 }
447 /* Ignore the tombstone unless filter permits explicitly.
448 * Remember expiration time. */
449 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
450 {
451 minimum_expiration.abs_value_us = rd[i].expiration_time;
452 if (0 != (filter & GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE))
453 {
454 rd_public[rd_count_tmp] = rd[i];
455 rd_count_tmp++;
456 }
457 continue;
458 }
459 /* No NICK records unless empty label */
460 if (have_empty_label &&
461 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type))
462 continue;
463
464 /**
465 * Check for delegation and redirect consistency.
466 * Note that we check for consistency BEFORE we filter for
467 * private records ON PURPOSE.
468 * We also want consistent record sets in our local zone(s).
469 * The only exception is the tombstone (above) which we ignore
470 * for the consistency check(s).
471 * FIXME: What about shadow records? Should we ignore them?
472 */
473 if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
474 {
475 /* No delegation records under empty label*/
476 if (have_empty_label)
477 {
478 *emsg = GNUNET_strdup (_ (
479 "Zone delegation record not allowed in apex."));
480 return GNUNET_SYSERR;
481 }
482 if ((GNUNET_YES == have_other) ||
483 (GNUNET_YES == have_redirect) ||
484 (GNUNET_YES == have_gns2dns))
485 {
486 *emsg = GNUNET_strdup (_ (
487 "Zone delegation record set contains mutually exclusive records."));
488 return GNUNET_SYSERR;
489 }
490 have_zone_delegation = GNUNET_YES;
491 }
492 else if (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[i].record_type)
493 {
494 if (GNUNET_YES == have_redirect)
495 {
496 *emsg = GNUNET_strdup (_ (
497 "Multiple REDIRECT records."));
498 return GNUNET_SYSERR;
499
500 }
501 if ((GNUNET_YES == have_other) ||
502 (GNUNET_YES == have_zone_delegation) ||
503 (GNUNET_YES == have_gns2dns))
504 {
505 *emsg = GNUNET_strdup (_ (
506 "Redirection record set contains mutually exclusive records."));
507 return GNUNET_SYSERR;
508 }
509 /* No redirection records under empty label*/
510 if (have_empty_label)
511 {
512 *emsg = GNUNET_strdup (_ (
513 "Redirection records not allowed in apex."));
514 return GNUNET_SYSERR;
515 }
516 have_redirect = GNUNET_YES;
517 }
518 else if (GNUNET_GNSRECORD_TYPE_GNS2DNS == rd[i].record_type)
519 {
520 /* No gns2dns records under empty label*/
521 if (have_empty_label)
522 {
523 *emsg = GNUNET_strdup (_ (
524 "Redirection records not allowed in apex.."));
525 return GNUNET_SYSERR;
526 }
527 if ((GNUNET_YES == have_other) ||
528 (GNUNET_YES == have_redirect) ||
529 (GNUNET_YES == have_zone_delegation))
530 {
531 *emsg = GNUNET_strdup (_ (
532 "Redirection record set contains mutually exclusive records."));
533 return GNUNET_SYSERR;
534 }
535 have_gns2dns = GNUNET_YES;
536 }
537 else
538 {
539 /* Some other record.
540 * Not allowed for zone delegations or redirections */
541 if ((GNUNET_YES == have_zone_delegation) ||
542 (GNUNET_YES == have_redirect) ||
543 (GNUNET_YES == have_gns2dns))
544 {
545 *emsg = GNUNET_strdup (_ (
546 "Mutually exclusive records."));
547 return GNUNET_SYSERR;
548 }
549 have_other = GNUNET_YES;
550 }
551
552 rd_public[rd_count_tmp] = rd[i];
553 /* Make sure critical record types are marked as such */
554 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
555 rd_public[rd_count_tmp].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
556 rd_count_tmp++;
557 }
558
559 *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_count_tmp,
560 rd_public,
561 minimum_expiration);
562 *rd_count_public = rd_count_tmp;
563 return GNUNET_OK;
564}
565
566
567/* end of gnsrecord_misc.c */
diff --git a/src/gnsrecord/gnsrecord_serialization.c b/src/gnsrecord/gnsrecord_serialization.c
deleted file mode 100644
index 053edfd33..000000000
--- a/src/gnsrecord/gnsrecord_serialization.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 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 gnsrecord/gnsrecord_serialization.c
23 * @brief API to serialize and deserialize GNS records
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_signatures.h"
32#include "gnunet_arm_service.h"
33#include "gnunet_gnsrecord_lib.h"
34
35#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
36
37/**
38 * Set to 1 to check that all records are well-formed (can be converted
39 * to string) during serialization/deserialization.
40 */
41#define DEBUG_GNSRECORDS 0
42
43GNUNET_NETWORK_STRUCT_BEGIN
44
45
46/**
47 * Internal format of a record in the serialized form.
48 */
49struct NetworkRecord
50{
51 /**
52 * Expiration time for the DNS record; relative or absolute depends
53 * on @e flags, network byte order.
54 */
55 uint64_t expiration_time GNUNET_PACKED;
56
57 /**
58 * Number of bytes in 'data', network byte order.
59 */
60 uint16_t data_size GNUNET_PACKED;
61
62 /**
63 * Flags for the record, network byte order.
64 */
65 uint16_t flags GNUNET_PACKED;
66
67 /**
68 * Type of the GNS/DNS record, network byte order.
69 */
70 uint32_t record_type GNUNET_PACKED;
71
72};
73
74GNUNET_NETWORK_STRUCT_END
75
76
77ssize_t
78GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
79 const struct GNUNET_GNSRECORD_Data *rd)
80{
81 size_t ret;
82
83 if (0 == rd_count)
84 return 0;
85
86 ret = sizeof(struct NetworkRecord) * rd_count;
87 for (unsigned int i = 0; i < rd_count; i++)
88 {
89 if ((ret + rd[i].data_size) < ret)
90 {
91 GNUNET_break (0);
92 return -1;
93 }
94 ret += rd[i].data_size;
95#if DEBUG_GNSRECORDS
96 {
97 char *str;
98
99 str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
100 rd[i].data,
101 rd[i].data_size);
102 if (NULL == str)
103 {
104 GNUNET_break_op (0);
105 return -1;
106 }
107 GNUNET_free (str);
108 }
109#endif
110 }
111 if (ret > SSIZE_MAX)
112 {
113 GNUNET_break (0);
114 return -1;
115 }
116 // Do not pad PKEY
117 if ((GNUNET_GNSRECORD_TYPE_PKEY == rd->record_type) ||
118 (GNUNET_GNSRECORD_TYPE_EDKEY == rd->record_type))
119 return ret;
120 /**
121 * Efficiently round up to the next
122 * power of 2 for padding
123 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
124 */ret--;
125 ret |= ret >> 1;
126 ret |= ret >> 2;
127 ret |= ret >> 4;
128 ret |= ret >> 8;
129 ret |= ret >> 16;
130 ret++;
131 return (ssize_t) ret;
132}
133
134
135ssize_t
136GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
137 const struct GNUNET_GNSRECORD_Data *rd,
138 size_t dest_size,
139 char *dest)
140{
141 struct NetworkRecord rec;
142 size_t off;
143
144 off = 0;
145 for (unsigned int i = 0; i < rd_count; i++)
146 {
147 LOG (GNUNET_ERROR_TYPE_DEBUG,
148 "Serializing record %u with flags %d and expiration time %llu\n",
149 i,
150 rd[i].flags,
151 (unsigned long long) rd[i].expiration_time);
152 rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
153 rec.data_size = htons ((uint16_t) rd[i].data_size);
154 rec.record_type = htonl (rd[i].record_type);
155 rec.flags = htons (rd[i].flags);
156 if ((off + sizeof(rec) > dest_size) ||
157 (off + sizeof(rec) < off))
158 {
159 GNUNET_break (0);
160 return -1;
161 }
162 GNUNET_memcpy (&dest[off],
163 &rec,
164 sizeof(rec));
165 off += sizeof(rec);
166 if ((off + rd[i].data_size > dest_size) ||
167 (off + rd[i].data_size < off))
168 {
169 GNUNET_break (0);
170 return -1;
171 }
172 GNUNET_memcpy (&dest[off],
173 rd[i].data,
174 rd[i].data_size);
175 off += rd[i].data_size;
176#if DEBUG_GNSRECORDS
177 {
178 char *str;
179
180 str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
181 rd[i].data,
182 rd[i].data_size);
183 if (NULL == str)
184 {
185 GNUNET_break_op (0);
186 return -1;
187 }
188 GNUNET_free (str);
189 }
190#endif
191 }
192 memset (&dest[off],
193 0,
194 dest_size - off);
195 return dest_size;
196}
197
198unsigned int
199GNUNET_GNSRECORD_records_deserialize_get_size (size_t len,
200 const char *src)
201{
202 struct NetworkRecord rec;
203 struct NetworkRecord rec_zero;
204 size_t off;
205 unsigned int rd_count = 0;
206
207 memset (&rec_zero, 0, sizeof (rec_zero));
208
209 off = 0;
210 for (off = 0; (off + sizeof(rec) <= len) && (off + sizeof(rec) >= off);)
211 {
212 GNUNET_memcpy (&rec,
213 &src[off],
214 sizeof(rec));
215 /*
216 * If we have found a byte string of zeroes, we have reached
217 * the padding
218 */
219 if (0 == GNUNET_memcmp (&rec, &rec_zero))
220 break;
221 off += sizeof(rec);
222 if ((off + ntohs ((uint16_t) rec.data_size) > len) ||
223 (off + ntohs ((uint16_t) rec.data_size) < off))
224 {
225 GNUNET_break_op (0);
226 return 0;
227 }
228 off += ntohs ((uint16_t) rec.data_size);
229 rd_count++;
230 }
231 return rd_count;
232}
233
234/**
235 * Deserialize the given records to the given destination.
236 *
237 * @param len size of the serialized record data
238 * @param src the serialized record data
239 * @param rd_count number of records parsed
240 * @param dest where to put the data
241 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
242 */
243int
244GNUNET_GNSRECORD_records_deserialize (size_t len,
245 const char *src,
246 unsigned int rd_count,
247 struct GNUNET_GNSRECORD_Data *dest)
248{
249 struct NetworkRecord rec;
250 size_t off;
251
252 off = 0;
253 for (unsigned int i = 0; i < rd_count; i++)
254 {
255 if ((off + sizeof(rec) > len) ||
256 (off + sizeof(rec) < off))
257 {
258 GNUNET_break_op (0);
259 return GNUNET_SYSERR;
260 }
261 GNUNET_memcpy (&rec,
262 &src[off],
263 sizeof(rec));
264 dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
265 dest[i].data_size = ntohs ((uint16_t) rec.data_size);
266 dest[i].record_type = ntohl (rec.record_type);
267 dest[i].flags = ntohs (rec.flags);
268 off += sizeof(rec);
269 if ((off + dest[i].data_size > len) ||
270 (off + dest[i].data_size < off))
271 {
272 GNUNET_break_op (0);
273 return GNUNET_SYSERR;
274 }
275 dest[i].data = &src[off];
276 off += dest[i].data_size;
277#if GNUNET_EXTRA_LOGGING
278 {
279 char *str;
280
281 str = GNUNET_GNSRECORD_value_to_string (dest[i].record_type,
282 dest[i].data,
283 dest[i].data_size);
284 if (NULL == str)
285 {
286 GNUNET_break_op (0);
287 return GNUNET_SYSERR;
288 }
289 GNUNET_free (str);
290 }
291#endif
292 LOG (GNUNET_ERROR_TYPE_DEBUG,
293 "Deserialized record %u with flags %d and expiration time %llu\n",
294 i,
295 dest[i].flags,
296 (unsigned long long) dest[i].expiration_time);
297 }
298 return GNUNET_OK;
299}
300
301
302/* end of gnsrecord_serialization.c */
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c
deleted file mode 100644
index eebbedf21..000000000
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ /dev/null
@@ -1,539 +0,0 @@
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_IDENTITY_PrivateKey id_priv;
150 struct GNUNET_IDENTITY_PublicKey id_pub;
151 struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
152 struct GNUNET_IDENTITY_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_IDENTITY_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_IDENTITY_public_key_get_length (&id_pub));
175 print_bytes (&id_pub, GNUNET_IDENTITY_public_key_get_length (&id_pub), 8);
176 GNUNET_STRINGS_data_to_string (&id_pub,
177 GNUNET_IDENTITY_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_IDENTITY_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_IDENTITY_PrivateKey id_priv;
289 struct GNUNET_IDENTITY_PublicKey id_pub;
290 struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
291 struct GNUNET_IDENTITY_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_IDENTITY_key_get_public (&id_priv,
304 &id_pub);
305
306 id_priv.type = htonl (GNUNET_IDENTITY_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_IDENTITY_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_IDENTITY_public_key_get_length (&id_pub));
320 print_bytes (&id_pub, GNUNET_IDENTITY_public_key_get_length (&id_pub), 8);
321 GNUNET_STRINGS_data_to_string (&id_pub,
322 GNUNET_IDENTITY_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_IDENTITY_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 */
diff --git a/src/gnsrecord/json_gnsrecord.c b/src/gnsrecord/json_gnsrecord.c
deleted file mode 100644
index cc96e42fb..000000000
--- a/src/gnsrecord/json_gnsrecord.c
+++ /dev/null
@@ -1,389 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 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 json/json_gnsrecord.c
23 * @brief JSON handling of GNS record data
24 * @author Philippe Buschmann
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_json_lib.h"
29#include "gnunet_gnsrecord_lib.h"
30
31#define GNUNET_JSON_GNSRECORD_VALUE "value"
32#define GNUNET_JSON_GNSRECORD_RECORD_DATA "data"
33#define GNUNET_JSON_GNSRECORD_TYPE "record_type"
34#define GNUNET_JSON_GNSRECORD_RELATIVE_EXPIRATION_TIME "relative_expiration"
35#define GNUNET_JSON_GNSRECORD_ABSOLUTE_EXPIRATION_TIME "absolute_expiration"
36#define GNUNET_JSON_GNSRECORD_FLAG_PRIVATE "is_private"
37#define GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL "is_supplemental"
38#define GNUNET_JSON_GNSRECORD_FLAG_RELATIVE "is_relative_expiration"
39#define GNUNET_JSON_GNSRECORD_FLAG_SHADOW "is_shadow"
40#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name"
41
42struct GnsRecordInfo
43{
44 char **name;
45
46 unsigned int *rd_count;
47
48 struct GNUNET_GNSRECORD_Data **rd;
49};
50
51
52static void
53cleanup_recordinfo (struct GnsRecordInfo *gnsrecord_info)
54{
55 char *tmp;
56
57 if (NULL != *(gnsrecord_info->rd))
58 {
59 for (int i = 0; i < *(gnsrecord_info->rd_count); i++)
60 {
61 tmp = (char*) (*(gnsrecord_info->rd))[i].data;
62 if (NULL != tmp)
63 GNUNET_free (tmp);
64 }
65 GNUNET_free (*(gnsrecord_info->rd));
66 *(gnsrecord_info->rd) = NULL;
67 }
68 if (NULL != *(gnsrecord_info->name))
69 GNUNET_free (*(gnsrecord_info->name));
70 *(gnsrecord_info->name) = NULL;
71}
72
73
74/**
75 * Parse given JSON object to gns record
76 *
77 * @param cls closure, NULL
78 * @param root the json object representing data
79 * @param spec where to write the data
80 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
81 */
82static int
83parse_record (json_t *data, struct GNUNET_GNSRECORD_Data *rd)
84{
85 struct GNUNET_TIME_Absolute abs_exp;
86 struct GNUNET_TIME_Relative rel_exp;
87 const char *value;
88 const char *record_type;
89 int private;
90 int supplemental;
91 int is_rel_exp;
92 int shadow;
93 int unpack_state = 0;
94 json_error_t err;
95
96 // interpret single gns record
97 unpack_state = json_unpack_ex (data,
98 &err,
99 0,
100 "{s:s, s:s, s:I, s:b, s:b, s:b, s:b}",
101 GNUNET_JSON_GNSRECORD_VALUE,
102 &value,
103 GNUNET_JSON_GNSRECORD_TYPE,
104 &record_type,
105 GNUNET_JSON_GNSRECORD_RELATIVE_EXPIRATION_TIME,
106 &rel_exp.rel_value_us,
107 GNUNET_JSON_GNSRECORD_FLAG_PRIVATE,
108 &private,
109 GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL,
110 &supplemental,
111 GNUNET_JSON_GNSRECORD_FLAG_RELATIVE,
112 &is_rel_exp,
113 GNUNET_JSON_GNSRECORD_FLAG_SHADOW,
114 &shadow);
115 if (0 != unpack_state)
116 {
117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
118 "Error gnsdata object has a wrong format: `%s'!\n",
119 err.text);
120 unpack_state = json_unpack_ex (data,
121 &err,
122 0,
123 "{s:s, s:s, s:I, s:b, s:b, s:b, s:b}",
124 GNUNET_JSON_GNSRECORD_VALUE,
125 &value,
126 GNUNET_JSON_GNSRECORD_TYPE,
127 &record_type,
128 GNUNET_JSON_GNSRECORD_ABSOLUTE_EXPIRATION_TIME,
129 &abs_exp.abs_value_us,
130 GNUNET_JSON_GNSRECORD_FLAG_PRIVATE,
131 &private,
132 GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL,
133 &supplemental,
134 GNUNET_JSON_GNSRECORD_FLAG_RELATIVE,
135 &is_rel_exp,
136 GNUNET_JSON_GNSRECORD_FLAG_SHADOW,
137 &shadow);
138 if ((0 != unpack_state) || (is_rel_exp))
139 {
140 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
141 "Error gnsdata object has a wrong format: `%s'!\n",
142 (is_rel_exp) ? "No relative expiration given" : err.text);
143 return GNUNET_SYSERR;
144 }
145 rd->expiration_time = abs_exp.abs_value_us;
146 }
147 else
148 {
149 rd->expiration_time = rel_exp.rel_value_us;
150 }
151 rd->record_type = GNUNET_GNSRECORD_typename_to_number (record_type);
152 if (UINT32_MAX == rd->record_type)
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n");
155 return GNUNET_SYSERR;
156 }
157 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (rd->record_type,
158 value,
159 (void **) &rd->data,
160 &rd->data_size))
161 {
162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n");
163 return GNUNET_SYSERR;
164 }
165
166 if (is_rel_exp)
167 rd->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
168 if (1 == private)
169 rd->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
170 if (1 == supplemental)
171 rd->flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
172 if (1 == shadow)
173 rd->flags |= GNUNET_GNSRECORD_RF_SHADOW;
174 return GNUNET_OK;
175}
176
177
178/**
179 * Parse given JSON object to gns record
180 *
181 * @param cls closure, NULL
182 * @param root the json object representing data
183 * @param spec where to write the data
184 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
185 */
186static int
187parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data)
188{
189 GNUNET_assert (NULL != data);
190 if (! json_is_array (data))
191 {
192 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
193 "Error gns record data JSON is not an array!\n");
194 return GNUNET_SYSERR;
195 }
196 *(gnsrecord_info->rd_count) = json_array_size (data);
197 *(gnsrecord_info->rd) = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Data)
198 * json_array_size (data));
199 size_t index;
200 json_t *value;
201 json_array_foreach (data, index, value)
202 {
203 if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index]))
204 return GNUNET_SYSERR;
205 }
206 return GNUNET_OK;
207}
208
209
210static int
211parse_gnsrecordobject (void *cls,
212 json_t *root,
213 struct GNUNET_JSON_Specification *spec)
214{
215 struct GnsRecordInfo *gnsrecord_info;
216 int unpack_state = 0;
217 const char *name;
218 json_t *data;
219
220 GNUNET_assert (NULL != root);
221 if (! json_is_object (root))
222 {
223 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
224 "Error record JSON is not an object!\n");
225 return GNUNET_SYSERR;
226 }
227 // interpret single gns record
228 unpack_state = json_unpack (root,
229 "{s:s, s:o!}",
230 GNUNET_JSON_GNSRECORD_RECORD_NAME,
231 &name,
232 GNUNET_JSON_GNSRECORD_RECORD_DATA,
233 &data);
234 if (0 != unpack_state)
235 {
236 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
237 "Error namestore records object has a wrong format!\n");
238 return GNUNET_SYSERR;
239 }
240 gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
241 *(gnsrecord_info->name) = GNUNET_strdup (name);
242 if (GNUNET_OK != parse_record_data (gnsrecord_info, data))
243 {
244 cleanup_recordinfo (gnsrecord_info);
245 return GNUNET_SYSERR;
246 }
247 return GNUNET_OK;
248}
249
250
251/**
252 * Cleanup data left from parsing the record.
253 *
254 * @param cls closure, NULL
255 * @param[out] spec where to free the data
256 */
257static void
258clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec)
259{
260 struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
261
262 GNUNET_free (gnsrecord_info);
263}
264
265
266/**
267 * JSON Specification for GNS Records.
268 *
269 * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill
270 * @return JSON Specification
271 */
272struct GNUNET_JSON_Specification
273GNUNET_GNSRECORD_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd,
274 unsigned int *rd_count,
275 char **name)
276{
277 struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo);
278
279 gnsrecord_info->rd = rd;
280 gnsrecord_info->name = name;
281 gnsrecord_info->rd_count = rd_count;
282 struct GNUNET_JSON_Specification ret = { .parser = &parse_gnsrecordobject,
283 .cleaner = &clean_gnsrecordobject,
284 .cls = NULL,
285 .field = NULL,
286 .ptr = (struct GnsRecordInfo *)
287 gnsrecord_info,
288 .ptr_size = 0,
289 .size_ptr = NULL };
290 return ret;
291}
292
293
294/**
295 * Convert GNS record to JSON.
296 *
297 * @param rname name of record
298 * @param rd record data
299 * @return corresponding JSON encoding
300 */
301json_t *
302GNUNET_GNSRECORD_JSON_from_gnsrecord (const char*rname,
303 const struct GNUNET_GNSRECORD_Data *rd,
304 unsigned int rd_count)
305{
306 const char *record_type_str;
307 char *value_str;
308 json_t *data;
309 json_t *record;
310 json_t *records;
311
312 data = json_object ();
313 if (NULL == data)
314 {
315 GNUNET_break (0);
316 return NULL;
317 }
318 if (0 !=
319 json_object_set_new (data,
320 "record_name",
321 json_string (rname)))
322 {
323 GNUNET_break (0);
324 json_decref (data);
325 return NULL;
326 }
327 records = json_array ();
328 if (NULL == records)
329 {
330 GNUNET_break (0);
331 json_decref (data);
332 return NULL;
333 }
334 for (int i = 0; i < rd_count; i++)
335 {
336 value_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
337 rd[i].data,
338 rd[i].data_size);
339 record_type_str = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
340 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
341 "Packing %s %s %" PRIu64 " %d\n",
342 value_str, record_type_str, rd[i].expiration_time, rd[i].flags);
343 record = json_pack ("{s:s,s:s,s:I,s:b,s:b,s:b,s:b}",
344 GNUNET_JSON_GNSRECORD_VALUE,
345 value_str,
346 GNUNET_JSON_GNSRECORD_TYPE,
347 record_type_str,
348 (rd[i].flags
349 & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) ?
350 GNUNET_JSON_GNSRECORD_RELATIVE_EXPIRATION_TIME :
351 GNUNET_JSON_GNSRECORD_ABSOLUTE_EXPIRATION_TIME,
352 rd[i].expiration_time,
353 GNUNET_JSON_GNSRECORD_FLAG_PRIVATE,
354 rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE,
355 GNUNET_JSON_GNSRECORD_FLAG_RELATIVE,
356 rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION,
357 GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL,
358 rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL,
359 GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL,
360 rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW);
361 GNUNET_free (value_str);
362 if (NULL == record)
363 {
364 GNUNET_break (0);
365 json_decref (records);
366 json_decref (data);
367 return NULL;
368 }
369 if (0 !=
370 json_array_append_new (records,
371 record))
372 {
373 GNUNET_break (0);
374 json_decref (records);
375 json_decref (data);
376 return NULL;
377 }
378 }
379 if (0 !=
380 json_object_set_new (data,
381 "data",
382 records))
383 {
384 GNUNET_break (0);
385 json_decref (data);
386 return NULL;
387 }
388 return data;
389}
diff --git a/src/gnsrecord/meson.build b/src/gnsrecord/meson.build
deleted file mode 100644
index 11b355796..000000000
--- a/src/gnsrecord/meson.build
+++ /dev/null
@@ -1,45 +0,0 @@
1libgnunetgnsrecord_src = ['gnsrecord.c',
2 'gnsrecord_serialization.c',
3 'gnsrecord_crypto.c',
4 'gnsrecord_misc.c']
5libgnunetgnsrecordjson_src = ['json_gnsrecord.c']
6
7if get_option('monolith')
8 foreach p : libgnunetgnsrecord_src + libgnunetgnsrecordjson_src
9 gnunet_src += 'gnsrecord/' + p
10 endforeach
11 subdir_done()
12endif
13
14libgnunetgnsrecord = library('gnunetgnsrecord',
15 libgnunetgnsrecord_src,
16 soversion: '0',
17 version: '0.0.0',
18 dependencies: [libgnunetutil_dep,
19 sodium_dep,
20 libgnunetidentity_dep,
21 gcrypt_dep],
22 include_directories: [incdir, configuration_inc],
23 install: true,
24 install_dir: get_option('libdir'))
25libgnunetgnsrecord_dep = declare_dependency(link_with : libgnunetgnsrecord)
26pkg.generate(libgnunetgnsrecord, url: 'https://www.gnunet.org',
27 description : 'Provides API for manipulating GNS records')
28
29
30libgnunetgnsrecordjson = library('gnunetgnsrecordjson',
31 libgnunetgnsrecordjson_src,
32 soversion: '0',
33 version: '0.0.0',
34 dependencies: [libgnunetutil_dep, libgnunetgnsrecord_dep, json_dep],
35 include_directories: [incdir, configuration_inc],
36 install: true,
37 install_dir: get_option('libdir'))
38libgnunetgnsrecordjson_dep = declare_dependency(link_with : libgnunetgnsrecordjson)
39
40shared_module('gnunet_plugin_gnsrecord_dns',
41 ['plugin_gnsrecord_dns.c'],
42 dependencies: [libgnunetutil_dep, libgnunetgnsrecord_dep],
43 include_directories: [incdir, configuration_inc],
44 install: true,
45 install_dir: get_option('libdir')/'gnunet')
diff --git a/src/gnsrecord/perf_gnsrecord_crypto.c b/src/gnsrecord/perf_gnsrecord_crypto.c
deleted file mode 100644
index 6b5f84235..000000000
--- a/src/gnsrecord/perf_gnsrecord_crypto.c
+++ /dev/null
@@ -1,139 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 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/**
21 * @file gnsrecord/test_gnsrecord_crypto.c
22 * @brief testcase for block creation, verification and decryption
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_gnsrecord_lib.h"
27
28#define ROUNDS 1000
29
30#define RECORDS 5
31
32#define TEST_RECORD_TYPE 1234
33
34#define TEST_RECORD_DATALEN 123
35
36#define TEST_RECORD_DATA 'a'
37
38#define TEST_REMOVE_RECORD_TYPE 4321
39
40#define TEST_REMOVE_RECORD_DATALEN 255
41
42#define TEST_REMOVE_RECORD_DATA 'b'
43
44
45static struct GNUNET_GNSRECORD_Data *
46create_record (int count)
47{
48 struct GNUNET_GNSRECORD_Data *rd;
49
50 rd = GNUNET_new_array (count,
51 struct GNUNET_GNSRECORD_Data);
52 for (unsigned int c = 0; c < count; c++)
53 {
54 rd[c].expiration_time = GNUNET_TIME_absolute_get ().abs_value_us
55 + 1000000000;
56 rd[c].record_type = TEST_RECORD_TYPE;
57 rd[c].data_size = TEST_RECORD_DATALEN;
58 rd[c].data = GNUNET_malloc (TEST_RECORD_DATALEN);
59 memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
60 }
61 return rd;
62}
63
64
65static void
66run (void *cls,
67 char *const *args,
68 const char *cfgfile,
69 const struct GNUNET_CONFIGURATION_Handle *cfg)
70{
71 struct GNUNET_GNSRECORD_Block *block;
72 struct GNUNET_HashCode query;
73 struct GNUNET_GNSRECORD_Data *s_rd;
74 const char *s_name;
75 struct GNUNET_TIME_Absolute start_time;
76 struct GNUNET_IDENTITY_PrivateKey privkey;
77 struct GNUNET_TIME_Absolute expire;
78
79 (void) cls;
80 (void) args;
81 (void) cfgfile;
82 (void) cfg;
83 expire = GNUNET_TIME_absolute_get ();
84 privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
85 GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
86
87 /* test block creation */
88 s_name = "DUMMY.dummy.gnunet";
89 s_rd = create_record (RECORDS);
90 start_time = GNUNET_TIME_absolute_get ();
91 for (unsigned int i = 0; i < ROUNDS; i++)
92 {
93 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (&privkey,
94 expire,
95 s_name,
96 s_rd,
97 RECORDS,
98 &block));
99 GNUNET_GNSRECORD_query_from_private_key (&privkey,
100 s_name,
101 &query);
102 GNUNET_free (block);
103 }
104 fprintf (stderr,
105 "Took %s to produce %u GNS blocks for the DHT\n",
106 GNUNET_STRINGS_relative_time_to_string (
107 GNUNET_TIME_absolute_get_duration (start_time),
108 GNUNET_YES),
109 ROUNDS);
110 for (unsigned int i = 0; i < RECORDS; i++)
111 GNUNET_free_nz ((void *) s_rd[i].data);
112 GNUNET_free (s_rd);
113}
114
115
116int
117main (int argc, char *argv[])
118{
119 static char *const argvx[] = {
120 "perf-gnsrecord-crypto",
121 NULL
122 };
123 static struct GNUNET_GETOPT_CommandLineOption options[] = {
124 GNUNET_GETOPT_OPTION_END
125 };
126
127 if (GNUNET_OK !=
128 GNUNET_PROGRAM_run ((sizeof(argvx) / sizeof(char *)) - 1,
129 argvx,
130 "perf-gnsrecord-crypto",
131 "nohelp", options,
132 &run,
133 NULL))
134 return 1;
135 return 0;
136}
137
138
139/* end of test_gnsrecord_crypto.c */
diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c
deleted file mode 100644
index 5844d9eda..000000000
--- a/src/gnsrecord/plugin_gnsrecord_dns.c
+++ /dev/null
@@ -1,818 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013, 2014 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 gnsrecord/plugin_gnsrecord_dns.c
23 * @brief gnsrecord plugin to provide the API for basic DNS records
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_gnsrecord_plugin.h"
29
30
31/**
32 * Convert the 'value' of a record to a string.
33 *
34 * @param cls closure, unused
35 * @param type type of the record
36 * @param data value in binary encoding
37 * @param data_size number of bytes in @a data
38 * @return NULL on error, otherwise human-readable representation of the value
39 */
40static char *
41dns_value_to_string (void *cls,
42 uint32_t type,
43 const void *data,
44 size_t data_size)
45{
46 char *result;
47 char tmp[INET6_ADDRSTRLEN];
48
49 switch (type)
50 {
51 case GNUNET_DNSPARSER_TYPE_A:
52 if (data_size != sizeof(struct in_addr))
53 return NULL;
54 if (NULL == inet_ntop (AF_INET, data, tmp, sizeof(tmp)))
55 return NULL;
56 return GNUNET_strdup (tmp);
57
58 case GNUNET_DNSPARSER_TYPE_NS: {
59 char *ns;
60 size_t off;
61
62 off = 0;
63 ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
64 if ((NULL == ns) || (off != data_size))
65 {
66 GNUNET_break_op (0);
67 GNUNET_free (ns);
68 return NULL;
69 }
70 return ns;
71 }
72
73 case GNUNET_DNSPARSER_TYPE_CNAME: {
74 char *cname;
75 size_t off;
76
77 off = 0;
78 cname = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
79 if ((NULL == cname) || (off != data_size))
80 {
81 GNUNET_break_op (0);
82 GNUNET_free (cname);
83 return NULL;
84 }
85 return cname;
86 }
87
88 case GNUNET_DNSPARSER_TYPE_SOA: {
89 struct GNUNET_DNSPARSER_SoaRecord *soa;
90 size_t off;
91
92 off = 0;
93 soa = GNUNET_DNSPARSER_parse_soa (data, data_size, &off);
94 if ((NULL == soa) || (off != data_size))
95 {
96 GNUNET_break_op (0);
97 if (NULL != soa)
98 GNUNET_DNSPARSER_free_soa (soa);
99 return NULL;
100 }
101 GNUNET_asprintf (&result,
102 "%s %s ( %u %u %u %u %u )",
103 soa->rname,
104 soa->mname,
105 soa->serial,
106 soa->refresh,
107 soa->retry,
108 soa->expire,
109 soa->minimum_ttl);
110 GNUNET_DNSPARSER_free_soa (soa);
111 return result;
112 }
113
114 case GNUNET_DNSPARSER_TYPE_PTR: {
115 char *ptr;
116 size_t off;
117
118 off = 0;
119 ptr = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
120 if ((NULL == ptr) || (off != data_size))
121 {
122 GNUNET_break_op (0);
123 GNUNET_free (ptr);
124 return NULL;
125 }
126 return ptr;
127 }
128
129 case GNUNET_DNSPARSER_TYPE_CERT: {
130 struct GNUNET_DNSPARSER_CertRecord *cert;
131 size_t off;
132 char *base64;
133 int len;
134
135 off = 0;
136 cert = GNUNET_DNSPARSER_parse_cert (data, data_size, &off);
137 if ((NULL == cert) || (off != data_size))
138 {
139 GNUNET_break_op (0);
140 GNUNET_DNSPARSER_free_cert (cert);
141 return NULL;
142 }
143 len = GNUNET_STRINGS_base64_encode (cert->certificate_data,
144 cert->certificate_size,
145 &base64);
146 GNUNET_asprintf (&result,
147 "%u %u %u %.*s",
148 cert->cert_type,
149 cert->cert_tag,
150 cert->algorithm,
151 len,
152 base64);
153 GNUNET_free (base64);
154 GNUNET_DNSPARSER_free_cert (cert);
155 return result;
156 }
157
158 case GNUNET_DNSPARSER_TYPE_MX: {
159 struct GNUNET_DNSPARSER_MxRecord *mx;
160 size_t off;
161
162 off = 0;
163 mx = GNUNET_DNSPARSER_parse_mx (data, data_size, &off);
164 if ((NULL == mx) || (off != data_size))
165 {
166 GNUNET_break_op (0);
167 GNUNET_DNSPARSER_free_mx (mx);
168 return NULL;
169 }
170 GNUNET_asprintf (&result,
171 "%u %s",
172 (unsigned int) mx->preference,
173 mx->mxhost);
174 GNUNET_DNSPARSER_free_mx (mx);
175 return result;
176 }
177
178 case GNUNET_DNSPARSER_TYPE_TXT:
179 return GNUNET_strndup (data, data_size);
180
181 case GNUNET_DNSPARSER_TYPE_AAAA:
182 if (data_size != sizeof(struct in6_addr))
183 return NULL;
184 if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof(tmp)))
185 return NULL;
186 return GNUNET_strdup (tmp);
187
188 case GNUNET_DNSPARSER_TYPE_SRV: {
189 struct GNUNET_DNSPARSER_SrvRecord *srv;
190 size_t off;
191
192 off = 0;
193 srv = GNUNET_DNSPARSER_parse_srv (data, data_size, &off);
194 if ((NULL == srv) || (off != data_size))
195 {
196 GNUNET_break_op (0);
197 if (NULL != srv)
198 GNUNET_DNSPARSER_free_srv (srv);
199 return NULL;
200 }
201 GNUNET_asprintf (&result,
202 "%d %d %d %s",
203 srv->priority,
204 srv->weight,
205 srv->port,
206 srv->target);
207 GNUNET_DNSPARSER_free_srv (srv);
208 return result;
209 }
210
211 case GNUNET_DNSPARSER_TYPE_TLSA: {
212 const struct GNUNET_TUN_DnsTlsaRecord *tlsa;
213 char *tlsa_str;
214 char *hex;
215
216 if (data_size < sizeof(struct GNUNET_TUN_DnsTlsaRecord))
217 return NULL; /* malformed */
218 tlsa = data;
219 hex =
220 GNUNET_DNSPARSER_bin_to_hex (&tlsa[1],
221 data_size
222 - sizeof(struct GNUNET_TUN_DnsTlsaRecord));
223 if (0 == GNUNET_asprintf (&tlsa_str,
224 "%u %u %u %s",
225 (unsigned int) tlsa->usage,
226 (unsigned int) tlsa->selector,
227 (unsigned int) tlsa->matching_type,
228 hex))
229 {
230 GNUNET_free (hex);
231 GNUNET_free (tlsa_str);
232 return NULL;
233 }
234 GNUNET_free (hex);
235 return tlsa_str;
236 }
237
238 case GNUNET_DNSPARSER_TYPE_CAA: { // RFC6844
239 const struct GNUNET_DNSPARSER_CaaRecord *caa;
240 char tag[15]; // between 1 and 15 bytes
241 char value[data_size];
242 char *caa_str;
243 if (data_size < sizeof(struct GNUNET_DNSPARSER_CaaRecord))
244 return NULL; /* malformed */
245 caa = data;
246 if ((1 > caa->tag_len) || (15 < caa->tag_len))
247 return NULL; /* malformed */
248 memset (tag, 0, sizeof(tag));
249 memset (value, 0, data_size);
250 memcpy (tag, &caa[1], caa->tag_len);
251 memcpy (value,
252 (char *) &caa[1] + caa->tag_len,
253 data_size - caa->tag_len - 2);
254 if (0 == GNUNET_asprintf (&caa_str,
255 "%u %s %s",
256 (unsigned int) caa->flags,
257 tag,
258 value))
259 {
260 GNUNET_free (caa_str);
261 return NULL;
262 }
263 return caa_str;
264 }
265
266 default:
267 return NULL;
268 }
269}
270
271
272/**
273 * Convert RFC 4394 Mnemonics to the corresponding integer values.
274 *
275 * @param mnemonic string to look up
276 * @return the value, 0 if not found
277 */
278static unsigned int
279rfc4398_mnemonic_to_value (const char *mnemonic)
280{
281 static struct
282 {
283 const char *mnemonic;
284 unsigned int val;
285 } table[] = { { "PKIX", 1 },
286 { "SPKI", 2 },
287 { "PGP", 3 },
288 { "IPKIX", 4 },
289 { "ISPKI", 5 },
290 { "IPGP", 6 },
291 { "ACPKIX", 7 },
292 { "IACPKIX", 8 },
293 { "URI", 253 },
294 { "OID", 254 },
295 { NULL, 0 } };
296 unsigned int i;
297
298 for (i = 0; NULL != table[i].mnemonic; i++)
299 if (0 == strcasecmp (mnemonic, table[i].mnemonic))
300 return table[i].val;
301 return 0;
302}
303
304
305/**
306 * Convert RFC 4034 algorithm types to the corresponding integer values.
307 *
308 * @param mnemonic string to look up
309 * @return the value, 0 if not found
310 */
311static unsigned int
312rfc4034_mnemonic_to_value (const char *mnemonic)
313{
314 static struct
315 {
316 const char *mnemonic;
317 unsigned int val;
318 } table[] = { { "RSAMD5", 1 },
319 { "DH", 2 },
320 { "DSA", 3 },
321 { "ECC", 4 },
322 { "RSASHA1", 5 },
323 { "INDIRECT", 252 },
324 { "PRIVATEDNS", 253 },
325 { "PRIVATEOID", 254 },
326 { NULL, 0 } };
327 unsigned int i;
328
329 for (i = 0; NULL != table[i].mnemonic; i++)
330 if (0 == strcasecmp (mnemonic, table[i].mnemonic))
331 return table[i].val;
332 return 0;
333}
334
335
336/**
337 * Convert human-readable version of a 'value' of a record to the binary
338 * representation.
339 *
340 * @param cls closure, unused
341 * @param type type of the record
342 * @param s human-readable string
343 * @param data set to value in binary encoding (will be allocated)
344 * @param data_size set to number of bytes in @a data
345 * @return #GNUNET_OK on success
346 */
347static int
348dns_string_to_value (void *cls,
349 uint32_t type,
350 const char *s,
351 void **data,
352 size_t *data_size)
353{
354 struct in_addr value_a;
355 struct in6_addr value_aaaa;
356 struct GNUNET_TUN_DnsTlsaRecord *tlsa;
357
358 if (NULL == s)
359 return GNUNET_SYSERR;
360 switch (type)
361 {
362 case GNUNET_DNSPARSER_TYPE_A:
363 if (1 != inet_pton (AF_INET, s, &value_a))
364 {
365 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
366 _ ("Unable to parse IPv4 address `%s'\n"),
367 s);
368 return GNUNET_SYSERR;
369 }
370 *data = GNUNET_new (struct in_addr);
371 GNUNET_memcpy (*data, &value_a, sizeof(value_a));
372 *data_size = sizeof(value_a);
373 return GNUNET_OK;
374
375 case GNUNET_DNSPARSER_TYPE_NS: {
376 char nsbuf[256];
377 size_t off;
378
379 off = 0;
380 if (GNUNET_OK !=
381 GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof(nsbuf), &off, s))
382 {
383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
384 _ ("Failed to serialize NS record with value `%s'\n"),
385 s);
386 return GNUNET_SYSERR;
387 }
388 *data_size = off;
389 *data = GNUNET_malloc (off);
390 GNUNET_memcpy (*data, nsbuf, off);
391 return GNUNET_OK;
392 }
393
394 case GNUNET_DNSPARSER_TYPE_CNAME: {
395 char cnamebuf[256];
396 size_t off;
397
398 off = 0;
399 if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (cnamebuf,
400 sizeof(cnamebuf),
401 &off,
402 s))
403 {
404 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
405 _ ("Failed to serialize CNAME record with value `%s'\n"),
406 s);
407 return GNUNET_SYSERR;
408 }
409 *data_size = off;
410 *data = GNUNET_malloc (off);
411 GNUNET_memcpy (*data, cnamebuf, off);
412 return GNUNET_OK;
413 }
414
415 case GNUNET_DNSPARSER_TYPE_CERT: {
416 char *sdup;
417 const char *typep;
418 const char *keyp;
419 const char *algp;
420 const char *certp;
421 unsigned int type;
422 unsigned int key;
423 unsigned int alg;
424 size_t cert_size;
425 char *cert_data;
426 struct GNUNET_DNSPARSER_CertRecord cert;
427
428 sdup = GNUNET_strdup (s);
429 typep = strtok (sdup, " ");
430 if ((NULL == typep) ||
431 ((0 == (type = rfc4398_mnemonic_to_value (typep))) &&
432 ((1 != sscanf (typep, "%u", &type)) || (type > UINT16_MAX))))
433 {
434 GNUNET_free (sdup);
435 return GNUNET_SYSERR;
436 }
437 keyp = strtok (NULL, " ");
438 if ((NULL == keyp) || (1 != sscanf (keyp, "%u", &key)) ||
439 (key > UINT16_MAX))
440 {
441 GNUNET_free (sdup);
442 return GNUNET_SYSERR;
443 }
444 alg = 0;
445 algp = strtok (NULL, " ");
446 if ((NULL == algp) ||
447 ((0 == (type = rfc4034_mnemonic_to_value (typep))) &&
448 ((1 != sscanf (algp, "%u", &alg)) || (alg > UINT8_MAX))))
449 {
450 GNUNET_free (sdup);
451 return GNUNET_SYSERR;
452 }
453 certp = strtok (NULL, " ");
454 if ((NULL == certp) || (0 == strlen (certp)))
455 {
456 GNUNET_free (sdup);
457 return GNUNET_SYSERR;
458 }
459 cert_size = GNUNET_STRINGS_base64_decode (certp,
460 strlen (certp),
461 (void **) &cert_data);
462 GNUNET_free (sdup);
463 cert.cert_type = type;
464 cert.cert_tag = key;
465 cert.algorithm = alg;
466 cert.certificate_size = cert_size;
467 cert.certificate_data = cert_data;
468 {
469 char certbuf[cert_size + sizeof(struct GNUNET_TUN_DnsCertRecord)];
470 size_t off;
471
472 off = 0;
473 if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_cert (certbuf,
474 sizeof(certbuf),
475 &off,
476 &cert))
477 {
478 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
479 _ ("Failed to serialize CERT record with %u bytes\n"),
480 (unsigned int) cert_size);
481 GNUNET_free (cert_data);
482 return GNUNET_SYSERR;
483 }
484 *data_size = off;
485 *data = GNUNET_malloc (off);
486 GNUNET_memcpy (*data, certbuf, off);
487 }
488 GNUNET_free (cert_data);
489 return GNUNET_OK;
490 }
491
492 case GNUNET_DNSPARSER_TYPE_SOA: {
493 struct GNUNET_DNSPARSER_SoaRecord soa;
494 char soabuf[540];
495 char soa_rname[253 + 1];
496 char soa_mname[253 + 1];
497 unsigned int soa_serial;
498 unsigned int soa_refresh;
499 unsigned int soa_retry;
500 unsigned int soa_expire;
501 unsigned int soa_min;
502 size_t off;
503
504 if (7 != sscanf (s,
505 "%253s %253s ( %u %u %u %u %u )",
506 soa_rname,
507 soa_mname,
508 &soa_serial,
509 &soa_refresh,
510 &soa_retry,
511 &soa_expire,
512 &soa_min))
513 {
514 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
515 _ ("Unable to parse SOA record `%s'\n"),
516 s);
517 return GNUNET_SYSERR;
518 }
519 soa.mname = soa_mname;
520 soa.rname = soa_rname;
521 soa.serial = (uint32_t) soa_serial;
522 soa.refresh = (uint32_t) soa_refresh;
523 soa.retry = (uint32_t) soa_retry;
524 soa.expire = (uint32_t) soa_expire;
525 soa.minimum_ttl = (uint32_t) soa_min;
526 off = 0;
527 if (GNUNET_OK !=
528 GNUNET_DNSPARSER_builder_add_soa (soabuf, sizeof(soabuf), &off, &soa))
529 {
530 GNUNET_log (
531 GNUNET_ERROR_TYPE_ERROR,
532 _ ("Failed to serialize SOA record with mname `%s' and rname `%s'\n"),
533 soa_mname,
534 soa_rname);
535 return GNUNET_SYSERR;
536 }
537 *data_size = off;
538 *data = GNUNET_malloc (off);
539 GNUNET_memcpy (*data, soabuf, off);
540 return GNUNET_OK;
541 }
542
543 case GNUNET_DNSPARSER_TYPE_PTR: {
544 char ptrbuf[256];
545 size_t off;
546
547 off = 0;
548 if (GNUNET_OK !=
549 GNUNET_DNSPARSER_builder_add_name (ptrbuf, sizeof(ptrbuf), &off, s))
550 {
551 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
552 _ ("Failed to serialize PTR record with value `%s'\n"),
553 s);
554 return GNUNET_SYSERR;
555 }
556 *data_size = off;
557 *data = GNUNET_malloc (off);
558 GNUNET_memcpy (*data, ptrbuf, off);
559 return GNUNET_OK;
560 }
561
562 case GNUNET_DNSPARSER_TYPE_MX: {
563 struct GNUNET_DNSPARSER_MxRecord mx;
564 char mxbuf[258];
565 char mxhost[253 + 1];
566 unsigned int mx_pref;
567 size_t off;
568
569 if (2 != sscanf (s, "%u %253s", &mx_pref, mxhost))
570 {
571 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
572 _ ("Unable to parse MX record `%s'\n"),
573 s);
574 return GNUNET_SYSERR;
575 }
576 mx.preference = (uint16_t) mx_pref;
577 mx.mxhost = mxhost;
578 off = 0;
579
580 if (GNUNET_OK !=
581 GNUNET_DNSPARSER_builder_add_mx (mxbuf, sizeof(mxbuf), &off, &mx))
582 {
583 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
584 _ ("Failed to serialize MX record with hostname `%s'\n"),
585 mxhost);
586 return GNUNET_SYSERR;
587 }
588 *data_size = off;
589 *data = GNUNET_malloc (off);
590 GNUNET_memcpy (*data, mxbuf, off);
591 return GNUNET_OK;
592 }
593
594 case GNUNET_DNSPARSER_TYPE_SRV: {
595 struct GNUNET_DNSPARSER_SrvRecord srv;
596 char srvbuf[270];
597 char srvtarget[253 + 1];
598 unsigned int priority;
599 unsigned int weight;
600 unsigned int port;
601 size_t off;
602
603 if (4 != sscanf (s, "%u %u %u %253s", &priority, &weight, &port,
604 srvtarget))
605 {
606 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
607 _ ("Unable to parse SRV record `%s'\n"),
608 s);
609 return GNUNET_SYSERR;
610 }
611 srv.priority = (uint16_t) priority;
612 srv.weight = (uint16_t) weight;
613 srv.port = (uint16_t) port;
614 srv.target = srvtarget;
615 off = 0;
616 if (GNUNET_OK !=
617 GNUNET_DNSPARSER_builder_add_srv (srvbuf, sizeof(srvbuf), &off, &srv))
618 {
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 _ ("Failed to serialize SRV record with target `%s'\n"),
621 srvtarget);
622 return GNUNET_SYSERR;
623 }
624 *data_size = off;
625 *data = GNUNET_malloc (off);
626 GNUNET_memcpy (*data, srvbuf, off);
627 return GNUNET_OK;
628 }
629
630 case GNUNET_DNSPARSER_TYPE_TXT:
631 *data = GNUNET_strdup (s);
632 *data_size = strlen (s);
633 return GNUNET_OK;
634
635 case GNUNET_DNSPARSER_TYPE_AAAA:
636 if (1 != inet_pton (AF_INET6, s, &value_aaaa))
637 {
638 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
639 _ ("Unable to parse IPv6 address `%s'\n"),
640 s);
641 return GNUNET_SYSERR;
642 }
643 *data = GNUNET_new (struct in6_addr);
644 *data_size = sizeof(struct in6_addr);
645 GNUNET_memcpy (*data, &value_aaaa, sizeof(value_aaaa));
646 return GNUNET_OK;
647
648 case GNUNET_DNSPARSER_TYPE_TLSA: {
649 unsigned int usage;
650 unsigned int selector;
651 unsigned int matching_type;
652 size_t slen = strlen (s) + 1;
653 char hex[slen];
654
655 if (4 != sscanf (s, "%u %u %u %s", &usage, &selector, &matching_type,
656 hex))
657 {
658 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
659 _ ("Unable to parse TLSA record string `%s'\n"),
660 s);
661 *data_size = 0;
662 return GNUNET_SYSERR;
663 }
664
665 *data_size = sizeof(struct GNUNET_TUN_DnsTlsaRecord) + strlen (hex) / 2;
666 *data = tlsa = GNUNET_malloc (*data_size);
667 tlsa->usage = (uint8_t) usage;
668 tlsa->selector = (uint8_t) selector;
669 tlsa->matching_type = (uint8_t) matching_type;
670 if (strlen (hex) / 2 != GNUNET_DNSPARSER_hex_to_bin (hex, &tlsa[1]))
671 {
672 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
673 _ ("Unable to parse TLSA record string `%s'\n"),
674 s);
675 GNUNET_free (*data);
676 *data = NULL;
677 *data_size = 0;
678 return GNUNET_SYSERR;
679 }
680 return GNUNET_OK;
681 }
682
683 case GNUNET_DNSPARSER_TYPE_CAA: { // RFC6844
684 struct GNUNET_DNSPARSER_CaaRecord *caa;
685 unsigned int flags;
686 char tag[15]; // Max tag length 15
687 char value[strlen (s) + 1]; // Should be more than enough
688
689 if (3 != sscanf (s, "%u %s %[^\n]", &flags, tag, value))
690 {
691 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
692 _ ("Unable to parse CAA record string `%s'\n"),
693 s);
694 *data_size = 0;
695 return GNUNET_SYSERR;
696 }
697 *data_size = sizeof(struct GNUNET_DNSPARSER_CaaRecord) + strlen (tag)
698 + strlen (value);
699 *data = caa = GNUNET_malloc (*data_size);
700 caa->flags = flags;
701 memcpy (&caa[1], tag, strlen (tag));
702 caa->tag_len = strlen (tag);
703 memcpy ((char *) &caa[1] + caa->tag_len, value, strlen (value));
704 return GNUNET_OK;
705 }
706
707 default:
708 return GNUNET_SYSERR;
709 }
710}
711
712
713/**
714 * Mapping of record type numbers to human-readable
715 * record type names.
716 */
717static struct
718{
719 const char *name;
720 uint32_t number;
721} name_map[] = { { "A", GNUNET_DNSPARSER_TYPE_A },
722 { "NS", GNUNET_DNSPARSER_TYPE_NS },
723 { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME },
724 { "SOA", GNUNET_DNSPARSER_TYPE_SOA },
725 { "PTR", GNUNET_DNSPARSER_TYPE_PTR },
726 { "MX", GNUNET_DNSPARSER_TYPE_MX },
727 { "TXT", GNUNET_DNSPARSER_TYPE_TXT },
728 { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA },
729 { "SRV", GNUNET_DNSPARSER_TYPE_SRV },
730 { "TLSA", GNUNET_DNSPARSER_TYPE_TLSA },
731 { "CERT", GNUNET_DNSPARSER_TYPE_CERT },
732 { "CAA", GNUNET_DNSPARSER_TYPE_CAA },
733 { NULL, UINT32_MAX } };
734
735
736/**
737 * Convert a type name (e.g. "AAAA") to the corresponding number.
738 *
739 * @param cls closure, unused
740 * @param dns_typename name to convert
741 * @return corresponding number, UINT32_MAX on error
742 */
743static uint32_t
744dns_typename_to_number (void *cls, const char *dns_typename)
745{
746 unsigned int i;
747
748 i = 0;
749 while ((NULL != name_map[i].name) &&
750 (0 != strcasecmp (dns_typename, name_map[i].name)))
751 i++;
752 return name_map[i].number;
753}
754
755
756/**
757 * Convert a type number to the corresponding type string (e.g. 1 to "A")
758 *
759 * @param cls closure, unused
760 * @param type number of a type to convert
761 * @return corresponding typestring, NULL on error
762 */
763static const char *
764dns_number_to_typename (void *cls, uint32_t type)
765{
766 unsigned int i;
767
768 i = 0;
769 while ((NULL != name_map[i].name) && (type != name_map[i].number))
770 i++;
771 return name_map[i].name;
772}
773
774
775static enum GNUNET_GenericReturnValue
776dns_is_critical (void *cls, uint32_t type)
777{
778 return GNUNET_NO;
779}
780
781/**
782 * Entry point for the plugin.
783 *
784 * @param cls NULL
785 * @return the exported block API
786 */
787void *
788libgnunet_plugin_gnsrecord_dns_init (void *cls)
789{
790 struct GNUNET_GNSRECORD_PluginFunctions *api;
791
792 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
793 api->value_to_string = &dns_value_to_string;
794 api->string_to_value = &dns_string_to_value;
795 api->typename_to_number = &dns_typename_to_number;
796 api->number_to_typename = &dns_number_to_typename;
797 api->is_critical = &dns_is_critical;
798 return api;
799}
800
801
802/**
803 * Exit point from the plugin.
804 *
805 * @param cls the return value from #libgnunet_plugin_block_test_init
806 * @return NULL
807 */
808void *
809libgnunet_plugin_gnsrecord_dns_done (void *cls)
810{
811 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
812
813 GNUNET_free (api);
814 return NULL;
815}
816
817
818/* end of plugin_gnsrecord_dns.c */
diff --git a/src/gnsrecord/test_gnsrecord_block_expiration.c b/src/gnsrecord/test_gnsrecord_block_expiration.c
deleted file mode 100644
index 3ef02e631..000000000
--- a/src/gnsrecord/test_gnsrecord_block_expiration.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 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 * @file gnsrecord/test_gnsrecord_crypto.c
22 * @brief testcase for block creation, verification and decryption
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_gnsrecord_lib.h"
27
28#define RECORDS 5
29
30#define TEST_RECORD_TYPE 1234
31
32#define TEST_RECORD_DATALEN 123
33
34#define TEST_RECORD_DATA 'a'
35
36#define TEST_REMOVE_RECORD_TYPE 4321
37
38#define TEST_REMOVE_RECORD_DATALEN 255
39
40#define TEST_REMOVE_RECORD_DATA 'b'
41
42static int res;
43
44
45static void
46run (void *cls, char *const *args, const char *cfgfile,
47 const struct GNUNET_CONFIGURATION_Handle *cfg)
48{
49 struct GNUNET_GNSRECORD_Data rd[2];
50 struct GNUNET_TIME_Absolute expiration_abs;
51 struct GNUNET_TIME_Absolute expiration_abs_shadow;
52
53 expiration_abs.abs_value_us = GNUNET_TIME_absolute_get ().abs_value_us
54 + GNUNET_TIME_UNIT_SECONDS.rel_value_us;
55 expiration_abs_shadow.abs_value_us = GNUNET_TIME_absolute_get ().abs_value_us
56 + GNUNET_TIME_UNIT_MINUTES.rel_value_us;
57
58 /* create record */
59 rd[0].expiration_time = expiration_abs.abs_value_us;
60 rd[0].record_type = TEST_RECORD_TYPE;
61 rd[0].data_size = TEST_RECORD_DATALEN;
62 rd[0].data = GNUNET_malloc (TEST_RECORD_DATALEN);
63 rd[0].flags = GNUNET_GNSRECORD_RF_NONE;
64 memset ((char *) rd[0].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
65
66 rd[1].expiration_time = expiration_abs.abs_value_us;
67 rd[1].record_type = TEST_RECORD_TYPE;
68 rd[1].data_size = TEST_RECORD_DATALEN;
69 rd[1].data = GNUNET_malloc (TEST_RECORD_DATALEN);
70 rd[1].flags = GNUNET_GNSRECORD_RF_NONE;
71 memset ((char *) rd[1].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
72
73 GNUNET_assert (expiration_abs.abs_value_us ==
74 GNUNET_GNSRECORD_record_get_expiration_time (2,
75 rd,
76 GNUNET_TIME_UNIT_ZERO_ABS).abs_value_us);
77
78 rd[1].expiration_time = expiration_abs_shadow.abs_value_us;
79 rd[1].record_type = TEST_RECORD_TYPE;
80 rd[1].data_size = TEST_RECORD_DATALEN;
81 GNUNET_free (rd[1].data);
82 rd[1].data = GNUNET_malloc (TEST_RECORD_DATALEN);
83 rd[1].flags = GNUNET_GNSRECORD_RF_SHADOW;
84 memset ((char *) rd[1].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
85
86 GNUNET_assert (expiration_abs_shadow.abs_value_us ==
87 GNUNET_GNSRECORD_record_get_expiration_time (2,
88 rd,
89 GNUNET_TIME_UNIT_ZERO_ABS).abs_value_us);
90 GNUNET_free (rd[0].data);
91 GNUNET_free (rd[1].data);
92 res = 0;
93}
94
95
96int
97main (int argc, char *argv[])
98{
99 static char *const argvx[] = { "test-gnsrecord-crypto",
100 NULL };
101 static struct GNUNET_GETOPT_CommandLineOption options[] = {
102 GNUNET_GETOPT_OPTION_END
103 };
104
105 res = 1;
106 GNUNET_PROGRAM_run ((sizeof(argvx) / sizeof(char *)) - 1, argvx,
107 "test-namestore-api",
108 "nohelp", options, &run, &res);
109 return res;
110}
111
112
113/* end of test_gnsrecord_crypto.c */
diff --git a/src/gnsrecord/test_gnsrecord_crypto.c b/src/gnsrecord/test_gnsrecord_crypto.c
deleted file mode 100644
index 92a7a9f1f..000000000
--- a/src/gnsrecord/test_gnsrecord_crypto.c
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 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 * @file gnsrecord/test_gnsrecord_crypto.c
22 * @brief testcase for block creation, verification and decryption
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_gnsrecord_lib.h"
27
28#define RECORDS 5
29
30#define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
31
32#define TEST_RECORD_DATALEN 123
33
34#define TEST_RECORD_DATA 'a'
35
36#define TEST_REMOVE_RECORD_TYPE 4321
37
38#define TEST_REMOVE_RECORD_DATALEN 255
39
40#define TEST_REMOVE_RECORD_DATA 'b'
41
42
43static struct GNUNET_GNSRECORD_Data *s_rd;
44
45static char *s_name;
46
47static int res;
48
49
50static struct GNUNET_GNSRECORD_Data *
51create_record (int count)
52{
53 struct GNUNET_GNSRECORD_Data *rd;
54
55 rd = GNUNET_new_array (count, struct GNUNET_GNSRECORD_Data);
56 for (unsigned int c = 0; c < count; c++)
57 {
58 rd[c].expiration_time = GNUNET_TIME_absolute_get ().abs_value_us
59 + 1000000000;
60 rd[c].record_type = TEST_RECORD_TYPE;
61 rd[c].data_size = TEST_RECORD_DATALEN;
62 rd[c].data = GNUNET_malloc (TEST_RECORD_DATALEN);
63 memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
64 }
65 return rd;
66}
67
68
69static void
70rd_decrypt_cb (void *cls,
71 unsigned int rd_count,
72 const struct GNUNET_GNSRECORD_Data *rd)
73{
74 char rd_cmp_data[TEST_RECORD_DATALEN];
75
76 GNUNET_assert (RECORDS == rd_count);
77 GNUNET_assert (NULL != rd);
78 memset (rd_cmp_data,
79 'a',
80 TEST_RECORD_DATALEN);
81 for (unsigned int c = 0; c < rd_count; c++)
82 {
83 GNUNET_assert (TEST_RECORD_TYPE == rd[c].record_type);
84 GNUNET_assert (TEST_RECORD_DATALEN == rd[c].data_size);
85 GNUNET_assert (0 == memcmp (&rd_cmp_data,
86 rd[c].data,
87 TEST_RECORD_DATALEN));
88 }
89 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
90 "Block was decrypted successfully \n");
91 res = 0;
92}
93
94
95static void
96test_with_type (struct GNUNET_IDENTITY_PrivateKey *privkey)
97{
98 struct GNUNET_GNSRECORD_Block *block;
99 struct GNUNET_IDENTITY_PublicKey pubkey;
100 struct GNUNET_HashCode query_pub;
101 struct GNUNET_HashCode query_priv;
102 struct GNUNET_HashCode query_block;
103 struct GNUNET_TIME_Absolute expire = GNUNET_TIME_UNIT_FOREVER_ABS;
104
105
106 /* get public key */
107 GNUNET_IDENTITY_key_get_public (privkey,
108 &pubkey);
109
110 /* test query derivation */
111 GNUNET_GNSRECORD_query_from_private_key (privkey,
112 "testlabel",
113 &query_priv);
114 GNUNET_GNSRECORD_query_from_public_key (&pubkey,
115 "testlabel",
116 &query_pub);
117 GNUNET_assert (0 == memcmp (&query_priv,
118 &query_pub,
119 sizeof(struct GNUNET_HashCode)));
120 /* create record */
121 s_name = "testlabel";
122 s_rd = create_record (RECORDS);
123
124 /* Create block */
125 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (privkey,
126 expire,
127 s_name,
128 s_rd,
129 RECORDS,
130 &block));
131 GNUNET_assert (GNUNET_OK ==
132 GNUNET_GNSRECORD_query_from_block (block,
133 &query_block));
134 GNUNET_assert (0 == memcmp (&query_pub,
135 &query_block,
136 sizeof(struct GNUNET_HashCode)));
137
138 GNUNET_assert (GNUNET_OK ==
139 GNUNET_GNSRECORD_block_verify (block));
140 GNUNET_assert (GNUNET_OK ==
141 GNUNET_GNSRECORD_block_decrypt (block,
142 &pubkey,
143 s_name,
144 &rd_decrypt_cb,
145 NULL));
146 for (int i = 0; i < RECORDS; i++) GNUNET_free(s_rd[i].data);
147 GNUNET_free (s_rd);
148 GNUNET_free (block);
149}
150
151
152static void
153run (void *cls,
154 char *const *args,
155 const char *cfgfile,
156 const struct GNUNET_CONFIGURATION_Handle *cfg)
157{
158 struct GNUNET_IDENTITY_PrivateKey privkey;
159 struct GNUNET_IDENTITY_PrivateKey privkey_ed;
160 struct GNUNET_TIME_Absolute start;
161 struct GNUNET_TIME_Absolute end;
162
163
164 privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
165 GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
166 start = GNUNET_TIME_absolute_get ();
167 test_with_type (&privkey);
168 end = GNUNET_TIME_absolute_get ();
169 printf ("Time: %llu ms\n", (unsigned long long)
170 GNUNET_TIME_absolute_get_difference (start,
171 end).rel_value_us);
172
173 privkey_ed.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
174 GNUNET_CRYPTO_eddsa_key_create (&privkey_ed.eddsa_key);
175 start = GNUNET_TIME_absolute_get ();
176 test_with_type (&privkey_ed);
177 end = GNUNET_TIME_absolute_get ();
178 printf ("Time: %llu ms\n", (unsigned long long)
179 GNUNET_TIME_absolute_get_difference (start,
180 end).rel_value_us);
181
182
183}
184
185
186int
187main (int argc, char *argv[])
188{
189 static char *const argvx[] = {
190 "test-gnsrecord-crypto",
191 NULL
192 };
193 static struct GNUNET_GETOPT_CommandLineOption options[] = {
194 GNUNET_GETOPT_OPTION_END
195 };
196
197 res = 1;
198 GNUNET_PROGRAM_run ((sizeof(argvx) / sizeof(char *)) - 1,
199 argvx,
200 "test-gnsrecord-crypto",
201 "nohelp", options,
202 &run, &res);
203 return res;
204}
205
206
207/* end of test_gnsrecord_crypto.c */
diff --git a/src/gnsrecord/test_gnsrecord_serialization.c b/src/gnsrecord/test_gnsrecord_serialization.c
deleted file mode 100644
index b06b3a0fe..000000000
--- a/src/gnsrecord/test_gnsrecord_serialization.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 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 * @file gnsrecord/test_gnsrecord_serialization.c
22 * @brief testcase for gnsrecord_serialization.c
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_gnsrecord_lib.h"
27
28#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
29
30static int res;
31
32
33static void
34run (void *cls,
35 char *const *args,
36 const char *cfgfile,
37 const struct GNUNET_CONFIGURATION_Handle *cfg)
38{
39 size_t len;
40 int c;
41
42 int rd_count = 3;
43 size_t data_len;
44 struct GNUNET_GNSRECORD_Data src[rd_count];
45
46 memset (src, '\0', rd_count * sizeof(struct GNUNET_GNSRECORD_Data));
47
48 data_len = 0;
49 for (c = 0; c < rd_count; c++)
50 {
51 src[c].record_type = GNUNET_DNSPARSER_TYPE_TXT;
52 src[c].data_size = data_len;
53 src[c].data = GNUNET_malloc (data_len);
54
55 /* Setting data to data_len * record_type */
56 memset ((char *) src[c].data, 'a', data_len);
57 data_len += 10;
58 }
59 res = 0;
60
61 len = GNUNET_GNSRECORD_records_get_size (rd_count, src);
62 char rd_ser[len];
63 GNUNET_assert (len ==
64 GNUNET_GNSRECORD_records_serialize (rd_count,
65 src,
66 len,
67 rd_ser));
68
69 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
70 "Serialized data len: %u\n",
71 (unsigned int) len);
72
73 GNUNET_assert (rd_ser != NULL);
74 {
75 struct GNUNET_GNSRECORD_Data dst[rd_count];
76 GNUNET_assert (GNUNET_OK ==
77 GNUNET_GNSRECORD_records_deserialize (len,
78 rd_ser,
79 rd_count,
80 dst));
81
82 GNUNET_assert (dst != NULL);
83
84 for (c = 0; c < rd_count; c++)
85 {
86 if (src[c].data_size != dst[c].data_size)
87 {
88 GNUNET_break (0);
89 res = 1;
90 }
91 if (src[c].expiration_time != dst[c].expiration_time)
92 {
93 GNUNET_break (0);
94 res = 1;
95 }
96 if (src[c].flags != dst[c].flags)
97 {
98 GNUNET_break (0);
99 res = 1;
100 }
101 if (src[c].record_type != dst[c].record_type)
102 {
103 GNUNET_break (0);
104 res = 1;
105 }
106
107 {
108 size_t data_size = src[c].data_size;
109 char data[data_size];
110
111 memset (data, 'a', data_size);
112 if (0 != memcmp (data, dst[c].data, data_size))
113 {
114 GNUNET_break (0);
115 res = 1;
116 }
117 if (0 != memcmp (data, src[c].data, data_size))
118 {
119 GNUNET_break (0);
120 res = 1;
121 }
122 if (0 != memcmp (src[c].data, dst[c].data, src[c].data_size))
123 {
124 GNUNET_break (0);
125 res = 1;
126 }
127 }
128 }
129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c);
130 }
131
132 for (c = 0; c < rd_count; c++)
133 {
134 GNUNET_free_nz ((void *) src[c].data);
135 }
136}
137
138
139int
140main (int argcx, char *argvx[])
141{
142 static char *const argv[] = { "test_gnsrecord_serialization",
143 NULL };
144 static struct GNUNET_GETOPT_CommandLineOption options[] = {
145 GNUNET_GETOPT_OPTION_END
146 };
147
148 res = 1;
149 GNUNET_PROGRAM_run ((sizeof(argv) / sizeof(char *)) - 1, argv,
150 "test_namestore_record_serialization",
151 "nohelp", options, &run, &res);
152 return res;
153}
154
155
156/* end of test_gnsrecord_serialization.c */
diff --git a/src/gnsrecord/test_gnsrecord_testvectors.c b/src/gnsrecord/test_gnsrecord_testvectors.c
deleted file mode 100644
index e0d959f0e..000000000
--- a/src/gnsrecord/test_gnsrecord_testvectors.c
+++ /dev/null
@@ -1,711 +0,0 @@
1#include "platform.h"
2#include "gnunet_util_lib.h"
3#include "gnunet_gns_service.h"
4#include "gnunet_gnsrecord_lib.h"
5#include <inttypes.h>
6#include "gnsrecord_crypto.h"
7
8int res;
9
10struct GnsTv
11{
12 uint32_t expected_rd_count;
13 struct GNUNET_GNSRECORD_Data expected_rd[2048];
14 char *d;
15 char *zid;
16 char *ztld;
17 char *label;
18 char *q;
19 char *rdata;
20 char *rrblock;
21 char *k;
22 char *nonce;
23};
24
25struct RevocationTv
26{
27 char *d;
28 char *zid;
29 char *ztld;
30 char *m;
31 char *proof;
32 int diff;
33 int epochs;
34};
35
36struct RevocationTv rtvs[] = {
37 {
38 .d =
39 "70 ed 98 b9 07 8c 47 f7"
40 "d5 78 3b 26 cc f9 8b 7d"
41 "d5 5f 60 88 d1 53 95 97"
42 "fa 8b f5 5a c0 32 ea 6f",
43 .zid =
44 "00 01 00 00 2c a2 23 e8"
45 "79 ec c4 bb de b5 da 17"
46 "31 92 81 d6 3b 2e 3b 69"
47 "55 f1 c3 77 5c 80 4a 98"
48 "d5 f8 dd aa",
49 .ztld =
50 "000G001CM8HYGYFCRJXXXDET2WRS50EP7CQ3PTANY71QEQ409ACDBY6XN8",
51 .m =
52 "00 00 00 34 00 00 00 03"
53 "00 05 fe b4 6d 86 5c 1c"
54 "00 01 00 00 2c a2 23 e8"
55 "79 ec c4 bb de b5 da 17"
56 "31 92 81 d6 3b 2e 3b 69"
57 "55 f1 c3 77 5c 80 4a 98"
58 "d5 f8 dd aa",
59 .proof =
60 "00 05 fe b4 6d 86 5c 1c"
61 "00 00 39 5d 18 27 c0 00"
62 "e6 6a 57 0b cc d4 b3 93"
63 "e6 6a 57 0b cc d4 b3 ea"
64 "e6 6a 57 0b cc d4 b5 36"
65 "e6 6a 57 0b cc d4 b5 42"
66 "e6 6a 57 0b cc d4 b6 13"
67 "e6 6a 57 0b cc d4 b6 5f"
68 "e6 6a 57 0b cc d4 b6 72"
69 "e6 6a 57 0b cc d4 b7 0a"
70 "e6 6a 57 0b cc d4 b7 1a"
71 "e6 6a 57 0b cc d4 b7 23"
72 "e6 6a 57 0b cc d4 b7 47"
73 "e6 6a 57 0b cc d4 b7 77"
74 "e6 6a 57 0b cc d4 b7 85"
75 "e6 6a 57 0b cc d4 b7 89"
76 "e6 6a 57 0b cc d4 b7 cf"
77 "e6 6a 57 0b cc d4 b7 dc"
78 "e6 6a 57 0b cc d4 b9 3a"
79 "e6 6a 57 0b cc d4 b9 56"
80 "e6 6a 57 0b cc d4 ba 4a"
81 "e6 6a 57 0b cc d4 ba 9d"
82 "e6 6a 57 0b cc d4 bb 28"
83 "e6 6a 57 0b cc d4 bb 5a"
84 "e6 6a 57 0b cc d4 bb 92"
85 "e6 6a 57 0b cc d4 bb a2"
86 "e6 6a 57 0b cc d4 bb d8"
87 "e6 6a 57 0b cc d4 bb e2"
88 "e6 6a 57 0b cc d4 bc 93"
89 "e6 6a 57 0b cc d4 bc 94"
90 "e6 6a 57 0b cc d4 bd 0f"
91 "e6 6a 57 0b cc d4 bd ce"
92 "e6 6a 57 0b cc d4 be 6a"
93 "e6 6a 57 0b cc d4 be 73"
94 "00 01 00 00 2c a2 23 e8"
95 "79 ec c4 bb de b5 da 17"
96 "31 92 81 d6 3b 2e 3b 69"
97 "55 f1 c3 77 5c 80 4a 98"
98 "d5 f8 dd aa 04 4a 87 8a"
99 "15 8b 40 f0 c8 41 d9 f9"
100 "78 cb 13 72 ea ee 51 99"
101 "a3 d8 7e 5e 2b db c7 2a"
102 "6c 8c 73 d0 00 18 1d fc"
103 "39 c3 aa a4 81 66 7b 16"
104 "5b 58 44 e4 50 71 3d 8a"
105 "b6 a3 b2 ba 8f ef 44 7b"
106 "65 07 6a 0f",
107 .diff = 5,
108 .epochs = 2
109 }
110};
111
112struct GnsTv tvs[] = {
113 { .d =
114 "50 d7 b6 52 a4 ef ea df"
115 "f3 73 96 90 97 85 e5 95"
116 "21 71 a0 21 78 c8 e7 d4"
117 "50 fa 90 79 25 fa fd 98",
118 .zid =
119 "00 01 00 00 67 7c 47 7d"
120 "2d 93 09 7c 85 b1 95 c6"
121 "f9 6d 84 ff 61 f5 98 2c"
122 "2c 4f e0 2d 5a 11 fe df"
123 "b0 c2 90 1f",
124 .ztld = "000G0037FH3QTBCK15Y8BCCNRVWPV17ZC7TSGB1C9ZG2TPGHZVFV1GMG3W",
125 .label = "74 65 73 74 64 65 6c 65"
126 "67 61 74 69 6f 6e",
127 .q =
128 "4a dc 67 c5 ec ee 9f 76"
129 "98 6a bd 71 c2 22 4a 3d"
130 "ce 2e 91 70 26 c9 a0 9d"
131 "fd 44 ce f3 d2 0f 55 a2"
132 "73 32 72 5a 6c 8a fb bb"
133 "b0 f7 ec 9a f1 cc 42 64"
134 "12 99 40 6b 04 fd 9b 5b"
135 "57 91 f8 6c 4b 08 d5 f4",
136 .nonce =
137 "e9 0a 00 61 00 1c ee 8c"
138 "10 e2 59 80 00 00 00 01",
139 .k =
140 "86 4e 71 38 ea e7 fd 91"
141 "a3 01 36 89 9c 13 2b 23"
142 "ac eb db 2c ef 43 cb 19"
143 "f6 bf 55 b6 7d b9 b3 b3",
144 .rdata =
145 "00 1c ee 8c 10 e2 59 80"
146 "00 20 00 01 00 01 00 00"
147 "21 e3 b3 0f f9 3b c6 d3"
148 "5a c8 c6 e0 e1 3a fd ff"
149 "79 4c b7 b4 4b bb c7 48"
150 "d2 59 d0 a0 28 4d be 84",
151 .rrblock =
152 "00 00 00 a0 00 01 00 00"
153 "18 2b b6 36 ed a7 9f 79"
154 "57 11 bc 27 08 ad bb 24"
155 "2a 60 44 6a d3 c3 08 03"
156 "12 1d 03 d3 48 b7 ce b6"
157 "0a d1 0b c1 3b 40 3b 5b"
158 "25 61 26 b2 14 5a 6f 60"
159 "c5 14 f9 51 ff a7 66 f7"
160 "a3 fd 4b ac 4a 4e 19 90"
161 "05 5c b8 7e 8d 1b fd 19"
162 "aa 09 a4 29 f7 29 e9 f5"
163 "c6 ee c2 47 0a ce e2 22"
164 "07 59 e9 e3 6c 88 6f 35"
165 "00 1c ee 8c 10 e2 59 80"
166 "0c 1e da 5c c0 94 a1 c7"
167 "a8 88 64 9d 25 fa ee bd"
168 "60 da e6 07 3d 57 d8 ae"
169 "8d 45 5f 4f 13 92 c0 74"
170 "e2 6a c6 69 bd ee c2 34"
171 "62 b9 62 95 2c c6 e9 eb"},
172 { .d =
173 "50 d7 b6 52 a4 ef ea df"
174 "f3 73 96 90 97 85 e5 95"
175 "21 71 a0 21 78 c8 e7 d4"
176 "50 fa 90 79 25 fa fd 98",
177 .zid =
178 "00 01 00 00 67 7c 47 7d"
179 "2d 93 09 7c 85 b1 95 c6"
180 "f9 6d 84 ff 61 f5 98 2c"
181 "2c 4f e0 2d 5a 11 fe df"
182 "b0 c2 90 1f",
183 .ztld = "000G0037FH3QTBCK15Y8BCCNRVWPV17ZC7TSGB1C9ZG2TPGHZVFV1GMG3W",
184 .label =
185 "e5 a4 a9 e4 b8 8b e7 84"
186 "a1 e6 95 b5",
187 .nonce =
188 "ee 96 33 c1 00 1c ee 8c"
189 "10 e2 59 80 00 00 00 01",
190 .k =
191 "fb 3a b5 de 23 bd da e1"
192 "99 7a af 7b 92 c2 d2 71"
193 "51 40 8b 77 af 7a 41 ac"
194 "79 05 7c 4d f5 38 3d 01",
195 .q =
196 "af f0 ad 6a 44 09 73 68"
197 "42 9a c4 76 df a1 f3 4b"
198 "ee 4c 36 e7 47 6d 07 aa"
199 "64 63 ff 20 91 5b 10 05"
200 "c0 99 1d ef 91 fc 3e 10"
201 "90 9f 87 02 c0 be 40 43"
202 "67 78 c7 11 f2 ca 47 d5"
203 "5c f0 b5 4d 23 5d a9 77",
204 .rdata =
205 "00 1c ee 8c 10 e2 59 80"
206 "00 10 00 00 00 00 00 1c"
207 "00 00 00 00 00 00 00 00"
208 "00 00 00 00 de ad be ef"
209 "00 3f f2 aa 54 08 db 40"
210 "00 06 00 00 00 01 00 01"
211 "e6 84 9b e7 a7 b0 00 28"
212 "bb 13 ff 37 19 40 00 0b"
213 "00 04 00 00 00 10 48 65"
214 "6c 6c 6f 20 57 6f 72 6c"
215 "64 00 00 00 00 00 00 00"
216 "00 00 00 00 00 00 00 00"
217 "00 00 00 00 00 00 00 00"
218 "00 00 00 00 00 00 00 00"
219 "00 00 00 00 00 00 00 00"
220 "00 00 00 00 00 00 00 00",
221 .rrblock =
222 "00 00 00 f0 00 01 00 00"
223 "a5 12 96 df 75 7e e2 75"
224 "ca 11 8d 4f 07 fa 7a ae"
225 "55 08 bc f5 12 aa 41 12"
226 "14 29 d4 a0 de 9d 05 7e"
227 "08 5b d6 5f d4 85 10 51"
228 "ba ce 2a 45 2a fc 8a 7e"
229 "4f 6b 2c 1f 74 f0 20 35"
230 "d9 64 1a cd ba a4 66 e0"
231 "00 ce d6 f2 d2 3b 63 1c"
232 "8e 8a 0b 38 e2 ba e7 9a"
233 "22 ca d8 1d 4c 50 d2 25"
234 "35 8e bc 17 ac 0f 89 9e"
235 "00 1c ee 8c 10 e2 59 80"
236 "d8 c2 8d 2f d6 96 7d 1a"
237 "b7 22 53 f2 10 98 b8 14"
238 "a4 10 be 1f 59 98 de 03"
239 "f5 8f 7e 7c db 7f 08 a6"
240 "16 51 be 4d 0b 6f 8a 61"
241 "df 15 30 44 0b d7 47 dc"
242 "f0 d7 10 4f 6b 8d 24 c2"
243 "ac 9b c1 3d 9c 6f e8 29"
244 "05 25 d2 a6 d0 f8 84 42"
245 "67 a1 57 0e 8e 29 4d c9"
246 "3a 31 9f cf c0 3e a2 70"
247 "17 d6 fd a3 47 b4 a7 94"
248 "97 d7 f6 b1 42 2d 4e dd"
249 "82 1c 19 93 4e 96 c1 aa"
250 "87 76 57 25 d4 94 c7 64"
251 "b1 55 dc 6d 13 26 91 74"},
252 { .d =
253 "5a f7 02 0e e1 91 60 32"
254 "88 32 35 2b bc 6a 68 a8"
255 "d7 1a 7c be 1b 92 99 69"
256 "a7 c6 6d 41 5a 0d 8f 65",
257 .zid =
258 "00 01 00 14 3c f4 b9 24"
259 "03 20 22 f0 dc 50 58 14"
260 "53 b8 5d 93 b0 47 b6 3d"
261 "44 6c 58 45 cb 48 44 5d"
262 "db 96 68 8f",
263 .ztld = "000G051WYJWJ80S04BRDRM2R2H9VGQCKP13VCFA4DHC4BJT88HEXQ5K8HW",
264 .label =
265 "74 65 73 74 64 65 6c 65"
266 "67 61 74 69 6f 6e",
267 .nonce =
268 "98 13 2e a8 68 59 d3 5c"
269 "88 bf d3 17 fa 99 1b cb"
270 "00 1c ee 8c 10 e2 59 80",
271 .k =
272 "85 c4 29 a9 56 7a a6 33"
273 "41 1a 96 91 e9 09 4c 45"
274 "28 16 72 be 58 60 34 aa"
275 "e4 a2 a2 cc 71 61 59 e2",
276 .q =
277 "ab aa ba c0 e1 24 94 59"
278 "75 98 83 95 aa c0 24 1e"
279 "55 59 c4 1c 40 74 e2 55"
280 "7b 9f e6 d1 54 b6 14 fb"
281 "cd d4 7f c7 f5 1d 78 6d"
282 "c2 e0 b1 ec e7 60 37 c0"
283 "a1 57 8c 38 4e c6 1d 44"
284 "56 36 a9 4e 88 03 29 e9",
285 .rdata =
286 "00 1c ee 8c 10 e2 59 80"
287 "00 20 00 01 00 01 00 00"
288 "21 e3 b3 0f f9 3b c6 d3"
289 "5a c8 c6 e0 e1 3a fd ff"
290 "79 4c b7 b4 4b bb c7 48"
291 "d2 59 d0 a0 28 4d be 84",
292 .rrblock =
293 "00 00 00 b0 00 01 00 14"
294 "9b f2 33 19 8c 6d 53 bb"
295 "db ac 49 5c ab d9 10 49"
296 "a6 84 af 3f 40 51 ba ca"
297 "b0 dc f2 1c 8c f2 7a 1a"
298 "9f 56 a8 86 ea 73 9d 59"
299 "17 50 8f 9b 75 56 39 f3"
300 "a9 ac fa ed ed ca 7f bf"
301 "a7 94 b1 92 e0 8b f9 ed"
302 "4c 7e c8 59 4c 9f 7b 4e"
303 "19 77 4f f8 38 ec 38 7a"
304 "8f 34 23 da ac 44 9f 59"
305 "db 4e 83 94 3f 90 72 00"
306 "00 1c ee 8c 10 e2 59 80"
307 "57 7c c6 c9 5a 14 e7 04"
308 "09 f2 0b 01 67 e6 36 d0"
309 "10 80 7c 4f 00 37 2d 69"
310 "8c 82 6b d9 2b c2 2b d6"
311 "bb 45 e5 27 7c 01 88 1d"
312 "6a 43 60 68 e4 dd f1 c6"
313 "b7 d1 41 6f af a6 69 7c"
314 "25 ed d9 ea e9 91 67 c3"},
315 { .d =
316 "5a f7 02 0e e1 91 60 32"
317 "88 32 35 2b bc 6a 68 a8"
318 "d7 1a 7c be 1b 92 99 69"
319 "a7 c6 6d 41 5a 0d 8f 65",
320 .zid =
321 "00 01 00 14 3c f4 b9 24"
322 "03 20 22 f0 dc 50 58 14"
323 "53 b8 5d 93 b0 47 b6 3d"
324 "44 6c 58 45 cb 48 44 5d"
325 "db 96 68 8f",
326 .ztld = "000G051WYJWJ80S04BRDRM2R2H9VGQCKP13VCFA4DHC4BJT88HEXQ5K8HW",
327 .label =
328 "e5 a4 a9 e4 b8 8b e7 84"
329 "a1 e6 95 b5",
330 .nonce =
331 "bb 0d 3f 0f bd 22 42 77"
332 "50 da 5d 69 12 16 e6 c9"
333 "00 1c ee 8c 10 e2 59 80",
334 .k =
335 "3d f8 05 bd 66 87 aa 14"
336 "20 96 28 c2 44 b1 11 91"
337 "88 c3 92 56 37 a4 1e 5d"
338 "76 49 6c 29 45 dc 37 7b",
339 .q =
340 "ba f8 21 77 ee c0 81 e0"
341 "74 a7 da 47 ff c6 48 77"
342 "58 fb 0d f0 1a 6c 7f bb"
343 "52 fc 8a 31 be f0 29 af"
344 "74 aa 0d c1 5a b8 e2 fa"
345 "7a 54 b4 f5 f6 37 f6 15"
346 "8f a7 f0 3c 3f ce be 78"
347 "d3 f9 d6 40 aa c0 d1 ed",
348 .rdata =
349 "00 1c ee 8c 10 e2 59 80"
350 "00 10 00 00 00 00 00 1c"
351 "00 00 00 00 00 00 00 00"
352 "00 00 00 00 de ad be ef"
353 "00 3f f2 aa 54 08 db 40"
354 "00 06 00 00 00 01 00 01"
355 "e6 84 9b e7 a7 b0 00 28"
356 "bb 13 ff 37 19 40 00 0b"
357 "00 04 00 00 00 10 48 65"
358 "6c 6c 6f 20 57 6f 72 6c"
359 "64 00 00 00 00 00 00 00"
360 "00 00 00 00 00 00 00 00"
361 "00 00 00 00 00 00 00 00"
362 "00 00 00 00 00 00 00 00"
363 "00 00 00 00 00 00 00 00"
364 "00 00 00 00 00 00 00 00",
365 .rrblock =
366 "00 00 01 00 00 01 00 14"
367 "74 f9 00 68 f1 67 69 53"
368 "52 a8 a6 c2 eb 98 48 98"
369 "c5 3a cc a0 98 04 70 c6"
370 "c8 12 64 cb dd 78 ad 11"
371 "75 6d 2c 15 7a d2 ea 4f"
372 "c0 b1 b9 1c 08 03 79 44"
373 "61 d3 de f2 0d d1 63 6c"
374 "fe dc 03 89 c5 49 d1 43"
375 "6c c3 5b 4e 1b f8 89 5a"
376 "64 6b d9 a6 f4 6b 83 48"
377 "1d 9c 0e 91 d4 e1 be bb"
378 "6a 83 52 6f b7 25 2a 06"
379 "00 1c ee 8c 10 e2 59 80"
380 "4e b3 5a 50 d4 0f e1 a4"
381 "29 c7 f4 b2 67 a0 59 de"
382 "4e 2c 8a 89 a5 ed 53 d3"
383 "d4 92 58 59 d2 94 9f 7f"
384 "30 d8 a2 0c aa 96 f8 81"
385 "45 05 2d 1c da 04 12 49"
386 "8f f2 5f f2 81 6e f0 ce"
387 "61 fe 69 9b fa c7 2c 15"
388 "dc 83 0e a9 b0 36 17 1c"
389 "cf ca bb dd a8 de 3c 86"
390 "ed e2 95 70 d0 17 4b 82"
391 "82 09 48 a9 28 b7 f0 0e"
392 "fb 40 1c 10 fe 80 bb bb"
393 "02 76 33 1b f7 f5 1b 8d"
394 "74 57 9c 14 14 f2 2d 50"
395 "1a d2 5a e2 49 f5 bb f2"
396 "a6 c3 72 59 d1 75 e4 40"
397 "b2 94 39 c6 05 19 cb b1"},
398 {.d = NULL}
399};
400
401static void
402print_bytes_ (void *buf,
403 size_t buf_len,
404 int fold,
405 int in_be)
406{
407 int i;
408
409 for (i = 0; i < buf_len; i++)
410 {
411 if (0 != i)
412 {
413 if ((0 != fold) && (i % fold == 0))
414 printf ("\n ");
415 else
416 printf (" ");
417 }
418 else
419 {
420 printf (" ");
421 }
422 if (in_be)
423 printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
424 else
425 printf ("%02x", ((unsigned char*) buf)[i]);
426 }
427 printf ("\n");
428}
429
430
431static void
432print_bytes (void *buf,
433 size_t buf_len,
434 int fold)
435{
436 print_bytes_ (buf, buf_len, fold, 0);
437}
438
439
440int
441parsehex (char *src, char *dst, size_t dstlen, int invert)
442{
443 int off;
444 int read_byte;
445 int data_len = 0;
446 char data[strlen (src) + 1];
447 char *pos = data;
448 int i = 0;
449 int j = 0;
450 memset (data, 0, strlen (src) + 1);
451
452 for (i = 0; i < strlen (src); i++)
453 {
454 if ((src[i] == ' ') || (src[i] == '\n'))
455 continue;
456 data[j++] = src[i];
457 }
458
459 while (sscanf (pos, " %02x%n", &read_byte, &off) == 1)
460 {
461 if (invert)
462 dst[dstlen - 1 - data_len++] = read_byte;
463 else
464 dst[data_len++] = read_byte;
465 pos += off;
466 }
467 return data_len;
468}
469
470
471void
472res_checker (void *cls,
473 unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
474{
475 struct GnsTv *tv = cls;
476 if (rd_count != tv->expected_rd_count)
477 {
478 printf ("FAIL: Record count expected: %u, was: %u\n", tv->expected_rd_count,
479 rd_count);
480 res = 1;
481 return;
482 }
483 for (int i = 0; i < rd_count; i++)
484 {
485 if (rd[i].record_type != tv->expected_rd[i].record_type)
486 {
487 printf ("FAIL: Record type expected: %u, was: %u\n",
488 tv->expected_rd[i].record_type,
489 rd[i].record_type);
490 res = 1;
491 return;
492 }
493 if (rd[i].expiration_time != tv->expected_rd[i].expiration_time)
494 {
495 printf ("FAIL: Expiration expected: %" PRIu64 ", was: %" PRIu64 "\n",
496 tv->expected_rd[i].expiration_time,
497 rd[i].expiration_time);
498 res = 1;
499 return;
500 }
501 if (rd[i].flags != tv->expected_rd[i].flags)
502 {
503 printf ("FAIL: Record flags expected: %u, was: %u\n",
504 tv->expected_rd[i].flags,
505 rd[i].flags);
506 res = 1;
507 return;
508 }
509 if (rd[i].data_size != tv->expected_rd[i].data_size)
510 {
511 printf ("FAIL: Record data size expected: %lu, was: %lu\n",
512 tv->expected_rd[i].data_size,
513 rd[i].data_size);
514 res = 1;
515 return;
516 }
517 if (0 != memcmp (rd[i].data, tv->expected_rd[i].data,
518 rd[i].data_size))
519 {
520 printf ("FAIL: Record data does not match\n");
521 res = 1;
522 return;
523 }
524 }
525}
526
527
528enum GNUNET_GenericReturnValue
529check_derivations_edkey (const char*label,
530 struct GNUNET_TIME_Absolute expire,
531 struct GNUNET_IDENTITY_PublicKey *pub,
532 struct GnsTv *tv)
533{
534 unsigned char nonce[crypto_secretbox_NONCEBYTES];
535 unsigned char skey[crypto_secretbox_KEYBYTES];
536 unsigned char nonce_expected[crypto_secretbox_NONCEBYTES];
537 unsigned char skey_expected[crypto_secretbox_KEYBYTES];
538
539
540 parsehex (tv->nonce,(char*) nonce_expected, crypto_secretbox_NONCEBYTES, 0);
541 parsehex (tv->k,(char*) skey_expected, crypto_secretbox_KEYBYTES, 0);
542 GNR_derive_block_xsalsa_key (nonce,
543 skey,
544 label,
545 GNUNET_TIME_absolute_hton (
546 expire).abs_value_us__,
547 &pub->eddsa_key);
548 /* Ignore random 128-bit nonce, can't check this here. Will be checked on
549 * decryption. */
550 if (0 != memcmp (nonce + 16, nonce_expected + 16, sizeof (nonce) - 16))
551 {
552 printf ("FAIL: Failed to derive nonce:\n");
553 print_bytes (nonce, sizeof (nonce), 8);
554 print_bytes (nonce_expected, sizeof (nonce), 8);
555 return GNUNET_NO;
556 }
557 if (0 != memcmp (skey, skey_expected, sizeof (skey)))
558 {
559 printf ("FAIL: Failed to derive secret key\n");
560 return GNUNET_NO;
561 }
562 return GNUNET_OK;
563}
564
565
566enum GNUNET_GenericReturnValue
567check_derivations_pkey (const char*label,
568 struct GNUNET_TIME_Absolute expire,
569 struct GNUNET_IDENTITY_PublicKey *pub,
570 struct GnsTv *tv)
571{
572 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
573 unsigned char ctr_expected[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
574 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
575 unsigned char skey_expected[GNUNET_CRYPTO_AES_KEY_LENGTH];
576
577 parsehex (tv->nonce,(char*) ctr_expected, sizeof (ctr), 0);
578 parsehex (tv->k,(char*) skey_expected, sizeof (skey), 0);
579 GNR_derive_block_aes_key (ctr,
580 skey,
581 label,
582 GNUNET_TIME_absolute_hton (
583 expire).abs_value_us__,
584 &pub->ecdsa_key);
585
586 /* Ignore random 32-bit nonce, can't check this here. Will be checked on
587 * decryption. */
588 if (0 != memcmp (ctr + 4, ctr_expected + 4, sizeof (ctr) - 4))
589 {
590 printf ("FAIL: Failed to derive nonce\n");
591 return GNUNET_NO;
592 }
593 if (0 != memcmp (skey, skey_expected, sizeof (skey)))
594 {
595 printf ("FAIL: Failed to derive secret key\n");
596 return GNUNET_NO;
597 }
598 return GNUNET_OK;
599}
600
601
602int
603main ()
604{
605 struct GNUNET_IDENTITY_PrivateKey priv;
606 struct GNUNET_IDENTITY_PublicKey pub;
607 struct GNUNET_IDENTITY_PublicKey pub_parsed;
608 struct GNUNET_GNSRECORD_Block *rrblock;
609 struct GNUNET_HashCode query;
610 struct GNUNET_HashCode expected_query;
611 struct GNUNET_TIME_Absolute expire;
612 struct GNUNET_TIME_Relative exprel;
613 struct GNUNET_REVOCATION_PowP *pow;
614 char label[128];
615 char rdata[8096];
616 char ztld[128];
617 res = 0;
618
619 for (int i = 0; NULL != tvs[i].d; i++)
620 {
621 printf ("Test vector #%d\n", i);
622 memset (label, 0, sizeof (label));
623 parsehex (tvs[i].zid,(char*) &pub_parsed, 36, 0);
624 parsehex (tvs[i].d,(char*) &priv.ecdsa_key, sizeof (priv.ecdsa_key),
625 (GNUNET_GNSRECORD_TYPE_PKEY == ntohl (pub_parsed.type)) ? 1 : 0);
626 priv.type = pub_parsed.type;
627 GNUNET_IDENTITY_key_get_public (&priv, &pub);
628 if (0 != memcmp (&pub, &pub_parsed, GNUNET_IDENTITY_public_key_get_length (
629 &pub)))
630 {
631 printf ("Wrong pubkey.\n");
632 print_bytes (&pub, 36, 8);
633 print_bytes (&pub_parsed, 36, 8);
634 res = 1;
635 break;
636 }
637 GNUNET_STRINGS_data_to_string (&pub,
638 GNUNET_IDENTITY_public_key_get_length (
639 &pub),
640 ztld,
641 sizeof (ztld));
642 if (0 != strcmp (ztld, tvs[i].ztld))
643 {
644 printf ("Wrong zTLD: expected %s, got %s\n", tvs[i].ztld, ztld);
645 res = 1;
646 break;
647 }
648 rrblock = GNUNET_malloc (strlen (tvs[i].rrblock));
649 parsehex (tvs[i].rrblock, (char*) rrblock, 0, 0);
650 parsehex (tvs[i].label, (char*) label, 0, 0);
651 parsehex (tvs[i].q, (char*) &query, 0, 0);
652 GNUNET_GNSRECORD_query_from_public_key (&pub_parsed,
653 label,
654 &expected_query);
655 if (0 != GNUNET_memcmp (&query, &expected_query))
656 {
657 printf ("FAIL: query does not match:");
658 printf (" expected: %s", GNUNET_h2s (&expected_query));
659 printf (", was: %s\n", GNUNET_h2s (&query));
660 res = 1;
661 break;
662 }
663 int len = parsehex (tvs[i].rdata, (char*) rdata, 0, 0);
664 tvs[i].expected_rd_count =
665 GNUNET_GNSRECORD_records_deserialize_get_size (len,
666 rdata);
667 GNUNET_assert (tvs[i].expected_rd_count < 2048);
668 if (GNUNET_OK !=
669 GNUNET_GNSRECORD_records_deserialize (len,
670 rdata,
671 tvs[i].expected_rd_count,
672 tvs[i].expected_rd))
673 {
674 printf ("FAIL: Deserialization of RDATA failed\n");
675 res = 1;
676 break;
677 }
678 expire = GNUNET_GNSRECORD_record_get_expiration_time (
679 tvs[i].expected_rd_count,
680 tvs[i].expected_rd,
681 GNUNET_TIME_UNIT_ZERO_ABS);
682 if ((GNUNET_GNSRECORD_TYPE_PKEY == ntohl (pub.type)) &&
683 (GNUNET_OK != check_derivations_pkey (label, expire, &pub, &tvs[i])))
684 {
685 res = 1;
686 break;
687 }
688 else if ((GNUNET_GNSRECORD_TYPE_EDKEY == ntohl (pub.type)) &&
689 (GNUNET_OK != check_derivations_edkey (label, expire, &pub,
690 &tvs[i])))
691 {
692 res = 1;
693 break;
694 }
695 if (GNUNET_OK != GNUNET_GNSRECORD_block_decrypt (rrblock,
696 &pub_parsed,
697 label,
698 &res_checker,
699 &tvs[i]))
700 {
701 printf ("FAIL: Decryption of RRBLOCK failed\n");
702 res = 1;
703 break;
704 }
705 if (0 != res)
706 break;
707 printf ("Good.\n");
708 }
709finish:
710 return res;
711}