aboutsummaryrefslogtreecommitdiff
path: root/src/gnsrecord
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnsrecord')
-rw-r--r--src/gnsrecord/.gitignore6
-rw-r--r--src/gnsrecord/Makefile.am128
-rw-r--r--src/gnsrecord/gnsrecord.c284
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c997
-rw-r--r--src/gnsrecord/gnsrecord_crypto.h87
-rw-r--r--src/gnsrecord/gnsrecord_misc.c587
-rw-r--r--src/gnsrecord/gnsrecord_serialization.c322
-rw-r--r--src/gnsrecord/gnunet-gnsrecord-tvg.c475
-rw-r--r--src/gnsrecord/json_gnsrecord.c391
-rw-r--r--src/gnsrecord/perf_gnsrecord_crypto.c139
-rw-r--r--src/gnsrecord/plugin_gnsrecord_dns.c819
-rw-r--r--src/gnsrecord/test_gnsrecord_block_expiration.c110
-rw-r--r--src/gnsrecord/test_gnsrecord_crypto.c206
-rw-r--r--src/gnsrecord/test_gnsrecord_serialization.c157
-rw-r--r--src/gnsrecord/test_gnsrecord_testvectors.c131
15 files changed, 0 insertions, 4839 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 e2538b1a2..000000000
--- a/src/gnsrecord/Makefile.am
+++ /dev/null
@@ -1,128 +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
15bin_PROGRAMS = \
16 gnunet-gnsrecord-tvg
17
18
19check_PROGRAMS = \
20 test_gnsrecord_crypto \
21 test_gnsrecord_serialization \
22 test_gnsrecord_block_expiration \
23 perf_gnsrecord_crypto
24
25if ENABLE_TEST_RUN
26AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
27TESTS = \
28 $(check_PROGRAMS) \
29 $(check_SCRIPTS)
30endif
31
32lib_LTLIBRARIES = \
33 libgnunetgnsrecord.la \
34 libgnunetgnsrecordjson.la
35
36gnunet_gnsrecord_tvg_SOURCES = \
37 gnunet-gnsrecord-tvg.c \
38 gnsrecord_crypto.h
39gnunet_gnsrecord_tvg_LDADD = \
40 $(top_builddir)/src/util/libgnunetutil.la \
41 $(top_builddir)/src/identity/libgnunetidentity.la \
42 libgnunetgnsrecord.la \
43 $(GN_LIBINTL)
44
45
46libgnunetgnsrecord_la_SOURCES = \
47 gnsrecord.c \
48 gnsrecord_serialization.c \
49 gnsrecord_crypto.c \
50 gnsrecord_misc.c
51libgnunetgnsrecord_la_LIBADD = \
52 $(top_builddir)/src/util/libgnunetutil.la \
53 $(top_builddir)/src/identity/libgnunetidentity.la \
54 $(LIBGCRYPT_LIBS) \
55 -lsodium \
56 $(GN_LIBINTL)
57libgnunetgnsrecord_la_LDFLAGS = \
58 $(GN_LIB_LDFLAGS) \
59 -version-info 0:0:0
60
61libgnunetgnsrecordjson_la_SOURCES = \
62 json_gnsrecord.c
63libgnunetgnsrecordjson_la_LIBADD = \
64 $(top_builddir)/src/util/libgnunetutil.la \
65 $(top_builddir)/src/identity/libgnunetidentity.la \
66 libgnunetgnsrecord.la \
67 -ljansson \
68 $(GN_LIBINTL)
69libgnunetgnsrecordjson_la_LDFLAGS = \
70 $(GN_LIB_LDFLAGS) \
71 -version-info 0:0:0
72
73plugin_LTLIBRARIES = \
74 libgnunet_plugin_gnsrecord_dns.la
75
76
77libgnunet_plugin_gnsrecord_dns_la_SOURCES = \
78 plugin_gnsrecord_dns.c
79libgnunet_plugin_gnsrecord_dns_la_LIBADD = \
80 $(top_builddir)/src/util/libgnunetutil.la \
81 $(LTLIBINTL)
82libgnunet_plugin_gnsrecord_dns_la_LDFLAGS = \
83 $(GN_PLUGIN_LDFLAGS)
84
85
86EXTRA_DIST = \
87 $(check_SCRIPTS)
88
89#test_gnsrecord_testvectors_SOURCES = \
90# test_gnsrecord_testvectors.c
91#test_gnsrecord_testvectors_LDADD = \
92# $(top_builddir)/src/testing/libgnunettesting.la \
93# $(top_builddir)/src/identity/libgnunetidentity.la \
94# libgnunetgnsrecord.la \
95# $(top_builddir)/src/util/libgnunetutil.la
96
97
98test_gnsrecord_serialization_SOURCES = \
99 test_gnsrecord_serialization.c
100test_gnsrecord_serialization_LDADD = \
101 $(top_builddir)/src/testing/libgnunettesting.la \
102 libgnunetgnsrecord.la \
103 $(top_builddir)/src/util/libgnunetutil.la
104
105test_gnsrecord_block_expiration_SOURCES = \
106 test_gnsrecord_block_expiration.c
107test_gnsrecord_block_expiration_LDADD = \
108 $(top_builddir)/src/testing/libgnunettesting.la \
109 libgnunetgnsrecord.la \
110 $(top_builddir)/src/util/libgnunetutil.la
111
112
113test_gnsrecord_crypto_SOURCES = \
114 test_gnsrecord_crypto.c
115test_gnsrecord_crypto_LDADD = \
116 $(top_builddir)/src/testing/libgnunettesting.la \
117 $(top_builddir)/src/identity/libgnunetidentity.la \
118 libgnunetgnsrecord.la \
119 $(top_builddir)/src/util/libgnunetutil.la
120
121
122perf_gnsrecord_crypto_SOURCES = \
123 perf_gnsrecord_crypto.c
124perf_gnsrecord_crypto_LDADD = \
125 $(top_builddir)/src/testing/libgnunettesting.la \
126 $(top_builddir)/src/identity/libgnunetidentity.la \
127 libgnunetgnsrecord.la \
128 $(top_builddir)/src/util/libgnunetutil.la
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c
deleted file mode 100644
index 52c480ef6..000000000
--- a/src/gnsrecord/gnsrecord.c
+++ /dev/null
@@ -1,284 +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#include "gnunet_tun_lib.h"
34
35#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
36
37
38/**
39 * Handle for a plugin.
40 */
41struct Plugin
42{
43 /**
44 * Name of the shared library.
45 */
46 char *library_name;
47
48 /**
49 * Plugin API.
50 */
51 struct GNUNET_GNSRECORD_PluginFunctions *api;
52};
53
54
55/**
56 * Array of our plugins.
57 */
58static struct Plugin **gns_plugins;
59
60/**
61 * Size of the 'plugins' array.
62 */
63static unsigned int num_plugins;
64
65/**
66 * Global to mark if we've run the initialization.
67 */
68static int once;
69
70
71/**
72 * Add a plugin to the list managed by the block library.
73 *
74 * @param cls NULL
75 * @param library_name name of the plugin
76 * @param lib_ret the plugin API
77 */
78static void
79add_plugin (void *cls,
80 const char *library_name,
81 void *lib_ret)
82{
83 struct GNUNET_GNSRECORD_PluginFunctions *api = lib_ret;
84 struct Plugin *plugin;
85
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "Loading block plugin `%s'\n",
88 library_name);
89 plugin = GNUNET_new (struct Plugin);
90 plugin->api = api;
91 plugin->library_name = GNUNET_strdup (library_name);
92 GNUNET_array_append (gns_plugins, num_plugins, plugin);
93}
94
95
96/**
97 * Loads all plugins (lazy initialization).
98 */
99static void
100init ()
101{
102 if (1 == once)
103 return;
104 once = 1;
105
106 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (),
107 "libgnunet_plugin_gnsrecord_",
108 NULL,
109 &add_plugin,
110 NULL);
111}
112
113
114/**
115 * Dual function to #init().
116 */
117void __attribute__ ((destructor))
118GNSRECORD_fini ()
119{
120 struct Plugin *plugin;
121 const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
122 const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
123
124 if (pd != dpd)
125 GNUNET_OS_init (dpd);
126
127 for (unsigned int i = 0; i < num_plugins; i++)
128 {
129 plugin = gns_plugins[i];
130 GNUNET_break (NULL ==
131 GNUNET_PLUGIN_unload (plugin->library_name,
132 plugin->api));
133 GNUNET_free (plugin->library_name);
134 GNUNET_free (plugin);
135 }
136 GNUNET_free (gns_plugins);
137
138 if (pd != dpd)
139 GNUNET_OS_init (pd);
140
141 gns_plugins = NULL;
142 once = 0;
143 num_plugins = 0;
144}
145
146
147/**
148 * Convert the 'value' of a record to a string.
149 *
150 * @param type type of the record
151 * @param data value in binary encoding
152 * @param data_size number of bytes in @a data
153 * @return NULL on error, otherwise human-readable representation of the value
154 */
155char *
156GNUNET_GNSRECORD_value_to_string (uint32_t type,
157 const void *data,
158 size_t data_size)
159{
160 struct Plugin *plugin;
161 char *ret;
162
163 init ();
164 for (unsigned int i = 0; i < num_plugins; i++)
165 {
166 plugin = gns_plugins[i];
167 if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls,
168 type,
169 data,
170 data_size)))
171 return ret;
172 }
173 return NULL;
174}
175
176
177/**
178 * Convert human-readable version of a 'value' of a record to the binary
179 * representation.
180 *
181 * @param type type of the record
182 * @param s human-readable string
183 * @param data set to value in binary encoding (will be allocated)
184 * @param data_size set to number of bytes in @a data
185 * @return #GNUNET_OK on success
186 */
187int
188GNUNET_GNSRECORD_string_to_value (uint32_t type,
189 const char *s,
190 void **data,
191 size_t *data_size)
192{
193 struct Plugin *plugin;
194
195 init ();
196 for (unsigned int i = 0; i < num_plugins; i++)
197 {
198 plugin = gns_plugins[i];
199 if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls,
200 type,
201 s,
202 data,
203 data_size))
204 return GNUNET_OK;
205 }
206 return GNUNET_SYSERR;
207}
208
209
210/**
211 * Convert a type name (e.g "AAAA") to the corresponding number.
212 *
213 * @param dns_typename name to convert
214 * @return corresponding number, UINT32_MAX on error
215 */
216uint32_t
217GNUNET_GNSRECORD_typename_to_number (const char *dns_typename)
218{
219 struct Plugin *plugin;
220 uint32_t ret;
221
222 if (0 == strcasecmp (dns_typename,
223 "ANY"))
224 return GNUNET_GNSRECORD_TYPE_ANY;
225 init ();
226 for (unsigned int i = 0; i < num_plugins; i++)
227 {
228 plugin = gns_plugins[i];
229 if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls,
230 dns_typename)))
231 return ret;
232 }
233 return UINT32_MAX;
234}
235
236
237/**
238 * Convert a type number to the corresponding type string (e.g. 1 to "A")
239 *
240 * @param type number of a type to convert
241 * @return corresponding typestring, NULL on error
242 */
243const char *
244GNUNET_GNSRECORD_number_to_typename (uint32_t type)
245{
246 struct Plugin *plugin;
247 const char *ret;
248
249 if (GNUNET_GNSRECORD_TYPE_ANY == type)
250 return "ANY";
251 init ();
252 for (unsigned int i = 0; i < num_plugins; i++)
253 {
254 plugin = gns_plugins[i];
255 if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls,
256 type)))
257 return ret;
258 }
259 return NULL;
260}
261
262
263enum GNUNET_GenericReturnValue
264GNUNET_GNSRECORD_is_critical (uint32_t type)
265{
266 struct Plugin *plugin;
267
268 if (GNUNET_GNSRECORD_TYPE_ANY == type)
269 return GNUNET_NO;
270 init ();
271 for (unsigned int i = 0; i < num_plugins; i++)
272 {
273 plugin = gns_plugins[i];
274 if (NULL == plugin->api->is_critical)
275 continue;
276 if (GNUNET_NO == plugin->api->is_critical (plugin->api->cls, type))
277 continue;
278 return GNUNET_YES;
279 }
280 return GNUNET_NO;
281}
282
283
284/* end of gnsrecord.c */
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
deleted file mode 100644
index b5e8be82b..000000000
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ /dev/null
@@ -1,997 +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 "gnsrecord_crypto.h"
29
30#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
31
32ssize_t
33ecdsa_symmetric_decrypt (
34 const void *block,
35 size_t size,
36 const unsigned char *key,
37 const unsigned char *ctr,
38 void *result)
39{
40 gcry_cipher_hd_t handle;
41 int rc;
42
43 GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
44 GCRY_CIPHER_MODE_CTR, 0));
45 rc = gcry_cipher_setkey (handle,
46 key,
47 GNUNET_CRYPTO_AES_KEY_LENGTH);
48 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
49 rc = gcry_cipher_setctr (handle,
50 ctr,
51 GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
52 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
53 GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size));
54 gcry_cipher_close (handle);
55 return size;
56}
57
58
59ssize_t
60ecdsa_symmetric_encrypt (
61 const void *block,
62 size_t size,
63 const unsigned char *key,
64 const unsigned char *ctr,
65 void *result)
66{
67 gcry_cipher_hd_t handle;
68 int rc;
69
70 GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
71 GCRY_CIPHER_MODE_CTR, 0));
72 rc = gcry_cipher_setkey (handle,
73 key,
74 GNUNET_CRYPTO_AES_KEY_LENGTH);
75 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
76 rc = gcry_cipher_setctr (handle,
77 ctr,
78 GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
79 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
80 GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size));
81 gcry_cipher_close (handle);
82 return size;
83}
84
85
86enum GNUNET_GenericReturnValue
87eddsa_symmetric_decrypt (
88 const void *block,
89 size_t size,
90 const unsigned char *key,
91 const unsigned char *nonce,
92 void *result)
93{
94 ssize_t ctlen = size - crypto_secretbox_MACBYTES;
95 if (ctlen < 0)
96 return GNUNET_SYSERR;
97 if (0 != crypto_secretbox_open_detached (result,
98 ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext
99 block, // Tag
100 ctlen,
101 nonce, key))
102 {
103 return GNUNET_SYSERR;
104 }
105 return GNUNET_OK;
106}
107
108
109enum GNUNET_GenericReturnValue
110eddsa_symmetric_encrypt (
111 const void *block,
112 size_t size,
113 const unsigned char *key,
114 const unsigned char *nonce,
115 void *result)
116{
117 if (size > crypto_secretbox_MESSAGEBYTES_MAX)
118 return GNUNET_SYSERR;
119 crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext
120 result, // TAG
121 block, size, nonce, key);
122 return GNUNET_OK;
123}
124
125
126void
127GNR_derive_block_aes_key (unsigned char *ctr,
128 unsigned char *key,
129 const char *label,
130 uint64_t exp,
131 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
132{
133 static const char ctx_key[] = "gns-aes-ctx-key";
134 static const char ctx_iv[] = "gns-aes-ctx-iv";
135
136 GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH,
137 ctx_key, strlen (ctx_key),
138 pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
139 label, strlen (label),
140 NULL, 0);
141 memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
142 /** 4 byte nonce **/
143 GNUNET_CRYPTO_kdf (ctr, 4,
144 ctx_iv, strlen (ctx_iv),
145 pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
146 label, strlen (label),
147 NULL, 0);
148 /** Expiration time 64 bit. **/
149 memcpy (ctr + 4, &exp, sizeof (exp));
150 /** Set counter part to 1 **/
151 ctr[15] |= 0x01;
152}
153
154
155void
156GNR_derive_block_xsalsa_key (unsigned char *nonce,
157 unsigned char *key,
158 const char *label,
159 uint64_t exp,
160 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
161{
162 static const char ctx_key[] = "gns-xsalsa-ctx-key";
163 static const char ctx_iv[] = "gns-xsalsa-ctx-iv";
164
165 GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES,
166 ctx_key, strlen (ctx_key),
167 pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
168 label, strlen (label),
169 NULL, 0);
170 memset (nonce, 0, crypto_secretbox_NONCEBYTES);
171 /** 16 byte nonce **/
172 GNUNET_CRYPTO_kdf (nonce, (crypto_secretbox_NONCEBYTES - sizeof (exp)),
173 ctx_iv, strlen (ctx_iv),
174 pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
175 label, strlen (label),
176 NULL, 0);
177 /** Expiration time 64 bit. **/
178 memcpy (nonce + (crypto_secretbox_NONCEBYTES - sizeof (exp)),
179 &exp, sizeof (exp));
180}
181
182
183static ssize_t
184block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
185 unsigned int rd_count)
186{
187 ssize_t len;
188
189 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
190 if (len < 0)
191 return -1;
192 len += sizeof(struct GNUNET_GNSRECORD_Block);
193 return len;
194}
195
196
197/**
198 * Sign name and records
199 *
200 * @param key the private key
201 * @param pkey associated public key
202 * @param expire block expiration
203 * @param label the name for the records
204 * @param rd record data
205 * @param rd_count number of records
206 * @param block the block result. Must be allocated sufficiently.
207 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
208 */
209static enum GNUNET_GenericReturnValue
210block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
211 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
212 struct GNUNET_TIME_Absolute expire,
213 const char *label,
214 const struct GNUNET_GNSRECORD_Data *rd,
215 unsigned int rd_count,
216 struct GNUNET_GNSRECORD_Block **block)
217{
218 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
219 rd);
220 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
221 struct GNRBlockPS *gnr_block;
222 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
223 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
224 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
225 struct GNUNET_TIME_Absolute now;
226
227 if (payload_len < 0)
228 {
229 GNUNET_break (0);
230 return GNUNET_SYSERR;
231 }
232 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
233 {
234 GNUNET_break (0);
235 return GNUNET_SYSERR;
236 }
237 /* convert relative to absolute times */
238 now = GNUNET_TIME_absolute_get ();
239 for (unsigned int i = 0; i < rd_count; i++)
240 {
241 rdc[i] = rd[i];
242 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
243 {
244 struct GNUNET_TIME_Relative t;
245
246 /* encrypted blocks must never have relative expiration times, convert! */
247 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
248 t.rel_value_us = rdc[i].expiration_time;
249 rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
250 }
251 }
252 /* serialize */
253 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
254 (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
255 {
256 char payload[payload_len];
257
258 GNUNET_assert (payload_len ==
259 GNUNET_GNSRECORD_records_serialize (rd_count,
260 rdc,
261 payload_len,
262 payload));
263 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
264 ecblock = &(*block)->ecdsa_block;
265 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
266 gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len);
267 gnr_block->purpose.purpose =
268 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
269 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
270 ecblock->expiration_time = gnr_block->expiration_time;
271 /* encrypt and sign */
272 GNUNET_CRYPTO_ecdsa_public_key_derive (pkey,
273 label,
274 "gns",
275 &ecblock->derived_key);
276 GNR_derive_block_aes_key (ctr,
277 skey,
278 label,
279 ecblock->expiration_time.abs_value_us__,
280 pkey);
281 GNUNET_assert (payload_len ==
282 ecdsa_symmetric_encrypt (payload,
283 payload_len,
284 skey,
285 ctr,
286 &ecblock[1]));
287 GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
288 }
289 if (GNUNET_OK !=
290 GNUNET_CRYPTO_ecdsa_sign_derived (key,
291 label,
292 "gns",
293 &gnr_block->purpose,
294 &ecblock->signature))
295 {
296 GNUNET_break (0);
297 GNUNET_free (*block);
298 GNUNET_free (gnr_block);
299 return GNUNET_SYSERR;
300 }
301 GNUNET_free (gnr_block);
302 return GNUNET_OK;
303}
304
305static ssize_t
306block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd,
307 unsigned int rd_count)
308{
309 ssize_t len;
310
311 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
312 if (len < 0)
313 return -1;
314 len += sizeof(struct GNUNET_GNSRECORD_Block);
315 len += crypto_secretbox_MACBYTES;
316 return len;
317}
318
319
320/**
321 * Sign name and records (EDDSA version)
322 *
323 * @param key the private key
324 * @param pkey associated public key
325 * @param expire block expiration
326 * @param label the name for the records
327 * @param rd record data
328 * @param rd_count number of records
329 * @param block where to store the block. Must be allocated sufficiently.
330 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
331 */
332enum GNUNET_GenericReturnValue
333block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
334 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
335 struct GNUNET_TIME_Absolute expire,
336 const char *label,
337 const struct GNUNET_GNSRECORD_Data *rd,
338 unsigned int rd_count,
339 struct GNUNET_GNSRECORD_Block **block)
340{
341 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
342 rd);
343 struct GNUNET_GNSRECORD_EddsaBlock *edblock;
344 struct GNRBlockPS *gnr_block;
345 unsigned char nonce[crypto_secretbox_NONCEBYTES];
346 unsigned char skey[crypto_secretbox_KEYBYTES];
347 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
348 struct GNUNET_TIME_Absolute now;
349
350 if (payload_len < 0)
351 {
352 GNUNET_break (0);
353 return GNUNET_SYSERR;
354 }
355 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
356 {
357 GNUNET_break (0);
358 return GNUNET_SYSERR;
359 }
360 /* convert relative to absolute times */
361 now = GNUNET_TIME_absolute_get ();
362 for (unsigned int i = 0; i < rd_count; i++)
363 {
364 rdc[i] = rd[i];
365 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
366 {
367 struct GNUNET_TIME_Relative t;
368
369 /* encrypted blocks must never have relative expiration times, convert! */
370 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
371 t.rel_value_us = rdc[i].expiration_time;
372 rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
373 }
374 }
375 /* serialize */
376 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
377 + payload_len + crypto_secretbox_MACBYTES);
378 (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block)
379 + payload_len + crypto_secretbox_MACBYTES);
380 {
381 char payload[payload_len];
382
383 GNUNET_assert (payload_len ==
384 GNUNET_GNSRECORD_records_serialize (rd_count,
385 rdc,
386 payload_len,
387 payload));
388 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
389 + payload_len
390 + crypto_secretbox_MACBYTES);
391 edblock = &(*block)->eddsa_block;
392 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
393 gnr_block->purpose.size =
394 htonl (sizeof(struct GNRBlockPS)
395 + payload_len
396 + crypto_secretbox_MACBYTES);
397 gnr_block->purpose.purpose =
398 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
399 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
400 edblock->expiration_time = gnr_block->expiration_time;
401 /* encrypt and sign */
402 GNUNET_CRYPTO_eddsa_public_key_derive (pkey,
403 label,
404 "gns",
405 &edblock->derived_key);
406 GNR_derive_block_xsalsa_key (nonce,
407 skey,
408 label,
409 edblock->expiration_time.abs_value_us__,
410 pkey);
411 GNUNET_assert (GNUNET_OK ==
412 eddsa_symmetric_encrypt (payload,
413 payload_len,
414 skey,
415 nonce,
416 &edblock[1]));
417 GNUNET_memcpy (&gnr_block[1], &edblock[1],
418 payload_len + crypto_secretbox_MACBYTES);
419
420 GNUNET_CRYPTO_eddsa_sign_derived (key,
421 label,
422 "gns",
423 &gnr_block->purpose,
424 &edblock->signature);
425 }
426 return GNUNET_OK;
427}
428
429ssize_t
430GNUNET_GNSRECORD_block_calculate_size (const struct
431 GNUNET_IDENTITY_PrivateKey *key,
432 const struct GNUNET_GNSRECORD_Data *rd,
433 unsigned int rd_count)
434{
435 struct GNUNET_IDENTITY_PublicKey pkey;
436 ssize_t res = -1;
437
438 GNUNET_IDENTITY_key_get_public (key,
439 &pkey);
440 switch (ntohl (key->type))
441 {
442 case GNUNET_GNSRECORD_TYPE_PKEY:
443 res = block_get_size_ecdsa (rd, rd_count);
444 break;
445 case GNUNET_GNSRECORD_TYPE_EDKEY:
446 res = block_get_size_eddsa (rd, rd_count);
447 break;
448 default:
449 GNUNET_assert (0);
450 }
451 return res;
452
453}
454
455enum GNUNET_GenericReturnValue
456GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
457 struct GNUNET_TIME_Absolute expire,
458 const char *label,
459 const struct GNUNET_GNSRECORD_Data *rd,
460 unsigned int rd_count,
461 struct GNUNET_GNSRECORD_Block **result)
462{
463 struct GNUNET_IDENTITY_PublicKey pkey;
464 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
465 char *norm_label;
466
467 GNUNET_IDENTITY_key_get_public (key,
468 &pkey);
469 norm_label = GNUNET_GNSRECORD_string_normalize (label);
470
471 switch (ntohl (key->type))
472 {
473 case GNUNET_GNSRECORD_TYPE_PKEY:
474 res = block_create_ecdsa (&key->ecdsa_key,
475 &pkey.ecdsa_key,
476 expire,
477 norm_label,
478 rd,
479 rd_count,
480 result);
481 break;
482 case GNUNET_GNSRECORD_TYPE_EDKEY:
483 res = block_create_eddsa (&key->eddsa_key,
484 &pkey.eddsa_key,
485 expire,
486 norm_label,
487 rd,
488 rd_count,
489 result);
490 break;
491 default:
492 GNUNET_assert (0);
493 }
494 GNUNET_free (norm_label);
495 return res;
496}
497
498
499/**
500 * Line in cache mapping private keys to public keys.
501 */
502struct KeyCacheLine
503{
504 /**
505 * A private key.
506 */
507 struct GNUNET_CRYPTO_EcdsaPrivateKey key;
508
509 /**
510 * Associated public key.
511 */
512 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
513};
514
515
516enum GNUNET_GenericReturnValue
517GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
518 struct GNUNET_TIME_Absolute expire,
519 const char *label,
520 const struct GNUNET_GNSRECORD_Data *rd,
521 unsigned int rd_count,
522 struct GNUNET_GNSRECORD_Block **result)
523{
524 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
525 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
526 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
527 char *norm_label;
528
529 norm_label = GNUNET_GNSRECORD_string_normalize (label);
530
531 if (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pkey->type))
532 {
533 key = &pkey->ecdsa_key;
534#define CSIZE 64
535 static struct KeyCacheLine cache[CSIZE];
536 struct KeyCacheLine *line;
537
538 line = &cache[(*(unsigned int *) key) % CSIZE];
539 if (0 != memcmp (&line->key,
540 key,
541 sizeof(*key)))
542 {
543 /* cache miss, recompute */
544 line->key = *key;
545 GNUNET_CRYPTO_ecdsa_key_get_public (key,
546 &line->pkey);
547 }
548#undef CSIZE
549 res = block_create_ecdsa (key,
550 &line->pkey,
551 expire,
552 norm_label,
553 rd,
554 rd_count,
555 result);
556 }
557 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
558 {
559 GNUNET_CRYPTO_eddsa_key_get_public (&pkey->eddsa_key,
560 &edpubkey);
561 res = block_create_eddsa (&pkey->eddsa_key,
562 &edpubkey,
563 expire,
564 norm_label,
565 rd,
566 rd_count,
567 result);
568 }
569 GNUNET_free (norm_label);
570 return res;
571}
572
573
574/**
575 * Check if a signature is valid. This API is used by the GNS Block
576 * to validate signatures received from the network.
577 *
578 * @param block block to verify
579 * @return #GNUNET_OK if the signature is valid
580 */
581enum GNUNET_GenericReturnValue
582GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
583{
584 struct GNRBlockPS *purp;
585 size_t payload_len = ntohl (block->size)
586 - sizeof (struct GNUNET_GNSRECORD_Block);
587 enum GNUNET_GenericReturnValue res = GNUNET_NO;
588 purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
589 purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
590 purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
591 GNUNET_memcpy (&purp[1],
592 &block[1],
593 payload_len);
594 switch (ntohl (block->type))
595 {
596 case GNUNET_GNSRECORD_TYPE_PKEY:
597 purp->expiration_time = block->ecdsa_block.expiration_time;
598 res = GNUNET_CRYPTO_ecdsa_verify_ (
599 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
600 &purp->purpose,
601 &block->ecdsa_block.signature,
602 &block->ecdsa_block.derived_key);
603 break;
604 case GNUNET_GNSRECORD_TYPE_EDKEY:
605 purp->expiration_time = block->eddsa_block.expiration_time;
606 res = GNUNET_CRYPTO_eddsa_verify_ (
607 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
608 &purp->purpose,
609 &block->eddsa_block.signature,
610 &block->eddsa_block.derived_key);
611 break;
612 default:
613 res = GNUNET_NO;
614 }
615 GNUNET_free (purp);
616 return res;
617}
618
619
620enum GNUNET_GenericReturnValue
621block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
622 const struct
623 GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
624 const char *label,
625 GNUNET_GNSRECORD_RecordCallback proc,
626 void *proc_cls)
627{
628 size_t payload_len = ntohl (block->size) - sizeof (struct
629 GNUNET_GNSRECORD_Block);
630 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
631 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
632
633 if (ntohl (block->size) <
634 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
635 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
636 {
637 GNUNET_break_op (0);
638 return GNUNET_SYSERR;
639 }
640 GNR_derive_block_aes_key (ctr,
641 key,
642 label,
643 block->ecdsa_block.expiration_time.abs_value_us__,
644 zone_key);
645 {
646 char payload[payload_len];
647 unsigned int rd_count;
648
649 GNUNET_assert (payload_len ==
650 ecdsa_symmetric_decrypt (&block[1], payload_len,
651 key, ctr,
652 payload));
653 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
654 payload);
655 if (rd_count > 2048)
656 {
657 /* limit to sane value */
658 GNUNET_break_op (0);
659 return GNUNET_SYSERR;
660 }
661 {
662 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
663 unsigned int j;
664 struct GNUNET_TIME_Absolute now;
665
666 if (GNUNET_OK !=
667 GNUNET_GNSRECORD_records_deserialize (payload_len,
668 payload,
669 rd_count,
670 rd))
671 {
672 GNUNET_break_op (0);
673 return GNUNET_SYSERR;
674 }
675 /* hide expired records */
676 now = GNUNET_TIME_absolute_get ();
677 j = 0;
678 for (unsigned int i = 0; i < rd_count; i++)
679 {
680 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
681 {
682 /* encrypted blocks must never have relative expiration times, skip! */
683 GNUNET_break_op (0);
684 continue;
685 }
686
687 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
688 {
689 int include_record = GNUNET_YES;
690 /* Shadow record, figure out if we have a not expired active record */
691 for (unsigned int k = 0; k < rd_count; k++)
692 {
693 if (k == i)
694 continue;
695 if (rd[i].expiration_time < now.abs_value_us)
696 include_record = GNUNET_NO; /* Shadow record is expired */
697 if ((rd[k].record_type == rd[i].record_type) &&
698 (rd[k].expiration_time >= now.abs_value_us) &&
699 (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
700 {
701 include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
702 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
703 "Ignoring shadow record\n");
704 break;
705 }
706 }
707 if (GNUNET_YES == include_record)
708 {
709 rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
710 if (j != i)
711 rd[j] = rd[i];
712 j++;
713 }
714 }
715 else if (rd[i].expiration_time >= now.abs_value_us)
716 {
717 /* Include this record */
718 if (j != i)
719 rd[j] = rd[i];
720 j++;
721 }
722 else
723 {
724 struct GNUNET_TIME_Absolute at;
725
726 at.abs_value_us = rd[i].expiration_time;
727 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
728 "Excluding record that expired %s (%llu ago)\n",
729 GNUNET_STRINGS_absolute_time_to_string (at),
730 (unsigned long long) rd[i].expiration_time
731 - now.abs_value_us);
732 }
733 }
734 rd_count = j;
735 if (NULL != proc)
736 proc (proc_cls,
737 rd_count,
738 (0 != rd_count) ? rd : NULL);
739 }
740 }
741 return GNUNET_OK;
742}
743
744
745enum GNUNET_GenericReturnValue
746block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
747 const struct
748 GNUNET_CRYPTO_EddsaPublicKey *zone_key,
749 const char *label,
750 GNUNET_GNSRECORD_RecordCallback proc,
751 void *proc_cls)
752{
753 size_t payload_len = ntohl (block->size) - sizeof (struct
754 GNUNET_GNSRECORD_Block);
755 unsigned char nonce[crypto_secretbox_NONCEBYTES];
756 unsigned char key[crypto_secretbox_KEYBYTES];
757
758 if (ntohl (block->size) <
759 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
760 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
761 {
762 GNUNET_break_op (0);
763 return GNUNET_SYSERR;
764 }
765 GNR_derive_block_xsalsa_key (nonce,
766 key,
767 label,
768 block->eddsa_block.expiration_time.abs_value_us__,
769 zone_key);
770 {
771 char payload[payload_len];
772 unsigned int rd_count;
773
774 GNUNET_assert (GNUNET_OK ==
775 eddsa_symmetric_decrypt (&block[1], payload_len,
776 key, nonce,
777 payload));
778 payload_len -= crypto_secretbox_MACBYTES;
779 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
780 payload);
781 if (rd_count > 2048)
782 {
783 /* limit to sane value */
784 GNUNET_break_op (0);
785 return GNUNET_SYSERR;
786 }
787 {
788 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
789 unsigned int j;
790 struct GNUNET_TIME_Absolute now;
791
792 if (GNUNET_OK !=
793 GNUNET_GNSRECORD_records_deserialize (payload_len,
794 payload,
795 rd_count,
796 rd))
797 {
798 GNUNET_break_op (0);
799 return GNUNET_SYSERR;
800 }
801 /* hide expired records */
802 now = GNUNET_TIME_absolute_get ();
803 j = 0;
804 for (unsigned int i = 0; i < rd_count; i++)
805 {
806 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
807 {
808 /* encrypted blocks must never have relative expiration times, skip! */
809 GNUNET_break_op (0);
810 continue;
811 }
812
813 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
814 {
815 int include_record = GNUNET_YES;
816 /* Shadow record, figure out if we have a not expired active record */
817 for (unsigned int k = 0; k < rd_count; k++)
818 {
819 if (k == i)
820 continue;
821 if (rd[i].expiration_time < now.abs_value_us)
822 include_record = GNUNET_NO; /* Shadow record is expired */
823 if ((rd[k].record_type == rd[i].record_type) &&
824 (rd[k].expiration_time >= now.abs_value_us) &&
825 (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
826 {
827 include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
828 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
829 "Ignoring shadow record\n");
830 break;
831 }
832 }
833 if (GNUNET_YES == include_record)
834 {
835 rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
836 if (j != i)
837 rd[j] = rd[i];
838 j++;
839 }
840 }
841 else if (rd[i].expiration_time >= now.abs_value_us)
842 {
843 /* Include this record */
844 if (j != i)
845 rd[j] = rd[i];
846 j++;
847 }
848 else
849 {
850 struct GNUNET_TIME_Absolute at;
851
852 at.abs_value_us = rd[i].expiration_time;
853 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
854 "Excluding record that expired %s (%llu ago)\n",
855 GNUNET_STRINGS_absolute_time_to_string (at),
856 (unsigned long long) rd[i].expiration_time
857 - now.abs_value_us);
858 }
859 }
860 rd_count = j;
861 if (NULL != proc)
862 proc (proc_cls,
863 rd_count,
864 (0 != rd_count) ? rd : NULL);
865 }
866 }
867 return GNUNET_OK;
868}
869
870
871/**
872 * Decrypt block.
873 *
874 * @param block block to decrypt
875 * @param zone_key public key of the zone
876 * @param label the name for the records
877 * @param proc function to call with the result
878 * @param proc_cls closure for proc
879 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was
880 * not well-formed
881 */
882enum GNUNET_GenericReturnValue
883GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
884 const struct
885 GNUNET_IDENTITY_PublicKey *zone_key,
886 const char *label,
887 GNUNET_GNSRECORD_RecordCallback proc,
888 void *proc_cls)
889{
890 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
891 char *norm_label;
892
893 norm_label = GNUNET_GNSRECORD_string_normalize (label);
894 switch (ntohl (zone_key->type))
895 {
896 case GNUNET_IDENTITY_TYPE_ECDSA:
897 res = block_decrypt_ecdsa (block,
898 &zone_key->ecdsa_key, norm_label, proc,
899 proc_cls);
900 break;
901 case GNUNET_IDENTITY_TYPE_EDDSA:
902 res = block_decrypt_eddsa (block,
903 &zone_key->eddsa_key, norm_label, proc,
904 proc_cls);
905 break;
906 default:
907 res = GNUNET_SYSERR;
908 }
909 GNUNET_free (norm_label);
910 return res;
911}
912
913
914/**
915 * Calculate the DHT query for a given @a label in a given @a zone.
916 *
917 * @param zone private key of the zone
918 * @param label label of the record
919 * @param query hash to use for the query
920 */
921void
922GNUNET_GNSRECORD_query_from_private_key (const struct
923 GNUNET_IDENTITY_PrivateKey *zone,
924 const char *label,
925 struct GNUNET_HashCode *query)
926{
927 char *norm_label;
928 struct GNUNET_IDENTITY_PublicKey pub;
929
930 norm_label = GNUNET_GNSRECORD_string_normalize (label);
931 switch (ntohl (zone->type))
932 {
933 case GNUNET_GNSRECORD_TYPE_PKEY:
934 case GNUNET_GNSRECORD_TYPE_EDKEY:
935
936 GNUNET_IDENTITY_key_get_public (zone,
937 &pub);
938 GNUNET_GNSRECORD_query_from_public_key (&pub,
939 norm_label,
940 query);
941 break;
942 default:
943 GNUNET_assert (0);
944 }
945 GNUNET_free (norm_label);
946}
947
948
949/**
950 * Calculate the DHT query for a given @a label in a given @a zone.
951 * FIXME: We may want to plugin-ize this at some point.
952 *
953 * @param pub public key of the zone
954 * @param label label of the record
955 * @param query hash to use for the query
956 */
957void
958GNUNET_GNSRECORD_query_from_public_key (const struct
959 GNUNET_IDENTITY_PublicKey *pub,
960 const char *label,
961 struct GNUNET_HashCode *query)
962{
963 char *norm_label;
964 struct GNUNET_IDENTITY_PublicKey pd;
965
966 norm_label = GNUNET_GNSRECORD_string_normalize (label);
967
968 switch (ntohl (pub->type))
969 {
970 case GNUNET_GNSRECORD_TYPE_PKEY:
971 pd.type = pub->type;
972 GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key,
973 norm_label,
974 "gns",
975 &pd.ecdsa_key);
976 GNUNET_CRYPTO_hash (&pd.ecdsa_key,
977 sizeof (pd.ecdsa_key),
978 query);
979 break;
980 case GNUNET_GNSRECORD_TYPE_EDKEY:
981 pd.type = pub->type;
982 GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key,
983 norm_label,
984 "gns",
985 &(pd.eddsa_key));
986 GNUNET_CRYPTO_hash (&pd.eddsa_key,
987 sizeof (pd.eddsa_key),
988 query);
989 break;
990 default:
991 GNUNET_assert (0);
992 }
993 GNUNET_free (norm_label);
994}
995
996
997/* end of gnsrecord_crypto.c */
diff --git a/src/gnsrecord/gnsrecord_crypto.h b/src/gnsrecord/gnsrecord_crypto.h
deleted file mode 100644
index 79a7e6fb9..000000000
--- a/src/gnsrecord/gnsrecord_crypto.h
+++ /dev/null
@@ -1,87 +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#include "gnunet_dnsparser_lib.h"
35#include "gnunet_tun_lib.h"
36
37/**
38 * Information we have in an encrypted block with record data (i.e. in the DHT).
39 */
40struct GNRBlockPS
41{
42 /**
43 * Number of bytes signed; also specifies the number of bytes
44 * of encrypted data that follow.
45 */
46 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
47
48 /**
49 * Expiration time of the block.
50 */
51 struct GNUNET_TIME_AbsoluteNBO expiration_time;
52
53 /* followed by encrypted data */
54};
55
56
57/**
58 * Derive session key and iv from label and public key.
59 *
60 * @param iv initialization vector to initialize
61 * @param skey session key to initialize
62 * @param label label to use for KDF
63 * @param pub public key to use for KDF
64 */
65void
66GNR_derive_block_aes_key (unsigned char *ctr,
67 unsigned char *key,
68 const char *label,
69 uint64_t exp,
70 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub);
71
72
73/**
74 * Derive session key and iv from label and public key.
75 *
76 * @param nonce initialization vector to initialize
77 * @param skey session key to initialize
78 * @param label label to use for KDF
79 * @param pub public key to use for KDF
80 */
81void
82GNR_derive_block_xsalsa_key (unsigned char *nonce,
83 unsigned char *key,
84 const char *label,
85 uint64_t exp,
86 const struct GNUNET_CRYPTO_EddsaPublicKey *pub);
87
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
deleted file mode 100644
index 5e3bbdb8c..000000000
--- a/src/gnsrecord/gnsrecord_misc.c
+++ /dev/null
@@ -1,587 +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#include "gnunet_dnsparser_lib.h"
35#include "gnunet_tun_lib.h"
36
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
39
40char *
41GNUNET_GNSRECORD_string_normalize (const char *src)
42{
43 /*FIXME: We may want to follow RFC5890/RFC5891 */
44 return GNUNET_STRINGS_utf8_normalize (src);
45}
46
47
48enum GNUNET_GenericReturnValue
49GNUNET_GNSRECORD_label_check (const char*label, char **emsg)
50{
51 if (NULL == label)
52 {
53 *emsg = GNUNET_strdup (_ ("Label is NULL which is not allowed\n"));
54 return GNUNET_NO;
55 }
56 if (0 != strchr (label, '.'))
57 {
58 *emsg = GNUNET_strdup (_ ("Label contains `.' which is not allowed\n"));
59 return GNUNET_NO;
60 }
61 return GNUNET_OK;
62}
63
64
65/**
66 * Convert a zone key to a string (for printing debug messages).
67 * This is one of the very few calls in the entire API that is
68 * NOT reentrant!
69 *
70 * @param z the zone key
71 * @return string form; will be overwritten by next call to #GNUNET_GNSRECORD_z2s
72 */
73const char *
74GNUNET_GNSRECORD_z2s (const struct GNUNET_IDENTITY_PublicKey *z)
75{
76 static char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) * 8];
77 char *end;
78
79 end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z,
80 sizeof(struct
81 GNUNET_IDENTITY_PublicKey),
82 buf, sizeof(buf));
83 if (NULL == end)
84 {
85 GNUNET_break (0);
86 return NULL;
87 }
88 *end = '\0';
89 return buf;
90}
91
92
93/**
94 * Compares if two records are equal (ignoring flags such
95 * as authority, private and pending, but not relative vs.
96 * absolute expiration time).
97 *
98 * @param a record
99 * @param b record
100 * @return #GNUNET_YES if the records are equal or #GNUNET_NO if they are not
101 */
102int
103GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a,
104 const struct GNUNET_GNSRECORD_Data *b)
105{
106 LOG (GNUNET_ERROR_TYPE_DEBUG,
107 "Comparing records\n");
108 if (a->record_type != b->record_type)
109 {
110 LOG (GNUNET_ERROR_TYPE_DEBUG,
111 "Record type %u != %u\n", a->record_type, b->record_type);
112 return GNUNET_NO;
113 }
114 if ((a->expiration_time != b->expiration_time) &&
115 ((a->expiration_time != 0) && (b->expiration_time != 0)))
116 {
117 LOG (GNUNET_ERROR_TYPE_DEBUG,
118 "Expiration time %llu != %llu\n",
119 (unsigned long long) a->expiration_time,
120 (unsigned long long) b->expiration_time);
121 return GNUNET_NO;
122 }
123 if ((a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)
124 != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS))
125 {
126 LOG (GNUNET_ERROR_TYPE_DEBUG,
127 "Flags %u (%u) != %u (%u)\n", a->flags,
128 a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags,
129 b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS);
130 return GNUNET_NO;
131 }
132 if (a->data_size != b->data_size)
133 {
134 LOG (GNUNET_ERROR_TYPE_DEBUG,
135 "Data size %lu != %lu\n",
136 a->data_size,
137 b->data_size);
138 return GNUNET_NO;
139 }
140 if (0 != memcmp (a->data, b->data, a->data_size))
141 {
142 LOG (GNUNET_ERROR_TYPE_DEBUG,
143 "Data contents do not match\n");
144 return GNUNET_NO;
145 }
146 LOG (GNUNET_ERROR_TYPE_DEBUG,
147 "Records are equal\n");
148 return GNUNET_YES;
149}
150
151
152struct GNUNET_TIME_Absolute
153GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count,
154 const struct
155 GNUNET_GNSRECORD_Data *rd,
156 struct GNUNET_TIME_Absolute min)
157{
158 struct GNUNET_TIME_Absolute expire;
159 struct GNUNET_TIME_Absolute at;
160 struct GNUNET_TIME_Relative rt;
161 struct GNUNET_TIME_Absolute at_shadow;
162 struct GNUNET_TIME_Relative rt_shadow;
163
164 if (0 == rd_count)
165 return GNUNET_TIME_absolute_max (GNUNET_TIME_UNIT_ZERO_ABS, min);
166 expire = GNUNET_TIME_UNIT_FOREVER_ABS;
167 for (unsigned int c = 0; c < rd_count; c++)
168 {
169 if (0 != (rd[c].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
170 {
171 rt.rel_value_us = rd[c].expiration_time;
172 at = GNUNET_TIME_relative_to_absolute (rt);
173 }
174 else
175 {
176 at.abs_value_us = rd[c].expiration_time;
177 }
178
179 for (unsigned int c2 = 0; c2 < rd_count; c2++)
180 {
181 /* Check for shadow record */
182 if ((c == c2) ||
183 (rd[c].record_type != rd[c2].record_type) ||
184 (0 == (rd[c2].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
185 continue;
186 /* We have a shadow record */
187 if (0 != (rd[c2].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
188 {
189 rt_shadow.rel_value_us = rd[c2].expiration_time;
190 at_shadow = GNUNET_TIME_relative_to_absolute (rt_shadow);
191 }
192 else
193 {
194 at_shadow.abs_value_us = rd[c2].expiration_time;
195 }
196 at = GNUNET_TIME_absolute_max (at,
197 at_shadow);
198 }
199 expire = GNUNET_TIME_absolute_min (at,
200 expire);
201 }
202 expire = GNUNET_TIME_absolute_max (expire, min);
203 LOG (GNUNET_ERROR_TYPE_DEBUG,
204 "Determined expiration time for block with %u records to be %s\n",
205 rd_count,
206 GNUNET_STRINGS_absolute_time_to_string (expire));
207 return expire;
208}
209
210
211/**
212 * Test if a given record is expired.
213 *
214 * @return #GNUNET_YES if the record is expired,
215 * #GNUNET_NO if not
216 */
217int
218GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd)
219{
220 struct GNUNET_TIME_Absolute at;
221
222 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
223 return GNUNET_NO;
224 at.abs_value_us = rd->expiration_time;
225 return (0 == GNUNET_TIME_absolute_get_remaining (at).rel_value_us) ?
226 GNUNET_YES : GNUNET_NO;
227}
228
229
230/**
231 * Convert public key to the respective absolute domain name in the
232 * ".zkey" pTLD.
233 * This is one of the very few calls in the entire API that is
234 * NOT reentrant!
235 *
236 * @param pkey a public key with a point on the eliptic curve
237 * @return string "X.zkey" where X is the public
238 * key in an encoding suitable for DNS labels.
239 */
240const char *
241GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_IDENTITY_PublicKey *pkey)
242{
243 static char ret[128];
244 char *pkeys;
245
246 pkeys = GNUNET_IDENTITY_public_key_to_string (pkey);
247 GNUNET_snprintf (ret,
248 sizeof(ret),
249 "%s",
250 pkeys);
251 GNUNET_free (pkeys);
252 return ret;
253}
254
255
256/**
257 * Convert an absolute domain name to the
258 * respective public key.
259 *
260 * @param zkey string encoding the coordinates of the public
261 * key in an encoding suitable for DNS labels.
262 * @param pkey set to a public key on the eliptic curve
263 * @return #GNUNET_SYSERR if @a zkey has the wrong syntax
264 */
265int
266GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey,
267 struct GNUNET_IDENTITY_PublicKey *pkey)
268{
269 if (GNUNET_OK !=
270 GNUNET_IDENTITY_public_key_from_string (zkey,
271 pkey))
272 return GNUNET_SYSERR;
273 return GNUNET_OK;
274}
275
276
277enum GNUNET_GenericReturnValue
278GNUNET_GNSRECORD_identity_from_data (const char *data,
279 size_t data_size,
280 uint32_t type,
281 struct GNUNET_IDENTITY_PublicKey *key)
282{
283 if (GNUNET_NO == GNUNET_GNSRECORD_is_zonekey_type (type))
284 return GNUNET_SYSERR;
285 switch (type)
286 {
287 case GNUNET_GNSRECORD_TYPE_PKEY:
288 if (data_size > sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))
289 return GNUNET_SYSERR;
290 memcpy (&key->ecdsa_key, data, data_size);
291 break;
292 case GNUNET_GNSRECORD_TYPE_EDKEY:
293 if (data_size > sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))
294 return GNUNET_SYSERR;
295 memcpy (&key->eddsa_key, data, data_size);
296 break;
297 default:
298 return GNUNET_NO;
299 }
300 key->type = htonl (type);
301
302 return GNUNET_YES;
303}
304
305
306enum GNUNET_GenericReturnValue
307GNUNET_GNSRECORD_data_from_identity (const struct
308 GNUNET_IDENTITY_PublicKey *key,
309 char **data,
310 size_t *data_size,
311 uint32_t *type)
312{
313 char *tmp;
314 *type = ntohl (key->type);
315 *data_size = GNUNET_IDENTITY_key_get_length (key) - sizeof (key->type);
316 if (0 == *data_size)
317 return GNUNET_SYSERR;
318 tmp = GNUNET_malloc (*data_size);
319 memcpy (tmp, ((char*) key) + sizeof (key->type), *data_size);
320 *data = tmp;
321 return GNUNET_OK;
322}
323
324
325enum GNUNET_GenericReturnValue
326GNUNET_GNSRECORD_is_zonekey_type (uint32_t type)
327{
328 switch (type)
329 {
330 case GNUNET_GNSRECORD_TYPE_PKEY:
331 case GNUNET_GNSRECORD_TYPE_EDKEY:
332 return GNUNET_YES;
333 default:
334 return GNUNET_NO;
335 }
336}
337
338
339size_t
340GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block)
341{
342 return ntohl (block->size);
343}
344
345
346struct GNUNET_TIME_Absolute
347GNUNET_GNSRECORD_block_get_expiration (const struct
348 GNUNET_GNSRECORD_Block *block)
349{
350
351 switch (ntohl (block->type))
352 {
353 case GNUNET_GNSRECORD_TYPE_PKEY:
354 return GNUNET_TIME_absolute_ntoh (block->ecdsa_block.expiration_time);
355 case GNUNET_GNSRECORD_TYPE_EDKEY:
356 return GNUNET_TIME_absolute_ntoh (block->eddsa_block.expiration_time);
357 default:
358 GNUNET_break (0); /* Hopefully we never get here, but we might */
359 }
360 return GNUNET_TIME_absolute_get_zero_ ();
361
362}
363
364
365enum GNUNET_GenericReturnValue
366GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block,
367 struct GNUNET_HashCode *query)
368{
369 switch (ntohl (block->type))
370 {
371 case GNUNET_GNSRECORD_TYPE_PKEY:
372 GNUNET_CRYPTO_hash (&(block->ecdsa_block.derived_key),
373 sizeof (block->ecdsa_block.derived_key),
374 query);
375 return GNUNET_OK;
376 case GNUNET_GNSRECORD_TYPE_EDKEY:
377 GNUNET_CRYPTO_hash (&block->eddsa_block.derived_key,
378 sizeof (block->eddsa_block.derived_key),
379 query);
380 return GNUNET_OK;
381 default:
382 return GNUNET_SYSERR;
383 }
384 return GNUNET_SYSERR;
385
386}
387
388
389enum GNUNET_GenericReturnValue
390GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd,
391 struct GNUNET_IDENTITY_PublicKey *key)
392{
393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
394 "Got record of type %u\n",
395 rd->record_type);
396 switch (rd->record_type)
397 {
398 case GNUNET_GNSRECORD_TYPE_PKEY:
399 key->type = htonl (rd->record_type);
400 memcpy (&key->ecdsa_key, rd->data, sizeof (key->ecdsa_key));
401 return GNUNET_OK;
402 case GNUNET_GNSRECORD_TYPE_EDKEY:
403 key->type = htonl (rd->record_type);
404 memcpy (&key->eddsa_key, rd->data, sizeof (key->eddsa_key));
405 return GNUNET_OK;
406 default:
407 return GNUNET_SYSERR;
408 }
409 return GNUNET_SYSERR;
410
411
412}
413
414
415enum GNUNET_GenericReturnValue
416GNUNET_GNSRECORD_normalize_record_set (const char *label,
417 const struct
418 GNUNET_GNSRECORD_Data *rd,
419 unsigned int rd_count,
420 struct GNUNET_GNSRECORD_Data *
421 rd_public,
422 unsigned int *rd_count_public,
423 struct GNUNET_TIME_Absolute *expiry,
424 int include_private,
425 char **emsg)
426{
427 struct GNUNET_TIME_Absolute now;
428 struct GNUNET_TIME_Absolute minimum_expiration;
429 int have_zone_delegation = GNUNET_NO;
430 int have_gns2dns = GNUNET_NO;
431 int have_other = GNUNET_NO;
432 int have_redirect = GNUNET_NO;
433 int have_empty_label = (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, label));
434 unsigned int rd_count_tmp;
435
436 minimum_expiration = GNUNET_TIME_UNIT_ZERO_ABS;
437 now = GNUNET_TIME_absolute_get ();
438 rd_count_tmp = 0;
439 for (unsigned int i = 0; i < rd_count; i++)
440 {
441 /* Ignore the tombstone. For maintenance only. Remember expiration time. */
442 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
443 {
444 minimum_expiration.abs_value_us = rd[i].expiration_time;
445 continue;
446 }
447 /* No NICK records unless empty label */
448 if (have_empty_label &&
449 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type))
450 continue;
451
452 /**
453 * Check for delegation and redirect consistency.
454 * Note that we check for consistency BEFORE we filter for
455 * private records ON PURPOSE.
456 * We also want consistent record sets in our local zone(s).
457 * The only exception is the tombstone (above) which we ignore
458 * for the consistency check(s).
459 * FIXME: What about shadow records? Should we ignore them?
460 */
461 if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
462 {
463 /* No delegation records under empty label*/
464 if (have_empty_label)
465 {
466 *emsg = GNUNET_strdup (_ (
467 "Zone delegation record not allowed in apex."));
468 return GNUNET_SYSERR;
469 }
470 if ((GNUNET_YES == have_other) ||
471 (GNUNET_YES == have_redirect) ||
472 (GNUNET_YES == have_gns2dns))
473 {
474 *emsg = GNUNET_strdup (_ (
475 "Zone delegation record set contains mutually exclusive records."));
476 return GNUNET_SYSERR;
477 }
478 have_zone_delegation = GNUNET_YES;
479 }
480 else if (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[i].record_type)
481 {
482 if (GNUNET_YES == have_redirect)
483 {
484 *emsg = GNUNET_strdup (_ (
485 "Multiple REDIRECT records."));
486 return GNUNET_SYSERR;
487
488 }
489 if ((GNUNET_YES == have_other) ||
490 (GNUNET_YES == have_zone_delegation) ||
491 (GNUNET_YES == have_gns2dns))
492 {
493 *emsg = GNUNET_strdup (_ (
494 "Redirection record set contains mutually exclusive records."));
495 return GNUNET_SYSERR;
496 }
497 /* No redirection records under empty label*/
498 if (have_empty_label)
499 {
500 *emsg = GNUNET_strdup (_ (
501 "Redirection records not allowed in apex."));
502 return GNUNET_SYSERR;
503 }
504 have_redirect = GNUNET_YES;
505 }
506 else if (GNUNET_GNSRECORD_TYPE_GNS2DNS == rd[i].record_type)
507 {
508 /* No gns2dns records under empty label*/
509 if (have_empty_label)
510 {
511 *emsg = GNUNET_strdup (_ (
512 "Redirection records not allowed in apex.."));
513 return GNUNET_SYSERR;
514 }
515 if ((GNUNET_YES == have_other) ||
516 (GNUNET_YES == have_redirect) ||
517 (GNUNET_YES == have_zone_delegation))
518 {
519 *emsg = GNUNET_strdup (_ (
520 "Redirection record set contains mutually exclusive records."));
521 return GNUNET_SYSERR;
522 }
523 have_gns2dns = GNUNET_YES;
524 }
525 else
526 {
527 /* Some other record.
528 * Not allowed for zone delegations or redirections */
529 if ((GNUNET_YES == have_zone_delegation) ||
530 (GNUNET_YES == have_redirect) ||
531 (GNUNET_YES == have_gns2dns))
532 {
533 *emsg = GNUNET_strdup (_ (
534 "Mutually exclusive records."));
535 return GNUNET_SYSERR;
536 }
537 have_other = GNUNET_YES;
538 }
539
540 /* Ignore private records for public record set */
541
542 if ((GNUNET_NO == include_private) &&
543 (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)))
544 continue;
545 /* Skip expired records */
546 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
547 (rd[i].expiration_time < now.abs_value_us))
548 continue; /* record already expired, skip it */
549 rd_public[rd_count_tmp] = rd[i];
550 /* Make sure critical record types are marked as such */
551 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
552 rd_public[rd_count_tmp].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
553 rd_count_tmp++;
554 }
555
556 *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_count_tmp,
557 rd_public,
558 minimum_expiration);
559 *rd_count_public = rd_count_tmp;
560 return GNUNET_OK;
561}
562
563
564enum GNUNET_GenericReturnValue
565GNUNET_GNSRECORD_convert_records_for_export (const char *label,
566 const struct
567 GNUNET_GNSRECORD_Data *rd,
568 unsigned int rd_count,
569 struct GNUNET_GNSRECORD_Data *
570 rd_public,
571 unsigned int *rd_count_public,
572 struct GNUNET_TIME_Absolute *expiry,
573 char **emsg)
574{
575 return GNUNET_GNSRECORD_normalize_record_set (label,
576 rd,
577 rd_count,
578 rd_public,
579 rd_count_public,
580 expiry,
581 GNUNET_NO,
582 emsg);
583
584}
585
586
587/* end of gnsrecord_misc.c */
diff --git a/src/gnsrecord/gnsrecord_serialization.c b/src/gnsrecord/gnsrecord_serialization.c
deleted file mode 100644
index 97c488c2b..000000000
--- a/src/gnsrecord/gnsrecord_serialization.c
+++ /dev/null
@@ -1,322 +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#include "gnunet_dnsparser_lib.h"
35#include "gnunet_tun_lib.h"
36
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
39
40/**
41 * Set to 1 to check that all records are well-formed (can be converted
42 * to string) during serialization/deserialization.
43 */
44#define DEBUG_GNSRECORDS 0
45
46GNUNET_NETWORK_STRUCT_BEGIN
47
48
49/**
50 * Internal format of a record in the serialized form.
51 */
52struct NetworkRecord
53{
54 /**
55 * Expiration time for the DNS record; relative or absolute depends
56 * on @e flags, network byte order.
57 */
58 uint64_t expiration_time GNUNET_PACKED;
59
60 /**
61 * Number of bytes in 'data', network byte order.
62 */
63 uint16_t data_size GNUNET_PACKED;
64
65 /**
66 * Flags for the record, network byte order.
67 */
68 uint16_t flags GNUNET_PACKED;
69
70 /**
71 * Type of the GNS/DNS record, network byte order.
72 */
73 uint32_t record_type GNUNET_PACKED;
74
75};
76
77GNUNET_NETWORK_STRUCT_END
78
79
80/**
81 * Calculate how many bytes we will need to serialize the given
82 * records.
83 *
84 * @param rd_count number of records in the rd array
85 * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
86 * @return the required size to serialize, -1 on error
87 */
88ssize_t
89GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
90 const struct GNUNET_GNSRECORD_Data *rd)
91{
92 size_t ret;
93
94 if (0 == rd_count)
95 return 0;
96
97 ret = sizeof(struct NetworkRecord) * rd_count;
98 for (unsigned int i = 0; i < rd_count; i++)
99 {
100 if ((ret + rd[i].data_size) < ret)
101 {
102 GNUNET_break (0);
103 return -1;
104 }
105 ret += rd[i].data_size;
106#if DEBUG_GNSRECORDS
107 {
108 char *str;
109
110 str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
111 rd[i].data,
112 rd[i].data_size);
113 if (NULL == str)
114 {
115 GNUNET_break_op (0);
116 return -1;
117 }
118 GNUNET_free (str);
119 }
120#endif
121 }
122 if (ret > SSIZE_MAX)
123 {
124 GNUNET_break (0);
125 return -1;
126 }
127 // Do not pad PKEY
128 if ((GNUNET_GNSRECORD_TYPE_PKEY == rd->record_type) ||
129 (GNUNET_GNSRECORD_TYPE_EDKEY == rd->record_type))
130 return ret;
131 /**
132 * Efficiently round up to the next
133 * power of 2 for padding
134 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
135 */ret--;
136 ret |= ret >> 1;
137 ret |= ret >> 2;
138 ret |= ret >> 4;
139 ret |= ret >> 8;
140 ret |= ret >> 16;
141 ret++;
142 return (ssize_t) ret;
143}
144
145
146/**
147 * Serialize the given records to the given destination buffer.
148 *
149 * @param rd_count number of records in the rd array
150 * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
151 * @param dest_size size of the destination array
152 * @param dest where to write the result
153 * @return the size of serialized records, -1 if records do not fit
154 */
155ssize_t
156GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
157 const struct GNUNET_GNSRECORD_Data *rd,
158 size_t dest_size,
159 char *dest)
160{
161 struct NetworkRecord rec;
162 size_t off;
163
164 off = 0;
165 for (unsigned int i = 0; i < rd_count; i++)
166 {
167 LOG (GNUNET_ERROR_TYPE_DEBUG,
168 "Serializing record %u with flags %d and expiration time %llu\n",
169 i,
170 rd[i].flags,
171 (unsigned long long) rd[i].expiration_time);
172 rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
173 rec.data_size = htons ((uint16_t) rd[i].data_size);
174 rec.record_type = htonl (rd[i].record_type);
175 rec.flags = htons (rd[i].flags);
176 if ((off + sizeof(rec) > dest_size) ||
177 (off + sizeof(rec) < off))
178 {
179 GNUNET_break (0);
180 return -1;
181 }
182 GNUNET_memcpy (&dest[off],
183 &rec,
184 sizeof(rec));
185 off += sizeof(rec);
186 if ((off + rd[i].data_size > dest_size) ||
187 (off + rd[i].data_size < off))
188 {
189 GNUNET_break (0);
190 return -1;
191 }
192 GNUNET_memcpy (&dest[off],
193 rd[i].data,
194 rd[i].data_size);
195 off += rd[i].data_size;
196#if DEBUG_GNSRECORDS
197 {
198 char *str;
199
200 str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
201 rd[i].data,
202 rd[i].data_size);
203 if (NULL == str)
204 {
205 GNUNET_break_op (0);
206 return -1;
207 }
208 GNUNET_free (str);
209 }
210#endif
211 }
212 memset (&dest[off],
213 0,
214 dest_size - off);
215 return dest_size;
216}
217
218unsigned int
219GNUNET_GNSRECORD_records_deserialize_get_size (size_t len,
220 const char *src)
221{
222 struct NetworkRecord rec;
223 struct NetworkRecord rec_zero;
224 size_t off;
225 unsigned int rd_count = 0;
226
227 memset (&rec_zero, 0, sizeof (rec_zero));
228
229 off = 0;
230 for (off = 0; (off + sizeof(rec) <= len) && (off + sizeof(rec) >= off);)
231 {
232 GNUNET_memcpy (&rec,
233 &src[off],
234 sizeof(rec));
235 /*
236 * If we have found a byte string of zeroes, we have reached
237 * the padding
238 */
239 if (0 == GNUNET_memcmp (&rec, &rec_zero))
240 break;
241 off += sizeof(rec);
242 if ((off + ntohs ((uint16_t) rec.data_size) > len) ||
243 (off + ntohs ((uint16_t) rec.data_size) < off))
244 {
245 GNUNET_break_op (0);
246 return 0;
247 }
248 off += ntohs ((uint16_t) rec.data_size);
249 rd_count++;
250 }
251 return rd_count;
252}
253
254/**
255 * Deserialize the given records to the given destination.
256 *
257 * @param len size of the serialized record data
258 * @param src the serialized record data
259 * @param rd_count number of records parsed
260 * @param dest where to put the data
261 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
262 */
263int
264GNUNET_GNSRECORD_records_deserialize (size_t len,
265 const char *src,
266 unsigned int rd_count,
267 struct GNUNET_GNSRECORD_Data *dest)
268{
269 struct NetworkRecord rec;
270 size_t off;
271
272 off = 0;
273 for (unsigned int i = 0; i < rd_count; i++)
274 {
275 if ((off + sizeof(rec) > len) ||
276 (off + sizeof(rec) < off))
277 {
278 GNUNET_break_op (0);
279 return GNUNET_SYSERR;
280 }
281 GNUNET_memcpy (&rec,
282 &src[off],
283 sizeof(rec));
284 dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
285 dest[i].data_size = ntohs ((uint16_t) rec.data_size);
286 dest[i].record_type = ntohl (rec.record_type);
287 dest[i].flags = ntohs (rec.flags);
288 off += sizeof(rec);
289 if ((off + dest[i].data_size > len) ||
290 (off + dest[i].data_size < off))
291 {
292 GNUNET_break_op (0);
293 return GNUNET_SYSERR;
294 }
295 dest[i].data = &src[off];
296 off += dest[i].data_size;
297#if GNUNET_EXTRA_LOGGING
298 {
299 char *str;
300
301 str = GNUNET_GNSRECORD_value_to_string (dest[i].record_type,
302 dest[i].data,
303 dest[i].data_size);
304 if (NULL == str)
305 {
306 GNUNET_break_op (0);
307 return GNUNET_SYSERR;
308 }
309 GNUNET_free (str);
310 }
311#endif
312 LOG (GNUNET_ERROR_TYPE_DEBUG,
313 "Deserialized record %u with flags %d and expiration time %llu\n",
314 i,
315 dest[i].flags,
316 (unsigned long long) dest[i].expiration_time);
317 }
318 return GNUNET_OK;
319}
320
321
322/* 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 d45b3a5d8..000000000
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ /dev/null
@@ -1,475 +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_dnsparser_lib.h"
32#include "gnunet_testing_lib.h"
33#include <inttypes.h>
34#include "gnsrecord_crypto.h"
35
36
37static char *d_pkey =
38 "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
39
40static char *d_edkey =
41 "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
42
43
44static int
45parsehex (char *src, char *dst, size_t dstlen, int invert)
46{
47 char *line = src;
48 char *data = line;
49 int off;
50 int read_byte;
51 int data_len = 0;
52
53 while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
54 {
55 if (invert)
56 dst[dstlen - 1 - data_len++] = read_byte;
57 else
58 dst[data_len++] = read_byte;
59 data += off;
60 }
61 return data_len;
62}
63
64
65static void
66print_bytes_ (void *buf,
67 size_t buf_len,
68 int fold,
69 int in_be)
70{
71 int i;
72
73 for (i = 0; i < buf_len; i++)
74 {
75 if ((0 != i) && (0 != fold) && (i % fold == 0))
76 printf ("\n");
77 if (in_be)
78 printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
79 else
80 printf ("%02x", ((unsigned char*) buf)[i]);
81 }
82 printf ("\n");
83}
84
85
86static void
87print_bytes (void *buf,
88 size_t buf_len,
89 int fold)
90{
91 print_bytes_ (buf, buf_len, fold, 0);
92}
93
94
95static void
96print_record (const struct GNUNET_GNSRECORD_Data *rd)
97{
98 uint16_t flags = htons (rd->flags);
99 uint64_t abs_nbo = GNUNET_htonll (rd->expiration_time);
100 uint16_t size_nbo = htons (rd->data_size);
101 uint32_t type_nbo = htonl (rd->record_type);
102 printf ("EXPIRATION:\n");
103 print_bytes (&abs_nbo, sizeof (abs_nbo), 8);
104 printf ("\nDATA_SIZE:\n");
105 print_bytes (&size_nbo, sizeof (size_nbo), 8);
106 printf ("\nTYPE:\n");
107 print_bytes (&type_nbo, sizeof (type_nbo), 8);
108 printf ("\nFLAGS: ");
109 print_bytes ((void*) &flags, sizeof (flags), 8);
110 printf ("\n");
111 fprintf (stdout,
112 "DATA:\n");
113 print_bytes ((char*) rd->data, rd->data_size, 8);
114 printf ("\n");
115}
116
117
118/**
119 * Main function that will be run.
120 *
121 * @param cls closure
122 * @param args remaining command-line arguments
123 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
124 * @param cfg configuration
125 */
126static void
127run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label)
128{
129 struct GNUNET_TIME_Absolute expire;
130 struct GNUNET_GNSRECORD_Block *rrblock;
131 char *bdata;
132 struct GNUNET_IDENTITY_PrivateKey id_priv;
133 struct GNUNET_IDENTITY_PublicKey id_pub;
134 struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
135 struct GNUNET_IDENTITY_PublicKey pkey_data;
136 struct GNUNET_HashCode query;
137 char *rdata;
138 char *conv_lbl;
139 size_t rdata_size;
140 char ztld[128];
141 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
142 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
143
144 id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
145 GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
146 parsehex (d_pkey,
147 (char*) &id_priv.ecdsa_key,
148 sizeof (id_priv.ecdsa_key), 1);
149
150 GNUNET_IDENTITY_key_get_public (&id_priv,
151 &id_pub);
152 printf ("Zone private key (d, big-endian):\n");
153 print_bytes_ (&id_priv.ecdsa_key,
154 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1);
155 printf ("\n");
156 printf ("Zone identifier (ztype|zkey):\n");
157 GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub));
158 print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
159 GNUNET_STRINGS_data_to_string (&id_pub,
160 GNUNET_IDENTITY_key_get_length (&id_pub),
161 ztld,
162 sizeof (ztld));
163 printf ("\n");
164 printf ("zTLD:\n");
165 printf ("%s\n", ztld);
166 printf ("\n");
167
168 pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
169 GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key);
170 GNUNET_IDENTITY_key_get_public (&pkey_data_p,
171 &pkey_data);
172 conv_lbl = GNUNET_GNSRECORD_string_normalize (label);
173 printf ("Label:\n");
174 print_bytes (conv_lbl, strlen (conv_lbl), 8);
175 GNUNET_free (conv_lbl);
176 printf ("\Number of records (integer): %d\n\n", rd_count);
177
178 for (int i = 0; i < rd_count; i++)
179 {
180 printf ("Record #%d := (\n", i);
181 print_record (&rd[i]);
182 printf (")\n\n");
183 }
184
185 rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count,
186 rd);
187 rdata = GNUNET_malloc (rdata_size);
188 GNUNET_GNSRECORD_records_serialize (rd_count,
189 rd,
190 (size_t) rdata_size,
191 rdata);
192 printf ("RDATA:\n");
193 print_bytes (rdata,
194 (size_t) rdata_size,
195 8);
196 printf ("\n");
197 expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count, rd,
198 GNUNET_TIME_UNIT_ZERO_ABS);
199 GNR_derive_block_aes_key (ctr,
200 skey,
201 label,
202 GNUNET_TIME_absolute_hton (
203 expire).abs_value_us__,
204 &id_pub.ecdsa_key);
205
206 printf ("Encryption NONCE|EXPIRATION|BLOCK COUNTER:\n");
207 print_bytes (ctr, sizeof (ctr), 8);
208 printf ("\n");
209 printf ("Encryption key (K):\n");
210 print_bytes (skey, sizeof (skey), 8);
211 printf ("\n");
212 GNUNET_GNSRECORD_query_from_public_key (&id_pub,
213 label,
214 &query);
215 printf ("Storage key (q):\n");
216 print_bytes (&query, sizeof (query), 8);
217 printf ("\n");
218 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
219 expire,
220 label,
221 rd,
222 rd_count,
223 &rrblock));
224 size_t bdata_size = ntohl (rrblock->size) - sizeof (struct
225 GNUNET_GNSRECORD_Block);
226
227 bdata = (char*) &(&rrblock->ecdsa_block)[1];
228 printf ("BDATA:\n");
229 print_bytes (bdata, bdata_size, 8);
230 printf ("\n");
231 printf ("RRBLOCK:\n");
232 print_bytes (rrblock, ntohl (rrblock->size), 8);
233 printf ("\n");
234 GNUNET_free (rdata);
235}
236
237
238/**
239 * Main function that will be run.
240 *
241 * @param cls closure
242 * @param args remaining command-line arguments
243 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
244 * @param cfg configuration
245 */
246static void
247run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label)
248{
249 struct GNUNET_TIME_Absolute expire;
250 struct GNUNET_GNSRECORD_Block *rrblock;
251 char *bdata;
252 struct GNUNET_IDENTITY_PrivateKey id_priv;
253 struct GNUNET_IDENTITY_PublicKey id_pub;
254 struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
255 struct GNUNET_IDENTITY_PublicKey pkey_data;
256 struct GNUNET_HashCode query;
257 char *rdata;
258 char *conv_lbl;
259 size_t rdata_size;
260
261 char ztld[128];
262 unsigned char nonce[crypto_secretbox_NONCEBYTES];
263 unsigned char skey[crypto_secretbox_KEYBYTES];
264
265 id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
266 GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
267 GNUNET_IDENTITY_key_get_public (&id_priv,
268 &id_pub);
269
270 id_priv.type = htonl (GNUNET_IDENTITY_TYPE_EDDSA);
271 GNUNET_CRYPTO_eddsa_key_create (&id_priv.eddsa_key);
272 parsehex (d_edkey,
273 (char*) &id_priv.eddsa_key,
274 sizeof (id_priv.eddsa_key), 0);
275 GNUNET_IDENTITY_key_get_public (&id_priv,
276 &id_pub);
277 fprintf (stdout,
278 "Zone private key (d):\n");
279 print_bytes (&id_priv.eddsa_key, sizeof (struct
280 GNUNET_CRYPTO_EddsaPrivateKey), 8);
281 printf ("\n");
282 printf ("Zone identifier (ztype|zkey):\n");
283 GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub));
284 print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
285 GNUNET_STRINGS_data_to_string (&id_pub,
286 GNUNET_IDENTITY_key_get_length (&id_pub),
287 ztld,
288 sizeof (ztld));
289 printf ("\n");
290 printf ("zTLD:\n");
291 printf ("%s\n", ztld);
292 printf ("\n");
293
294 pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
295 GNUNET_CRYPTO_eddsa_key_create (&pkey_data_p.eddsa_key);
296 GNUNET_IDENTITY_key_get_public (&pkey_data_p,
297 &pkey_data);
298 conv_lbl = GNUNET_GNSRECORD_string_normalize (label);
299 printf ("Label:\n");
300 print_bytes (conv_lbl, strlen (conv_lbl), 8);
301 GNUNET_free (conv_lbl);
302 fprintf (stdout,
303 "\Number of records (integer): %d\n\n", rd_count);
304
305 for (int i = 0; i < rd_count; i++)
306 {
307 printf ("Record #%d := (\n", i);
308 print_record (&rd[i]);
309 printf (")\n\n");
310 }
311
312 rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count,
313 rd);
314 expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count,
315 rd,
316 GNUNET_TIME_UNIT_ZERO_ABS);
317 GNUNET_assert (0 < rdata_size);
318 rdata = GNUNET_malloc ((size_t) rdata_size);
319 GNUNET_GNSRECORD_records_serialize (rd_count,
320 rd,
321 (size_t) rdata_size,
322 rdata);
323 printf ("RDATA:\n");
324 print_bytes (rdata,
325 (size_t) rdata_size,
326 8);
327 printf ("\n");
328 GNR_derive_block_xsalsa_key (nonce,
329 skey,
330 label,
331 GNUNET_TIME_absolute_hton (
332 expire).abs_value_us__,
333 &id_pub.eddsa_key);
334 printf ("Encryption NONCE|EXPIRATION:\n");
335 print_bytes (nonce, sizeof (nonce), 8);
336 printf ("\n");
337 printf ("Encryption key (K):\n");
338 print_bytes (skey, sizeof (skey), 8);
339 printf ("\n");
340 GNUNET_GNSRECORD_query_from_public_key (&id_pub,
341 label,
342 &query);
343 printf ("Storage key (q):\n");
344 print_bytes (&query, sizeof (query), 8);
345 printf ("\n");
346
347 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
348 expire,
349 label,
350 rd,
351 rd_count,
352 &rrblock));
353 size_t bdata_size = ntohl (rrblock->size) - sizeof (struct
354 GNUNET_GNSRECORD_Block);
355
356 bdata = (char*) &(&rrblock->eddsa_block)[1];
357 printf ("BDATA:\n");
358 print_bytes (bdata, bdata_size, 8);
359 printf ("\n");
360 printf ("RRBLOCK:\n");
361 print_bytes (rrblock, ntohl (rrblock->size), 8);
362 printf ("\n");
363 GNUNET_free (rdata);
364}
365
366
367/**
368 * Main function that will be run.
369 *
370 * @param cls closure
371 * @param args remaining command-line arguments
372 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
373 * @param cfg configuration
374 */
375static void
376run (void *cls,
377 char *const *args,
378 const char *cfgfile,
379 const struct GNUNET_CONFIGURATION_Handle *cfg)
380{
381 struct GNUNET_GNSRECORD_Data rd_pkey;
382 struct GNUNET_GNSRECORD_Data rd[3];
383 struct GNUNET_TIME_Absolute exp1;
384 struct GNUNET_TIME_Absolute exp2;
385 struct GNUNET_TIME_Relative exp3;
386 size_t pkey_data_size;
387 size_t ip_data_size;
388 char *pkey_data;
389 char *ip_data;
390
391 /*
392 * Make different expiration times
393 */
394 GNUNET_STRINGS_fancy_time_to_absolute ("2048-01-23 10:51:34",
395 &exp1);
396 GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01",
397 &exp2);
398 GNUNET_STRINGS_fancy_time_to_relative ("100y",
399 &exp3);
400
401
402 memset (&rd_pkey, 0, sizeof (struct GNUNET_GNSRECORD_Data));
403 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (
404 GNUNET_GNSRECORD_TYPE_PKEY,
405 "000G0011WESGZY9VRV9NNJ66W3GKNZFZF56BFD2BQF3MHMJST2G2GKDYGG",
406 (void**) &pkey_data,
407 &pkey_data_size));
408 rd_pkey.data = pkey_data;
409 rd_pkey.data_size = pkey_data_size;
410 rd_pkey.expiration_time = exp1.abs_value_us;
411 rd_pkey.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
412 rd_pkey.flags = GNUNET_GNSRECORD_RF_CRITICAL;
413 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (
414 GNUNET_DNSPARSER_TYPE_AAAA,
415 "::dead:beef",
416 (void**) &ip_data,
417 &ip_data_size));
418
419 rd[0].data = ip_data;
420 rd[0].data_size = ip_data_size;
421 rd[0].expiration_time = exp1.abs_value_us;
422 rd[0].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
423 rd[0].flags = GNUNET_GNSRECORD_RF_NONE;
424
425 rd[1].data = "\u611b\u79f0";
426 rd[1].data_size = strlen (rd[1].data);
427 rd[1].expiration_time = exp2.abs_value_us;
428 rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK;
429 rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
430
431 rd[2].data = "Hello World";
432 rd[2].data_size = strlen (rd[2].data);
433 rd[2].expiration_time = exp3.rel_value_us;
434 rd[2].record_type = GNUNET_DNSPARSER_TYPE_TXT;
435 rd[2].flags = GNUNET_GNSRECORD_RF_SUPPLEMENTAL
436 | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
437
438 run_pkey (&rd_pkey, 1, "testdelegation");
439 run_pkey (rd, 3, "\u5929\u4e0b\u7121\u6575");
440 run_edkey (&rd_pkey, 1, "testdelegation");
441 run_edkey (rd, 3, "\u5929\u4e0b\u7121\u6575");
442}
443
444
445/**
446 * The main function of the test vector generation tool.
447 *
448 * @param argc number of arguments from the command line
449 * @param argv command line arguments
450 * @return 0 ok, 1 on error
451 */
452int
453main (int argc,
454 char *const *argv)
455{
456 const struct GNUNET_GETOPT_CommandLineOption options[] = {
457 GNUNET_GETOPT_OPTION_END
458 };
459
460 GNUNET_assert (GNUNET_OK ==
461 GNUNET_log_setup ("gnunet-gns-tvg",
462 "INFO",
463 NULL));
464 if (GNUNET_OK !=
465 GNUNET_PROGRAM_run (argc, argv,
466 "gnunet-gns-tvg",
467 "Generate test vectors for GNS",
468 options,
469 &run, NULL))
470 return 1;
471 return 0;
472}
473
474
475/* end of gnunet-gns-tvg.c */
diff --git a/src/gnsrecord/json_gnsrecord.c b/src/gnsrecord/json_gnsrecord.c
deleted file mode 100644
index 068ff48c1..000000000
--- a/src/gnsrecord/json_gnsrecord.c
+++ /dev/null
@@ -1,391 +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_EXPIRATION_TIME "expiration_time"
35#define GNUNET_JSON_GNSRECORD_FLAG_PRIVATE "private"
36#define GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL "supplemental"
37#define GNUNET_JSON_GNSRECORD_FLAG_RELATIVE "relative_expiration"
38#define GNUNET_JSON_GNSRECORD_FLAG_SHADOW "shadow"
39#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name"
40#define GNUNET_JSON_GNSRECORD_NEVER "never"
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_expiration_time;
86 struct GNUNET_TIME_Relative rel_expiration_time;
87 const char *value;
88 const char *record_type;
89 const char *expiration_time;
90 int private;
91 int supplemental;
92 int rel_exp;
93 int shadow;
94 int unpack_state = 0;
95
96 // interpret single gns record
97 unpack_state = json_unpack (data,
98 "{s:s, s:s, s:s, s:b, s:b, s:b, s:b}",
99 GNUNET_JSON_GNSRECORD_VALUE,
100 &value,
101 GNUNET_JSON_GNSRECORD_TYPE,
102 &record_type,
103 GNUNET_JSON_GNSRECORD_EXPIRATION_TIME,
104 &expiration_time,
105 GNUNET_JSON_GNSRECORD_FLAG_PRIVATE,
106 &private,
107 GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL,
108 &supplemental,
109 GNUNET_JSON_GNSRECORD_FLAG_RELATIVE,
110 &rel_exp,
111 GNUNET_JSON_GNSRECORD_FLAG_SHADOW,
112 &shadow);
113 if (0 != unpack_state)
114 {
115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
116 "Error gnsdata object has a wrong format!\n");
117 return GNUNET_SYSERR;
118 }
119 rd->record_type = GNUNET_GNSRECORD_typename_to_number (record_type);
120 if (UINT32_MAX == rd->record_type)
121 {
122 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n");
123 return GNUNET_SYSERR;
124 }
125 if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (rd->record_type,
126 value,
127 (void **) &rd->data,
128 &rd->data_size))
129 {
130 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n");
131 return GNUNET_SYSERR;
132 }
133
134 if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER))
135 {
136 rd->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
137 }
138 else if ((1 != rel_exp) &&
139 (GNUNET_OK ==
140 GNUNET_STRINGS_fancy_time_to_absolute (expiration_time,
141 &abs_expiration_time)))
142 {
143 rd->expiration_time = abs_expiration_time.abs_value_us;
144 }
145 else if (GNUNET_OK ==
146 GNUNET_STRINGS_fancy_time_to_relative (expiration_time,
147 &rel_expiration_time))
148 {
149 rd->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
150 rd->expiration_time = rel_expiration_time.rel_value_us;
151 }
152 else
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expiration time invalid\n");
155 return GNUNET_SYSERR;
156 }
157 if (1 == private)
158 rd->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
159 if (1 == supplemental)
160 rd->flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
161 if (1 == shadow)
162 rd->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
163 return GNUNET_OK;
164}
165
166
167/**
168 * Parse given JSON object to gns record
169 *
170 * @param cls closure, NULL
171 * @param root the json object representing data
172 * @param spec where to write the data
173 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
174 */
175static int
176parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data)
177{
178 GNUNET_assert (NULL != data);
179 if (! json_is_array (data))
180 {
181 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
182 "Error gns record data JSON is not an array!\n");
183 return GNUNET_SYSERR;
184 }
185 *(gnsrecord_info->rd_count) = json_array_size (data);
186 *(gnsrecord_info->rd) = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Data)
187 * json_array_size (data));
188 size_t index;
189 json_t *value;
190 json_array_foreach (data, index, value)
191 {
192 if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index]))
193 return GNUNET_SYSERR;
194 }
195 return GNUNET_OK;
196}
197
198
199static int
200parse_gnsrecordobject (void *cls,
201 json_t *root,
202 struct GNUNET_JSON_Specification *spec)
203{
204 struct GnsRecordInfo *gnsrecord_info;
205 int unpack_state = 0;
206 const char *name;
207 json_t *data;
208
209 GNUNET_assert (NULL != root);
210 if (! json_is_object (root))
211 {
212 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
213 "Error record JSON is not an object!\n");
214 return GNUNET_SYSERR;
215 }
216 // interpret single gns record
217 unpack_state = json_unpack (root,
218 "{s:s, s:o!}",
219 GNUNET_JSON_GNSRECORD_RECORD_NAME,
220 &name,
221 GNUNET_JSON_GNSRECORD_RECORD_DATA,
222 &data);
223 if (0 != unpack_state)
224 {
225 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
226 "Error namestore records object has a wrong format!\n");
227 return GNUNET_SYSERR;
228 }
229 gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
230 *(gnsrecord_info->name) = GNUNET_strdup (name);
231 if (GNUNET_OK != parse_record_data (gnsrecord_info, data))
232 {
233 cleanup_recordinfo (gnsrecord_info);
234 return GNUNET_SYSERR;
235 }
236 return GNUNET_OK;
237}
238
239
240/**
241 * Cleanup data left from parsing the record.
242 *
243 * @param cls closure, NULL
244 * @param[out] spec where to free the data
245 */
246static void
247clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec)
248{
249 struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
250
251 GNUNET_free (gnsrecord_info);
252}
253
254
255/**
256 * JSON Specification for GNS Records.
257 *
258 * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill
259 * @return JSON Specification
260 */
261struct GNUNET_JSON_Specification
262GNUNET_GNSRECORD_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd,
263 unsigned int *rd_count,
264 char **name)
265{
266 struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo);
267
268 gnsrecord_info->rd = rd;
269 gnsrecord_info->name = name;
270 gnsrecord_info->rd_count = rd_count;
271 struct GNUNET_JSON_Specification ret = { .parser = &parse_gnsrecordobject,
272 .cleaner = &clean_gnsrecordobject,
273 .cls = NULL,
274 .field = NULL,
275 .ptr = (struct GnsRecordInfo *)
276 gnsrecord_info,
277 .ptr_size = 0,
278 .size_ptr = NULL };
279 return ret;
280}
281
282
283/**
284 * Convert GNS record to JSON.
285 *
286 * @param rname name of record
287 * @param rd record data
288 * @return corresponding JSON encoding
289 */
290json_t *
291GNUNET_GNSRECORD_JSON_from_gnsrecord (const char*rname,
292 const struct GNUNET_GNSRECORD_Data *rd,
293 unsigned int rd_count)
294{
295 struct GNUNET_TIME_Absolute abs_exp;
296 struct GNUNET_TIME_Relative rel_exp;
297 const char *expiration_time_str;
298 const char *record_type_str;
299 char *value_str;
300 json_t *data;
301 json_t *record;
302 json_t *records;
303
304 data = json_object ();
305 if (NULL == data)
306 {
307 GNUNET_break (0);
308 return NULL;
309 }
310 if (0 !=
311 json_object_set_new (data,
312 "record_name",
313 json_string (rname)))
314 {
315 GNUNET_break (0);
316 json_decref (data);
317 return NULL;
318 }
319 records = json_array ();
320 if (NULL == records)
321 {
322 GNUNET_break (0);
323 json_decref (data);
324 return NULL;
325 }
326 for (int i = 0; i < rd_count; i++)
327 {
328 value_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
329 rd[i].data,
330 rd[i].data_size);
331 if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd[i].flags)
332 {
333 rel_exp.rel_value_us = rd[i].expiration_time;
334 expiration_time_str = GNUNET_STRINGS_relative_time_to_string (rel_exp,
335 GNUNET_NO);
336 }
337 else
338 {
339 abs_exp.abs_value_us = rd[i].expiration_time;
340 expiration_time_str = GNUNET_STRINGS_absolute_time_to_string (abs_exp);
341 }
342 record_type_str = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
344 "Packing %s %s %s %d\n",
345 value_str, record_type_str, expiration_time_str, rd[i].flags);
346 record = json_pack ("{s:s,s:s,s:s,s:b,s:b,s:b,s:b}",
347 "value",
348 value_str,
349 "record_type",
350 record_type_str,
351 "expiration_time",
352 expiration_time_str,
353 "private",
354 rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE,
355 "relative_expiration",
356 rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION,
357 "supplemental",
358 rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL,
359 "shadow",
360 rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD);
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}
390
391
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 649133cd1..000000000
--- a/src/gnsrecord/plugin_gnsrecord_dns.c
+++ /dev/null
@@ -1,819 +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_dnsparser_lib.h"
29#include "gnunet_gnsrecord_plugin.h"
30
31
32/**
33 * Convert the 'value' of a record to a string.
34 *
35 * @param cls closure, unused
36 * @param type type of the record
37 * @param data value in binary encoding
38 * @param data_size number of bytes in @a data
39 * @return NULL on error, otherwise human-readable representation of the value
40 */
41static char *
42dns_value_to_string (void *cls,
43 uint32_t type,
44 const void *data,
45 size_t data_size)
46{
47 char *result;
48 char tmp[INET6_ADDRSTRLEN];
49
50 switch (type)
51 {
52 case GNUNET_DNSPARSER_TYPE_A:
53 if (data_size != sizeof(struct in_addr))
54 return NULL;
55 if (NULL == inet_ntop (AF_INET, data, tmp, sizeof(tmp)))
56 return NULL;
57 return GNUNET_strdup (tmp);
58
59 case GNUNET_DNSPARSER_TYPE_NS: {
60 char *ns;
61 size_t off;
62
63 off = 0;
64 ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
65 if ((NULL == ns) || (off != data_size))
66 {
67 GNUNET_break_op (0);
68 GNUNET_free (ns);
69 return NULL;
70 }
71 return ns;
72 }
73
74 case GNUNET_DNSPARSER_TYPE_CNAME: {
75 char *cname;
76 size_t off;
77
78 off = 0;
79 cname = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
80 if ((NULL == cname) || (off != data_size))
81 {
82 GNUNET_break_op (0);
83 GNUNET_free (cname);
84 return NULL;
85 }
86 return cname;
87 }
88
89 case GNUNET_DNSPARSER_TYPE_SOA: {
90 struct GNUNET_DNSPARSER_SoaRecord *soa;
91 size_t off;
92
93 off = 0;
94 soa = GNUNET_DNSPARSER_parse_soa (data, data_size, &off);
95 if ((NULL == soa) || (off != data_size))
96 {
97 GNUNET_break_op (0);
98 if (NULL != soa)
99 GNUNET_DNSPARSER_free_soa (soa);
100 return NULL;
101 }
102 GNUNET_asprintf (&result,
103 "rname=%s mname=%s %u,%u,%u,%u,%u",
104 soa->rname,
105 soa->mname,
106 soa->serial,
107 soa->refresh,
108 soa->retry,
109 soa->expire,
110 soa->minimum_ttl);
111 GNUNET_DNSPARSER_free_soa (soa);
112 return result;
113 }
114
115 case GNUNET_DNSPARSER_TYPE_PTR: {
116 char *ptr;
117 size_t off;
118
119 off = 0;
120 ptr = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
121 if ((NULL == ptr) || (off != data_size))
122 {
123 GNUNET_break_op (0);
124 GNUNET_free (ptr);
125 return NULL;
126 }
127 return ptr;
128 }
129
130 case GNUNET_DNSPARSER_TYPE_CERT: {
131 struct GNUNET_DNSPARSER_CertRecord *cert;
132 size_t off;
133 char *base64;
134 int len;
135
136 off = 0;
137 cert = GNUNET_DNSPARSER_parse_cert (data, data_size, &off);
138 if ((NULL == cert) || (off != data_size))
139 {
140 GNUNET_break_op (0);
141 GNUNET_DNSPARSER_free_cert (cert);
142 return NULL;
143 }
144 len = GNUNET_STRINGS_base64_encode (cert->certificate_data,
145 cert->certificate_size,
146 &base64);
147 GNUNET_asprintf (&result,
148 "%u %u %u %.*s",
149 cert->cert_type,
150 cert->cert_tag,
151 cert->algorithm,
152 len,
153 base64);
154 GNUNET_free (base64);
155 GNUNET_DNSPARSER_free_cert (cert);
156 return result;
157 }
158
159 case GNUNET_DNSPARSER_TYPE_MX: {
160 struct GNUNET_DNSPARSER_MxRecord *mx;
161 size_t off;
162
163 off = 0;
164 mx = GNUNET_DNSPARSER_parse_mx (data, data_size, &off);
165 if ((NULL == mx) || (off != data_size))
166 {
167 GNUNET_break_op (0);
168 GNUNET_DNSPARSER_free_mx (mx);
169 return NULL;
170 }
171 GNUNET_asprintf (&result,
172 "%u,%s",
173 (unsigned int) mx->preference,
174 mx->mxhost);
175 GNUNET_DNSPARSER_free_mx (mx);
176 return result;
177 }
178
179 case GNUNET_DNSPARSER_TYPE_TXT:
180 return GNUNET_strndup (data, data_size);
181
182 case GNUNET_DNSPARSER_TYPE_AAAA:
183 if (data_size != sizeof(struct in6_addr))
184 return NULL;
185 if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof(tmp)))
186 return NULL;
187 return GNUNET_strdup (tmp);
188
189 case GNUNET_DNSPARSER_TYPE_SRV: {
190 struct GNUNET_DNSPARSER_SrvRecord *srv;
191 size_t off;
192
193 off = 0;
194 srv = GNUNET_DNSPARSER_parse_srv (data, data_size, &off);
195 if ((NULL == srv) || (off != data_size))
196 {
197 GNUNET_break_op (0);
198 if (NULL != srv)
199 GNUNET_DNSPARSER_free_srv (srv);
200 return NULL;
201 }
202 GNUNET_asprintf (&result,
203 "%d %d %d %s",
204 srv->priority,
205 srv->weight,
206 srv->port,
207 srv->target);
208 GNUNET_DNSPARSER_free_srv (srv);
209 return result;
210 }
211
212 case GNUNET_DNSPARSER_TYPE_TLSA: {
213 const struct GNUNET_TUN_DnsTlsaRecord *tlsa;
214 char *tlsa_str;
215 char *hex;
216
217 if (data_size < sizeof(struct GNUNET_TUN_DnsTlsaRecord))
218 return NULL; /* malformed */
219 tlsa = data;
220 hex =
221 GNUNET_DNSPARSER_bin_to_hex (&tlsa[1],
222 data_size
223 - sizeof(struct GNUNET_TUN_DnsTlsaRecord));
224 if (0 == GNUNET_asprintf (&tlsa_str,
225 "%u %u %u %s",
226 (unsigned int) tlsa->usage,
227 (unsigned int) tlsa->selector,
228 (unsigned int) tlsa->matching_type,
229 hex))
230 {
231 GNUNET_free (hex);
232 GNUNET_free (tlsa_str);
233 return NULL;
234 }
235 GNUNET_free (hex);
236 return tlsa_str;
237 }
238
239 case GNUNET_DNSPARSER_TYPE_CAA: { // RFC6844
240 const struct GNUNET_DNSPARSER_CaaRecord *caa;
241 char tag[15]; // between 1 and 15 bytes
242 char value[data_size];
243 char *caa_str;
244 if (data_size < sizeof(struct GNUNET_DNSPARSER_CaaRecord))
245 return NULL; /* malformed */
246 caa = data;
247 if ((1 > caa->tag_len) || (15 < caa->tag_len))
248 return NULL; /* malformed */
249 memset (tag, 0, sizeof(tag));
250 memset (value, 0, data_size);
251 memcpy (tag, &caa[1], caa->tag_len);
252 memcpy (value,
253 (char *) &caa[1] + caa->tag_len,
254 data_size - caa->tag_len - 2);
255 if (0 == GNUNET_asprintf (&caa_str,
256 "%u %s %s",
257 (unsigned int) caa->flags,
258 tag,
259 value))
260 {
261 GNUNET_free (caa_str);
262 return NULL;
263 }
264 return caa_str;
265 }
266
267 default:
268 return NULL;
269 }
270}
271
272
273/**
274 * Convert RFC 4394 Mnemonics to the corresponding integer values.
275 *
276 * @param mnemonic string to look up
277 * @return the value, 0 if not found
278 */
279static unsigned int
280rfc4398_mnemonic_to_value (const char *mnemonic)
281{
282 static struct
283 {
284 const char *mnemonic;
285 unsigned int val;
286 } table[] = { { "PKIX", 1 },
287 { "SPKI", 2 },
288 { "PGP", 3 },
289 { "IPKIX", 4 },
290 { "ISPKI", 5 },
291 { "IPGP", 6 },
292 { "ACPKIX", 7 },
293 { "IACPKIX", 8 },
294 { "URI", 253 },
295 { "OID", 254 },
296 { NULL, 0 } };
297 unsigned int i;
298
299 for (i = 0; NULL != table[i].mnemonic; i++)
300 if (0 == strcasecmp (mnemonic, table[i].mnemonic))
301 return table[i].val;
302 return 0;
303}
304
305
306/**
307 * Convert RFC 4034 algorithm types to the corresponding integer values.
308 *
309 * @param mnemonic string to look up
310 * @return the value, 0 if not found
311 */
312static unsigned int
313rfc4034_mnemonic_to_value (const char *mnemonic)
314{
315 static struct
316 {
317 const char *mnemonic;
318 unsigned int val;
319 } table[] = { { "RSAMD5", 1 },
320 { "DH", 2 },
321 { "DSA", 3 },
322 { "ECC", 4 },
323 { "RSASHA1", 5 },
324 { "INDIRECT", 252 },
325 { "PRIVATEDNS", 253 },
326 { "PRIVATEOID", 254 },
327 { NULL, 0 } };
328 unsigned int i;
329
330 for (i = 0; NULL != table[i].mnemonic; i++)
331 if (0 == strcasecmp (mnemonic, table[i].mnemonic))
332 return table[i].val;
333 return 0;
334}
335
336
337/**
338 * Convert human-readable version of a 'value' of a record to the binary
339 * representation.
340 *
341 * @param cls closure, unused
342 * @param type type of the record
343 * @param s human-readable string
344 * @param data set to value in binary encoding (will be allocated)
345 * @param data_size set to number of bytes in @a data
346 * @return #GNUNET_OK on success
347 */
348static int
349dns_string_to_value (void *cls,
350 uint32_t type,
351 const char *s,
352 void **data,
353 size_t *data_size)
354{
355 struct in_addr value_a;
356 struct in6_addr value_aaaa;
357 struct GNUNET_TUN_DnsTlsaRecord *tlsa;
358
359 if (NULL == s)
360 return GNUNET_SYSERR;
361 switch (type)
362 {
363 case GNUNET_DNSPARSER_TYPE_A:
364 if (1 != inet_pton (AF_INET, s, &value_a))
365 {
366 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
367 _ ("Unable to parse IPv4 address `%s'\n"),
368 s);
369 return GNUNET_SYSERR;
370 }
371 *data = GNUNET_new (struct in_addr);
372 GNUNET_memcpy (*data, &value_a, sizeof(value_a));
373 *data_size = sizeof(value_a);
374 return GNUNET_OK;
375
376 case GNUNET_DNSPARSER_TYPE_NS: {
377 char nsbuf[256];
378 size_t off;
379
380 off = 0;
381 if (GNUNET_OK !=
382 GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof(nsbuf), &off, s))
383 {
384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
385 _ ("Failed to serialize NS record with value `%s'\n"),
386 s);
387 return GNUNET_SYSERR;
388 }
389 *data_size = off;
390 *data = GNUNET_malloc (off);
391 GNUNET_memcpy (*data, nsbuf, off);
392 return GNUNET_OK;
393 }
394
395 case GNUNET_DNSPARSER_TYPE_CNAME: {
396 char cnamebuf[256];
397 size_t off;
398
399 off = 0;
400 if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (cnamebuf,
401 sizeof(cnamebuf),
402 &off,
403 s))
404 {
405 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
406 _ ("Failed to serialize CNAME record with value `%s'\n"),
407 s);
408 return GNUNET_SYSERR;
409 }
410 *data_size = off;
411 *data = GNUNET_malloc (off);
412 GNUNET_memcpy (*data, cnamebuf, off);
413 return GNUNET_OK;
414 }
415
416 case GNUNET_DNSPARSER_TYPE_CERT: {
417 char *sdup;
418 const char *typep;
419 const char *keyp;
420 const char *algp;
421 const char *certp;
422 unsigned int type;
423 unsigned int key;
424 unsigned int alg;
425 size_t cert_size;
426 char *cert_data;
427 struct GNUNET_DNSPARSER_CertRecord cert;
428
429 sdup = GNUNET_strdup (s);
430 typep = strtok (sdup, " ");
431 if ((NULL == typep) ||
432 ((0 == (type = rfc4398_mnemonic_to_value (typep))) &&
433 ((1 != sscanf (typep, "%u", &type)) || (type > UINT16_MAX))))
434 {
435 GNUNET_free (sdup);
436 return GNUNET_SYSERR;
437 }
438 keyp = strtok (NULL, " ");
439 if ((NULL == keyp) || (1 != sscanf (keyp, "%u", &key)) ||
440 (key > UINT16_MAX))
441 {
442 GNUNET_free (sdup);
443 return GNUNET_SYSERR;
444 }
445 alg = 0;
446 algp = strtok (NULL, " ");
447 if ((NULL == algp) ||
448 ((0 == (type = rfc4034_mnemonic_to_value (typep))) &&
449 ((1 != sscanf (algp, "%u", &alg)) || (alg > UINT8_MAX))))
450 {
451 GNUNET_free (sdup);
452 return GNUNET_SYSERR;
453 }
454 certp = strtok (NULL, " ");
455 if ((NULL == certp) || (0 == strlen (certp)))
456 {
457 GNUNET_free (sdup);
458 return GNUNET_SYSERR;
459 }
460 cert_size = GNUNET_STRINGS_base64_decode (certp,
461 strlen (certp),
462 (void **) &cert_data);
463 GNUNET_free (sdup);
464 cert.cert_type = type;
465 cert.cert_tag = key;
466 cert.algorithm = alg;
467 cert.certificate_size = cert_size;
468 cert.certificate_data = cert_data;
469 {
470 char certbuf[cert_size + sizeof(struct GNUNET_TUN_DnsCertRecord)];
471 size_t off;
472
473 off = 0;
474 if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_cert (certbuf,
475 sizeof(certbuf),
476 &off,
477 &cert))
478 {
479 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
480 _ ("Failed to serialize CERT record with %u bytes\n"),
481 (unsigned int) cert_size);
482 GNUNET_free (cert_data);
483 return GNUNET_SYSERR;
484 }
485 *data_size = off;
486 *data = GNUNET_malloc (off);
487 GNUNET_memcpy (*data, certbuf, off);
488 }
489 GNUNET_free (cert_data);
490 return GNUNET_OK;
491 }
492
493 case GNUNET_DNSPARSER_TYPE_SOA: {
494 struct GNUNET_DNSPARSER_SoaRecord soa;
495 char soabuf[540];
496 char soa_rname[253 + 1];
497 char soa_mname[253 + 1];
498 unsigned int soa_serial;
499 unsigned int soa_refresh;
500 unsigned int soa_retry;
501 unsigned int soa_expire;
502 unsigned int soa_min;
503 size_t off;
504
505 if (7 != sscanf (s,
506 "rname=%253s mname=%253s %u,%u,%u,%u,%u",
507 soa_rname,
508 soa_mname,
509 &soa_serial,
510 &soa_refresh,
511 &soa_retry,
512 &soa_expire,
513 &soa_min))
514 {
515 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
516 _ ("Unable to parse SOA record `%s'\n"),
517 s);
518 return GNUNET_SYSERR;
519 }
520 soa.mname = soa_mname;
521 soa.rname = soa_rname;
522 soa.serial = (uint32_t) soa_serial;
523 soa.refresh = (uint32_t) soa_refresh;
524 soa.retry = (uint32_t) soa_retry;
525 soa.expire = (uint32_t) soa_expire;
526 soa.minimum_ttl = (uint32_t) soa_min;
527 off = 0;
528 if (GNUNET_OK !=
529 GNUNET_DNSPARSER_builder_add_soa (soabuf, sizeof(soabuf), &off, &soa))
530 {
531 GNUNET_log (
532 GNUNET_ERROR_TYPE_ERROR,
533 _ ("Failed to serialize SOA record with mname `%s' and rname `%s'\n"),
534 soa_mname,
535 soa_rname);
536 return GNUNET_SYSERR;
537 }
538 *data_size = off;
539 *data = GNUNET_malloc (off);
540 GNUNET_memcpy (*data, soabuf, off);
541 return GNUNET_OK;
542 }
543
544 case GNUNET_DNSPARSER_TYPE_PTR: {
545 char ptrbuf[256];
546 size_t off;
547
548 off = 0;
549 if (GNUNET_OK !=
550 GNUNET_DNSPARSER_builder_add_name (ptrbuf, sizeof(ptrbuf), &off, s))
551 {
552 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
553 _ ("Failed to serialize PTR record with value `%s'\n"),
554 s);
555 return GNUNET_SYSERR;
556 }
557 *data_size = off;
558 *data = GNUNET_malloc (off);
559 GNUNET_memcpy (*data, ptrbuf, off);
560 return GNUNET_OK;
561 }
562
563 case GNUNET_DNSPARSER_TYPE_MX: {
564 struct GNUNET_DNSPARSER_MxRecord mx;
565 char mxbuf[258];
566 char mxhost[253 + 1];
567 unsigned int mx_pref;
568 size_t off;
569
570 if (2 != sscanf (s, "%u,%253s", &mx_pref, mxhost))
571 {
572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
573 _ ("Unable to parse MX record `%s'\n"),
574 s);
575 return GNUNET_SYSERR;
576 }
577 mx.preference = (uint16_t) mx_pref;
578 mx.mxhost = mxhost;
579 off = 0;
580
581 if (GNUNET_OK !=
582 GNUNET_DNSPARSER_builder_add_mx (mxbuf, sizeof(mxbuf), &off, &mx))
583 {
584 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
585 _ ("Failed to serialize MX record with hostname `%s'\n"),
586 mxhost);
587 return GNUNET_SYSERR;
588 }
589 *data_size = off;
590 *data = GNUNET_malloc (off);
591 GNUNET_memcpy (*data, mxbuf, off);
592 return GNUNET_OK;
593 }
594
595 case GNUNET_DNSPARSER_TYPE_SRV: {
596 struct GNUNET_DNSPARSER_SrvRecord srv;
597 char srvbuf[270];
598 char srvtarget[253 + 1];
599 unsigned int priority;
600 unsigned int weight;
601 unsigned int port;
602 size_t off;
603
604 if (4 != sscanf (s, "%u %u %u %253s", &priority, &weight, &port,
605 srvtarget))
606 {
607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
608 _ ("Unable to parse SRV record `%s'\n"),
609 s);
610 return GNUNET_SYSERR;
611 }
612 srv.priority = (uint16_t) priority;
613 srv.weight = (uint16_t) weight;
614 srv.port = (uint16_t) port;
615 srv.target = srvtarget;
616 off = 0;
617 if (GNUNET_OK !=
618 GNUNET_DNSPARSER_builder_add_srv (srvbuf, sizeof(srvbuf), &off, &srv))
619 {
620 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
621 _ ("Failed to serialize SRV record with target `%s'\n"),
622 srvtarget);
623 return GNUNET_SYSERR;
624 }
625 *data_size = off;
626 *data = GNUNET_malloc (off);
627 GNUNET_memcpy (*data, srvbuf, off);
628 return GNUNET_OK;
629 }
630
631 case GNUNET_DNSPARSER_TYPE_TXT:
632 *data = GNUNET_strdup (s);
633 *data_size = strlen (s);
634 return GNUNET_OK;
635
636 case GNUNET_DNSPARSER_TYPE_AAAA:
637 if (1 != inet_pton (AF_INET6, s, &value_aaaa))
638 {
639 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
640 _ ("Unable to parse IPv6 address `%s'\n"),
641 s);
642 return GNUNET_SYSERR;
643 }
644 *data = GNUNET_new (struct in6_addr);
645 *data_size = sizeof(struct in6_addr);
646 GNUNET_memcpy (*data, &value_aaaa, sizeof(value_aaaa));
647 return GNUNET_OK;
648
649 case GNUNET_DNSPARSER_TYPE_TLSA: {
650 unsigned int usage;
651 unsigned int selector;
652 unsigned int matching_type;
653 size_t slen = strlen (s) + 1;
654 char hex[slen];
655
656 if (4 != sscanf (s, "%u %u %u %s", &usage, &selector, &matching_type,
657 hex))
658 {
659 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
660 _ ("Unable to parse TLSA record string `%s'\n"),
661 s);
662 *data_size = 0;
663 return GNUNET_SYSERR;
664 }
665
666 *data_size = sizeof(struct GNUNET_TUN_DnsTlsaRecord) + strlen (hex) / 2;
667 *data = tlsa = GNUNET_malloc (*data_size);
668 tlsa->usage = (uint8_t) usage;
669 tlsa->selector = (uint8_t) selector;
670 tlsa->matching_type = (uint8_t) matching_type;
671 if (strlen (hex) / 2 != GNUNET_DNSPARSER_hex_to_bin (hex, &tlsa[1]))
672 {
673 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
674 _ ("Unable to parse TLSA record string `%s'\n"),
675 s);
676 GNUNET_free (*data);
677 *data = NULL;
678 *data_size = 0;
679 return GNUNET_SYSERR;
680 }
681 return GNUNET_OK;
682 }
683
684 case GNUNET_DNSPARSER_TYPE_CAA: { // RFC6844
685 struct GNUNET_DNSPARSER_CaaRecord *caa;
686 unsigned int flags;
687 char tag[15]; // Max tag length 15
688 char value[strlen (s) + 1]; // Should be more than enough
689
690 if (3 != sscanf (s, "%u %s %[^\n]", &flags, tag, value))
691 {
692 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
693 _ ("Unable to parse CAA record string `%s'\n"),
694 s);
695 *data_size = 0;
696 return GNUNET_SYSERR;
697 }
698 *data_size = sizeof(struct GNUNET_DNSPARSER_CaaRecord) + strlen (tag)
699 + strlen (value);
700 *data = caa = GNUNET_malloc (*data_size);
701 caa->flags = flags;
702 memcpy (&caa[1], tag, strlen (tag));
703 caa->tag_len = strlen (tag);
704 memcpy ((char *) &caa[1] + caa->tag_len, value, strlen (value));
705 return GNUNET_OK;
706 }
707
708 default:
709 return GNUNET_SYSERR;
710 }
711}
712
713
714/**
715 * Mapping of record type numbers to human-readable
716 * record type names.
717 */
718static struct
719{
720 const char *name;
721 uint32_t number;
722} name_map[] = { { "A", GNUNET_DNSPARSER_TYPE_A },
723 { "NS", GNUNET_DNSPARSER_TYPE_NS },
724 { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME },
725 { "SOA", GNUNET_DNSPARSER_TYPE_SOA },
726 { "PTR", GNUNET_DNSPARSER_TYPE_PTR },
727 { "MX", GNUNET_DNSPARSER_TYPE_MX },
728 { "TXT", GNUNET_DNSPARSER_TYPE_TXT },
729 { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA },
730 { "SRV", GNUNET_DNSPARSER_TYPE_SRV },
731 { "TLSA", GNUNET_DNSPARSER_TYPE_TLSA },
732 { "CERT", GNUNET_DNSPARSER_TYPE_CERT },
733 { "CAA", GNUNET_DNSPARSER_TYPE_CAA },
734 { NULL, UINT32_MAX } };
735
736
737/**
738 * Convert a type name (e.g. "AAAA") to the corresponding number.
739 *
740 * @param cls closure, unused
741 * @param dns_typename name to convert
742 * @return corresponding number, UINT32_MAX on error
743 */
744static uint32_t
745dns_typename_to_number (void *cls, const char *dns_typename)
746{
747 unsigned int i;
748
749 i = 0;
750 while ((NULL != name_map[i].name) &&
751 (0 != strcasecmp (dns_typename, name_map[i].name)))
752 i++;
753 return name_map[i].number;
754}
755
756
757/**
758 * Convert a type number to the corresponding type string (e.g. 1 to "A")
759 *
760 * @param cls closure, unused
761 * @param type number of a type to convert
762 * @return corresponding typestring, NULL on error
763 */
764static const char *
765dns_number_to_typename (void *cls, uint32_t type)
766{
767 unsigned int i;
768
769 i = 0;
770 while ((NULL != name_map[i].name) && (type != name_map[i].number))
771 i++;
772 return name_map[i].name;
773}
774
775
776static enum GNUNET_GenericReturnValue
777dns_is_critical (void *cls, uint32_t type)
778{
779 return GNUNET_NO;
780}
781
782/**
783 * Entry point for the plugin.
784 *
785 * @param cls NULL
786 * @return the exported block API
787 */
788void *
789libgnunet_plugin_gnsrecord_dns_init (void *cls)
790{
791 struct GNUNET_GNSRECORD_PluginFunctions *api;
792
793 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
794 api->value_to_string = &dns_value_to_string;
795 api->string_to_value = &dns_string_to_value;
796 api->typename_to_number = &dns_typename_to_number;
797 api->number_to_typename = &dns_number_to_typename;
798 api->is_critical = &dns_is_critical;
799 return api;
800}
801
802
803/**
804 * Exit point from the plugin.
805 *
806 * @param cls the return value from #libgnunet_plugin_block_test_init
807 * @return NULL
808 */
809void *
810libgnunet_plugin_gnsrecord_dns_done (void *cls)
811{
812 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
813
814 GNUNET_free (api);
815 return NULL;
816}
817
818
819/* 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 d14ce3914..000000000
--- a/src/gnsrecord/test_gnsrecord_block_expiration.c
+++ /dev/null
@@ -1,110 +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 rd[1].data = GNUNET_malloc (TEST_RECORD_DATALEN);
82 rd[1].flags = GNUNET_GNSRECORD_RF_SHADOW_RECORD;
83 memset ((char *) rd[1].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
84
85 GNUNET_assert (expiration_abs_shadow.abs_value_us ==
86 GNUNET_GNSRECORD_record_get_expiration_time (2,
87 rd,
88 GNUNET_TIME_UNIT_ZERO_ABS).abs_value_us);
89 res = 0;
90}
91
92
93int
94main (int argc, char *argv[])
95{
96 static char *const argvx[] = { "test-gnsrecord-crypto",
97 NULL };
98 static struct GNUNET_GETOPT_CommandLineOption options[] = {
99 GNUNET_GETOPT_OPTION_END
100 };
101
102 res = 1;
103 GNUNET_PROGRAM_run ((sizeof(argvx) / sizeof(char *)) - 1, argvx,
104 "test-namestore-api",
105 "nohelp", options, &run, &res);
106 return res;
107}
108
109
110/* 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 ad7b62cc8..000000000
--- a/src/gnsrecord/test_gnsrecord_crypto.c
+++ /dev/null
@@ -1,206 +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_dnsparser_lib.h"
27#include "gnunet_gnsrecord_lib.h"
28
29#define RECORDS 5
30
31#define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
32
33#define TEST_RECORD_DATALEN 123
34
35#define TEST_RECORD_DATA 'a'
36
37#define TEST_REMOVE_RECORD_TYPE 4321
38
39#define TEST_REMOVE_RECORD_DATALEN 255
40
41#define TEST_REMOVE_RECORD_DATA 'b'
42
43
44static struct GNUNET_GNSRECORD_Data *s_rd;
45
46static char *s_name;
47
48static int res;
49
50
51static struct GNUNET_GNSRECORD_Data *
52create_record (int count)
53{
54 struct GNUNET_GNSRECORD_Data *rd;
55
56 rd = GNUNET_new_array (count, struct GNUNET_GNSRECORD_Data);
57 for (unsigned int c = 0; c < count; c++)
58 {
59 rd[c].expiration_time = GNUNET_TIME_absolute_get ().abs_value_us
60 + 1000000000;
61 rd[c].record_type = TEST_RECORD_TYPE;
62 rd[c].data_size = TEST_RECORD_DATALEN;
63 rd[c].data = GNUNET_malloc (TEST_RECORD_DATALEN);
64 memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
65 }
66 return rd;
67}
68
69
70static void
71rd_decrypt_cb (void *cls,
72 unsigned int rd_count,
73 const struct GNUNET_GNSRECORD_Data *rd)
74{
75 char rd_cmp_data[TEST_RECORD_DATALEN];
76
77 GNUNET_assert (RECORDS == rd_count);
78 GNUNET_assert (NULL != rd);
79 memset (rd_cmp_data,
80 'a',
81 TEST_RECORD_DATALEN);
82 for (unsigned int c = 0; c < rd_count; c++)
83 {
84 GNUNET_assert (TEST_RECORD_TYPE == rd[c].record_type);
85 GNUNET_assert (TEST_RECORD_DATALEN == rd[c].data_size);
86 GNUNET_assert (0 == memcmp (&rd_cmp_data,
87 rd[c].data,
88 TEST_RECORD_DATALEN));
89 }
90 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
91 "Block was decrypted successfully \n");
92 res = 0;
93}
94
95
96static void
97test_with_type (struct GNUNET_IDENTITY_PrivateKey *privkey)
98{
99 struct GNUNET_GNSRECORD_Block *block;
100 struct GNUNET_IDENTITY_PublicKey pubkey;
101 struct GNUNET_HashCode query_pub;
102 struct GNUNET_HashCode query_priv;
103 struct GNUNET_HashCode query_block;
104 struct GNUNET_TIME_Absolute expire = GNUNET_TIME_UNIT_FOREVER_ABS;
105
106
107 /* get public key */
108 GNUNET_IDENTITY_key_get_public (privkey,
109 &pubkey);
110
111 /* test query derivation */
112 GNUNET_GNSRECORD_query_from_private_key (privkey,
113 "testlabel",
114 &query_priv);
115 GNUNET_GNSRECORD_query_from_public_key (&pubkey,
116 "testlabel",
117 &query_pub);
118 GNUNET_assert (0 == memcmp (&query_priv,
119 &query_pub,
120 sizeof(struct GNUNET_HashCode)));
121 /* create record */
122 s_name = "testlabel";
123 s_rd = create_record (RECORDS);
124
125 /* Create block */
126 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (privkey,
127 expire,
128 s_name,
129 s_rd,
130 RECORDS,
131 &block));
132 GNUNET_assert (GNUNET_OK ==
133 GNUNET_GNSRECORD_query_from_block (block,
134 &query_block));
135 GNUNET_assert (0 == memcmp (&query_pub,
136 &query_block,
137 sizeof(struct GNUNET_HashCode)));
138
139 GNUNET_assert (GNUNET_OK ==
140 GNUNET_GNSRECORD_block_verify (block));
141 GNUNET_assert (GNUNET_OK ==
142 GNUNET_GNSRECORD_block_decrypt (block,
143 &pubkey,
144 s_name,
145 &rd_decrypt_cb,
146 NULL));
147 GNUNET_free (block);
148}
149
150
151static void
152run (void *cls,
153 char *const *args,
154 const char *cfgfile,
155 const struct GNUNET_CONFIGURATION_Handle *cfg)
156{
157 struct GNUNET_IDENTITY_PrivateKey privkey;
158 struct GNUNET_IDENTITY_PrivateKey privkey_ed;
159 struct GNUNET_TIME_Absolute start;
160 struct GNUNET_TIME_Absolute end;
161
162
163 privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
164 GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
165 start = GNUNET_TIME_absolute_get ();
166 test_with_type (&privkey);
167 end = GNUNET_TIME_absolute_get ();
168 printf ("Time: %llu ms\n", (unsigned long long)
169 GNUNET_TIME_absolute_get_difference (start,
170 end).rel_value_us);
171
172 privkey_ed.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
173 GNUNET_CRYPTO_eddsa_key_create (&privkey_ed.eddsa_key);
174 start = GNUNET_TIME_absolute_get ();
175 test_with_type (&privkey_ed);
176 end = GNUNET_TIME_absolute_get ();
177 printf ("Time: %llu ms\n", (unsigned long long)
178 GNUNET_TIME_absolute_get_difference (start,
179 end).rel_value_us);
180
181
182}
183
184
185int
186main (int argc, char *argv[])
187{
188 static char *const argvx[] = {
189 "test-gnsrecord-crypto",
190 NULL
191 };
192 static struct GNUNET_GETOPT_CommandLineOption options[] = {
193 GNUNET_GETOPT_OPTION_END
194 };
195
196 res = 1;
197 GNUNET_PROGRAM_run ((sizeof(argvx) / sizeof(char *)) - 1,
198 argvx,
199 "test-gnsrecord-crypto",
200 "nohelp", options,
201 &run, &res);
202 return res;
203}
204
205
206/* 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 d268cb7f3..000000000
--- a/src/gnsrecord/test_gnsrecord_serialization.c
+++ /dev/null
@@ -1,157 +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#include "gnunet_dnsparser_lib.h"
28
29#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
30
31static int res;
32
33
34static void
35run (void *cls,
36 char *const *args,
37 const char *cfgfile,
38 const struct GNUNET_CONFIGURATION_Handle *cfg)
39{
40 size_t len;
41 int c;
42
43 int rd_count = 3;
44 size_t data_len;
45 struct GNUNET_GNSRECORD_Data src[rd_count];
46
47 memset (src, '\0', rd_count * sizeof(struct GNUNET_GNSRECORD_Data));
48
49 data_len = 0;
50 for (c = 0; c < rd_count; c++)
51 {
52 src[c].record_type = GNUNET_DNSPARSER_TYPE_TXT;
53 src[c].data_size = data_len;
54 src[c].data = GNUNET_malloc (data_len);
55
56 /* Setting data to data_len * record_type */
57 memset ((char *) src[c].data, 'a', data_len);
58 data_len += 10;
59 }
60 res = 0;
61
62 len = GNUNET_GNSRECORD_records_get_size (rd_count, src);
63 char rd_ser[len];
64 GNUNET_assert (len ==
65 GNUNET_GNSRECORD_records_serialize (rd_count,
66 src,
67 len,
68 rd_ser));
69
70 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
71 "Serialized data len: %u\n",
72 (unsigned int) len);
73
74 GNUNET_assert (rd_ser != NULL);
75 {
76 struct GNUNET_GNSRECORD_Data dst[rd_count];
77 GNUNET_assert (GNUNET_OK ==
78 GNUNET_GNSRECORD_records_deserialize (len,
79 rd_ser,
80 rd_count,
81 dst));
82
83 GNUNET_assert (dst != NULL);
84
85 for (c = 0; c < rd_count; c++)
86 {
87 if (src[c].data_size != dst[c].data_size)
88 {
89 GNUNET_break (0);
90 res = 1;
91 }
92 if (src[c].expiration_time != dst[c].expiration_time)
93 {
94 GNUNET_break (0);
95 res = 1;
96 }
97 if (src[c].flags != dst[c].flags)
98 {
99 GNUNET_break (0);
100 res = 1;
101 }
102 if (src[c].record_type != dst[c].record_type)
103 {
104 GNUNET_break (0);
105 res = 1;
106 }
107
108 {
109 size_t data_size = src[c].data_size;
110 char data[data_size];
111
112 memset (data, 'a', data_size);
113 if (0 != memcmp (data, dst[c].data, data_size))
114 {
115 GNUNET_break (0);
116 res = 1;
117 }
118 if (0 != memcmp (data, src[c].data, data_size))
119 {
120 GNUNET_break (0);
121 res = 1;
122 }
123 if (0 != memcmp (src[c].data, dst[c].data, src[c].data_size))
124 {
125 GNUNET_break (0);
126 res = 1;
127 }
128 }
129 }
130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c);
131 }
132
133 for (c = 0; c < rd_count; c++)
134 {
135 GNUNET_free_nz ((void *) src[c].data);
136 }
137}
138
139
140int
141main (int argcx, char *argvx[])
142{
143 static char *const argv[] = { "test_gnsrecord_serialization",
144 NULL };
145 static struct GNUNET_GETOPT_CommandLineOption options[] = {
146 GNUNET_GETOPT_OPTION_END
147 };
148
149 res = 1;
150 GNUNET_PROGRAM_run ((sizeof(argv) / sizeof(char *)) - 1, argv,
151 "test_namestore_record_serialization",
152 "nohelp", options, &run, &res);
153 return res;
154}
155
156
157/* 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 bb4922417..000000000
--- a/src/gnsrecord/test_gnsrecord_testvectors.c
+++ /dev/null
@@ -1,131 +0,0 @@
1#include "platform.h"
2#include "gnunet_util_lib.h"
3#include "gnunet_signatures.h"
4#include "gnunet_gns_service.h"
5#include "gnunet_gnsrecord_lib.h"
6#include "gnunet_dnsparser_lib.h"
7#include "gnunet_testing_lib.h"
8#include <inttypes.h>
9
10
11
12static char *d =
13 "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
14
15
16static char *zid =
17 "00010000677c477d2d93097c85b195c6f96d84ff61f5982c2c4fe02d5a11fedfb0c2901f";
18
19#define RRCOUNT 2
20#define LABEL "namesystem"
21
22#define R0_EXPIRATION
23#define R0_DATA_SIZE 4
24#define R0_TYPE 1
25#define R0_FLAGS 0
26#define R0_DATA "01020304"
27
28/* Record #1*/
29#define R1_EXPIRATION 26147096139323793
30#define R1_DATA_SIZE 36
31#define R1_TYPE 65536
32#define R1_FLAGS 2
33#define R1_DATA \
34 "000100000e601be42eb57fb4697610cf3a3b18347b65a33f025b5b174abefb30807bfecf"
35
36#define R1_RRBLOCK \
37 "000100008e16da87203b5159c5538e9b765742e968c54af9afbc0890dc80205ad14c84e107b0c115fc0089aa38b9c7ab9cbe1d77040d282a51a2ad493f61f3495f02d8170fe473a55ec6bdf9a509ab1701ffc37ea3bb4cac4a672520986df96e67cc1a73000000940000000f0034e53be193799100e4837eb5d04f92903de4b5234e8ccac5736c9793379a59c33375fc8951aca2eb7aad067bf9af60bf26758646a17f5e5c3b6215f94079545b1c4d4f1b2ebb22c2b4dad44126817b6f001530d476401dd67ac0148554e806353da9e4298079f3e1b16942c48d90c4360c61238c40d9d52911aea52cc0037ac7160bb3cf5b2f4a722fd96b"
38
39int parsehex (char *src, char *dst, size_t dstlen, int invert)
40{
41 char *line = src;
42 char *data = line;
43 int off;
44 int read_byte;
45 int data_len = 0;
46
47 while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
48 {
49 if (invert)
50 dst[dstlen - 1 - data_len++] = read_byte;
51 else
52 dst[data_len++] = read_byte;
53 data += off;
54 }
55 return data_len;
56}
57
58void
59res_checker (void *cls,
60 unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
61{
62 int r0_found = 0;
63 int r1_found = 0;
64 char r0_data[R0_DATA_SIZE];
65 char r1_data[R1_DATA_SIZE];
66 parsehex (R0_DATA, (char*) r0_data, 0, 0);
67 parsehex (R1_DATA, (char*) r1_data, 0, 0);
68 GNUNET_assert (rd_count == RRCOUNT);
69 for (int i = 0; i < RRCOUNT; i++)
70 {
71 if (rd[i].record_type == R0_TYPE)
72 {
73 if (0 != memcmp (rd[i].data, r0_data, R0_DATA_SIZE))
74 {
75 printf ("R0 Data mismatch\n");
76 continue;
77 }
78 if (rd[i].expiration_time != R0_EXPIRATION)
79 {
80 printf ("R0 expiration mismatch\n");
81 continue;
82 }
83 r0_found = 1;
84 }
85 if (rd[i].record_type == R1_TYPE)
86 {
87 if (0 != memcmp (rd[i].data, r1_data, R1_DATA_SIZE))
88 {
89 printf ("R1 Data mismatch\n");
90 continue;
91 }
92 if (rd[i].expiration_time != R1_EXPIRATION)
93 {
94 printf ("R1 expiration mismatch\n");
95 continue;
96 }
97
98 r1_found = 1;
99 }
100
101 }
102 GNUNET_assert (r0_found);
103 GNUNET_assert (r1_found);
104}
105
106
107int
108main ()
109{
110 struct GNUNET_IDENTITY_PrivateKey priv;
111 struct GNUNET_IDENTITY_PublicKey pub;
112 struct GNUNET_IDENTITY_PublicKey pub_parsed;
113 struct GNUNET_GNSRECORD_Block *rrblock;
114 char *bdata;
115
116 parsehex (d,(char*) &priv.ecdsa_key, sizeof (priv.ecdsa_key), 1);
117 priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
118 parsehex (zid,(char*) &pub_parsed, 0, 0);
119 GNUNET_IDENTITY_key_get_public (&priv, &pub);
120 GNUNET_assert (0 == memcmp (&pub, &pub_parsed, sizeof (pub)));
121 rrblock = GNUNET_malloc (strlen (R1_RRBLOCK) / 2);
122 parsehex (R1_RRBLOCK, (char*) rrblock, 0, 0);
123 GNUNET_assert (GNUNET_YES
124 == GNUNET_GNSRECORD_is_critical (GNUNET_GNSRECORD_TYPE_PKEY));
125 GNUNET_GNSRECORD_block_decrypt (rrblock,
126 &pub_parsed,
127 LABEL,
128 &res_checker,
129 NULL);
130 return 0;
131}