diff options
author | t3sserakt <t3ss@posteo.de> | 2020-10-16 17:31:21 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2020-10-16 17:40:12 +0200 |
commit | cde9403a6cc6bc03e571c872cdee205bbd838c31 (patch) | |
tree | 431929de91b2da817816370f9caf98b646d2745e /src/gnsrecord | |
parent | 4b69b0866d7f29efeb92176e518ddbb6a9052033 (diff) | |
parent | e8b0bc481b8a30c325faf55a964cac2cd151f999 (diff) | |
download | gnunet-cde9403a6cc6bc03e571c872cdee205bbd838c31.tar.gz gnunet-cde9403a6cc6bc03e571c872cdee205bbd838c31.zip |
Merge branch 'master' of ssh://gnunet.org/gnunet
Diffstat (limited to 'src/gnsrecord')
-rw-r--r-- | src/gnsrecord/Makefile.am | 19 | ||||
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 315 | ||||
-rw-r--r-- | src/gnsrecord/gnsrecord_misc.c | 95 | ||||
-rw-r--r-- | src/gnsrecord/gnunet-gnsrecord-tvg.c | 35 | ||||
-rw-r--r-- | src/gnsrecord/json_gnsrecord.c | 391 | ||||
-rw-r--r-- | src/gnsrecord/perf_gnsrecord_crypto.c | 5 | ||||
-rw-r--r-- | src/gnsrecord/plugin_gnsrecord_dns.c | 2 | ||||
-rw-r--r-- | src/gnsrecord/test_gnsrecord_crypto.c | 11 |
8 files changed, 744 insertions, 129 deletions
diff --git a/src/gnsrecord/Makefile.am b/src/gnsrecord/Makefile.am index 2e6eca7ba..84d218519 100644 --- a/src/gnsrecord/Makefile.am +++ b/src/gnsrecord/Makefile.am | |||
@@ -30,12 +30,14 @@ TESTS = \ | |||
30 | endif | 30 | endif |
31 | 31 | ||
32 | lib_LTLIBRARIES = \ | 32 | lib_LTLIBRARIES = \ |
33 | libgnunetgnsrecord.la | 33 | libgnunetgnsrecord.la \ |
34 | libgnunetgnsrecordjson.la | ||
34 | 35 | ||
35 | gnunet_gnsrecord_tvg_SOURCES = \ | 36 | gnunet_gnsrecord_tvg_SOURCES = \ |
36 | gnunet-gnsrecord-tvg.c | 37 | gnunet-gnsrecord-tvg.c |
37 | gnunet_gnsrecord_tvg_LDADD = \ | 38 | gnunet_gnsrecord_tvg_LDADD = \ |
38 | $(top_builddir)/src/util/libgnunetutil.la \ | 39 | $(top_builddir)/src/util/libgnunetutil.la \ |
40 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
39 | libgnunetgnsrecord.la \ | 41 | libgnunetgnsrecord.la \ |
40 | $(GN_LIBINTL) | 42 | $(GN_LIBINTL) |
41 | 43 | ||
@@ -47,11 +49,26 @@ libgnunetgnsrecord_la_SOURCES = \ | |||
47 | gnsrecord_misc.c | 49 | gnsrecord_misc.c |
48 | libgnunetgnsrecord_la_LIBADD = \ | 50 | libgnunetgnsrecord_la_LIBADD = \ |
49 | $(top_builddir)/src/util/libgnunetutil.la \ | 51 | $(top_builddir)/src/util/libgnunetutil.la \ |
52 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
53 | $(LIBGCRYPT_LIBS) \ | ||
50 | $(GN_LIBINTL) | 54 | $(GN_LIBINTL) |
55 | libgnunetgnsrecord_la_DEPENDENCIES = \ | ||
56 | $(top_builddir)/src/identity/libgnunetidentity.la | ||
51 | libgnunetgnsrecord_la_LDFLAGS = \ | 57 | libgnunetgnsrecord_la_LDFLAGS = \ |
52 | $(GN_LIB_LDFLAGS) \ | 58 | $(GN_LIB_LDFLAGS) \ |
53 | -version-info 0:0:0 | 59 | -version-info 0:0:0 |
54 | 60 | ||
61 | libgnunetgnsrecordjson_la_SOURCES = \ | ||
62 | json_gnsrecord.c | ||
63 | libgnunetgnsrecordjson_la_LIBADD = \ | ||
64 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
65 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
66 | libgnunetgnsrecord.la \ | ||
67 | -ljansson \ | ||
68 | $(GN_LIBINTL) | ||
69 | libgnunetgnsrecordjson_la_LDFLAGS = \ | ||
70 | $(GN_LIB_LDFLAGS) \ | ||
71 | -version-info 0:0:0 | ||
55 | 72 | ||
56 | plugin_LTLIBRARIES = \ | 73 | plugin_LTLIBRARIES = \ |
57 | libgnunet_plugin_gnsrecord_dns.la | 74 | libgnunet_plugin_gnsrecord_dns.la |
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index c8919760a..9c551a936 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -37,6 +37,61 @@ | |||
37 | 37 | ||
38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) | 38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) |
39 | 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 | |||
68 | ssize_t | ||
69 | ecdsa_symmetric_encrypt ( | ||
70 | const void *block, | ||
71 | size_t size, | ||
72 | const unsigned char *key, | ||
73 | const unsigned char *ctr, | ||
74 | void *result) | ||
75 | { | ||
76 | gcry_cipher_hd_t handle; | ||
77 | int rc; | ||
78 | |||
79 | GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, | ||
80 | GCRY_CIPHER_MODE_CTR, 0)); | ||
81 | rc = gcry_cipher_setkey (handle, | ||
82 | key, | ||
83 | GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
84 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
85 | rc = gcry_cipher_setctr (handle, | ||
86 | ctr, | ||
87 | GNUNET_CRYPTO_AES_KEY_LENGTH / 2); | ||
88 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
89 | GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size)); | ||
90 | gcry_cipher_close (handle); | ||
91 | return size; | ||
92 | } | ||
93 | |||
94 | |||
40 | 95 | ||
41 | /** | 96 | /** |
42 | * Derive session key and iv from label and public key. | 97 | * Derive session key and iv from label and public key. |
@@ -47,25 +102,31 @@ | |||
47 | * @param pub public key to use for KDF | 102 | * @param pub public key to use for KDF |
48 | */ | 103 | */ |
49 | static void | 104 | static void |
50 | derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 105 | derive_block_aes_key (unsigned char *ctr, |
51 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | 106 | unsigned char *key, |
52 | const char *label, | 107 | const char *label, |
108 | uint64_t exp, | ||
53 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 109 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) |
54 | { | 110 | { |
55 | static const char ctx_key[] = "gns-aes-ctx-key"; | 111 | static const char ctx_key[] = "gns-aes-ctx-key"; |
56 | static const char ctx_iv[] = "gns-aes-ctx-iv"; | 112 | static const char ctx_iv[] = "gns-aes-ctx-iv"; |
57 | 113 | ||
58 | GNUNET_CRYPTO_kdf (skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | 114 | GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH, |
59 | ctx_key, strlen (ctx_key), | 115 | ctx_key, strlen (ctx_key), |
60 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 116 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
61 | label, strlen (label), | 117 | label, strlen (label), |
62 | NULL, 0); | 118 | NULL, 0); |
63 | GNUNET_CRYPTO_kdf (iv, sizeof(struct | 119 | memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2); |
64 | GNUNET_CRYPTO_SymmetricInitializationVector), | 120 | /** 4 byte nonce **/ |
121 | GNUNET_CRYPTO_kdf (ctr, 4, | ||
65 | ctx_iv, strlen (ctx_iv), | 122 | ctx_iv, strlen (ctx_iv), |
66 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 123 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
67 | label, strlen (label), | 124 | label, strlen (label), |
68 | NULL, 0); | 125 | NULL, 0); |
126 | /** Expiration time 64 bit. **/ | ||
127 | memcpy (ctr + 4, &exp, sizeof (exp)); | ||
128 | /** Set counter part to 1 **/ | ||
129 | ctr[15] |= 0x01; | ||
69 | } | 130 | } |
70 | 131 | ||
71 | 132 | ||
@@ -81,19 +142,20 @@ derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
81 | * @return NULL on error (block too large) | 142 | * @return NULL on error (block too large) |
82 | */ | 143 | */ |
83 | static struct GNUNET_GNSRECORD_Block * | 144 | static struct GNUNET_GNSRECORD_Block * |
84 | block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 145 | block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, |
85 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | 146 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, |
86 | struct GNUNET_TIME_Absolute expire, | 147 | struct GNUNET_TIME_Absolute expire, |
87 | const char *label, | 148 | const char *label, |
88 | const struct GNUNET_GNSRECORD_Data *rd, | 149 | const struct GNUNET_GNSRECORD_Data *rd, |
89 | unsigned int rd_count) | 150 | unsigned int rd_count) |
90 | { | 151 | { |
91 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, | 152 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, |
92 | rd); | 153 | rd); |
93 | struct GNUNET_GNSRECORD_Block *block; | 154 | struct GNUNET_GNSRECORD_Block *block; |
155 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | ||
94 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; | 156 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; |
95 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 157 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
96 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 158 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
97 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 159 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
98 | uint32_t rd_count_nbo; | 160 | uint32_t rd_count_nbo; |
99 | struct GNUNET_TIME_Absolute now; | 161 | struct GNUNET_TIME_Absolute now; |
@@ -140,35 +202,38 @@ block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
140 | block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) | 202 | block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) |
141 | + sizeof(uint32_t) | 203 | + sizeof(uint32_t) |
142 | + payload_len); | 204 | + payload_len); |
143 | block->purpose.size = htonl (sizeof(uint32_t) | 205 | ecblock = &block->ecdsa_block; |
144 | + payload_len | 206 | block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
145 | + sizeof(struct | 207 | ecblock->purpose.size = htonl (sizeof(uint32_t) |
146 | GNUNET_CRYPTO_EccSignaturePurpose) | 208 | + payload_len |
147 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)); | 209 | + sizeof(struct |
148 | block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | 210 | GNUNET_CRYPTO_EccSignaturePurpose) |
149 | block->expiration_time = GNUNET_TIME_absolute_hton (expire); | 211 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)); |
212 | ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
213 | ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire); | ||
150 | /* encrypt and sign */ | 214 | /* encrypt and sign */ |
151 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, | 215 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, |
152 | label, | 216 | label, |
153 | "gns"); | 217 | "gns"); |
154 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, | 218 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, |
155 | &block->derived_key); | 219 | &ecblock->derived_key); |
156 | derive_block_aes_key (&iv, | 220 | derive_block_aes_key (ctr, |
157 | &skey, | 221 | skey, |
158 | label, | 222 | label, |
223 | ecblock->expiration_time.abs_value_us__, | ||
159 | pkey); | 224 | pkey); |
160 | GNUNET_break (payload_len + sizeof(uint32_t) == | 225 | GNUNET_break (payload_len + sizeof(uint32_t) == |
161 | GNUNET_CRYPTO_symmetric_encrypt (payload, | 226 | ecdsa_symmetric_encrypt (payload, |
162 | payload_len | 227 | payload_len |
163 | + sizeof(uint32_t), | 228 | + sizeof(uint32_t), |
164 | &skey, | 229 | skey, |
165 | &iv, | 230 | ctr, |
166 | &block[1])); | 231 | &ecblock[1])); |
167 | } | 232 | } |
168 | if (GNUNET_OK != | 233 | if (GNUNET_OK != |
169 | GNUNET_CRYPTO_ecdsa_sign_ (dkey, | 234 | GNUNET_CRYPTO_ecdsa_sign_ (dkey, |
170 | &block->purpose, | 235 | &ecblock->purpose, |
171 | &block->signature)) | 236 | &ecblock->signature)) |
172 | { | 237 | { |
173 | GNUNET_break (0); | 238 | GNUNET_break (0); |
174 | GNUNET_free (dkey); | 239 | GNUNET_free (dkey); |
@@ -191,7 +256,7 @@ block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
191 | * @return NULL on error (block too large) | 256 | * @return NULL on error (block too large) |
192 | */ | 257 | */ |
193 | struct GNUNET_GNSRECORD_Block * | 258 | struct GNUNET_GNSRECORD_Block * |
194 | GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 259 | GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, |
195 | struct GNUNET_TIME_Absolute expire, | 260 | struct GNUNET_TIME_Absolute expire, |
196 | const char *label, | 261 | const char *label, |
197 | const struct GNUNET_GNSRECORD_Data *rd, | 262 | const struct GNUNET_GNSRECORD_Data *rd, |
@@ -199,14 +264,21 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
199 | { | 264 | { |
200 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | 265 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; |
201 | 266 | ||
202 | GNUNET_CRYPTO_ecdsa_key_get_public (key, | 267 | switch (ntohl (key->type)) |
203 | &pkey); | 268 | { |
204 | return block_create (key, | 269 | case GNUNET_GNSRECORD_TYPE_PKEY: |
205 | &pkey, | 270 | GNUNET_CRYPTO_ecdsa_key_get_public (&key->ecdsa_key, |
206 | expire, | 271 | &pkey); |
207 | label, | 272 | return block_create_ecdsa (&key->ecdsa_key, |
208 | rd, | 273 | &pkey, |
209 | rd_count); | 274 | expire, |
275 | label, | ||
276 | rd, | ||
277 | rd_count); | ||
278 | default: | ||
279 | GNUNET_assert (0); | ||
280 | } | ||
281 | return NULL; | ||
210 | } | 282 | } |
211 | 283 | ||
212 | 284 | ||
@@ -240,12 +312,19 @@ struct KeyCacheLine | |||
240 | * @return NULL on error (block too large) | 312 | * @return NULL on error (block too large) |
241 | */ | 313 | */ |
242 | struct GNUNET_GNSRECORD_Block * | 314 | struct GNUNET_GNSRECORD_Block * |
243 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 315 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, |
244 | struct GNUNET_TIME_Absolute expire, | 316 | struct GNUNET_TIME_Absolute expire, |
245 | const char *label, | 317 | const char *label, |
246 | const struct GNUNET_GNSRECORD_Data *rd, | 318 | const struct GNUNET_GNSRECORD_Data *rd, |
247 | unsigned int rd_count) | 319 | unsigned int rd_count) |
248 | { | 320 | { |
321 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; | ||
322 | |||
323 | if (GNUNET_IDENTITY_TYPE_ECDSA != ntohl (pkey->type)) | ||
324 | { | ||
325 | return NULL; // FIXME | ||
326 | } | ||
327 | key = &pkey->ecdsa_key; | ||
249 | #define CSIZE 64 | 328 | #define CSIZE 64 |
250 | static struct KeyCacheLine cache[CSIZE]; | 329 | static struct KeyCacheLine cache[CSIZE]; |
251 | struct KeyCacheLine *line; | 330 | struct KeyCacheLine *line; |
@@ -261,12 +340,12 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
261 | &line->pkey); | 340 | &line->pkey); |
262 | } | 341 | } |
263 | #undef CSIZE | 342 | #undef CSIZE |
264 | return block_create (key, | 343 | return block_create_ecdsa (key, |
265 | &line->pkey, | 344 | &line->pkey, |
266 | expire, | 345 | expire, |
267 | label, | 346 | label, |
268 | rd, | 347 | rd, |
269 | rd_count); | 348 | rd_count); |
270 | } | 349 | } |
271 | 350 | ||
272 | 351 | ||
@@ -277,40 +356,40 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
277 | * @param block block to verify | 356 | * @param block block to verify |
278 | * @return #GNUNET_OK if the signature is valid | 357 | * @return #GNUNET_OK if the signature is valid |
279 | */ | 358 | */ |
280 | int | 359 | enum GNUNET_GenericReturnValue |
281 | GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) | 360 | GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) |
282 | { | 361 | { |
362 | const struct GNUNET_CRYPTO_EcdsaPublicKey *key; | ||
363 | const struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | ||
364 | |||
365 | if (GNUNET_GNSRECORD_TYPE_PKEY != ntohl (block->type)) | ||
366 | { | ||
367 | GNUNET_break (0); | ||
368 | return GNUNET_NO; | ||
369 | } | ||
370 | ecblock = &block->ecdsa_block; | ||
371 | key = &ecblock->derived_key; | ||
372 | |||
283 | return GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, | 373 | return GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, |
284 | &block->purpose, | 374 | &ecblock->purpose, |
285 | &block->signature, | 375 | &ecblock->signature, |
286 | &block->derived_key); | 376 | key); |
287 | } | 377 | } |
288 | 378 | ||
289 | 379 | ||
290 | /** | 380 | enum GNUNET_GenericReturnValue |
291 | * Decrypt block. | 381 | block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, |
292 | * | 382 | const struct |
293 | * @param block block to decrypt | 383 | GNUNET_CRYPTO_EcdsaPublicKey *zone_key, |
294 | * @param zone_key public key of the zone | 384 | const char *label, |
295 | * @param label the name for the records | 385 | GNUNET_GNSRECORD_RecordCallback proc, |
296 | * @param proc function to call with the result | 386 | void *proc_cls) |
297 | * @param proc_cls closure for proc | ||
298 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was | ||
299 | * not well-formed | ||
300 | */ | ||
301 | int | ||
302 | GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | ||
303 | const struct | ||
304 | GNUNET_CRYPTO_EcdsaPublicKey *zone_key, | ||
305 | const char *label, | ||
306 | GNUNET_GNSRECORD_RecordCallback proc, | ||
307 | void *proc_cls) | ||
308 | { | 387 | { |
309 | size_t payload_len = ntohl (block->purpose.size) | 388 | size_t payload_len = ntohl (block->purpose.size) |
310 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 389 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
311 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); | 390 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); |
312 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 391 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
313 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 392 | unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
314 | 393 | ||
315 | if (ntohl (block->purpose.size) < | 394 | if (ntohl (block->purpose.size) < |
316 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 395 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
@@ -319,18 +398,19 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
319 | GNUNET_break_op (0); | 398 | GNUNET_break_op (0); |
320 | return GNUNET_SYSERR; | 399 | return GNUNET_SYSERR; |
321 | } | 400 | } |
322 | derive_block_aes_key (&iv, | 401 | derive_block_aes_key (ctr, |
323 | &skey, | 402 | key, |
324 | label, | 403 | label, |
404 | block->expiration_time.abs_value_us__, | ||
325 | zone_key); | 405 | zone_key); |
326 | { | 406 | { |
327 | char payload[payload_len]; | 407 | char payload[payload_len]; |
328 | uint32_t rd_count; | 408 | uint32_t rd_count; |
329 | 409 | ||
330 | GNUNET_break (payload_len == | 410 | GNUNET_break (payload_len == |
331 | GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, | 411 | ecdsa_symmetric_decrypt (&block[1], payload_len, |
332 | &skey, &iv, | 412 | key, ctr, |
333 | payload)); | 413 | payload)); |
334 | GNUNET_memcpy (&rd_count, | 414 | GNUNET_memcpy (&rd_count, |
335 | payload, | 415 | payload, |
336 | sizeof(uint32_t)); | 416 | sizeof(uint32_t)); |
@@ -426,6 +506,39 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
426 | 506 | ||
427 | 507 | ||
428 | /** | 508 | /** |
509 | * Decrypt block. | ||
510 | * | ||
511 | * @param block block to decrypt | ||
512 | * @param zone_key public key of the zone | ||
513 | * @param label the name for the records | ||
514 | * @param proc function to call with the result | ||
515 | * @param proc_cls closure for proc | ||
516 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was | ||
517 | * not well-formed | ||
518 | */ | ||
519 | enum GNUNET_GenericReturnValue | ||
520 | GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | ||
521 | const struct | ||
522 | GNUNET_IDENTITY_PublicKey *zone_key, | ||
523 | const char *label, | ||
524 | GNUNET_GNSRECORD_RecordCallback proc, | ||
525 | void *proc_cls) | ||
526 | { | ||
527 | const struct GNUNET_CRYPTO_EcdsaPublicKey *key; | ||
528 | |||
529 | if (GNUNET_IDENTITY_TYPE_ECDSA != ntohl (zone_key->type)) | ||
530 | { | ||
531 | return GNUNET_NO; | ||
532 | } | ||
533 | key = &zone_key->ecdsa_key; | ||
534 | |||
535 | return block_decrypt_ecdsa (&block->ecdsa_block, | ||
536 | key, label, proc, proc_cls); | ||
537 | |||
538 | } | ||
539 | |||
540 | |||
541 | /** | ||
429 | * Calculate the DHT query for a given @a label in a given @a zone. | 542 | * Calculate the DHT query for a given @a label in a given @a zone. |
430 | * | 543 | * |
431 | * @param zone private key of the zone | 544 | * @param zone private key of the zone |
@@ -434,17 +547,24 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
434 | */ | 547 | */ |
435 | void | 548 | void |
436 | GNUNET_GNSRECORD_query_from_private_key (const struct | 549 | GNUNET_GNSRECORD_query_from_private_key (const struct |
437 | GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 550 | GNUNET_IDENTITY_PrivateKey *zone, |
438 | const char *label, | 551 | const char *label, |
439 | struct GNUNET_HashCode *query) | 552 | struct GNUNET_HashCode *query) |
440 | { | 553 | { |
441 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | 554 | struct GNUNET_IDENTITY_PublicKey pub; |
442 | 555 | switch (ntohl (zone->type)) | |
443 | GNUNET_CRYPTO_ecdsa_key_get_public (zone, | 556 | { |
444 | &pub); | 557 | case GNUNET_GNSRECORD_TYPE_PKEY: |
445 | GNUNET_GNSRECORD_query_from_public_key (&pub, | 558 | |
446 | label, | 559 | GNUNET_IDENTITY_key_get_public (zone, |
447 | query); | 560 | &pub); |
561 | GNUNET_GNSRECORD_query_from_public_key (&pub, | ||
562 | label, | ||
563 | query); | ||
564 | break; | ||
565 | default: | ||
566 | GNUNET_assert (0); | ||
567 | } | ||
448 | } | 568 | } |
449 | 569 | ||
450 | 570 | ||
@@ -457,18 +577,27 @@ GNUNET_GNSRECORD_query_from_private_key (const struct | |||
457 | */ | 577 | */ |
458 | void | 578 | void |
459 | GNUNET_GNSRECORD_query_from_public_key (const struct | 579 | GNUNET_GNSRECORD_query_from_public_key (const struct |
460 | GNUNET_CRYPTO_EcdsaPublicKey *pub, | 580 | GNUNET_IDENTITY_PublicKey *pub, |
461 | const char *label, | 581 | const char *label, |
462 | struct GNUNET_HashCode *query) | 582 | struct GNUNET_HashCode *query) |
463 | { | 583 | { |
464 | struct GNUNET_CRYPTO_EcdsaPublicKey pd; | 584 | struct GNUNET_IDENTITY_PublicKey pd; |
465 | GNUNET_CRYPTO_ecdsa_public_key_derive (pub, | 585 | |
466 | label, | 586 | switch (ntohl (pub->type)) |
467 | "gns", | 587 | { |
468 | &pd); | 588 | case GNUNET_GNSRECORD_TYPE_PKEY: |
469 | GNUNET_CRYPTO_hash (&pd, | 589 | pd.type = pub->type; |
470 | sizeof(pd), | 590 | GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key, |
471 | query); | 591 | label, |
592 | "gns", | ||
593 | &pd.ecdsa_key); | ||
594 | GNUNET_CRYPTO_hash (&pd.ecdsa_key, | ||
595 | sizeof (pd.ecdsa_key), | ||
596 | query); | ||
597 | break; | ||
598 | default: | ||
599 | GNUNET_assert (0); | ||
600 | } | ||
472 | } | 601 | } |
473 | 602 | ||
474 | 603 | ||
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c index 5061f8493..4b1695d69 100644 --- a/src/gnsrecord/gnsrecord_misc.c +++ b/src/gnsrecord/gnsrecord_misc.c | |||
@@ -62,14 +62,14 @@ GNUNET_GNSRECORD_string_to_lowercase (const char *src) | |||
62 | * @return string form; will be overwritten by next call to #GNUNET_GNSRECORD_z2s | 62 | * @return string form; will be overwritten by next call to #GNUNET_GNSRECORD_z2s |
63 | */ | 63 | */ |
64 | const char * | 64 | const char * |
65 | GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z) | 65 | GNUNET_GNSRECORD_z2s (const struct GNUNET_IDENTITY_PublicKey *z) |
66 | { | 66 | { |
67 | static char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) * 8]; | 67 | static char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) * 8]; |
68 | char *end; | 68 | char *end; |
69 | 69 | ||
70 | end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z, | 70 | end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z, |
71 | sizeof(struct | 71 | sizeof(struct |
72 | GNUNET_CRYPTO_EcdsaPublicKey), | 72 | GNUNET_IDENTITY_PublicKey), |
73 | buf, sizeof(buf)); | 73 | buf, sizeof(buf)); |
74 | if (NULL == end) | 74 | if (NULL == end) |
75 | { | 75 | { |
@@ -99,7 +99,7 @@ GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, | |||
99 | if (a->record_type != b->record_type) | 99 | if (a->record_type != b->record_type) |
100 | { | 100 | { |
101 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 101 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
102 | "Record type %lu != %lu\n", a->record_type, b->record_type); | 102 | "Record type %u != %u\n", a->record_type, b->record_type); |
103 | return GNUNET_NO; | 103 | return GNUNET_NO; |
104 | } | 104 | } |
105 | if ((a->expiration_time != b->expiration_time) && | 105 | if ((a->expiration_time != b->expiration_time) && |
@@ -115,7 +115,7 @@ GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, | |||
115 | != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)) | 115 | != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)) |
116 | { | 116 | { |
117 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 117 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
118 | "Flags %lu (%lu) != %lu (%lu)\n", a->flags, | 118 | "Flags %u (%u) != %u (%u)\n", a->flags, |
119 | a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags, | 119 | a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags, |
120 | b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS); | 120 | b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS); |
121 | return GNUNET_NO; | 121 | return GNUNET_NO; |
@@ -236,12 +236,12 @@ GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd) | |||
236 | * key in an encoding suitable for DNS labels. | 236 | * key in an encoding suitable for DNS labels. |
237 | */ | 237 | */ |
238 | const char * | 238 | const char * |
239 | GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) | 239 | GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_IDENTITY_PublicKey *pkey) |
240 | { | 240 | { |
241 | static char ret[128]; | 241 | static char ret[128]; |
242 | char *pkeys; | 242 | char *pkeys; |
243 | 243 | ||
244 | pkeys = GNUNET_CRYPTO_ecdsa_public_key_to_string (pkey); | 244 | pkeys = GNUNET_IDENTITY_public_key_to_string (pkey); |
245 | GNUNET_snprintf (ret, | 245 | GNUNET_snprintf (ret, |
246 | sizeof(ret), | 246 | sizeof(ret), |
247 | "%s", | 247 | "%s", |
@@ -262,15 +262,88 @@ GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) | |||
262 | */ | 262 | */ |
263 | int | 263 | int |
264 | GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, | 264 | GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, |
265 | struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) | 265 | struct GNUNET_IDENTITY_PublicKey *pkey) |
266 | { | 266 | { |
267 | if (GNUNET_OK != | 267 | if (GNUNET_OK != |
268 | GNUNET_CRYPTO_ecdsa_public_key_from_string (zkey, | 268 | GNUNET_IDENTITY_public_key_from_string (zkey, |
269 | strlen (zkey), | 269 | pkey)) |
270 | pkey)) | ||
271 | return GNUNET_SYSERR; | 270 | return GNUNET_SYSERR; |
272 | return GNUNET_OK; | 271 | return GNUNET_OK; |
273 | } | 272 | } |
274 | 273 | ||
275 | 274 | ||
275 | size_t | ||
276 | GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block) | ||
277 | { | ||
278 | switch (ntohl (block->type)) | ||
279 | { | ||
280 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
281 | return sizeof (uint32_t) /* zone type */ | ||
282 | + sizeof (block->ecdsa_block) /* EcdsaBlock */ | ||
283 | + ntohl (block->ecdsa_block.purpose.size) /* Length of signed data */ | ||
284 | - sizeof (block->ecdsa_block.purpose); /* Purpose already in EcdsaBlock */ | ||
285 | break; | ||
286 | default: | ||
287 | return 0; | ||
288 | } | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | |||
293 | struct GNUNET_TIME_Absolute | ||
294 | GNUNET_GNSRECORD_block_get_expiration (const struct | ||
295 | GNUNET_GNSRECORD_Block *block) | ||
296 | { | ||
297 | |||
298 | switch (ntohl (block->type)) | ||
299 | { | ||
300 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
301 | return GNUNET_TIME_absolute_ntoh (block->ecdsa_block.expiration_time); | ||
302 | default: | ||
303 | return GNUNET_TIME_absolute_get_zero_ (); | ||
304 | } | ||
305 | return GNUNET_TIME_absolute_get_zero_ (); | ||
306 | |||
307 | } | ||
308 | |||
309 | |||
310 | enum GNUNET_GenericReturnValue | ||
311 | GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block, | ||
312 | struct GNUNET_HashCode *query) | ||
313 | { | ||
314 | switch (ntohl (block->type)) | ||
315 | { | ||
316 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
317 | GNUNET_CRYPTO_hash (&block->ecdsa_block.derived_key, | ||
318 | sizeof (block->ecdsa_block.derived_key), | ||
319 | query); | ||
320 | return GNUNET_OK; | ||
321 | default: | ||
322 | return GNUNET_SYSERR; | ||
323 | } | ||
324 | return GNUNET_SYSERR; | ||
325 | |||
326 | } | ||
327 | |||
328 | enum GNUNET_GenericReturnValue | ||
329 | GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd, | ||
330 | struct GNUNET_IDENTITY_PublicKey *key) | ||
331 | { | ||
332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
333 | "Got record of type %u\n", | ||
334 | rd->record_type); | ||
335 | switch (rd->record_type) | ||
336 | { | ||
337 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
338 | key->type = htonl (rd->record_type); | ||
339 | memcpy (&key->ecdsa_key, rd->data, sizeof (key->ecdsa_key)); | ||
340 | return GNUNET_OK; | ||
341 | default: | ||
342 | return GNUNET_SYSERR; | ||
343 | } | ||
344 | return GNUNET_SYSERR; | ||
345 | |||
346 | |||
347 | } | ||
348 | |||
276 | /* end of gnsrecord_misc.c */ | 349 | /* end of gnsrecord_misc.c */ |
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c index 789ff8aa3..6e6f6414c 100644 --- a/src/gnsrecord/gnunet-gnsrecord-tvg.c +++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c | |||
@@ -90,28 +90,30 @@ run (void *cls, | |||
90 | struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get (); | 90 | struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get (); |
91 | struct GNUNET_GNSRECORD_Block *rrblock; | 91 | struct GNUNET_GNSRECORD_Block *rrblock; |
92 | char *bdata; | 92 | char *bdata; |
93 | struct GNUNET_CRYPTO_EcdsaPrivateKey id_priv; | 93 | struct GNUNET_IDENTITY_PrivateKey id_priv; |
94 | struct GNUNET_CRYPTO_EcdsaPublicKey id_pub; | 94 | struct GNUNET_IDENTITY_PublicKey id_pub; |
95 | struct GNUNET_CRYPTO_EcdsaPrivateKey pkey_data_p; | 95 | struct GNUNET_IDENTITY_PrivateKey pkey_data_p; |
96 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey_data; | 96 | struct GNUNET_IDENTITY_PublicKey pkey_data; |
97 | void *data; | 97 | void *data; |
98 | size_t data_size; | 98 | size_t data_size; |
99 | char *rdata; | 99 | char *rdata; |
100 | size_t rdata_size; | 100 | size_t rdata_size; |
101 | 101 | ||
102 | GNUNET_CRYPTO_ecdsa_key_create (&id_priv); | 102 | id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
103 | GNUNET_CRYPTO_ecdsa_key_get_public (&id_priv, | 103 | GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); |
104 | &id_pub); | 104 | GNUNET_IDENTITY_key_get_public (&id_priv, |
105 | &id_pub); | ||
105 | fprintf (stdout, "Zone private key (d, little-endian scalar):\n"); | 106 | fprintf (stdout, "Zone private key (d, little-endian scalar):\n"); |
106 | print_bytes (&id_priv, sizeof(id_priv), 0); | 107 | print_bytes (&id_priv, GNUNET_IDENTITY_key_get_length (&id_pub), 0); //FIXME length for privkey? |
107 | fprintf (stdout, "\n"); | 108 | fprintf (stdout, "\n"); |
108 | fprintf (stdout, "Zone public key (zk):\n"); | 109 | fprintf (stdout, "Zone public key (zk):\n"); |
109 | print_bytes (&id_pub, sizeof(id_pub), 0); | 110 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 0); |
110 | fprintf (stdout, "\n"); | 111 | fprintf (stdout, "\n"); |
111 | 112 | ||
112 | GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p); | 113 | pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
113 | GNUNET_CRYPTO_ecdsa_key_get_public (&pkey_data_p, | 114 | GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key); |
114 | &pkey_data); | 115 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, |
116 | &pkey_data); | ||
115 | fprintf (stdout, | 117 | fprintf (stdout, |
116 | "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT); | 118 | "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT); |
117 | memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2); | 119 | memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2); |
@@ -147,19 +149,20 @@ run (void *cls, | |||
147 | TEST_RECORD_LABEL, | 149 | TEST_RECORD_LABEL, |
148 | rd, | 150 | rd, |
149 | TEST_RRCOUNT); | 151 | TEST_RRCOUNT); |
150 | size_t bdata_size = ntohl (rrblock->purpose.size) | 152 | size_t bdata_size = ntohl (rrblock->ecdsa_block.purpose.size) |
151 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | 153 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
152 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); | 154 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); |
153 | size_t rrblock_size = ntohl (rrblock->purpose.size) | 155 | size_t ecblock_size = ntohl (rrblock->ecdsa_block.purpose.size) |
154 | + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) | 156 | + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) |
155 | + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); | 157 | + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); |
158 | size_t block_size = ecblock_size + sizeof (uint32_t); | ||
156 | 159 | ||
157 | bdata = (char*) &rrblock[1]; | 160 | bdata = (char*) &(&rrblock->ecdsa_block)[1]; |
158 | fprintf (stdout, "BDATA:\n"); | 161 | fprintf (stdout, "BDATA:\n"); |
159 | print_bytes (bdata, bdata_size, 8); | 162 | print_bytes (bdata, bdata_size, 8); |
160 | fprintf (stdout, "\n"); | 163 | fprintf (stdout, "\n"); |
161 | fprintf (stdout, "RRBLOCK:\n"); | 164 | fprintf (stdout, "RRBLOCK:\n"); |
162 | print_bytes (rrblock, rrblock_size, 8); | 165 | print_bytes (rrblock, block_size, 8); |
163 | fprintf (stdout, "\n"); | 166 | fprintf (stdout, "\n"); |
164 | 167 | ||
165 | } | 168 | } |
diff --git a/src/gnsrecord/json_gnsrecord.c b/src/gnsrecord/json_gnsrecord.c new file mode 100644 index 000000000..068ff48c1 --- /dev/null +++ b/src/gnsrecord/json_gnsrecord.c | |||
@@ -0,0 +1,391 @@ | |||
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 index eb4633f75..d9a3c20cf 100644 --- a/src/gnsrecord/perf_gnsrecord_crypto.c +++ b/src/gnsrecord/perf_gnsrecord_crypto.c | |||
@@ -73,7 +73,7 @@ run (void *cls, | |||
73 | struct GNUNET_GNSRECORD_Data *s_rd; | 73 | struct GNUNET_GNSRECORD_Data *s_rd; |
74 | const char *s_name; | 74 | const char *s_name; |
75 | struct GNUNET_TIME_Absolute start_time; | 75 | struct GNUNET_TIME_Absolute start_time; |
76 | struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; | 76 | struct GNUNET_IDENTITY_PrivateKey privkey; |
77 | struct GNUNET_TIME_Absolute expire; | 77 | struct GNUNET_TIME_Absolute expire; |
78 | 78 | ||
79 | (void) cls; | 79 | (void) cls; |
@@ -81,7 +81,8 @@ run (void *cls, | |||
81 | (void) cfgfile; | 81 | (void) cfgfile; |
82 | (void) cfg; | 82 | (void) cfg; |
83 | expire = GNUNET_TIME_absolute_get (); | 83 | expire = GNUNET_TIME_absolute_get (); |
84 | GNUNET_CRYPTO_ecdsa_key_create (&privkey); | 84 | privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
85 | GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); | ||
85 | 86 | ||
86 | /* test block creation */ | 87 | /* test block creation */ |
87 | s_name = "DUMMY.dummy.gnunet"; | 88 | s_name = "DUMMY.dummy.gnunet"; |
diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c index 9ac6fb9e6..bde9944e2 100644 --- a/src/gnsrecord/plugin_gnsrecord_dns.c +++ b/src/gnsrecord/plugin_gnsrecord_dns.c | |||
@@ -100,7 +100,7 @@ dns_value_to_string (void *cls, | |||
100 | return NULL; | 100 | return NULL; |
101 | } | 101 | } |
102 | GNUNET_asprintf (&result, | 102 | GNUNET_asprintf (&result, |
103 | "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", | 103 | "rname=%s mname=%s %u,%u,%u,%u,%u", |
104 | soa->rname, | 104 | soa->rname, |
105 | soa->mname, | 105 | soa->mname, |
106 | soa->serial, | 106 | soa->serial, |
diff --git a/src/gnsrecord/test_gnsrecord_crypto.c b/src/gnsrecord/test_gnsrecord_crypto.c index b67e9a123..d541f3076 100644 --- a/src/gnsrecord/test_gnsrecord_crypto.c +++ b/src/gnsrecord/test_gnsrecord_crypto.c | |||
@@ -100,17 +100,18 @@ run (void *cls, | |||
100 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 100 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
101 | { | 101 | { |
102 | struct GNUNET_GNSRECORD_Block *block; | 102 | struct GNUNET_GNSRECORD_Block *block; |
103 | struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; | 103 | struct GNUNET_IDENTITY_PublicKey pubkey; |
104 | struct GNUNET_HashCode query_pub; | 104 | struct GNUNET_HashCode query_pub; |
105 | struct GNUNET_HashCode query_priv; | 105 | struct GNUNET_HashCode query_priv; |
106 | struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get (); | 106 | struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get (); |
107 | struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; | 107 | struct GNUNET_IDENTITY_PrivateKey privkey; |
108 | 108 | ||
109 | 109 | ||
110 | GNUNET_CRYPTO_ecdsa_key_create (&privkey); | 110 | privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
111 | GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); | ||
111 | /* get public key */ | 112 | /* get public key */ |
112 | GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, | 113 | GNUNET_IDENTITY_key_get_public (&privkey, |
113 | &pubkey); | 114 | &pubkey); |
114 | 115 | ||
115 | /* test query derivation */ | 116 | /* test query derivation */ |
116 | GNUNET_GNSRECORD_query_from_private_key (&privkey, | 117 | GNUNET_GNSRECORD_query_from_private_key (&privkey, |