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