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.am119
-rw-r--r--src/gnsrecord/gnsrecord.c263
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c948
-rw-r--r--src/gnsrecord/gnsrecord_misc.c423
-rw-r--r--src/gnsrecord/gnsrecord_serialization.c286
-rw-r--r--src/gnsrecord/gnunet-gnsrecord-tvg.c328
-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.c812
-rw-r--r--src/gnsrecord/test_gnsrecord_block_expiration.c108
-rw-r--r--src/gnsrecord/test_gnsrecord_crypto.c206
-rw-r--r--src/gnsrecord/test_gnsrecord_serialization.c157
13 files changed, 0 insertions, 4186 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 42ac4ede4..000000000
--- a/src/gnsrecord/Makefile.am
+++ /dev/null
@@ -1,119 +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
38gnunet_gnsrecord_tvg_LDADD = \
39 $(top_builddir)/src/util/libgnunetutil.la \
40 $(top_builddir)/src/identity/libgnunetidentity.la \
41 libgnunetgnsrecord.la \
42 $(GN_LIBINTL)
43
44
45libgnunetgnsrecord_la_SOURCES = \
46 gnsrecord.c \
47 gnsrecord_serialization.c \
48 gnsrecord_crypto.c \
49 gnsrecord_misc.c
50libgnunetgnsrecord_la_LIBADD = \
51 $(top_builddir)/src/util/libgnunetutil.la \
52 $(top_builddir)/src/identity/libgnunetidentity.la \
53 $(LIBGCRYPT_LIBS) \
54 -lsodium \
55 $(GN_LIBINTL)
56libgnunetgnsrecord_la_LDFLAGS = \
57 $(GN_LIB_LDFLAGS) \
58 -version-info 0:0:0
59
60libgnunetgnsrecordjson_la_SOURCES = \
61 json_gnsrecord.c
62libgnunetgnsrecordjson_la_LIBADD = \
63 $(top_builddir)/src/util/libgnunetutil.la \
64 $(top_builddir)/src/identity/libgnunetidentity.la \
65 libgnunetgnsrecord.la \
66 -ljansson \
67 $(GN_LIBINTL)
68libgnunetgnsrecordjson_la_LDFLAGS = \
69 $(GN_LIB_LDFLAGS) \
70 -version-info 0:0:0
71
72plugin_LTLIBRARIES = \
73 libgnunet_plugin_gnsrecord_dns.la
74
75
76libgnunet_plugin_gnsrecord_dns_la_SOURCES = \
77 plugin_gnsrecord_dns.c
78libgnunet_plugin_gnsrecord_dns_la_LIBADD = \
79 $(top_builddir)/src/util/libgnunetutil.la \
80 $(LTLIBINTL)
81libgnunet_plugin_gnsrecord_dns_la_LDFLAGS = \
82 $(GN_PLUGIN_LDFLAGS)
83
84
85EXTRA_DIST = \
86 $(check_SCRIPTS)
87
88
89test_gnsrecord_serialization_SOURCES = \
90 test_gnsrecord_serialization.c
91test_gnsrecord_serialization_LDADD = \
92 $(top_builddir)/src/testing/libgnunettesting.la \
93 libgnunetgnsrecord.la \
94 $(top_builddir)/src/util/libgnunetutil.la
95
96test_gnsrecord_block_expiration_SOURCES = \
97 test_gnsrecord_block_expiration.c
98test_gnsrecord_block_expiration_LDADD = \
99 $(top_builddir)/src/testing/libgnunettesting.la \
100 libgnunetgnsrecord.la \
101 $(top_builddir)/src/util/libgnunetutil.la
102
103
104test_gnsrecord_crypto_SOURCES = \
105 test_gnsrecord_crypto.c
106test_gnsrecord_crypto_LDADD = \
107 $(top_builddir)/src/testing/libgnunettesting.la \
108 $(top_builddir)/src/identity/libgnunetidentity.la \
109 libgnunetgnsrecord.la \
110 $(top_builddir)/src/util/libgnunetutil.la
111
112
113perf_gnsrecord_crypto_SOURCES = \
114 perf_gnsrecord_crypto.c
115perf_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
diff --git a/src/gnsrecord/gnsrecord.c b/src/gnsrecord/gnsrecord.c
deleted file mode 100644
index e9994a868..000000000
--- a/src/gnsrecord/gnsrecord.c
+++ /dev/null
@@ -1,263 +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
263/* end of gnsrecord.c */
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
deleted file mode 100644
index feb60ade9..000000000
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ /dev/null
@@ -1,948 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file gnsrecord/gnsrecord_crypto.c
23 * @brief API for GNS record-related crypto
24 * @author Martin Schanzenbach
25 * @author Matthias Wachs
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "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
40ssize_t
41ecdsa_symmetric_decrypt (
42 const void *block,
43 size_t size,
44 const unsigned char *key,
45 const unsigned char *ctr,
46 void *result)
47{
48 gcry_cipher_hd_t handle;
49 int rc;
50
51 GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
52 GCRY_CIPHER_MODE_CTR, 0));
53 rc = gcry_cipher_setkey (handle,
54 key,
55 GNUNET_CRYPTO_AES_KEY_LENGTH);
56 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
57 rc = gcry_cipher_setctr (handle,
58 ctr,
59 GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
60 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
61 GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size));
62 gcry_cipher_close (handle);
63 return size;
64}
65
66
67ssize_t
68ecdsa_symmetric_encrypt (
69 const void *block,
70 size_t size,
71 const unsigned char *key,
72 const unsigned char *ctr,
73 void *result)
74{
75 gcry_cipher_hd_t handle;
76 int rc;
77
78 GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256,
79 GCRY_CIPHER_MODE_CTR, 0));
80 rc = gcry_cipher_setkey (handle,
81 key,
82 GNUNET_CRYPTO_AES_KEY_LENGTH);
83 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
84 rc = gcry_cipher_setctr (handle,
85 ctr,
86 GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
87 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
88 GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size));
89 gcry_cipher_close (handle);
90 return size;
91}
92
93
94enum GNUNET_GenericReturnValue
95eddsa_symmetric_decrypt (
96 const void *block,
97 size_t size,
98 const unsigned char *key,
99 const unsigned char *nonce,
100 void *result)
101{
102 ssize_t ctlen = size - crypto_secretbox_MACBYTES;
103 if (ctlen < 0)
104 return GNUNET_SYSERR;
105 if (0 != crypto_secretbox_open_detached (result,
106 block, // Ciphertext
107 ((unsigned char*)block) + ctlen, // TAG
108 ctlen,
109 nonce, key))
110 {
111 return GNUNET_SYSERR;
112 }
113 return GNUNET_OK;
114}
115
116
117enum GNUNET_GenericReturnValue
118eddsa_symmetric_encrypt (
119 const void *block,
120 size_t size,
121 const unsigned char *key,
122 const unsigned char *nonce,
123 void *result)
124{
125 if (size > crypto_secretbox_MESSAGEBYTES_MAX)
126 return GNUNET_SYSERR;
127 crypto_secretbox_detached (result, // Ciphertext
128 result + size, // TAG
129 block, size, nonce, key);
130 return GNUNET_OK;
131}
132
133
134/**
135 * Derive session key and iv from label and public key.
136 *
137 * @param iv initialization vector to initialize
138 * @param skey session key to initialize
139 * @param label label to use for KDF
140 * @param pub public key to use for KDF
141 */
142static void
143derive_block_aes_key (unsigned char *ctr,
144 unsigned char *key,
145 const char *label,
146 uint64_t exp,
147 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
148{
149 static const char ctx_key[] = "gns-aes-ctx-key";
150 static const char ctx_iv[] = "gns-aes-ctx-iv";
151
152 GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH,
153 ctx_key, strlen (ctx_key),
154 pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
155 label, strlen (label),
156 NULL, 0);
157 memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2);
158 /** 4 byte nonce **/
159 GNUNET_CRYPTO_kdf (ctr, 4,
160 ctx_iv, strlen (ctx_iv),
161 pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
162 label, strlen (label),
163 NULL, 0);
164 /** Expiration time 64 bit. **/
165 memcpy (ctr + 4, &exp, sizeof (exp));
166 /** Set counter part to 1 **/
167 ctr[15] |= 0x01;
168}
169
170
171/**
172 * Derive session key and iv from label and public key.
173 *
174 * @param nonce initialization vector to initialize
175 * @param skey session key to initialize
176 * @param label label to use for KDF
177 * @param pub public key to use for KDF
178 */
179static void
180derive_block_xsalsa_key (unsigned char *nonce,
181 unsigned char *key,
182 const char *label,
183 uint64_t exp,
184 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
185{
186 static const char ctx_key[] = "gns-aes-ctx-key";
187 static const char ctx_iv[] = "gns-aes-ctx-iv";
188
189 GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES,
190 ctx_key, strlen (ctx_key),
191 pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
192 label, strlen (label),
193 NULL, 0);
194 memset (nonce, 0, crypto_secretbox_NONCEBYTES);
195 /** 16 byte nonce **/
196 GNUNET_CRYPTO_kdf (nonce, (crypto_secretbox_NONCEBYTES - sizeof (exp)),
197 ctx_iv, strlen (ctx_iv),
198 pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
199 label, strlen (label),
200 NULL, 0);
201 /** Expiration time 64 bit. **/
202 memcpy (nonce + (crypto_secretbox_NONCEBYTES - sizeof (exp)),
203 &exp, sizeof (exp));
204}
205
206
207/**
208 * Sign name and records
209 *
210 * @param key the private key
211 * @param pkey associated public key
212 * @param expire block expiration
213 * @param label the name for the records
214 * @param rd record data
215 * @param rd_count number of records
216 * @return NULL on error (block too large)
217 */
218static struct GNUNET_GNSRECORD_Block *
219block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
220 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
221 struct GNUNET_TIME_Absolute expire,
222 const char *label,
223 const struct GNUNET_GNSRECORD_Data *rd,
224 unsigned int rd_count)
225{
226 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
227 rd);
228 struct GNUNET_GNSRECORD_Block *block;
229 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
230 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
231 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
232 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
233 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
234 uint32_t rd_count_nbo;
235 struct GNUNET_TIME_Absolute now;
236
237 if (payload_len < 0)
238 {
239 GNUNET_break (0);
240 return NULL;
241 }
242 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
243 {
244 GNUNET_break (0);
245 return NULL;
246 }
247 /* convert relative to absolute times */
248 now = GNUNET_TIME_absolute_get ();
249 for (unsigned int i = 0; i < rd_count; i++)
250 {
251 rdc[i] = rd[i];
252 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
253 {
254 struct GNUNET_TIME_Relative t;
255
256 /* encrypted blocks must never have relative expiration times, convert! */
257 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
258 t.rel_value_us = rdc[i].expiration_time;
259 rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
260 }
261 }
262 /* serialize */
263 rd_count_nbo = htonl (rd_count);
264 {
265 char payload[sizeof(uint32_t) + payload_len];
266
267 GNUNET_memcpy (payload,
268 &rd_count_nbo,
269 sizeof(uint32_t));
270 GNUNET_assert (payload_len ==
271 GNUNET_GNSRECORD_records_serialize (rd_count,
272 rdc,
273 payload_len,
274 &payload[sizeof(uint32_t)
275 ]));
276 block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
277 + sizeof(uint32_t)
278 + payload_len);
279 ecblock = &block->ecdsa_block;
280 block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
281 ecblock->purpose.size = htonl (sizeof(uint32_t)
282 + payload_len
283 + sizeof(struct
284 GNUNET_CRYPTO_EccSignaturePurpose)
285 + sizeof(struct GNUNET_TIME_AbsoluteNBO));
286 ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
287 ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
288 /* encrypt and sign */
289 dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key,
290 label,
291 "gns");
292 GNUNET_CRYPTO_ecdsa_key_get_public (dkey,
293 &ecblock->derived_key);
294 derive_block_aes_key (ctr,
295 skey,
296 label,
297 ecblock->expiration_time.abs_value_us__,
298 pkey);
299 GNUNET_break (payload_len + sizeof(uint32_t) ==
300 ecdsa_symmetric_encrypt (payload,
301 payload_len
302 + sizeof(uint32_t),
303 skey,
304 ctr,
305 &ecblock[1]));
306 }
307 if (GNUNET_OK !=
308 GNUNET_CRYPTO_ecdsa_sign_ (dkey,
309 &ecblock->purpose,
310 &ecblock->signature))
311 {
312 GNUNET_break (0);
313 GNUNET_free (dkey);
314 GNUNET_free (block);
315 return NULL;
316 }
317 GNUNET_free (dkey);
318 return block;
319}
320
321
322/**
323 * Sign name and records (EDDSA version)
324 *
325 * @param key the private key
326 * @param pkey associated public key
327 * @param expire block expiration
328 * @param label the name for the records
329 * @param rd record data
330 * @param rd_count number of records
331 * @return NULL on error (block too large)
332 */
333static struct GNUNET_GNSRECORD_Block *
334block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
335 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
336 struct GNUNET_TIME_Absolute expire,
337 const char *label,
338 const struct GNUNET_GNSRECORD_Data *rd,
339 unsigned int rd_count)
340{
341 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
342 rd);
343 struct GNUNET_GNSRECORD_Block *block;
344 struct GNUNET_GNSRECORD_EddsaBlock *edblock;
345 struct GNUNET_CRYPTO_EddsaPrivateScalar dkey;
346 unsigned char nonce[crypto_secretbox_NONCEBYTES];
347 unsigned char skey[crypto_secretbox_KEYBYTES];
348 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
349 uint32_t rd_count_nbo;
350 struct GNUNET_TIME_Absolute now;
351
352 if (payload_len < 0)
353 {
354 GNUNET_break (0);
355 return NULL;
356 }
357 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
358 {
359 GNUNET_break (0);
360 return NULL;
361 }
362 /* convert relative to absolute times */
363 now = GNUNET_TIME_absolute_get ();
364 for (unsigned int i = 0; i < rd_count; i++)
365 {
366 rdc[i] = rd[i];
367 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
368 {
369 struct GNUNET_TIME_Relative t;
370
371 /* encrypted blocks must never have relative expiration times, convert! */
372 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
373 t.rel_value_us = rdc[i].expiration_time;
374 rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
375 }
376 }
377 /* serialize */
378 rd_count_nbo = htonl (rd_count);
379 {
380 char payload[sizeof(uint32_t) + payload_len];
381
382 GNUNET_memcpy (payload,
383 &rd_count_nbo,
384 sizeof(uint32_t));
385 GNUNET_assert (payload_len ==
386 GNUNET_GNSRECORD_records_serialize (rd_count,
387 rdc,
388 payload_len,
389 &payload[sizeof(uint32_t)
390 ]));
391 block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
392 + sizeof(uint32_t)
393 + payload_len
394 + crypto_secretbox_MACBYTES);
395 edblock = &block->eddsa_block;
396 block->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
397 edblock->purpose.size = htonl (sizeof(uint32_t)
398 + payload_len
399 + sizeof(struct
400 GNUNET_CRYPTO_EccSignaturePurpose)
401 + sizeof(struct GNUNET_TIME_AbsoluteNBO)
402 + crypto_secretbox_MACBYTES);
403 edblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
404 edblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
405 /* encrypt and sign */
406 GNUNET_CRYPTO_eddsa_private_key_derive (key,
407 label,
408 "gns",
409 &dkey);
410 GNUNET_CRYPTO_eddsa_key_get_public_from_scalar (&dkey,
411 &edblock->derived_key);
412 derive_block_xsalsa_key (nonce,
413 skey,
414 label,
415 edblock->expiration_time.abs_value_us__,
416 pkey);
417 GNUNET_break (GNUNET_OK ==
418 eddsa_symmetric_encrypt (payload,
419 payload_len
420 + sizeof(uint32_t),
421 skey,
422 nonce,
423 &edblock[1]));
424 }
425 GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey,
426 &edblock->purpose,
427 &edblock->signature);
428 return block;
429}
430
431
432/**
433 * Sign name and records
434 *
435 * @param key the private key
436 * @param expire block expiration
437 * @param label the name for the records
438 * @param rd record data
439 * @param rd_count number of records
440 * @return NULL on error (block too large)
441 */
442struct GNUNET_GNSRECORD_Block *
443GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
444 struct GNUNET_TIME_Absolute expire,
445 const char *label,
446 const struct GNUNET_GNSRECORD_Data *rd,
447 unsigned int rd_count)
448{
449 struct GNUNET_IDENTITY_PublicKey pkey;
450 GNUNET_IDENTITY_key_get_public (key,
451 &pkey);
452 switch (ntohl (key->type))
453 {
454 case GNUNET_GNSRECORD_TYPE_PKEY:
455 return block_create_ecdsa (&key->ecdsa_key,
456 &pkey.ecdsa_key,
457 expire,
458 label,
459 rd,
460 rd_count);
461 case GNUNET_GNSRECORD_TYPE_EDKEY:
462 return block_create_eddsa (&key->eddsa_key,
463 &pkey.eddsa_key,
464 expire,
465 label,
466 rd,
467 rd_count);
468 default:
469 GNUNET_assert (0);
470 }
471 return NULL;
472}
473
474
475/**
476 * Line in cache mapping private keys to public keys.
477 */
478struct KeyCacheLine
479{
480 /**
481 * A private key.
482 */
483 struct GNUNET_CRYPTO_EcdsaPrivateKey key;
484
485 /**
486 * Associated public key.
487 */
488 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
489};
490
491
492/**
493 * Sign name and records, cache derived public key (also keeps the
494 * private key in static memory, so do not use this function if
495 * keeping the private key in the process'es RAM is a major issue).
496 *
497 * @param key the private key
498 * @param expire block expiration
499 * @param label the name for the records
500 * @param rd record data
501 * @param rd_count number of records
502 * @return NULL on error (block too large)
503 */
504struct GNUNET_GNSRECORD_Block *
505GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
506 struct GNUNET_TIME_Absolute expire,
507 const char *label,
508 const struct GNUNET_GNSRECORD_Data *rd,
509 unsigned int rd_count)
510{
511 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
512 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
513
514 if (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pkey->type))
515 {
516 key = &pkey->ecdsa_key;
517#define CSIZE 64
518 static struct KeyCacheLine cache[CSIZE];
519 struct KeyCacheLine *line;
520
521 line = &cache[(*(unsigned int *) key) % CSIZE];
522 if (0 != memcmp (&line->key,
523 key,
524 sizeof(*key)))
525 {
526 /* cache miss, recompute */
527 line->key = *key;
528 GNUNET_CRYPTO_ecdsa_key_get_public (key,
529 &line->pkey);
530 }
531#undef CSIZE
532 return block_create_ecdsa (key,
533 &line->pkey,
534 expire,
535 label,
536 rd,
537 rd_count);
538 }
539 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
540 {
541 GNUNET_CRYPTO_eddsa_key_get_public (&pkey->eddsa_key,
542 &edpubkey);
543 return block_create_eddsa (&pkey->eddsa_key,
544 &edpubkey,
545 expire,
546 label,
547 rd,
548 rd_count);
549 }
550 return NULL;
551}
552
553
554/**
555 * Check if a signature is valid. This API is used by the GNS Block
556 * to validate signatures received from the network.
557 *
558 * @param block block to verify
559 * @return #GNUNET_OK if the signature is valid
560 */
561enum GNUNET_GenericReturnValue
562GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
563{
564 switch (ntohl (block->type))
565 {
566 case GNUNET_GNSRECORD_TYPE_PKEY:
567 return GNUNET_CRYPTO_ecdsa_verify_ (
568 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
569 &block->ecdsa_block.purpose,
570 &block->ecdsa_block.signature,
571 &block->ecdsa_block.derived_key);
572 case GNUNET_GNSRECORD_TYPE_EDKEY:
573 return GNUNET_CRYPTO_eddsa_verify_ (
574 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
575 &block->eddsa_block.purpose,
576 &block->eddsa_block.signature,
577 &block->eddsa_block.derived_key);
578 default:
579 return GNUNET_NO;
580 }
581}
582
583
584enum GNUNET_GenericReturnValue
585block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
586 const struct
587 GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
588 const char *label,
589 GNUNET_GNSRECORD_RecordCallback proc,
590 void *proc_cls)
591{
592 size_t payload_len = ntohl (block->purpose.size)
593 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
594 - sizeof(struct GNUNET_TIME_AbsoluteNBO);
595 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
596 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
597
598 if (ntohl (block->purpose.size) <
599 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
600 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
601 {
602 GNUNET_break_op (0);
603 return GNUNET_SYSERR;
604 }
605 derive_block_aes_key (ctr,
606 key,
607 label,
608 block->expiration_time.abs_value_us__,
609 zone_key);
610 {
611 char payload[payload_len];
612 uint32_t rd_count;
613
614 GNUNET_break (payload_len ==
615 ecdsa_symmetric_decrypt (&block[1], payload_len,
616 key, ctr,
617 payload));
618 GNUNET_memcpy (&rd_count,
619 payload,
620 sizeof(uint32_t));
621 rd_count = ntohl (rd_count);
622 if (rd_count > 2048)
623 {
624 /* limit to sane value */
625 GNUNET_break_op (0);
626 return GNUNET_SYSERR;
627 }
628 {
629 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
630 unsigned int j;
631 struct GNUNET_TIME_Absolute now;
632
633 if (GNUNET_OK !=
634 GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t),
635 &payload[sizeof(uint32_t)],
636 rd_count,
637 rd))
638 {
639 GNUNET_break_op (0);
640 return GNUNET_SYSERR;
641 }
642 /* hide expired records */
643 now = GNUNET_TIME_absolute_get ();
644 j = 0;
645 for (unsigned int i = 0; i < rd_count; i++)
646 {
647 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
648 {
649 /* encrypted blocks must never have relative expiration times, skip! */
650 GNUNET_break_op (0);
651 continue;
652 }
653
654 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
655 {
656 int include_record = GNUNET_YES;
657 /* Shadow record, figure out if we have a not expired active record */
658 for (unsigned int k = 0; k < rd_count; k++)
659 {
660 if (k == i)
661 continue;
662 if (rd[i].expiration_time < now.abs_value_us)
663 include_record = GNUNET_NO; /* Shadow record is expired */
664 if ((rd[k].record_type == rd[i].record_type) &&
665 (rd[k].expiration_time >= now.abs_value_us) &&
666 (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
667 {
668 include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
669 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
670 "Ignoring shadow record\n");
671 break;
672 }
673 }
674 if (GNUNET_YES == include_record)
675 {
676 rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
677 if (j != i)
678 rd[j] = rd[i];
679 j++;
680 }
681 }
682 else if (rd[i].expiration_time >= now.abs_value_us)
683 {
684 /* Include this record */
685 if (j != i)
686 rd[j] = rd[i];
687 j++;
688 }
689 else
690 {
691 struct GNUNET_TIME_Absolute at;
692
693 at.abs_value_us = rd[i].expiration_time;
694 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
695 "Excluding record that expired %s (%llu ago)\n",
696 GNUNET_STRINGS_absolute_time_to_string (at),
697 (unsigned long long) rd[i].expiration_time
698 - now.abs_value_us);
699 }
700 }
701 rd_count = j;
702 if (NULL != proc)
703 proc (proc_cls,
704 rd_count,
705 (0 != rd_count) ? rd : NULL);
706 }
707 }
708 return GNUNET_OK;
709}
710
711
712enum GNUNET_GenericReturnValue
713block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
714 const struct
715 GNUNET_CRYPTO_EddsaPublicKey *zone_key,
716 const char *label,
717 GNUNET_GNSRECORD_RecordCallback proc,
718 void *proc_cls)
719{
720 size_t payload_len = ntohl (block->purpose.size)
721 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
722 - sizeof(struct GNUNET_TIME_AbsoluteNBO);
723 unsigned char nonce[crypto_secretbox_NONCEBYTES];
724 unsigned char key[crypto_secretbox_KEYBYTES];
725
726 if (ntohl (block->purpose.size) <
727 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
728 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
729 {
730 GNUNET_break_op (0);
731 return GNUNET_SYSERR;
732 }
733 derive_block_xsalsa_key (nonce,
734 key,
735 label,
736 block->expiration_time.abs_value_us__,
737 zone_key);
738 {
739 char payload[payload_len];
740 uint32_t rd_count;
741
742 GNUNET_break (GNUNET_OK ==
743 eddsa_symmetric_decrypt (&block[1], payload_len,
744 key, nonce,
745 payload));
746 GNUNET_memcpy (&rd_count,
747 payload,
748 sizeof(uint32_t));
749 rd_count = ntohl (rd_count);
750 if (rd_count > 2048)
751 {
752 /* limit to sane value */
753 GNUNET_break_op (0);
754 return GNUNET_SYSERR;
755 }
756 {
757 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
758 unsigned int j;
759 struct GNUNET_TIME_Absolute now;
760
761 if (GNUNET_OK !=
762 GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t),
763 &payload[sizeof(uint32_t)],
764 rd_count,
765 rd))
766 {
767 GNUNET_break_op (0);
768 return GNUNET_SYSERR;
769 }
770 /* hide expired records */
771 now = GNUNET_TIME_absolute_get ();
772 j = 0;
773 for (unsigned int i = 0; i < rd_count; i++)
774 {
775 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
776 {
777 /* encrypted blocks must never have relative expiration times, skip! */
778 GNUNET_break_op (0);
779 continue;
780 }
781
782 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
783 {
784 int include_record = GNUNET_YES;
785 /* Shadow record, figure out if we have a not expired active record */
786 for (unsigned int k = 0; k < rd_count; k++)
787 {
788 if (k == i)
789 continue;
790 if (rd[i].expiration_time < now.abs_value_us)
791 include_record = GNUNET_NO; /* Shadow record is expired */
792 if ((rd[k].record_type == rd[i].record_type) &&
793 (rd[k].expiration_time >= now.abs_value_us) &&
794 (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
795 {
796 include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
797 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
798 "Ignoring shadow record\n");
799 break;
800 }
801 }
802 if (GNUNET_YES == include_record)
803 {
804 rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
805 if (j != i)
806 rd[j] = rd[i];
807 j++;
808 }
809 }
810 else if (rd[i].expiration_time >= now.abs_value_us)
811 {
812 /* Include this record */
813 if (j != i)
814 rd[j] = rd[i];
815 j++;
816 }
817 else
818 {
819 struct GNUNET_TIME_Absolute at;
820
821 at.abs_value_us = rd[i].expiration_time;
822 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
823 "Excluding record that expired %s (%llu ago)\n",
824 GNUNET_STRINGS_absolute_time_to_string (at),
825 (unsigned long long) rd[i].expiration_time
826 - now.abs_value_us);
827 }
828 }
829 rd_count = j;
830 if (NULL != proc)
831 proc (proc_cls,
832 rd_count,
833 (0 != rd_count) ? rd : NULL);
834 }
835 }
836 return GNUNET_OK;
837}
838
839
840/**
841 * Decrypt block.
842 *
843 * @param block block to decrypt
844 * @param zone_key public key of the zone
845 * @param label the name for the records
846 * @param proc function to call with the result
847 * @param proc_cls closure for proc
848 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was
849 * not well-formed
850 */
851enum GNUNET_GenericReturnValue
852GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
853 const struct
854 GNUNET_IDENTITY_PublicKey *zone_key,
855 const char *label,
856 GNUNET_GNSRECORD_RecordCallback proc,
857 void *proc_cls)
858{
859 switch (ntohl (zone_key->type))
860 {
861 case GNUNET_IDENTITY_TYPE_ECDSA:
862 return block_decrypt_ecdsa (&block->ecdsa_block,
863 &zone_key->ecdsa_key, label, proc, proc_cls);
864 case GNUNET_IDENTITY_TYPE_EDDSA:
865 return block_decrypt_eddsa (&block->eddsa_block,
866 &zone_key->eddsa_key, label, proc, proc_cls);
867 default:
868 return GNUNET_SYSERR;
869 }
870}
871
872
873/**
874 * Calculate the DHT query for a given @a label in a given @a zone.
875 *
876 * @param zone private key of the zone
877 * @param label label of the record
878 * @param query hash to use for the query
879 */
880void
881GNUNET_GNSRECORD_query_from_private_key (const struct
882 GNUNET_IDENTITY_PrivateKey *zone,
883 const char *label,
884 struct GNUNET_HashCode *query)
885{
886 struct GNUNET_IDENTITY_PublicKey pub;
887 switch (ntohl (zone->type))
888 {
889 case GNUNET_GNSRECORD_TYPE_PKEY:
890 case GNUNET_GNSRECORD_TYPE_EDKEY:
891
892 GNUNET_IDENTITY_key_get_public (zone,
893 &pub);
894 GNUNET_GNSRECORD_query_from_public_key (&pub,
895 label,
896 query);
897 break;
898 default:
899 GNUNET_assert (0);
900 }
901}
902
903
904/**
905 * Calculate the DHT query for a given @a label in a given @a zone.
906 * FIXME: We may want to plugin-ize this at some point.
907 *
908 * @param pub public key of the zone
909 * @param label label of the record
910 * @param query hash to use for the query
911 */
912void
913GNUNET_GNSRECORD_query_from_public_key (const struct
914 GNUNET_IDENTITY_PublicKey *pub,
915 const char *label,
916 struct GNUNET_HashCode *query)
917{
918 struct GNUNET_IDENTITY_PublicKey pd;
919
920 switch (ntohl (pub->type))
921 {
922 case GNUNET_GNSRECORD_TYPE_PKEY:
923 pd.type = pub->type;
924 GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key,
925 label,
926 "gns",
927 &pd.ecdsa_key);
928 GNUNET_CRYPTO_hash (&pd.ecdsa_key,
929 sizeof (pd.ecdsa_key),
930 query);
931 break;
932 case GNUNET_GNSRECORD_TYPE_EDKEY:
933 pd.type = pub->type;
934 GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key,
935 label,
936 "gns",
937 &(pd.eddsa_key));
938 GNUNET_CRYPTO_hash (&pd.eddsa_key,
939 sizeof (pd.eddsa_key),
940 query);
941 break;
942 default:
943 GNUNET_assert (0);
944 }
945}
946
947
948/* end of gnsrecord_crypto.c */
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
deleted file mode 100644
index 8d3a6421f..000000000
--- a/src/gnsrecord/gnsrecord_misc.c
+++ /dev/null
@@ -1,423 +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
40/**
41 * Convert a UTF-8 string to UTF-8 lowercase
42 * @param src source string
43 * @return converted result
44 */
45char *
46GNUNET_GNSRECORD_string_to_lowercase (const char *src)
47{
48 char *res;
49
50 res = GNUNET_strdup (src);
51 GNUNET_STRINGS_utf8_tolower (src, res);
52 return res;
53}
54
55
56/**
57 * Convert a zone key to a string (for printing debug messages).
58 * This is one of the very few calls in the entire API that is
59 * NOT reentrant!
60 *
61 * @param z the zone key
62 * @return string form; will be overwritten by next call to #GNUNET_GNSRECORD_z2s
63 */
64const char *
65GNUNET_GNSRECORD_z2s (const struct GNUNET_IDENTITY_PublicKey *z)
66{
67 static char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) * 8];
68 char *end;
69
70 end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z,
71 sizeof(struct
72 GNUNET_IDENTITY_PublicKey),
73 buf, sizeof(buf));
74 if (NULL == end)
75 {
76 GNUNET_break (0);
77 return NULL;
78 }
79 *end = '\0';
80 return buf;
81}
82
83
84/**
85 * Compares if two records are equal (ignoring flags such
86 * as authority, private and pending, but not relative vs.
87 * absolute expiration time).
88 *
89 * @param a record
90 * @param b record
91 * @return #GNUNET_YES if the records are equal or #GNUNET_NO if they are not
92 */
93int
94GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a,
95 const struct GNUNET_GNSRECORD_Data *b)
96{
97 LOG (GNUNET_ERROR_TYPE_DEBUG,
98 "Comparing records\n");
99 if (a->record_type != b->record_type)
100 {
101 LOG (GNUNET_ERROR_TYPE_DEBUG,
102 "Record type %u != %u\n", a->record_type, b->record_type);
103 return GNUNET_NO;
104 }
105 if ((a->expiration_time != b->expiration_time) &&
106 ((a->expiration_time != 0) && (b->expiration_time != 0)))
107 {
108 LOG (GNUNET_ERROR_TYPE_DEBUG,
109 "Expiration time %llu != %llu\n",
110 (unsigned long long) a->expiration_time,
111 (unsigned long long) b->expiration_time);
112 return GNUNET_NO;
113 }
114 if ((a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)
115 != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS))
116 {
117 LOG (GNUNET_ERROR_TYPE_DEBUG,
118 "Flags %u (%u) != %u (%u)\n", a->flags,
119 a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags,
120 b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS);
121 return GNUNET_NO;
122 }
123 if (a->data_size != b->data_size)
124 {
125 LOG (GNUNET_ERROR_TYPE_DEBUG,
126 "Data size %lu != %lu\n",
127 a->data_size,
128 b->data_size);
129 return GNUNET_NO;
130 }
131 if (0 != memcmp (a->data, b->data, a->data_size))
132 {
133 LOG (GNUNET_ERROR_TYPE_DEBUG,
134 "Data contents do not match\n");
135 return GNUNET_NO;
136 }
137 LOG (GNUNET_ERROR_TYPE_DEBUG,
138 "Records are equal\n");
139 return GNUNET_YES;
140}
141
142
143/**
144 * Returns the expiration time of the given block of records. The block
145 * expiration time is the expiration time of the record with smallest
146 * expiration time.
147 *
148 * @param rd_count number of records given in @a rd
149 * @param rd array of records
150 * @return absolute expiration time
151 */
152struct GNUNET_TIME_Absolute
153GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count,
154 const struct
155 GNUNET_GNSRECORD_Data *rd)
156{
157 struct GNUNET_TIME_Absolute expire;
158 struct GNUNET_TIME_Absolute at;
159 struct GNUNET_TIME_Relative rt;
160 struct GNUNET_TIME_Absolute at_shadow;
161 struct GNUNET_TIME_Relative rt_shadow;
162
163 if (NULL == rd)
164 return GNUNET_TIME_UNIT_ZERO_ABS;
165 expire = GNUNET_TIME_UNIT_FOREVER_ABS;
166 for (unsigned int c = 0; c < rd_count; c++)
167 {
168 if (0 != (rd[c].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
169 {
170 rt.rel_value_us = rd[c].expiration_time;
171 at = GNUNET_TIME_relative_to_absolute (rt);
172 }
173 else
174 {
175 at.abs_value_us = rd[c].expiration_time;
176 }
177
178 for (unsigned int c2 = 0; c2 < rd_count; c2++)
179 {
180 /* Check for shadow record */
181 if ((c == c2) ||
182 (rd[c].record_type != rd[c2].record_type) ||
183 (0 == (rd[c2].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
184 continue;
185 /* We have a shadow record */
186 if (0 != (rd[c2].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
187 {
188 rt_shadow.rel_value_us = rd[c2].expiration_time;
189 at_shadow = GNUNET_TIME_relative_to_absolute (rt_shadow);
190 }
191 else
192 {
193 at_shadow.abs_value_us = rd[c2].expiration_time;
194 }
195 at = GNUNET_TIME_absolute_max (at,
196 at_shadow);
197 }
198 expire = GNUNET_TIME_absolute_min (at,
199 expire);
200 }
201 LOG (GNUNET_ERROR_TYPE_DEBUG,
202 "Determined expiration time for block with %u records to be %s\n",
203 rd_count,
204 GNUNET_STRINGS_absolute_time_to_string (expire));
205 return expire;
206}
207
208
209/**
210 * Test if a given record is expired.
211 *
212 * @return #GNUNET_YES if the record is expired,
213 * #GNUNET_NO if not
214 */
215int
216GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd)
217{
218 struct GNUNET_TIME_Absolute at;
219
220 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
221 return GNUNET_NO;
222 at.abs_value_us = rd->expiration_time;
223 return (0 == GNUNET_TIME_absolute_get_remaining (at).rel_value_us) ?
224 GNUNET_YES : GNUNET_NO;
225}
226
227
228/**
229 * Convert public key to the respective absolute domain name in the
230 * ".zkey" pTLD.
231 * This is one of the very few calls in the entire API that is
232 * NOT reentrant!
233 *
234 * @param pkey a public key with a point on the eliptic curve
235 * @return string "X.zkey" where X is the public
236 * key in an encoding suitable for DNS labels.
237 */
238const char *
239GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_IDENTITY_PublicKey *pkey)
240{
241 static char ret[128];
242 char *pkeys;
243
244 pkeys = GNUNET_IDENTITY_public_key_to_string (pkey);
245 GNUNET_snprintf (ret,
246 sizeof(ret),
247 "%s",
248 pkeys);
249 GNUNET_free (pkeys);
250 return ret;
251}
252
253
254/**
255 * Convert an absolute domain name to the
256 * respective public key.
257 *
258 * @param zkey string encoding the coordinates of the public
259 * key in an encoding suitable for DNS labels.
260 * @param pkey set to a public key on the eliptic curve
261 * @return #GNUNET_SYSERR if @a zkey has the wrong syntax
262 */
263int
264GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey,
265 struct GNUNET_IDENTITY_PublicKey *pkey)
266{
267 if (GNUNET_OK !=
268 GNUNET_IDENTITY_public_key_from_string (zkey,
269 pkey))
270 return GNUNET_SYSERR;
271 return GNUNET_OK;
272}
273
274
275enum GNUNET_GenericReturnValue
276GNUNET_GNSRECORD_identity_from_data (const char *data,
277 size_t data_size,
278 uint32_t type,
279 struct GNUNET_IDENTITY_PublicKey *key)
280{
281 if (GNUNET_NO == GNUNET_GNSRECORD_is_zonekey_type (type))
282 return GNUNET_SYSERR;
283 if (data_size > sizeof (struct GNUNET_IDENTITY_PublicKey))
284 return GNUNET_SYSERR;
285 return (GNUNET_IDENTITY_read_key_from_buffer (key, data, data_size) ==
286 data_size?
287 GNUNET_OK :
288 GNUNET_SYSERR);
289}
290
291
292enum GNUNET_GenericReturnValue
293GNUNET_GNSRECORD_data_from_identity (const struct
294 GNUNET_IDENTITY_PublicKey *key,
295 char **data,
296 size_t *data_size,
297 uint32_t *type)
298{
299 char *tmp;
300 *type = ntohl (key->type);
301 *data_size = GNUNET_IDENTITY_key_get_length (key);
302 if (0 == *data_size)
303 return GNUNET_SYSERR;
304 tmp = GNUNET_malloc (*data_size);
305 if (GNUNET_IDENTITY_write_key_to_buffer (key, tmp, *data_size)
306 != *data_size) {
307 GNUNET_free (tmp);
308 *data_size = 0;
309 return GNUNET_SYSERR;
310 }
311 *data = tmp;
312 return GNUNET_OK;
313}
314
315
316enum GNUNET_GenericReturnValue
317GNUNET_GNSRECORD_is_zonekey_type (uint32_t type)
318{
319 switch (type)
320 {
321 case GNUNET_GNSRECORD_TYPE_PKEY:
322 case GNUNET_GNSRECORD_TYPE_EDKEY:
323 return GNUNET_YES;
324 default:
325 return GNUNET_NO;
326 }
327}
328
329
330size_t
331GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block)
332{
333 switch (ntohl (block->type))
334 {
335 case GNUNET_GNSRECORD_TYPE_PKEY:
336 return sizeof (uint32_t) /* zone type */
337 + sizeof (block->ecdsa_block) /* EcdsaBlock */
338 + ntohl (block->ecdsa_block.purpose.size) /* Length of signed data */
339 - sizeof (block->ecdsa_block.purpose); /* Purpose already in EcdsaBlock */
340 break;
341 case GNUNET_GNSRECORD_TYPE_EDKEY:
342 return sizeof (uint32_t) /* zone type */
343 + sizeof (block->eddsa_block) /* EddsaBlock */
344 + ntohl (block->eddsa_block.purpose.size) /* Length of signed data */
345 - sizeof (block->ecdsa_block.purpose); /* Purpose already in EcdsaBlock */
346
347 default:
348 return 0;
349 }
350 return 0;
351}
352
353
354struct GNUNET_TIME_Absolute
355GNUNET_GNSRECORD_block_get_expiration (const struct
356 GNUNET_GNSRECORD_Block *block)
357{
358
359 switch (ntohl (block->type))
360 {
361 case GNUNET_GNSRECORD_TYPE_PKEY:
362 return GNUNET_TIME_absolute_ntoh (block->ecdsa_block.expiration_time);
363 case GNUNET_GNSRECORD_TYPE_EDKEY:
364 return GNUNET_TIME_absolute_ntoh (block->eddsa_block.expiration_time);
365 default:
366 GNUNET_break (0); /* Hopefully we never get here, but we might */
367 }
368 return GNUNET_TIME_absolute_get_zero_ ();
369
370}
371
372
373enum GNUNET_GenericReturnValue
374GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block,
375 struct GNUNET_HashCode *query)
376{
377 switch (ntohl (block->type))
378 {
379 case GNUNET_GNSRECORD_TYPE_PKEY:
380 GNUNET_CRYPTO_hash (&(block->ecdsa_block.derived_key),
381 sizeof (block->ecdsa_block.derived_key),
382 query);
383 return GNUNET_OK;
384 case GNUNET_GNSRECORD_TYPE_EDKEY:
385 GNUNET_CRYPTO_hash (&block->eddsa_block.derived_key,
386 sizeof (block->eddsa_block.derived_key),
387 query);
388 return GNUNET_OK;
389 default:
390 return GNUNET_SYSERR;
391 }
392 return GNUNET_SYSERR;
393
394}
395
396
397enum GNUNET_GenericReturnValue
398GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd,
399 struct GNUNET_IDENTITY_PublicKey *key)
400{
401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
402 "Got record of type %u\n",
403 rd->record_type);
404 switch (rd->record_type)
405 {
406 case GNUNET_GNSRECORD_TYPE_PKEY:
407 key->type = htonl (rd->record_type);
408 memcpy (&key->ecdsa_key, rd->data, sizeof (key->ecdsa_key));
409 return GNUNET_OK;
410 case GNUNET_GNSRECORD_TYPE_EDKEY:
411 key->type = htonl (rd->record_type);
412 memcpy (&key->eddsa_key, rd->data, sizeof (key->eddsa_key));
413 return GNUNET_OK;
414 default:
415 return GNUNET_SYSERR;
416 }
417 return GNUNET_SYSERR;
418
419
420}
421
422
423/* end of gnsrecord_misc.c */
diff --git a/src/gnsrecord/gnsrecord_serialization.c b/src/gnsrecord/gnsrecord_serialization.c
deleted file mode 100644
index cb6957605..000000000
--- a/src/gnsrecord/gnsrecord_serialization.c
+++ /dev/null
@@ -1,286 +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 uint32_t data_size GNUNET_PACKED;
64
65 /**
66 * Type of the GNS/DNS record, network byte order.
67 */
68 uint32_t record_type GNUNET_PACKED;
69
70 /**
71 * Flags for the record, network byte order.
72 */
73 uint32_t flags GNUNET_PACKED;
74};
75
76GNUNET_NETWORK_STRUCT_END
77
78
79/**
80 * Calculate how many bytes we will need to serialize the given
81 * records.
82 *
83 * @param rd_count number of records in the rd array
84 * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
85 * @return the required size to serialize, -1 on error
86 */
87ssize_t
88GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
89 const struct GNUNET_GNSRECORD_Data *rd)
90{
91 size_t ret;
92
93 if (0 == rd_count)
94 return 0;
95
96 ret = sizeof(struct NetworkRecord) * rd_count;
97 for (unsigned int i = 0; i < rd_count; i++)
98 {
99 if ((ret + rd[i].data_size) < ret)
100 {
101 GNUNET_break (0);
102 return -1;
103 }
104 ret += rd[i].data_size;
105#if DEBUG_GNSRECORDS
106 {
107 char *str;
108
109 str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
110 rd[i].data,
111 rd[i].data_size);
112 if (NULL == str)
113 {
114 GNUNET_break_op (0);
115 return -1;
116 }
117 GNUNET_free (str);
118 }
119#endif
120 }
121 if (ret > SSIZE_MAX)
122 {
123 GNUNET_break (0);
124 return -1;
125 }
126 // Do not pad PKEY
127 if ((GNUNET_GNSRECORD_TYPE_PKEY == rd->record_type) ||
128 (GNUNET_GNSRECORD_TYPE_EDKEY == rd->record_type))
129 return ret;
130 /**
131 * Efficiently round up to the next
132 * power of 2 for padding
133 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
134 */ret--;
135 ret |= ret >> 1;
136 ret |= ret >> 2;
137 ret |= ret >> 4;
138 ret |= ret >> 8;
139 ret |= ret >> 16;
140 ret++;
141 return (ssize_t) ret;
142}
143
144
145/**
146 * Serialize the given records to the given destination buffer.
147 *
148 * @param rd_count number of records in the rd array
149 * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
150 * @param dest_size size of the destination array
151 * @param dest where to write the result
152 * @return the size of serialized records, -1 if records do not fit
153 */
154ssize_t
155GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
156 const struct GNUNET_GNSRECORD_Data *rd,
157 size_t dest_size,
158 char *dest)
159{
160 struct NetworkRecord rec;
161 size_t off;
162
163 off = 0;
164 for (unsigned int i = 0; i < rd_count; i++)
165 {
166 LOG (GNUNET_ERROR_TYPE_DEBUG,
167 "Serializing record %u with flags %d and expiration time %llu\n",
168 i,
169 rd[i].flags,
170 (unsigned long long) rd[i].expiration_time);
171 rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
172 rec.data_size = htonl ((uint32_t) rd[i].data_size);
173 rec.record_type = htonl (rd[i].record_type);
174 rec.flags = htonl (rd[i].flags);
175 if ((off + sizeof(rec) > dest_size) ||
176 (off + sizeof(rec) < off))
177 {
178 GNUNET_break (0);
179 return -1;
180 }
181 GNUNET_memcpy (&dest[off],
182 &rec,
183 sizeof(rec));
184 off += sizeof(rec);
185 if ((off + rd[i].data_size > dest_size) ||
186 (off + rd[i].data_size < off))
187 {
188 GNUNET_break (0);
189 return -1;
190 }
191 GNUNET_memcpy (&dest[off],
192 rd[i].data,
193 rd[i].data_size);
194 off += rd[i].data_size;
195#if DEBUG_GNSRECORDS
196 {
197 char *str;
198
199 str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
200 rd[i].data,
201 rd[i].data_size);
202 if (NULL == str)
203 {
204 GNUNET_break_op (0);
205 return -1;
206 }
207 GNUNET_free (str);
208 }
209#endif
210 }
211 memset (&dest[off],
212 0,
213 dest_size - off);
214 return dest_size;
215}
216
217
218/**
219 * Deserialize the given records to the given destination.
220 *
221 * @param len size of the serialized record data
222 * @param src the serialized record data
223 * @param rd_count number of records in the rd array
224 * @param dest where to put the data
225 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
226 */
227int
228GNUNET_GNSRECORD_records_deserialize (size_t len,
229 const char *src,
230 unsigned int rd_count,
231 struct GNUNET_GNSRECORD_Data *dest)
232{
233 struct NetworkRecord rec;
234 size_t off;
235
236 off = 0;
237 for (unsigned int i = 0; i < rd_count; i++)
238 {
239 if ((off + sizeof(rec) > len) ||
240 (off + sizeof(rec) < off))
241 {
242 GNUNET_break_op (0);
243 return GNUNET_SYSERR;
244 }
245 GNUNET_memcpy (&rec,
246 &src[off],
247 sizeof(rec));
248 dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
249 dest[i].data_size = ntohl ((uint32_t) rec.data_size);
250 dest[i].record_type = ntohl (rec.record_type);
251 dest[i].flags = ntohl (rec.flags);
252 off += sizeof(rec);
253 if ((off + dest[i].data_size > len) ||
254 (off + dest[i].data_size < off))
255 {
256 GNUNET_break_op (0);
257 return GNUNET_SYSERR;
258 }
259 dest[i].data = &src[off];
260 off += dest[i].data_size;
261#if GNUNET_EXTRA_LOGGING
262 {
263 char *str;
264
265 str = GNUNET_GNSRECORD_value_to_string (dest[i].record_type,
266 dest[i].data,
267 dest[i].data_size);
268 if (NULL == str)
269 {
270 GNUNET_break_op (0);
271 return GNUNET_SYSERR;
272 }
273 GNUNET_free (str);
274 }
275#endif
276 LOG (GNUNET_ERROR_TYPE_DEBUG,
277 "Deserialized record %u with flags %d and expiration time %llu\n",
278 i,
279 dest[i].flags,
280 (unsigned long long) dest[i].expiration_time);
281 }
282 return GNUNET_OK;
283}
284
285
286/* 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 16a360bdc..000000000
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ /dev/null
@@ -1,328 +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
35#define TEST_RECORD_LABEL "test"
36#define TEST_RECORD_A "1.2.3.4"
37#define TEST_RRCOUNT 2
38
39static void
40print_bytes (void *buf,
41 size_t buf_len,
42 int fold)
43{
44 int i;
45
46 for (i = 0; i < buf_len; i++)
47 {
48 if ((0 != i) && (0 != fold) && (i % fold == 0))
49 printf ("\n");
50 printf ("%02x", ((unsigned char*) buf)[i]);
51 }
52 printf ("\n");
53}
54
55
56static void
57print_record (const struct GNUNET_GNSRECORD_Data *rd)
58{
59
60 fprintf (stdout,
61 "EXPIRATION: %" PRIu64 "\n", rd->expiration_time);
62 fprintf (stdout,
63 "DATA_SIZE: %zu\n", rd->data_size);
64 fprintf (stdout,
65 "TYPE: %d\n", rd->record_type);
66 fprintf (stdout,
67 "FLAGS: %d\n", rd->flags);
68 fprintf (stdout,
69 "DATA:\n");
70 print_bytes ((char*) rd->data, rd->data_size, 8);
71 fprintf (stdout, "\n");
72}
73
74
75/**
76 * Main function that will be run.
77 *
78 * @param cls closure
79 * @param args remaining command-line arguments
80 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
81 * @param cfg configuration
82 */
83static void
84run_pkey (void)
85{
86 struct GNUNET_GNSRECORD_Data rd[2];
87 struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get ();
88 struct GNUNET_GNSRECORD_Block *rrblock;
89 char *bdata;
90 struct GNUNET_IDENTITY_PrivateKey id_priv;
91 struct GNUNET_IDENTITY_PublicKey id_pub;
92 struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
93 struct GNUNET_IDENTITY_PublicKey pkey_data;
94 void *data;
95 size_t data_size;
96 char *rdata;
97 size_t rdata_size;
98 char ztld[128];
99
100 id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
101 GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
102 GNUNET_IDENTITY_key_get_public (&id_priv,
103 &id_pub);
104 fprintf (stdout,
105 "Zone private key (d, little-endian, with ztype prepended):\n");
106 print_bytes (&id_priv, GNUNET_IDENTITY_key_get_length (&id_pub), 8); // FIXME length for privkey?
107 fprintf (stdout, "\n");
108 fprintf (stdout, "Zone identifier (zid):\n");
109 print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
110 GNUNET_STRINGS_data_to_string (&id_pub,
111 GNUNET_IDENTITY_key_get_length (&id_pub),
112 ztld,
113 sizeof (ztld));
114 fprintf (stdout, "\n");
115 fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n");
116 fprintf (stdout, "%s\n", ztld);
117 fprintf (stdout, "\n");
118
119 pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
120 GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key);
121 GNUNET_IDENTITY_key_get_public (&pkey_data_p,
122 &pkey_data);
123 fprintf (stdout,
124 "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT);
125 memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2);
126 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (
127 GNUNET_DNSPARSER_TYPE_A, TEST_RECORD_A, &data, &data_size));
128 rd[0].data = data;
129 rd[0].data_size = data_size;
130 rd[0].expiration_time = exp_abs.abs_value_us;
131 rd[0].record_type = GNUNET_DNSPARSER_TYPE_A;
132 fprintf (stdout, "Record #0\n");
133 print_record (&rd[0]);
134
135 rd[1].data = &pkey_data;
136 rd[1].data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
137 rd[1].expiration_time = exp_abs.abs_value_us;
138 rd[1].record_type = GNUNET_GNSRECORD_TYPE_PKEY;
139 rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
140 fprintf (stdout, "Record #1\n");
141 print_record (&rd[1]);
142
143 rdata_size = GNUNET_GNSRECORD_records_get_size (2,
144 rd);
145 rdata = GNUNET_malloc (rdata_size);
146 GNUNET_GNSRECORD_records_serialize (2,
147 rd,
148 rdata_size,
149 rdata);
150 fprintf (stdout, "RDATA:\n");
151 print_bytes (rdata, rdata_size, 8);
152 fprintf (stdout, "\n");
153 rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
154 exp_abs,
155 TEST_RECORD_LABEL,
156 rd,
157 TEST_RRCOUNT);
158 size_t bdata_size = ntohl (rrblock->ecdsa_block.purpose.size)
159 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
160 - sizeof(struct GNUNET_TIME_AbsoluteNBO);
161 size_t ecblock_size = ntohl (rrblock->ecdsa_block.purpose.size)
162 + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
163 + sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
164 size_t block_size = ecblock_size + sizeof (uint32_t);
165
166 bdata = (char*) &(&rrblock->ecdsa_block)[1];
167 fprintf (stdout, "BDATA:\n");
168 print_bytes (bdata, bdata_size, 8);
169 fprintf (stdout, "\n");
170 fprintf (stdout, "RRBLOCK:\n");
171 print_bytes (rrblock, block_size, 8);
172 fprintf (stdout, "\n");
173 GNUNET_free (rdata);
174}
175
176
177/**
178 * Main function that will be run.
179 *
180 * @param cls closure
181 * @param args remaining command-line arguments
182 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
183 * @param cfg configuration
184 */
185static void
186run_edkey (void)
187{
188 struct GNUNET_GNSRECORD_Data rd[2];
189 struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get ();
190 struct GNUNET_GNSRECORD_Block *rrblock;
191 char *bdata;
192 struct GNUNET_IDENTITY_PrivateKey id_priv;
193 struct GNUNET_IDENTITY_PublicKey id_pub;
194 struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
195 struct GNUNET_IDENTITY_PublicKey pkey_data;
196 void *data;
197 size_t data_size;
198 char *rdata;
199 size_t rdata_size;
200 char ztld[128];
201
202 id_priv.type = htonl (GNUNET_IDENTITY_TYPE_EDDSA);
203 GNUNET_CRYPTO_eddsa_key_create (&id_priv.eddsa_key);
204 GNUNET_IDENTITY_key_get_public (&id_priv,
205 &id_pub);
206 fprintf (stdout,
207 "Zone private key (d, little-endian, with ztype prepended):\n");
208 print_bytes (&id_priv, GNUNET_IDENTITY_key_get_length (&id_pub), 8); // FIXME length for privkey?
209 fprintf (stdout, "\n");
210 fprintf (stdout, "Zone identifier (zid):\n");
211 print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
212 GNUNET_STRINGS_data_to_string (&id_pub,
213 GNUNET_IDENTITY_key_get_length (&id_pub),
214 ztld,
215 sizeof (ztld));
216 fprintf (stdout, "\n");
217 fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n");
218 fprintf (stdout, "%s\n", ztld);
219 fprintf (stdout, "\n");
220
221 pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
222 GNUNET_CRYPTO_eddsa_key_create (&pkey_data_p.eddsa_key);
223 GNUNET_IDENTITY_key_get_public (&pkey_data_p,
224 &pkey_data);
225 fprintf (stdout,
226 "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT);
227 memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2);
228 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (
229 GNUNET_DNSPARSER_TYPE_A, TEST_RECORD_A, &data, &data_size));
230 rd[0].data = data;
231 rd[0].data_size = data_size;
232 rd[0].expiration_time = exp_abs.abs_value_us;
233 rd[0].record_type = GNUNET_DNSPARSER_TYPE_A;
234 fprintf (stdout, "Record #0\n");
235 print_record (&rd[0]);
236
237 rd[1].data = &pkey_data;
238 rd[1].data_size = sizeof (struct GNUNET_CRYPTO_EddsaPublicKey);
239 rd[1].expiration_time = exp_abs.abs_value_us;
240 rd[1].record_type = GNUNET_GNSRECORD_TYPE_EDKEY;
241 rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
242 fprintf (stdout, "Record #1\n");
243 print_record (&rd[1]);
244
245 rdata_size = GNUNET_GNSRECORD_records_get_size (2,
246 rd);
247 rdata = GNUNET_malloc (rdata_size);
248 GNUNET_GNSRECORD_records_serialize (2,
249 rd,
250 rdata_size,
251 rdata);
252 fprintf (stdout, "RDATA:\n");
253 print_bytes (rdata, rdata_size, 8);
254 fprintf (stdout, "\n");
255 rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
256 exp_abs,
257 TEST_RECORD_LABEL,
258 rd,
259 TEST_RRCOUNT);
260 size_t bdata_size = ntohl (rrblock->eddsa_block.purpose.size)
261 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
262 - sizeof(struct GNUNET_TIME_AbsoluteNBO);
263 size_t ecblock_size = ntohl (rrblock->eddsa_block.purpose.size)
264 + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
265 + sizeof(struct GNUNET_CRYPTO_EddsaSignature);
266 size_t block_size = ecblock_size + sizeof (uint32_t);
267
268 bdata = (char*) &(&rrblock->eddsa_block)[1];
269 fprintf (stdout, "BDATA:\n");
270 print_bytes (bdata, bdata_size, 8);
271 fprintf (stdout, "\n");
272 fprintf (stdout, "RRBLOCK:\n");
273 print_bytes (rrblock, block_size, 8);
274 fprintf (stdout, "\n");
275 GNUNET_free (rdata);
276}
277
278
279/**
280 * Main function that will be run.
281 *
282 * @param cls closure
283 * @param args remaining command-line arguments
284 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
285 * @param cfg configuration
286 */
287static void
288run (void *cls,
289 char *const *args,
290 const char *cfgfile,
291 const struct GNUNET_CONFIGURATION_Handle *cfg)
292{
293 run_pkey();
294 run_edkey();
295}
296
297
298/**
299 * The main function of the test vector generation tool.
300 *
301 * @param argc number of arguments from the command line
302 * @param argv command line arguments
303 * @return 0 ok, 1 on error
304 */
305int
306main (int argc,
307 char *const *argv)
308{
309 const struct GNUNET_GETOPT_CommandLineOption options[] = {
310 GNUNET_GETOPT_OPTION_END
311 };
312
313 GNUNET_assert (GNUNET_OK ==
314 GNUNET_log_setup ("gnunet-gns-tvg",
315 "INFO",
316 NULL));
317 if (GNUNET_OK !=
318 GNUNET_PROGRAM_run (argc, argv,
319 "gnunet-gns-tvg",
320 "Generate test vectors for GNS",
321 options,
322 &run, NULL))
323 return 1;
324 return 0;
325}
326
327
328/* 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 d9a3c20cf..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 (NULL != (block =
94 GNUNET_GNSRECORD_block_create2 (&privkey,
95 expire,
96 s_name,
97 s_rd,
98 RECORDS)));
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 123c59905..000000000
--- a/src/gnsrecord/plugin_gnsrecord_dns.c
+++ /dev/null
@@ -1,812 +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
776/**
777 * Entry point for the plugin.
778 *
779 * @param cls NULL
780 * @return the exported block API
781 */
782void *
783libgnunet_plugin_gnsrecord_dns_init (void *cls)
784{
785 struct GNUNET_GNSRECORD_PluginFunctions *api;
786
787 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
788 api->value_to_string = &dns_value_to_string;
789 api->string_to_value = &dns_string_to_value;
790 api->typename_to_number = &dns_typename_to_number;
791 api->number_to_typename = &dns_number_to_typename;
792 return api;
793}
794
795
796/**
797 * Exit point from the plugin.
798 *
799 * @param cls the return value from #libgnunet_plugin_block_test_init
800 * @return NULL
801 */
802void *
803libgnunet_plugin_gnsrecord_dns_done (void *cls)
804{
805 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
806
807 GNUNET_free (api);
808 return NULL;
809}
810
811
812/* 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 b53d7d7e8..000000000
--- a/src/gnsrecord/test_gnsrecord_block_expiration.c
+++ /dev/null
@@ -1,108 +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).abs_value_us);
76
77 rd[1].expiration_time = expiration_abs_shadow.abs_value_us;
78 rd[1].record_type = TEST_RECORD_TYPE;
79 rd[1].data_size = TEST_RECORD_DATALEN;
80 rd[1].data = GNUNET_malloc (TEST_RECORD_DATALEN);
81 rd[1].flags = GNUNET_GNSRECORD_RF_SHADOW_RECORD;
82 memset ((char *) rd[1].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN);
83
84 GNUNET_assert (expiration_abs_shadow.abs_value_us ==
85 GNUNET_GNSRECORD_record_get_expiration_time (2,
86 rd).abs_value_us);
87 res = 0;
88}
89
90
91int
92main (int argc, char *argv[])
93{
94 static char *const argvx[] = { "test-gnsrecord-crypto",
95 NULL };
96 static struct GNUNET_GETOPT_CommandLineOption options[] = {
97 GNUNET_GETOPT_OPTION_END
98 };
99
100 res = 1;
101 GNUNET_PROGRAM_run ((sizeof(argvx) / sizeof(char *)) - 1, argvx,
102 "test-namestore-api",
103 "nohelp", options, &run, &res);
104 return res;
105}
106
107
108/* 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 9e5a1aa7e..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_absolute_get ();
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 (NULL != (block =
127 GNUNET_GNSRECORD_block_create (privkey,
128 expire,
129 s_name,
130 s_rd,
131 RECORDS)));
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 s_name));
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 */