diff options
Diffstat (limited to 'src/gnsrecord/gnsrecord_crypto.c')
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 1091 |
1 files changed, 0 insertions, 1091 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c deleted file mode 100644 index 384336c97..000000000 --- a/src/gnsrecord/gnsrecord_crypto.c +++ /dev/null | |||
@@ -1,1091 +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 "gnsrecord_crypto.h" | ||
30 | |||
31 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) | ||
32 | |||
33 | ssize_t | ||
34 | ecdsa_symmetric_decrypt ( | ||
35 | const void *block, | ||
36 | size_t size, | ||
37 | const unsigned char *key, | ||
38 | const unsigned char *ctr, | ||
39 | void *result) | ||
40 | { | ||
41 | gcry_cipher_hd_t handle; | ||
42 | int rc; | ||
43 | |||
44 | GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, | ||
45 | GCRY_CIPHER_MODE_CTR, 0)); | ||
46 | rc = gcry_cipher_setkey (handle, | ||
47 | key, | ||
48 | GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
49 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
50 | rc = gcry_cipher_setctr (handle, | ||
51 | ctr, | ||
52 | GNUNET_CRYPTO_AES_KEY_LENGTH / 2); | ||
53 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
54 | GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size)); | ||
55 | gcry_cipher_close (handle); | ||
56 | return size; | ||
57 | } | ||
58 | |||
59 | |||
60 | ssize_t | ||
61 | ecdsa_symmetric_encrypt ( | ||
62 | const void *block, | ||
63 | size_t size, | ||
64 | const unsigned char *key, | ||
65 | const unsigned char *ctr, | ||
66 | void *result) | ||
67 | { | ||
68 | gcry_cipher_hd_t handle; | ||
69 | int rc; | ||
70 | |||
71 | GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, | ||
72 | GCRY_CIPHER_MODE_CTR, 0)); | ||
73 | rc = gcry_cipher_setkey (handle, | ||
74 | key, | ||
75 | GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
76 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
77 | rc = gcry_cipher_setctr (handle, | ||
78 | ctr, | ||
79 | GNUNET_CRYPTO_AES_KEY_LENGTH / 2); | ||
80 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
81 | GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size)); | ||
82 | gcry_cipher_close (handle); | ||
83 | return size; | ||
84 | } | ||
85 | |||
86 | |||
87 | enum GNUNET_GenericReturnValue | ||
88 | eddsa_symmetric_decrypt ( | ||
89 | const void *block, | ||
90 | size_t size, | ||
91 | const unsigned char *key, | ||
92 | const unsigned char *nonce, | ||
93 | void *result) | ||
94 | { | ||
95 | ssize_t ctlen = size - crypto_secretbox_MACBYTES; | ||
96 | if (ctlen < 0) | ||
97 | return GNUNET_SYSERR; | ||
98 | if (0 != crypto_secretbox_open_detached (result, | ||
99 | ((unsigned char*) block) | ||
100 | + crypto_secretbox_MACBYTES, // Ciphertext | ||
101 | block, // Tag | ||
102 | ctlen, | ||
103 | nonce, key)) | ||
104 | { | ||
105 | return GNUNET_SYSERR; | ||
106 | } | ||
107 | return GNUNET_OK; | ||
108 | } | ||
109 | |||
110 | |||
111 | enum GNUNET_GenericReturnValue | ||
112 | eddsa_symmetric_encrypt ( | ||
113 | const void *block, | ||
114 | size_t size, | ||
115 | const unsigned char *key, | ||
116 | const unsigned char *nonce, | ||
117 | void *result) | ||
118 | { | ||
119 | if (size > crypto_secretbox_MESSAGEBYTES_MAX) | ||
120 | return GNUNET_SYSERR; | ||
121 | crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext | ||
122 | result, // TAG | ||
123 | block, size, nonce, key); | ||
124 | return GNUNET_OK; | ||
125 | } | ||
126 | |||
127 | |||
128 | void | ||
129 | GNR_derive_block_aes_key (unsigned char *ctr, | ||
130 | unsigned char *key, | ||
131 | const char *label, | ||
132 | uint64_t exp, | ||
133 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | ||
134 | { | ||
135 | static const char ctx_key[] = "gns-aes-ctx-key"; | ||
136 | static const char ctx_iv[] = "gns-aes-ctx-iv"; | ||
137 | |||
138 | GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH, | ||
139 | ctx_key, strlen (ctx_key), | ||
140 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | ||
141 | label, strlen (label), | ||
142 | NULL, 0); | ||
143 | memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2); | ||
144 | /** 4 byte nonce **/ | ||
145 | GNUNET_CRYPTO_kdf (ctr, 4, | ||
146 | ctx_iv, strlen (ctx_iv), | ||
147 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | ||
148 | label, strlen (label), | ||
149 | NULL, 0); | ||
150 | /** Expiration time 64 bit. **/ | ||
151 | memcpy (ctr + 4, &exp, sizeof (exp)); | ||
152 | /** Set counter part to 1 **/ | ||
153 | ctr[15] |= 0x01; | ||
154 | } | ||
155 | |||
156 | |||
157 | void | ||
158 | GNR_derive_block_xsalsa_key (unsigned char *nonce, | ||
159 | unsigned char *key, | ||
160 | const char *label, | ||
161 | uint64_t exp, | ||
162 | const struct GNUNET_CRYPTO_EddsaPublicKey *pub) | ||
163 | { | ||
164 | static const char ctx_key[] = "gns-xsalsa-ctx-key"; | ||
165 | static const char ctx_iv[] = "gns-xsalsa-ctx-iv"; | ||
166 | |||
167 | GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES, | ||
168 | ctx_key, strlen (ctx_key), | ||
169 | pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey), | ||
170 | label, strlen (label), | ||
171 | NULL, 0); | ||
172 | memset (nonce, 0, crypto_secretbox_NONCEBYTES); | ||
173 | /** 16 byte nonce **/ | ||
174 | GNUNET_CRYPTO_kdf (nonce, (crypto_secretbox_NONCEBYTES - sizeof (exp)), | ||
175 | ctx_iv, strlen (ctx_iv), | ||
176 | pub, sizeof(struct GNUNET_CRYPTO_EddsaPublicKey), | ||
177 | label, strlen (label), | ||
178 | NULL, 0); | ||
179 | /** Expiration time 64 bit. **/ | ||
180 | memcpy (nonce + (crypto_secretbox_NONCEBYTES - sizeof (exp)), | ||
181 | &exp, sizeof (exp)); | ||
182 | } | ||
183 | |||
184 | |||
185 | static ssize_t | ||
186 | block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd, | ||
187 | unsigned int rd_count) | ||
188 | { | ||
189 | ssize_t len; | ||
190 | |||
191 | len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); | ||
192 | if (len < 0) | ||
193 | return -1; | ||
194 | len += sizeof(struct GNUNET_GNSRECORD_Block); | ||
195 | return len; | ||
196 | } | ||
197 | |||
198 | |||
199 | enum GNUNET_GenericReturnValue | ||
200 | block_sign_ecdsa (const struct | ||
201 | GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
202 | const struct | ||
203 | GNUNET_CRYPTO_EcdsaPublicKey *pkey, | ||
204 | const char *label, | ||
205 | struct GNUNET_GNSRECORD_Block *block) | ||
206 | { | ||
207 | struct GNRBlockPS *gnr_block; | ||
208 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | ||
209 | size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block); | ||
210 | |||
211 | gnr_block = GNUNET_malloc (size); | ||
212 | ecblock = &(block)->ecdsa_block; | ||
213 | gnr_block->purpose.size = htonl (size); | ||
214 | gnr_block->purpose.purpose = | ||
215 | htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
216 | gnr_block->expiration_time = ecblock->expiration_time; | ||
217 | /* encrypt and sign */ | ||
218 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], | ||
219 | size - sizeof (*gnr_block)); | ||
220 | GNUNET_CRYPTO_ecdsa_public_key_derive (pkey, | ||
221 | label, | ||
222 | "gns", | ||
223 | &ecblock->derived_key); | ||
224 | if (GNUNET_OK != | ||
225 | GNUNET_CRYPTO_ecdsa_sign_derived (key, | ||
226 | label, | ||
227 | "gns", | ||
228 | &gnr_block->purpose, | ||
229 | &ecblock->signature)) | ||
230 | { | ||
231 | GNUNET_break (0); | ||
232 | GNUNET_free (gnr_block); | ||
233 | return GNUNET_SYSERR; | ||
234 | } | ||
235 | GNUNET_free (gnr_block); | ||
236 | return GNUNET_OK; | ||
237 | } | ||
238 | |||
239 | |||
240 | enum GNUNET_GenericReturnValue | ||
241 | block_sign_eddsa (const struct | ||
242 | GNUNET_CRYPTO_EddsaPrivateKey *key, | ||
243 | const struct | ||
244 | GNUNET_CRYPTO_EddsaPublicKey *pkey, | ||
245 | const char *label, | ||
246 | struct GNUNET_GNSRECORD_Block *block) | ||
247 | { | ||
248 | struct GNRBlockPS *gnr_block; | ||
249 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; | ||
250 | size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block); | ||
251 | gnr_block = GNUNET_malloc (size); | ||
252 | edblock = &(block)->eddsa_block; | ||
253 | gnr_block->purpose.size = htonl (size); | ||
254 | gnr_block->purpose.purpose = | ||
255 | htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
256 | gnr_block->expiration_time = edblock->expiration_time; | ||
257 | GNUNET_memcpy (&gnr_block[1], &edblock[1], | ||
258 | size - sizeof (*gnr_block)); | ||
259 | /* encrypt and sign */ | ||
260 | GNUNET_CRYPTO_eddsa_public_key_derive (pkey, | ||
261 | label, | ||
262 | "gns", | ||
263 | &edblock->derived_key); | ||
264 | GNUNET_CRYPTO_eddsa_sign_derived (key, | ||
265 | label, | ||
266 | "gns", | ||
267 | &gnr_block->purpose, | ||
268 | &edblock->signature); | ||
269 | GNUNET_free (gnr_block); | ||
270 | return GNUNET_OK; | ||
271 | } | ||
272 | |||
273 | |||
274 | enum GNUNET_GenericReturnValue | ||
275 | GNUNET_GNSRECORD_block_sign (const struct | ||
276 | GNUNET_IDENTITY_PrivateKey *key, | ||
277 | const char *label, | ||
278 | struct GNUNET_GNSRECORD_Block *block) | ||
279 | { | ||
280 | struct GNUNET_IDENTITY_PublicKey pkey; | ||
281 | enum GNUNET_GenericReturnValue res = GNUNET_SYSERR; | ||
282 | char *norm_label; | ||
283 | |||
284 | GNUNET_IDENTITY_key_get_public (key, | ||
285 | &pkey); | ||
286 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
287 | |||
288 | switch (ntohl (key->type)) | ||
289 | { | ||
290 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
291 | res = block_sign_ecdsa (&key->ecdsa_key, | ||
292 | &pkey.ecdsa_key, | ||
293 | norm_label, | ||
294 | block); | ||
295 | break; | ||
296 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
297 | res = block_sign_eddsa (&key->eddsa_key, | ||
298 | &pkey.eddsa_key, | ||
299 | norm_label, | ||
300 | block); | ||
301 | break; | ||
302 | default: | ||
303 | GNUNET_assert (0); | ||
304 | } | ||
305 | GNUNET_free (norm_label); | ||
306 | return res; | ||
307 | } | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Sign name and records | ||
312 | * | ||
313 | * @param key the private key | ||
314 | * @param pkey associated public key | ||
315 | * @param expire block expiration | ||
316 | * @param label the name for the records | ||
317 | * @param rd record data | ||
318 | * @param rd_count number of records | ||
319 | * @param block the block result. Must be allocated sufficiently. | ||
320 | * @param sign sign the block GNUNET_NO if block will be signed later. | ||
321 | * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) | ||
322 | */ | ||
323 | static enum GNUNET_GenericReturnValue | ||
324 | block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
325 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | ||
326 | struct GNUNET_TIME_Absolute expire, | ||
327 | const char *label, | ||
328 | const struct GNUNET_GNSRECORD_Data *rd, | ||
329 | unsigned int rd_count, | ||
330 | struct GNUNET_GNSRECORD_Block **block, | ||
331 | int sign) | ||
332 | { | ||
333 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, | ||
334 | rd); | ||
335 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | ||
336 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | ||
337 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; | ||
338 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | ||
339 | struct GNUNET_TIME_Absolute now; | ||
340 | |||
341 | if (payload_len < 0) | ||
342 | { | ||
343 | GNUNET_break (0); | ||
344 | return GNUNET_SYSERR; | ||
345 | } | ||
346 | if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) | ||
347 | { | ||
348 | GNUNET_break (0); | ||
349 | return GNUNET_SYSERR; | ||
350 | } | ||
351 | /* convert relative to absolute times */ | ||
352 | now = GNUNET_TIME_absolute_get (); | ||
353 | for (unsigned int i = 0; i < rd_count; i++) | ||
354 | { | ||
355 | rdc[i] = rd[i]; | ||
356 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
357 | { | ||
358 | struct GNUNET_TIME_Relative t; | ||
359 | |||
360 | /* encrypted blocks must never have relative expiration times, convert! */ | ||
361 | rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
362 | t.rel_value_us = rdc[i].expiration_time; | ||
363 | rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us; | ||
364 | } | ||
365 | } | ||
366 | /* serialize */ | ||
367 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); | ||
368 | (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); | ||
369 | { | ||
370 | char payload[payload_len]; | ||
371 | |||
372 | GNUNET_assert (payload_len == | ||
373 | GNUNET_GNSRECORD_records_serialize (rd_count, | ||
374 | rdc, | ||
375 | payload_len, | ||
376 | payload)); | ||
377 | ecblock = &(*block)->ecdsa_block; | ||
378 | (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | ||
379 | ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire); | ||
380 | GNR_derive_block_aes_key (ctr, | ||
381 | skey, | ||
382 | label, | ||
383 | ecblock->expiration_time.abs_value_us__, | ||
384 | pkey); | ||
385 | GNUNET_assert (payload_len == | ||
386 | ecdsa_symmetric_encrypt (payload, | ||
387 | payload_len, | ||
388 | skey, | ||
389 | ctr, | ||
390 | &ecblock[1])); | ||
391 | } | ||
392 | if (GNUNET_YES != sign) | ||
393 | return GNUNET_OK; | ||
394 | if (GNUNET_OK != | ||
395 | block_sign_ecdsa (key, pkey, label, *block)) | ||
396 | { | ||
397 | GNUNET_break (0); | ||
398 | GNUNET_free (*block); | ||
399 | return GNUNET_SYSERR; | ||
400 | } | ||
401 | return GNUNET_OK; | ||
402 | } | ||
403 | |||
404 | |||
405 | static ssize_t | ||
406 | block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd, | ||
407 | unsigned int rd_count) | ||
408 | { | ||
409 | ssize_t len; | ||
410 | |||
411 | len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); | ||
412 | if (len < 0) | ||
413 | return -1; | ||
414 | len += sizeof(struct GNUNET_GNSRECORD_Block); | ||
415 | len += crypto_secretbox_MACBYTES; | ||
416 | return len; | ||
417 | } | ||
418 | |||
419 | |||
420 | /** | ||
421 | * Sign name and records (EDDSA version) | ||
422 | * | ||
423 | * @param key the private key | ||
424 | * @param pkey associated public key | ||
425 | * @param expire block expiration | ||
426 | * @param label the name for the records | ||
427 | * @param rd record data | ||
428 | * @param rd_count number of records | ||
429 | * @param block where to store the block. Must be allocated sufficiently. | ||
430 | * @param sign GNUNET_YES if block shall be signed as well | ||
431 | * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) | ||
432 | */ | ||
433 | enum GNUNET_GenericReturnValue | ||
434 | block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | ||
435 | const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, | ||
436 | struct GNUNET_TIME_Absolute expire, | ||
437 | const char *label, | ||
438 | const struct GNUNET_GNSRECORD_Data *rd, | ||
439 | unsigned int rd_count, | ||
440 | struct GNUNET_GNSRECORD_Block **block, | ||
441 | int sign) | ||
442 | { | ||
443 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, | ||
444 | rd); | ||
445 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; | ||
446 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | ||
447 | unsigned char skey[crypto_secretbox_KEYBYTES]; | ||
448 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | ||
449 | struct GNUNET_TIME_Absolute now; | ||
450 | |||
451 | if (payload_len < 0) | ||
452 | { | ||
453 | GNUNET_break (0); | ||
454 | return GNUNET_SYSERR; | ||
455 | } | ||
456 | if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) | ||
457 | { | ||
458 | GNUNET_break (0); | ||
459 | return GNUNET_SYSERR; | ||
460 | } | ||
461 | /* convert relative to absolute times */ | ||
462 | now = GNUNET_TIME_absolute_get (); | ||
463 | for (unsigned int i = 0; i < rd_count; i++) | ||
464 | { | ||
465 | rdc[i] = rd[i]; | ||
466 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
467 | { | ||
468 | struct GNUNET_TIME_Relative t; | ||
469 | |||
470 | /* encrypted blocks must never have relative expiration times, convert! */ | ||
471 | rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
472 | t.rel_value_us = rdc[i].expiration_time; | ||
473 | rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us; | ||
474 | } | ||
475 | } | ||
476 | /* serialize */ | ||
477 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) | ||
478 | + payload_len + crypto_secretbox_MACBYTES); | ||
479 | (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) | ||
480 | + payload_len + crypto_secretbox_MACBYTES); | ||
481 | { | ||
482 | char payload[payload_len]; | ||
483 | |||
484 | GNUNET_assert (payload_len == | ||
485 | GNUNET_GNSRECORD_records_serialize (rd_count, | ||
486 | rdc, | ||
487 | payload_len, | ||
488 | payload)); | ||
489 | edblock = &(*block)->eddsa_block; | ||
490 | (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); | ||
491 | edblock->expiration_time = GNUNET_TIME_absolute_hton (expire); | ||
492 | GNR_derive_block_xsalsa_key (nonce, | ||
493 | skey, | ||
494 | label, | ||
495 | edblock->expiration_time.abs_value_us__, | ||
496 | pkey); | ||
497 | GNUNET_assert (GNUNET_OK == | ||
498 | eddsa_symmetric_encrypt (payload, | ||
499 | payload_len, | ||
500 | skey, | ||
501 | nonce, | ||
502 | &edblock[1])); | ||
503 | if (GNUNET_YES != sign) | ||
504 | return GNUNET_OK; | ||
505 | block_sign_eddsa (key, pkey, label, *block); | ||
506 | } | ||
507 | return GNUNET_OK; | ||
508 | } | ||
509 | |||
510 | |||
511 | ssize_t | ||
512 | GNUNET_GNSRECORD_block_calculate_size (const struct | ||
513 | GNUNET_IDENTITY_PrivateKey *key, | ||
514 | const struct GNUNET_GNSRECORD_Data *rd, | ||
515 | unsigned int rd_count) | ||
516 | { | ||
517 | struct GNUNET_IDENTITY_PublicKey pkey; | ||
518 | ssize_t res = -1; | ||
519 | |||
520 | GNUNET_IDENTITY_key_get_public (key, | ||
521 | &pkey); | ||
522 | switch (ntohl (key->type)) | ||
523 | { | ||
524 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
525 | res = block_get_size_ecdsa (rd, rd_count); | ||
526 | break; | ||
527 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
528 | res = block_get_size_eddsa (rd, rd_count); | ||
529 | break; | ||
530 | default: | ||
531 | GNUNET_assert (0); | ||
532 | } | ||
533 | return res; | ||
534 | |||
535 | } | ||
536 | |||
537 | |||
538 | enum GNUNET_GenericReturnValue | ||
539 | GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, | ||
540 | struct GNUNET_TIME_Absolute expire, | ||
541 | const char *label, | ||
542 | const struct GNUNET_GNSRECORD_Data *rd, | ||
543 | unsigned int rd_count, | ||
544 | struct GNUNET_GNSRECORD_Block **result) | ||
545 | { | ||
546 | struct GNUNET_IDENTITY_PublicKey pkey; | ||
547 | enum GNUNET_GenericReturnValue res = GNUNET_SYSERR; | ||
548 | char *norm_label; | ||
549 | |||
550 | GNUNET_IDENTITY_key_get_public (key, | ||
551 | &pkey); | ||
552 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
553 | |||
554 | switch (ntohl (key->type)) | ||
555 | { | ||
556 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
557 | res = block_create_ecdsa (&key->ecdsa_key, | ||
558 | &pkey.ecdsa_key, | ||
559 | expire, | ||
560 | norm_label, | ||
561 | rd, | ||
562 | rd_count, | ||
563 | result, | ||
564 | GNUNET_YES); | ||
565 | break; | ||
566 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
567 | res = block_create_eddsa (&key->eddsa_key, | ||
568 | &pkey.eddsa_key, | ||
569 | expire, | ||
570 | norm_label, | ||
571 | rd, | ||
572 | rd_count, | ||
573 | result, | ||
574 | GNUNET_YES); | ||
575 | break; | ||
576 | default: | ||
577 | GNUNET_assert (0); | ||
578 | } | ||
579 | GNUNET_free (norm_label); | ||
580 | return res; | ||
581 | } | ||
582 | |||
583 | |||
584 | /** | ||
585 | * Line in cache mapping private keys to public keys. | ||
586 | */ | ||
587 | struct KeyCacheLine | ||
588 | { | ||
589 | /** | ||
590 | * A private key. | ||
591 | */ | ||
592 | struct GNUNET_CRYPTO_EcdsaPrivateKey key; | ||
593 | |||
594 | /** | ||
595 | * Associated public key. | ||
596 | */ | ||
597 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | ||
598 | }; | ||
599 | |||
600 | |||
601 | static enum GNUNET_GenericReturnValue | ||
602 | block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
603 | struct GNUNET_TIME_Absolute expire, | ||
604 | const char *label, | ||
605 | const struct GNUNET_GNSRECORD_Data *rd, | ||
606 | unsigned int rd_count, | ||
607 | struct GNUNET_GNSRECORD_Block **result, | ||
608 | int sign) | ||
609 | { | ||
610 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; | ||
611 | struct GNUNET_CRYPTO_EddsaPublicKey edpubkey; | ||
612 | enum GNUNET_GenericReturnValue res = GNUNET_SYSERR; | ||
613 | char *norm_label; | ||
614 | |||
615 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
616 | |||
617 | if (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pkey->type)) | ||
618 | { | ||
619 | key = &pkey->ecdsa_key; | ||
620 | #define CSIZE 64 | ||
621 | static struct KeyCacheLine cache[CSIZE]; | ||
622 | struct KeyCacheLine *line; | ||
623 | |||
624 | line = &cache[(*(unsigned int *) key) % CSIZE]; | ||
625 | if (0 != memcmp (&line->key, | ||
626 | key, | ||
627 | sizeof(*key))) | ||
628 | { | ||
629 | /* cache miss, recompute */ | ||
630 | line->key = *key; | ||
631 | GNUNET_CRYPTO_ecdsa_key_get_public (key, | ||
632 | &line->pkey); | ||
633 | } | ||
634 | #undef CSIZE | ||
635 | res = block_create_ecdsa (key, | ||
636 | &line->pkey, | ||
637 | expire, | ||
638 | norm_label, | ||
639 | rd, | ||
640 | rd_count, | ||
641 | result, | ||
642 | sign); | ||
643 | } | ||
644 | else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type)) | ||
645 | { | ||
646 | GNUNET_CRYPTO_eddsa_key_get_public (&pkey->eddsa_key, | ||
647 | &edpubkey); | ||
648 | res = block_create_eddsa (&pkey->eddsa_key, | ||
649 | &edpubkey, | ||
650 | expire, | ||
651 | norm_label, | ||
652 | rd, | ||
653 | rd_count, | ||
654 | result, | ||
655 | sign); | ||
656 | } | ||
657 | GNUNET_free (norm_label); | ||
658 | return res; | ||
659 | } | ||
660 | |||
661 | |||
662 | enum GNUNET_GenericReturnValue | ||
663 | GNUNET_GNSRECORD_block_create_unsigned (const struct | ||
664 | GNUNET_IDENTITY_PrivateKey *pkey, | ||
665 | struct GNUNET_TIME_Absolute expire, | ||
666 | const char *label, | ||
667 | const struct GNUNET_GNSRECORD_Data *rd, | ||
668 | unsigned int rd_count, | ||
669 | struct GNUNET_GNSRECORD_Block **result) | ||
670 | { | ||
671 | return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_NO); | ||
672 | } | ||
673 | |||
674 | |||
675 | enum GNUNET_GenericReturnValue | ||
676 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
677 | struct GNUNET_TIME_Absolute expire, | ||
678 | const char *label, | ||
679 | const struct GNUNET_GNSRECORD_Data *rd, | ||
680 | unsigned int rd_count, | ||
681 | struct GNUNET_GNSRECORD_Block **result) | ||
682 | { | ||
683 | return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_YES); | ||
684 | } | ||
685 | |||
686 | |||
687 | /** | ||
688 | * Check if a signature is valid. This API is used by the GNS Block | ||
689 | * to validate signatures received from the network. | ||
690 | * | ||
691 | * @param block block to verify | ||
692 | * @return #GNUNET_OK if the signature is valid | ||
693 | */ | ||
694 | enum GNUNET_GenericReturnValue | ||
695 | GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) | ||
696 | { | ||
697 | struct GNRBlockPS *purp; | ||
698 | size_t payload_len = ntohl (block->size) | ||
699 | - sizeof (struct GNUNET_GNSRECORD_Block); | ||
700 | enum GNUNET_GenericReturnValue res = GNUNET_NO; | ||
701 | purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len); | ||
702 | purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len); | ||
703 | purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
704 | GNUNET_memcpy (&purp[1], | ||
705 | &block[1], | ||
706 | payload_len); | ||
707 | switch (ntohl (block->type)) | ||
708 | { | ||
709 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
710 | purp->expiration_time = block->ecdsa_block.expiration_time; | ||
711 | res = GNUNET_CRYPTO_ecdsa_verify_ ( | ||
712 | GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, | ||
713 | &purp->purpose, | ||
714 | &block->ecdsa_block.signature, | ||
715 | &block->ecdsa_block.derived_key); | ||
716 | break; | ||
717 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
718 | purp->expiration_time = block->eddsa_block.expiration_time; | ||
719 | res = GNUNET_CRYPTO_eddsa_verify_ ( | ||
720 | GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, | ||
721 | &purp->purpose, | ||
722 | &block->eddsa_block.signature, | ||
723 | &block->eddsa_block.derived_key); | ||
724 | break; | ||
725 | default: | ||
726 | res = GNUNET_NO; | ||
727 | } | ||
728 | GNUNET_free (purp); | ||
729 | return res; | ||
730 | } | ||
731 | |||
732 | |||
733 | enum GNUNET_GenericReturnValue | ||
734 | block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block, | ||
735 | const struct | ||
736 | GNUNET_CRYPTO_EcdsaPublicKey *zone_key, | ||
737 | const char *label, | ||
738 | GNUNET_GNSRECORD_RecordCallback proc, | ||
739 | void *proc_cls) | ||
740 | { | ||
741 | size_t payload_len = ntohl (block->size) - sizeof (struct | ||
742 | GNUNET_GNSRECORD_Block); | ||
743 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | ||
744 | unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH]; | ||
745 | |||
746 | if (ntohl (block->size) < | ||
747 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
748 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)) | ||
749 | { | ||
750 | GNUNET_break_op (0); | ||
751 | return GNUNET_SYSERR; | ||
752 | } | ||
753 | GNR_derive_block_aes_key (ctr, | ||
754 | key, | ||
755 | label, | ||
756 | block->ecdsa_block.expiration_time.abs_value_us__, | ||
757 | zone_key); | ||
758 | { | ||
759 | char payload[payload_len]; | ||
760 | unsigned int rd_count; | ||
761 | |||
762 | GNUNET_assert (payload_len == | ||
763 | ecdsa_symmetric_decrypt (&block[1], payload_len, | ||
764 | key, ctr, | ||
765 | payload)); | ||
766 | rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len, | ||
767 | payload); | ||
768 | if (rd_count > 2048) | ||
769 | { | ||
770 | /* limit to sane value */ | ||
771 | GNUNET_break_op (0); | ||
772 | return GNUNET_SYSERR; | ||
773 | } | ||
774 | { | ||
775 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; | ||
776 | unsigned int j; | ||
777 | struct GNUNET_TIME_Absolute now; | ||
778 | |||
779 | if (GNUNET_OK != | ||
780 | GNUNET_GNSRECORD_records_deserialize (payload_len, | ||
781 | payload, | ||
782 | rd_count, | ||
783 | rd)) | ||
784 | { | ||
785 | GNUNET_break_op (0); | ||
786 | return GNUNET_SYSERR; | ||
787 | } | ||
788 | /* hide expired records */ | ||
789 | now = GNUNET_TIME_absolute_get (); | ||
790 | j = 0; | ||
791 | for (unsigned int i = 0; i < rd_count; i++) | ||
792 | { | ||
793 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
794 | { | ||
795 | /* encrypted blocks must never have relative expiration times, skip! */ | ||
796 | GNUNET_break_op (0); | ||
797 | continue; | ||
798 | } | ||
799 | |||
800 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) | ||
801 | { | ||
802 | int include_record = GNUNET_YES; | ||
803 | /* Shadow record, figure out if we have a not expired active record */ | ||
804 | for (unsigned int k = 0; k < rd_count; k++) | ||
805 | { | ||
806 | if (k == i) | ||
807 | continue; | ||
808 | if (rd[i].expiration_time < now.abs_value_us) | ||
809 | include_record = GNUNET_NO; /* Shadow record is expired */ | ||
810 | if ((rd[k].record_type == rd[i].record_type) && | ||
811 | (rd[k].expiration_time >= now.abs_value_us) && | ||
812 | (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW))) | ||
813 | { | ||
814 | include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ | ||
815 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
816 | "Ignoring shadow record\n"); | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | if (GNUNET_YES == include_record) | ||
821 | { | ||
822 | rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW; /* Remove Flag */ | ||
823 | if (j != i) | ||
824 | rd[j] = rd[i]; | ||
825 | j++; | ||
826 | } | ||
827 | } | ||
828 | else if (rd[i].expiration_time >= now.abs_value_us) | ||
829 | { | ||
830 | /* Include this record */ | ||
831 | if (j != i) | ||
832 | rd[j] = rd[i]; | ||
833 | j++; | ||
834 | } | ||
835 | else | ||
836 | { | ||
837 | struct GNUNET_TIME_Absolute at; | ||
838 | |||
839 | at.abs_value_us = rd[i].expiration_time; | ||
840 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
841 | "Excluding record that expired %s (%llu ago)\n", | ||
842 | GNUNET_STRINGS_absolute_time_to_string (at), | ||
843 | (unsigned long long) rd[i].expiration_time | ||
844 | - now.abs_value_us); | ||
845 | } | ||
846 | } | ||
847 | rd_count = j; | ||
848 | if (NULL != proc) | ||
849 | proc (proc_cls, | ||
850 | rd_count, | ||
851 | (0 != rd_count) ? rd : NULL); | ||
852 | } | ||
853 | } | ||
854 | return GNUNET_OK; | ||
855 | } | ||
856 | |||
857 | |||
858 | enum GNUNET_GenericReturnValue | ||
859 | block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block, | ||
860 | const struct | ||
861 | GNUNET_CRYPTO_EddsaPublicKey *zone_key, | ||
862 | const char *label, | ||
863 | GNUNET_GNSRECORD_RecordCallback proc, | ||
864 | void *proc_cls) | ||
865 | { | ||
866 | size_t payload_len = ntohl (block->size) - sizeof (struct | ||
867 | GNUNET_GNSRECORD_Block); | ||
868 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | ||
869 | unsigned char key[crypto_secretbox_KEYBYTES]; | ||
870 | |||
871 | if (ntohl (block->size) < | ||
872 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
873 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)) | ||
874 | { | ||
875 | GNUNET_break_op (0); | ||
876 | return GNUNET_SYSERR; | ||
877 | } | ||
878 | GNR_derive_block_xsalsa_key (nonce, | ||
879 | key, | ||
880 | label, | ||
881 | block->eddsa_block.expiration_time.abs_value_us__, | ||
882 | zone_key); | ||
883 | { | ||
884 | char payload[payload_len]; | ||
885 | unsigned int rd_count; | ||
886 | |||
887 | GNUNET_assert (GNUNET_OK == | ||
888 | eddsa_symmetric_decrypt (&block[1], payload_len, | ||
889 | key, nonce, | ||
890 | payload)); | ||
891 | payload_len -= crypto_secretbox_MACBYTES; | ||
892 | rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len, | ||
893 | payload); | ||
894 | if (rd_count > 2048) | ||
895 | { | ||
896 | /* limit to sane value */ | ||
897 | GNUNET_break_op (0); | ||
898 | return GNUNET_SYSERR; | ||
899 | } | ||
900 | { | ||
901 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; | ||
902 | unsigned int j; | ||
903 | struct GNUNET_TIME_Absolute now; | ||
904 | |||
905 | if (GNUNET_OK != | ||
906 | GNUNET_GNSRECORD_records_deserialize (payload_len, | ||
907 | payload, | ||
908 | rd_count, | ||
909 | rd)) | ||
910 | { | ||
911 | GNUNET_break_op (0); | ||
912 | return GNUNET_SYSERR; | ||
913 | } | ||
914 | /* hide expired records */ | ||
915 | now = GNUNET_TIME_absolute_get (); | ||
916 | j = 0; | ||
917 | for (unsigned int i = 0; i < rd_count; i++) | ||
918 | { | ||
919 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
920 | { | ||
921 | /* encrypted blocks must never have relative expiration times, skip! */ | ||
922 | GNUNET_break_op (0); | ||
923 | continue; | ||
924 | } | ||
925 | |||
926 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW)) | ||
927 | { | ||
928 | int include_record = GNUNET_YES; | ||
929 | /* Shadow record, figure out if we have a not expired active record */ | ||
930 | for (unsigned int k = 0; k < rd_count; k++) | ||
931 | { | ||
932 | if (k == i) | ||
933 | continue; | ||
934 | if (rd[i].expiration_time < now.abs_value_us) | ||
935 | include_record = GNUNET_NO; /* Shadow record is expired */ | ||
936 | if ((rd[k].record_type == rd[i].record_type) && | ||
937 | (rd[k].expiration_time >= now.abs_value_us) && | ||
938 | (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW))) | ||
939 | { | ||
940 | include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ | ||
941 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
942 | "Ignoring shadow record\n"); | ||
943 | break; | ||
944 | } | ||
945 | } | ||
946 | if (GNUNET_YES == include_record) | ||
947 | { | ||
948 | rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW; /* Remove Flag */ | ||
949 | if (j != i) | ||
950 | rd[j] = rd[i]; | ||
951 | j++; | ||
952 | } | ||
953 | } | ||
954 | else if (rd[i].expiration_time >= now.abs_value_us) | ||
955 | { | ||
956 | /* Include this record */ | ||
957 | if (j != i) | ||
958 | rd[j] = rd[i]; | ||
959 | j++; | ||
960 | } | ||
961 | else | ||
962 | { | ||
963 | struct GNUNET_TIME_Absolute at; | ||
964 | |||
965 | at.abs_value_us = rd[i].expiration_time; | ||
966 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
967 | "Excluding record that expired %s (%llu ago)\n", | ||
968 | GNUNET_STRINGS_absolute_time_to_string (at), | ||
969 | (unsigned long long) rd[i].expiration_time | ||
970 | - now.abs_value_us); | ||
971 | } | ||
972 | } | ||
973 | rd_count = j; | ||
974 | if (NULL != proc) | ||
975 | proc (proc_cls, | ||
976 | rd_count, | ||
977 | (0 != rd_count) ? rd : NULL); | ||
978 | } | ||
979 | } | ||
980 | return GNUNET_OK; | ||
981 | } | ||
982 | |||
983 | |||
984 | enum GNUNET_GenericReturnValue | ||
985 | GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | ||
986 | const struct | ||
987 | GNUNET_IDENTITY_PublicKey *zone_key, | ||
988 | const char *label, | ||
989 | GNUNET_GNSRECORD_RecordCallback proc, | ||
990 | void *proc_cls) | ||
991 | { | ||
992 | enum GNUNET_GenericReturnValue res = GNUNET_SYSERR; | ||
993 | char *norm_label; | ||
994 | |||
995 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
996 | switch (ntohl (zone_key->type)) | ||
997 | { | ||
998 | case GNUNET_IDENTITY_TYPE_ECDSA: | ||
999 | res = block_decrypt_ecdsa (block, | ||
1000 | &zone_key->ecdsa_key, norm_label, proc, | ||
1001 | proc_cls); | ||
1002 | break; | ||
1003 | case GNUNET_IDENTITY_TYPE_EDDSA: | ||
1004 | res = block_decrypt_eddsa (block, | ||
1005 | &zone_key->eddsa_key, norm_label, proc, | ||
1006 | proc_cls); | ||
1007 | break; | ||
1008 | default: | ||
1009 | res = GNUNET_SYSERR; | ||
1010 | } | ||
1011 | GNUNET_free (norm_label); | ||
1012 | return res; | ||
1013 | } | ||
1014 | |||
1015 | |||
1016 | /** | ||
1017 | * Calculate the DHT query for a given @a label in a given @a zone. | ||
1018 | * | ||
1019 | * @param zone private key of the zone | ||
1020 | * @param label label of the record | ||
1021 | * @param query hash to use for the query | ||
1022 | */ | ||
1023 | void | ||
1024 | GNUNET_GNSRECORD_query_from_private_key (const struct | ||
1025 | GNUNET_IDENTITY_PrivateKey *zone, | ||
1026 | const char *label, | ||
1027 | struct GNUNET_HashCode *query) | ||
1028 | { | ||
1029 | char *norm_label; | ||
1030 | struct GNUNET_IDENTITY_PublicKey pub; | ||
1031 | |||
1032 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
1033 | switch (ntohl (zone->type)) | ||
1034 | { | ||
1035 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
1036 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
1037 | |||
1038 | GNUNET_IDENTITY_key_get_public (zone, | ||
1039 | &pub); | ||
1040 | GNUNET_GNSRECORD_query_from_public_key (&pub, | ||
1041 | norm_label, | ||
1042 | query); | ||
1043 | break; | ||
1044 | default: | ||
1045 | GNUNET_assert (0); | ||
1046 | } | ||
1047 | GNUNET_free (norm_label); | ||
1048 | } | ||
1049 | |||
1050 | |||
1051 | void | ||
1052 | GNUNET_GNSRECORD_query_from_public_key (const struct | ||
1053 | GNUNET_IDENTITY_PublicKey *pub, | ||
1054 | const char *label, | ||
1055 | struct GNUNET_HashCode *query) | ||
1056 | { | ||
1057 | char *norm_label; | ||
1058 | struct GNUNET_IDENTITY_PublicKey pd; | ||
1059 | |||
1060 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
1061 | |||
1062 | switch (ntohl (pub->type)) | ||
1063 | { | ||
1064 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
1065 | pd.type = pub->type; | ||
1066 | GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key, | ||
1067 | norm_label, | ||
1068 | "gns", | ||
1069 | &pd.ecdsa_key); | ||
1070 | GNUNET_CRYPTO_hash (&pd.ecdsa_key, | ||
1071 | sizeof (pd.ecdsa_key), | ||
1072 | query); | ||
1073 | break; | ||
1074 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
1075 | pd.type = pub->type; | ||
1076 | GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key, | ||
1077 | norm_label, | ||
1078 | "gns", | ||
1079 | &(pd.eddsa_key)); | ||
1080 | GNUNET_CRYPTO_hash (&pd.eddsa_key, | ||
1081 | sizeof (pd.eddsa_key), | ||
1082 | query); | ||
1083 | break; | ||
1084 | default: | ||
1085 | GNUNET_assert (0); | ||
1086 | } | ||
1087 | GNUNET_free (norm_label); | ||
1088 | } | ||
1089 | |||
1090 | |||
1091 | /* end of gnsrecord_crypto.c */ | ||