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