aboutsummaryrefslogtreecommitdiff
path: root/src/gnsrecord/gnsrecord_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnsrecord/gnsrecord_crypto.c')
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c535
1 files changed, 280 insertions, 255 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index fe7db88b9..890ddb011 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -25,15 +25,7 @@
25 * @author Matthias Wachs 25 * @author Matthias Wachs
26 * @author Christian Grothoff 26 * @author Christian Grothoff
27 */ 27 */
28#include "platform.h" 28#include "gnsrecord_crypto.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 29
38#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) 30#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
39 31
@@ -103,8 +95,8 @@ eddsa_symmetric_decrypt (
103 if (ctlen < 0) 95 if (ctlen < 0)
104 return GNUNET_SYSERR; 96 return GNUNET_SYSERR;
105 if (0 != crypto_secretbox_open_detached (result, 97 if (0 != crypto_secretbox_open_detached (result,
106 block, // Ciphertext 98 ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext
107 ((unsigned char*)block) + ctlen, // TAG 99 block, // Tag
108 ctlen, 100 ctlen,
109 nonce, key)) 101 nonce, key))
110 { 102 {
@@ -124,27 +116,19 @@ eddsa_symmetric_encrypt (
124{ 116{
125 if (size > crypto_secretbox_MESSAGEBYTES_MAX) 117 if (size > crypto_secretbox_MESSAGEBYTES_MAX)
126 return GNUNET_SYSERR; 118 return GNUNET_SYSERR;
127 crypto_secretbox_detached (result, // Ciphertext 119 crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext
128 result + size, // TAG 120 result, // TAG
129 block, size, nonce, key); 121 block, size, nonce, key);
130 return GNUNET_OK; 122 return GNUNET_OK;
131} 123}
132 124
133 125
134/** 126void
135 * Derive session key and iv from label and public key. 127GNR_derive_block_aes_key (unsigned char *ctr,
136 * 128 unsigned char *key,
137 * @param iv initialization vector to initialize 129 const char *label,
138 * @param skey session key to initialize 130 uint64_t exp,
139 * @param label label to use for KDF 131 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
140 * @param pub public key to use for KDF
141 */
142static void
143derive_block_aes_key (unsigned char *ctr,
144 unsigned char *key,
145 const char *label,
146 uint64_t exp,
147 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
148{ 132{
149 static const char ctx_key[] = "gns-aes-ctx-key"; 133 static const char ctx_key[] = "gns-aes-ctx-key";
150 static const char ctx_iv[] = "gns-aes-ctx-iv"; 134 static const char ctx_iv[] = "gns-aes-ctx-iv";
@@ -168,23 +152,15 @@ derive_block_aes_key (unsigned char *ctr,
168} 152}
169 153
170 154
171/** 155void
172 * Derive session key and iv from label and public key. 156GNR_derive_block_xsalsa_key (unsigned char *nonce,
173 * 157 unsigned char *key,
174 * @param nonce initialization vector to initialize 158 const char *label,
175 * @param skey session key to initialize 159 uint64_t exp,
176 * @param label label to use for KDF 160 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
177 * @param pub public key to use for KDF
178 */
179static void
180derive_block_xsalsa_key (unsigned char *nonce,
181 unsigned char *key,
182 const char *label,
183 uint64_t exp,
184 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
185{ 161{
186 static const char ctx_key[] = "gns-aes-ctx-key"; 162 static const char ctx_key[] = "gns-xsalsa-ctx-key";
187 static const char ctx_iv[] = "gns-aes-ctx-iv"; 163 static const char ctx_iv[] = "gns-xsalsa-ctx-iv";
188 164
189 GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES, 165 GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES,
190 ctx_key, strlen (ctx_key), 166 ctx_key, strlen (ctx_key),
@@ -204,6 +180,20 @@ derive_block_xsalsa_key (unsigned char *nonce,
204} 180}
205 181
206 182
183static ssize_t
184block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
185 unsigned int rd_count)
186{
187 ssize_t len;
188
189 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
190 if (len < 0)
191 return -1;
192 len += sizeof(struct GNUNET_GNSRECORD_Block);
193 return len;
194}
195
196
207/** 197/**
208 * Sign name and records 198 * Sign name and records
209 * 199 *
@@ -213,20 +203,22 @@ derive_block_xsalsa_key (unsigned char *nonce,
213 * @param label the name for the records 203 * @param label the name for the records
214 * @param rd record data 204 * @param rd record data
215 * @param rd_count number of records 205 * @param rd_count number of records
216 * @return NULL on error (block too large) 206 * @param block the block result. Must be allocated sufficiently.
207 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
217 */ 208 */
218static struct GNUNET_GNSRECORD_Block * 209static enum GNUNET_GenericReturnValue
219block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, 210block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
220 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, 211 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
221 struct GNUNET_TIME_Absolute expire, 212 struct GNUNET_TIME_Absolute expire,
222 const char *label, 213 const char *label,
223 const struct GNUNET_GNSRECORD_Data *rd, 214 const struct GNUNET_GNSRECORD_Data *rd,
224 unsigned int rd_count) 215 unsigned int rd_count,
216 struct GNUNET_GNSRECORD_Block **block)
225{ 217{
226 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 218 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
227 rd); 219 rd);
228 struct GNUNET_GNSRECORD_Block *block;
229 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; 220 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
221 struct GNRBlockPS *gnr_block;
230 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; 222 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
231 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; 223 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
232 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; 224 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
@@ -237,12 +229,12 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
237 if (payload_len < 0) 229 if (payload_len < 0)
238 { 230 {
239 GNUNET_break (0); 231 GNUNET_break (0);
240 return NULL; 232 return GNUNET_SYSERR;
241 } 233 }
242 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) 234 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
243 { 235 {
244 GNUNET_break (0); 236 GNUNET_break (0);
245 return NULL; 237 return GNUNET_SYSERR;
246 } 238 }
247 /* convert relative to absolute times */ 239 /* convert relative to absolute times */
248 now = GNUNET_TIME_absolute_get (); 240 now = GNUNET_TIME_absolute_get ();
@@ -260,62 +252,70 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
260 } 252 }
261 } 253 }
262 /* serialize */ 254 /* serialize */
255 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
256 (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
263 rd_count_nbo = htonl (rd_count); 257 rd_count_nbo = htonl (rd_count);
264 { 258 {
265 char payload[sizeof(uint32_t) + payload_len]; 259 char payload[payload_len];
266 260
267 GNUNET_memcpy (payload,
268 &rd_count_nbo,
269 sizeof(uint32_t));
270 GNUNET_assert (payload_len == 261 GNUNET_assert (payload_len ==
271 GNUNET_GNSRECORD_records_serialize (rd_count, 262 GNUNET_GNSRECORD_records_serialize (rd_count,
272 rdc, 263 rdc,
273 payload_len, 264 payload_len,
274 &payload[sizeof(uint32_t) 265 payload));
275 ])); 266 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
276 block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) 267 ecblock = &(*block)->ecdsa_block;
277 + sizeof(uint32_t) 268 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
278 + payload_len); 269 gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len);
279 ecblock = &block->ecdsa_block; 270 gnr_block->purpose.purpose =
280 block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); 271 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
281 ecblock->purpose.size = htonl (sizeof(uint32_t) 272 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
282 + payload_len 273 ecblock->expiration_time = gnr_block->expiration_time;
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 */ 274 /* encrypt and sign */
289 dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, 275 dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key,
290 label, 276 label,
291 "gns"); 277 "gns");
292 GNUNET_CRYPTO_ecdsa_key_get_public (dkey, 278 GNUNET_CRYPTO_ecdsa_key_get_public (dkey,
293 &ecblock->derived_key); 279 &ecblock->derived_key);
294 derive_block_aes_key (ctr, 280 GNR_derive_block_aes_key (ctr,
295 skey, 281 skey,
296 label, 282 label,
297 ecblock->expiration_time.abs_value_us__, 283 ecblock->expiration_time.abs_value_us__,
298 pkey); 284 pkey);
299 GNUNET_break (payload_len + sizeof(uint32_t) == 285 GNUNET_break (payload_len ==
300 ecdsa_symmetric_encrypt (payload, 286 ecdsa_symmetric_encrypt (payload,
301 payload_len 287 payload_len,
302 + sizeof(uint32_t),
303 skey, 288 skey,
304 ctr, 289 ctr,
305 &ecblock[1])); 290 &ecblock[1]));
291 GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
306 } 292 }
307 if (GNUNET_OK != 293 if (GNUNET_OK !=
308 GNUNET_CRYPTO_ecdsa_sign_ (dkey, 294 GNUNET_CRYPTO_ecdsa_sign_ (dkey,
309 &ecblock->purpose, 295 &gnr_block->purpose,
310 &ecblock->signature)) 296 &ecblock->signature))
311 { 297 {
312 GNUNET_break (0); 298 GNUNET_break (0);
299 GNUNET_free (*block);
313 GNUNET_free (dkey); 300 GNUNET_free (dkey);
314 GNUNET_free (block); 301 return GNUNET_SYSERR;
315 return NULL;
316 } 302 }
317 GNUNET_free (dkey); 303 GNUNET_free (dkey);
318 return block; 304 return GNUNET_OK;
305}
306
307static ssize_t
308block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd,
309 unsigned int rd_count)
310{
311 ssize_t len;
312
313 len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
314 if (len < 0)
315 return -1;
316 len += sizeof(struct GNUNET_GNSRECORD_Block);
317 len += crypto_secretbox_MACBYTES;
318 return len;
319} 319}
320 320
321 321
@@ -328,20 +328,22 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
328 * @param label the name for the records 328 * @param label the name for the records
329 * @param rd record data 329 * @param rd record data
330 * @param rd_count number of records 330 * @param rd_count number of records
331 * @return NULL on error (block too large) 331 * @param block where to store the block. Must be allocated sufficiently.
332 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
332 */ 333 */
333static struct GNUNET_GNSRECORD_Block * 334enum GNUNET_GenericReturnValue
334block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, 335block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
335 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, 336 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
336 struct GNUNET_TIME_Absolute expire, 337 struct GNUNET_TIME_Absolute expire,
337 const char *label, 338 const char *label,
338 const struct GNUNET_GNSRECORD_Data *rd, 339 const struct GNUNET_GNSRECORD_Data *rd,
339 unsigned int rd_count) 340 unsigned int rd_count,
341 struct GNUNET_GNSRECORD_Block **block)
340{ 342{
341 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 343 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
342 rd); 344 rd);
343 struct GNUNET_GNSRECORD_Block *block;
344 struct GNUNET_GNSRECORD_EddsaBlock *edblock; 345 struct GNUNET_GNSRECORD_EddsaBlock *edblock;
346 struct GNRBlockPS *gnr_block;
345 struct GNUNET_CRYPTO_EddsaPrivateScalar dkey; 347 struct GNUNET_CRYPTO_EddsaPrivateScalar dkey;
346 unsigned char nonce[crypto_secretbox_NONCEBYTES]; 348 unsigned char nonce[crypto_secretbox_NONCEBYTES];
347 unsigned char skey[crypto_secretbox_KEYBYTES]; 349 unsigned char skey[crypto_secretbox_KEYBYTES];
@@ -352,12 +354,12 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
352 if (payload_len < 0) 354 if (payload_len < 0)
353 { 355 {
354 GNUNET_break (0); 356 GNUNET_break (0);
355 return NULL; 357 return GNUNET_SYSERR;
356 } 358 }
357 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) 359 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
358 { 360 {
359 GNUNET_break (0); 361 GNUNET_break (0);
360 return NULL; 362 return GNUNET_SYSERR;
361 } 363 }
362 /* convert relative to absolute times */ 364 /* convert relative to absolute times */
363 now = GNUNET_TIME_absolute_get (); 365 now = GNUNET_TIME_absolute_get ();
@@ -375,33 +377,32 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
375 } 377 }
376 } 378 }
377 /* serialize */ 379 /* serialize */
380 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
381 + payload_len + crypto_secretbox_MACBYTES);
382 (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block)
383 + payload_len + crypto_secretbox_MACBYTES);
378 rd_count_nbo = htonl (rd_count); 384 rd_count_nbo = htonl (rd_count);
379 { 385 {
380 char payload[sizeof(uint32_t) + payload_len]; 386 char payload[payload_len];
381 387
382 GNUNET_memcpy (payload,
383 &rd_count_nbo,
384 sizeof(uint32_t));
385 GNUNET_assert (payload_len == 388 GNUNET_assert (payload_len ==
386 GNUNET_GNSRECORD_records_serialize (rd_count, 389 GNUNET_GNSRECORD_records_serialize (rd_count,
387 rdc, 390 rdc,
388 payload_len, 391 payload_len,
389 &payload[sizeof(uint32_t) 392 payload));
390 ])); 393 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
391 block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) 394 + payload_len
392 + sizeof(uint32_t) 395 + crypto_secretbox_MACBYTES);
393 + payload_len 396 edblock = &(*block)->eddsa_block;
394 + crypto_secretbox_MACBYTES); 397 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
395 edblock = &block->eddsa_block; 398 gnr_block->purpose.size =
396 block->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); 399 htonl (sizeof(struct GNRBlockPS)
397 edblock->purpose.size = htonl (sizeof(uint32_t) 400 + payload_len
398 + payload_len 401 + crypto_secretbox_MACBYTES);
399 + sizeof(struct 402 gnr_block->purpose.purpose =
400 GNUNET_CRYPTO_EccSignaturePurpose) 403 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
401 + sizeof(struct GNUNET_TIME_AbsoluteNBO) 404 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
402 + crypto_secretbox_MACBYTES); 405 edblock->expiration_time = gnr_block->expiration_time;
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 /* encrypt and sign */
406 GNUNET_CRYPTO_eddsa_private_key_derive (key, 407 GNUNET_CRYPTO_eddsa_private_key_derive (key,
407 label, 408 label,
@@ -409,45 +410,63 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
409 &dkey); 410 &dkey);
410 GNUNET_CRYPTO_eddsa_key_get_public_from_scalar (&dkey, 411 GNUNET_CRYPTO_eddsa_key_get_public_from_scalar (&dkey,
411 &edblock->derived_key); 412 &edblock->derived_key);
412 derive_block_xsalsa_key (nonce, 413 GNR_derive_block_xsalsa_key (nonce,
413 skey, 414 skey,
414 label, 415 label,
415 edblock->expiration_time.abs_value_us__, 416 edblock->expiration_time.abs_value_us__,
416 pkey); 417 pkey);
417 GNUNET_break (GNUNET_OK == 418 GNUNET_break (GNUNET_OK ==
418 eddsa_symmetric_encrypt (payload, 419 eddsa_symmetric_encrypt (payload,
419 payload_len 420 payload_len,
420 + sizeof(uint32_t),
421 skey, 421 skey,
422 nonce, 422 nonce,
423 &edblock[1])); 423 &edblock[1]));
424 GNUNET_memcpy (&gnr_block[1], &edblock[1],
425 payload_len + crypto_secretbox_MACBYTES);
426
427 GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey,
428 &gnr_block->purpose,
429 &edblock->signature);
424 } 430 }
425 GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey, 431 return GNUNET_OK;
426 &edblock->purpose,
427 &edblock->signature);
428 return block;
429} 432}
430 433
434ssize_t
435GNUNET_GNSRECORD_block_calculate_size (const struct
436 GNUNET_IDENTITY_PrivateKey *key,
437 const struct GNUNET_GNSRECORD_Data *rd,
438 unsigned int rd_count)
439{
440 struct GNUNET_IDENTITY_PublicKey pkey;
441 ssize_t res;
431 442
432/** 443 GNUNET_IDENTITY_key_get_public (key,
433 * Sign name and records 444 &pkey);
434 * 445 switch (ntohl (key->type))
435 * @param key the private key 446 {
436 * @param expire block expiration 447 case GNUNET_GNSRECORD_TYPE_PKEY:
437 * @param label the name for the records 448 res = block_get_size_ecdsa (rd, rd_count);
438 * @param rd record data 449 break;
439 * @param rd_count number of records 450 case GNUNET_GNSRECORD_TYPE_EDKEY:
440 * @return NULL on error (block too large) 451 res = block_get_size_eddsa (rd, rd_count);
441 */ 452 break;
442struct GNUNET_GNSRECORD_Block * 453 default:
454 GNUNET_assert (0);
455 }
456 return -1;
457
458}
459
460enum GNUNET_GenericReturnValue
443GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, 461GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
444 struct GNUNET_TIME_Absolute expire, 462 struct GNUNET_TIME_Absolute expire,
445 const char *label, 463 const char *label,
446 const struct GNUNET_GNSRECORD_Data *rd, 464 const struct GNUNET_GNSRECORD_Data *rd,
447 unsigned int rd_count) 465 unsigned int rd_count,
466 struct GNUNET_GNSRECORD_Block **result)
448{ 467{
449 struct GNUNET_IDENTITY_PublicKey pkey; 468 struct GNUNET_IDENTITY_PublicKey pkey;
450 struct GNUNET_GNSRECORD_Block *res = NULL; 469 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
451 char *norm_label; 470 char *norm_label;
452 471
453 GNUNET_IDENTITY_key_get_public (key, 472 GNUNET_IDENTITY_key_get_public (key,
@@ -456,24 +475,26 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
456 475
457 switch (ntohl (key->type)) 476 switch (ntohl (key->type))
458 { 477 {
459 case GNUNET_GNSRECORD_TYPE_PKEY: 478 case GNUNET_GNSRECORD_TYPE_PKEY:
460 res = block_create_ecdsa (&key->ecdsa_key, 479 res = block_create_ecdsa (&key->ecdsa_key,
461 &pkey.ecdsa_key, 480 &pkey.ecdsa_key,
462 expire, 481 expire,
463 norm_label, 482 norm_label,
464 rd, 483 rd,
465 rd_count); 484 rd_count,
466 break; 485 result);
467 case GNUNET_GNSRECORD_TYPE_EDKEY: 486 break;
468 res = block_create_eddsa (&key->eddsa_key, 487 case GNUNET_GNSRECORD_TYPE_EDKEY:
469 &pkey.eddsa_key, 488 res = block_create_eddsa (&key->eddsa_key,
470 expire, 489 &pkey.eddsa_key,
471 norm_label, 490 expire,
472 rd, 491 norm_label,
473 rd_count); 492 rd,
474 break; 493 rd_count,
475 default: 494 result);
476 GNUNET_assert (0); 495 break;
496 default:
497 GNUNET_assert (0);
477 } 498 }
478 GNUNET_free (norm_label); 499 GNUNET_free (norm_label);
479 return res; 500 return res;
@@ -497,28 +518,17 @@ struct KeyCacheLine
497}; 518};
498 519
499 520
500/** 521enum GNUNET_GenericReturnValue
501 * Sign name and records, cache derived public key (also keeps the
502 * private key in static memory, so do not use this function if
503 * keeping the private key in the process'es RAM is a major issue).
504 *
505 * @param key the private key
506 * @param expire block expiration
507 * @param label the name for the records
508 * @param rd record data
509 * @param rd_count number of records
510 * @return NULL on error (block too large)
511 */
512struct GNUNET_GNSRECORD_Block *
513GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, 522GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
514 struct GNUNET_TIME_Absolute expire, 523 struct GNUNET_TIME_Absolute expire,
515 const char *label, 524 const char *label,
516 const struct GNUNET_GNSRECORD_Data *rd, 525 const struct GNUNET_GNSRECORD_Data *rd,
517 unsigned int rd_count) 526 unsigned int rd_count,
527 struct GNUNET_GNSRECORD_Block **result)
518{ 528{
519 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; 529 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
520 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey; 530 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
521 struct GNUNET_GNSRECORD_Block *res = NULL; 531 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
522 char *norm_label; 532 char *norm_label;
523 533
524 norm_label = GNUNET_GNSRECORD_string_normalize (label); 534 norm_label = GNUNET_GNSRECORD_string_normalize (label);
@@ -546,7 +556,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
546 expire, 556 expire,
547 norm_label, 557 norm_label,
548 rd, 558 rd,
549 rd_count); 559 rd_count,
560 result);
550 } 561 }
551 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type)) 562 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
552 { 563 {
@@ -557,7 +568,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
557 expire, 568 expire,
558 norm_label, 569 norm_label,
559 rd, 570 rd,
560 rd_count); 571 rd_count,
572 result);
561 } 573 }
562 GNUNET_free (norm_label); 574 GNUNET_free (norm_label);
563 return res; 575 return res;
@@ -574,64 +586,76 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
574enum GNUNET_GenericReturnValue 586enum GNUNET_GenericReturnValue
575GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) 587GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
576{ 588{
589 struct GNRBlockPS *purp;
590 size_t payload_len = ntohl (block->size)
591 - sizeof (struct GNUNET_GNSRECORD_Block);
592 enum GNUNET_GenericReturnValue res = GNUNET_NO;
593 purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
594 purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
595 purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
596 GNUNET_memcpy (&purp[1], &block[1], payload_len);
597
577 switch (ntohl (block->type)) 598 switch (ntohl (block->type))
578 { 599 {
579 case GNUNET_GNSRECORD_TYPE_PKEY: 600 case GNUNET_GNSRECORD_TYPE_PKEY:
580 return GNUNET_CRYPTO_ecdsa_verify_ ( 601 purp->expiration_time = block->ecdsa_block.expiration_time;
581 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, 602 res = GNUNET_CRYPTO_ecdsa_verify_ (
582 &block->ecdsa_block.purpose, 603 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
583 &block->ecdsa_block.signature, 604 &purp->purpose,
584 &block->ecdsa_block.derived_key); 605 &block->ecdsa_block.signature,
585 case GNUNET_GNSRECORD_TYPE_EDKEY: 606 &block->ecdsa_block.derived_key);
586 return GNUNET_CRYPTO_eddsa_verify_ ( 607 break;
587 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, 608 case GNUNET_GNSRECORD_TYPE_EDKEY:
588 &block->eddsa_block.purpose, 609 purp->expiration_time = block->eddsa_block.expiration_time;
589 &block->eddsa_block.signature, 610 res = GNUNET_CRYPTO_eddsa_verify_ (
590 &block->eddsa_block.derived_key); 611 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
591 default: 612 &purp->purpose,
592 return GNUNET_NO; 613 &block->eddsa_block.signature,
614 &block->eddsa_block.derived_key);
615 break;
616 default:
617 res = GNUNET_NO;
593 } 618 }
619 GNUNET_free (purp);
620 return res;
594} 621}
595 622
596 623
597enum GNUNET_GenericReturnValue 624enum GNUNET_GenericReturnValue
598block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, 625block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
599 const struct 626 const struct
600 GNUNET_CRYPTO_EcdsaPublicKey *zone_key, 627 GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
601 const char *label, 628 const char *label,
602 GNUNET_GNSRECORD_RecordCallback proc, 629 GNUNET_GNSRECORD_RecordCallback proc,
603 void *proc_cls) 630 void *proc_cls)
604{ 631{
605 size_t payload_len = ntohl (block->purpose.size) 632 size_t payload_len = ntohl (block->size) - sizeof (struct
606 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 633 GNUNET_GNSRECORD_Block);
607 - sizeof(struct GNUNET_TIME_AbsoluteNBO);
608 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; 634 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
609 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH]; 635 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
610 636
611 if (ntohl (block->purpose.size) < 637 if (ntohl (block->size) <
612 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 638 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
613 + sizeof(struct GNUNET_TIME_AbsoluteNBO)) 639 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
614 { 640 {
615 GNUNET_break_op (0); 641 GNUNET_break_op (0);
616 return GNUNET_SYSERR; 642 return GNUNET_SYSERR;
617 } 643 }
618 derive_block_aes_key (ctr, 644 GNR_derive_block_aes_key (ctr,
619 key, 645 key,
620 label, 646 label,
621 block->expiration_time.abs_value_us__, 647 block->ecdsa_block.expiration_time.abs_value_us__,
622 zone_key); 648 zone_key);
623 { 649 {
624 char payload[payload_len]; 650 char payload[payload_len];
625 uint32_t rd_count; 651 unsigned int rd_count;
626 652
627 GNUNET_break (payload_len == 653 GNUNET_break (payload_len ==
628 ecdsa_symmetric_decrypt (&block[1], payload_len, 654 ecdsa_symmetric_decrypt (&block[1], payload_len,
629 key, ctr, 655 key, ctr,
630 payload)); 656 payload));
631 GNUNET_memcpy (&rd_count, 657 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
632 payload, 658 payload);
633 sizeof(uint32_t));
634 rd_count = ntohl (rd_count);
635 if (rd_count > 2048) 659 if (rd_count > 2048)
636 { 660 {
637 /* limit to sane value */ 661 /* limit to sane value */
@@ -644,8 +668,8 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
644 struct GNUNET_TIME_Absolute now; 668 struct GNUNET_TIME_Absolute now;
645 669
646 if (GNUNET_OK != 670 if (GNUNET_OK !=
647 GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t), 671 GNUNET_GNSRECORD_records_deserialize (payload_len,
648 &payload[sizeof(uint32_t)], 672 payload,
649 rd_count, 673 rd_count,
650 rd)) 674 rd))
651 { 675 {
@@ -723,43 +747,42 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
723 747
724 748
725enum GNUNET_GenericReturnValue 749enum GNUNET_GenericReturnValue
726block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block, 750block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
727 const struct 751 const struct
728 GNUNET_CRYPTO_EddsaPublicKey *zone_key, 752 GNUNET_CRYPTO_EddsaPublicKey *zone_key,
729 const char *label, 753 const char *label,
730 GNUNET_GNSRECORD_RecordCallback proc, 754 GNUNET_GNSRECORD_RecordCallback proc,
731 void *proc_cls) 755 void *proc_cls)
732{ 756{
733 size_t payload_len = ntohl (block->purpose.size) 757 const struct GNUNET_GNSRECORD_EddsaBlock *edblock = &block->eddsa_block;
734 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 758 size_t payload_len = ntohl (block->size) - sizeof (struct
735 - sizeof(struct GNUNET_TIME_AbsoluteNBO); 759 GNUNET_GNSRECORD_Block);
736 unsigned char nonce[crypto_secretbox_NONCEBYTES]; 760 unsigned char nonce[crypto_secretbox_NONCEBYTES];
737 unsigned char key[crypto_secretbox_KEYBYTES]; 761 unsigned char key[crypto_secretbox_KEYBYTES];
738 762
739 if (ntohl (block->purpose.size) < 763 if (ntohl (block->size) <
740 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 764 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
741 + sizeof(struct GNUNET_TIME_AbsoluteNBO)) 765 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
742 { 766 {
743 GNUNET_break_op (0); 767 GNUNET_break_op (0);
744 return GNUNET_SYSERR; 768 return GNUNET_SYSERR;
745 } 769 }
746 derive_block_xsalsa_key (nonce, 770 GNR_derive_block_xsalsa_key (nonce,
747 key, 771 key,
748 label, 772 label,
749 block->expiration_time.abs_value_us__, 773 block->eddsa_block.expiration_time.abs_value_us__,
750 zone_key); 774 zone_key);
751 { 775 {
752 char payload[payload_len]; 776 char payload[payload_len];
753 uint32_t rd_count; 777 unsigned int rd_count;
754 778
755 GNUNET_break (GNUNET_OK == 779 GNUNET_break (GNUNET_OK ==
756 eddsa_symmetric_decrypt (&block[1], payload_len, 780 eddsa_symmetric_decrypt (&block[1], payload_len,
757 key, nonce, 781 key, nonce,
758 payload)); 782 payload));
759 GNUNET_memcpy (&rd_count, 783 payload_len -= crypto_secretbox_MACBYTES;
760 payload, 784 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
761 sizeof(uint32_t)); 785 payload);
762 rd_count = ntohl (rd_count);
763 if (rd_count > 2048) 786 if (rd_count > 2048)
764 { 787 {
765 /* limit to sane value */ 788 /* limit to sane value */
@@ -772,8 +795,8 @@ block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
772 struct GNUNET_TIME_Absolute now; 795 struct GNUNET_TIME_Absolute now;
773 796
774 if (GNUNET_OK != 797 if (GNUNET_OK !=
775 GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t), 798 GNUNET_GNSRECORD_records_deserialize (payload_len,
776 &payload[sizeof(uint32_t)], 799 payload,
777 rd_count, 800 rd_count,
778 rd)) 801 rd))
779 { 802 {
@@ -875,16 +898,18 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
875 norm_label = GNUNET_GNSRECORD_string_normalize (label); 898 norm_label = GNUNET_GNSRECORD_string_normalize (label);
876 switch (ntohl (zone_key->type)) 899 switch (ntohl (zone_key->type))
877 { 900 {
878 case GNUNET_IDENTITY_TYPE_ECDSA: 901 case GNUNET_IDENTITY_TYPE_ECDSA:
879 res = block_decrypt_ecdsa (&block->ecdsa_block, 902 res = block_decrypt_ecdsa (block,
880 &zone_key->ecdsa_key, norm_label, proc, proc_cls); 903 &zone_key->ecdsa_key, norm_label, proc,
881 break; 904 proc_cls);
882 case GNUNET_IDENTITY_TYPE_EDDSA: 905 break;
883 res = block_decrypt_eddsa (&block->eddsa_block, 906 case GNUNET_IDENTITY_TYPE_EDDSA:
884 &zone_key->eddsa_key, norm_label, proc, proc_cls); 907 res = block_decrypt_eddsa (block,
885 break; 908 &zone_key->eddsa_key, norm_label, proc,
886 default: 909 proc_cls);
887 return GNUNET_SYSERR; 910 break;
911 default:
912 return GNUNET_SYSERR;
888 } 913 }
889 GNUNET_free (norm_label); 914 GNUNET_free (norm_label);
890 return res; 915 return res;
@@ -910,17 +935,17 @@ GNUNET_GNSRECORD_query_from_private_key (const struct
910 norm_label = GNUNET_GNSRECORD_string_normalize (label); 935 norm_label = GNUNET_GNSRECORD_string_normalize (label);
911 switch (ntohl (zone->type)) 936 switch (ntohl (zone->type))
912 { 937 {
913 case GNUNET_GNSRECORD_TYPE_PKEY: 938 case GNUNET_GNSRECORD_TYPE_PKEY:
914 case GNUNET_GNSRECORD_TYPE_EDKEY: 939 case GNUNET_GNSRECORD_TYPE_EDKEY:
915 940
916 GNUNET_IDENTITY_key_get_public (zone, 941 GNUNET_IDENTITY_key_get_public (zone,
917 &pub); 942 &pub);
918 GNUNET_GNSRECORD_query_from_public_key (&pub, 943 GNUNET_GNSRECORD_query_from_public_key (&pub,
919 norm_label, 944 norm_label,
920 query); 945 query);
921 break; 946 break;
922 default: 947 default:
923 GNUNET_assert (0); 948 GNUNET_assert (0);
924 } 949 }
925 GNUNET_free (norm_label); 950 GNUNET_free (norm_label);
926} 951}
@@ -947,28 +972,28 @@ GNUNET_GNSRECORD_query_from_public_key (const struct
947 972
948 switch (ntohl (pub->type)) 973 switch (ntohl (pub->type))
949 { 974 {
950 case GNUNET_GNSRECORD_TYPE_PKEY: 975 case GNUNET_GNSRECORD_TYPE_PKEY:
951 pd.type = pub->type; 976 pd.type = pub->type;
952 GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key, 977 GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key,
953 norm_label, 978 norm_label,
954 "gns", 979 "gns",
955 &pd.ecdsa_key); 980 &pd.ecdsa_key);
956 GNUNET_CRYPTO_hash (&pd.ecdsa_key, 981 GNUNET_CRYPTO_hash (&pd.ecdsa_key,
957 sizeof (pd.ecdsa_key), 982 sizeof (pd.ecdsa_key),
958 query); 983 query);
959 break; 984 break;
960 case GNUNET_GNSRECORD_TYPE_EDKEY: 985 case GNUNET_GNSRECORD_TYPE_EDKEY:
961 pd.type = pub->type; 986 pd.type = pub->type;
962 GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key, 987 GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key,
963 norm_label, 988 norm_label,
964 "gns", 989 "gns",
965 &(pd.eddsa_key)); 990 &(pd.eddsa_key));
966 GNUNET_CRYPTO_hash (&pd.eddsa_key, 991 GNUNET_CRYPTO_hash (&pd.eddsa_key,
967 sizeof (pd.eddsa_key), 992 sizeof (pd.eddsa_key),
968 query); 993 query);
969 break; 994 break;
970 default: 995 default:
971 GNUNET_assert (0); 996 GNUNET_assert (0);
972 } 997 }
973 GNUNET_free (norm_label); 998 GNUNET_free (norm_label);
974} 999}