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.c311
1 files changed, 179 insertions, 132 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index 24f4c48ca..890ddb011 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -95,8 +95,8 @@ eddsa_symmetric_decrypt (
95 if (ctlen < 0) 95 if (ctlen < 0)
96 return GNUNET_SYSERR; 96 return GNUNET_SYSERR;
97 if (0 != crypto_secretbox_open_detached (result, 97 if (0 != crypto_secretbox_open_detached (result,
98 block, // Ciphertext 98 ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext
99 ((unsigned char*) block) + ctlen, // TAG 99 block, // Tag
100 ctlen, 100 ctlen,
101 nonce, key)) 101 nonce, key))
102 { 102 {
@@ -116,8 +116,8 @@ eddsa_symmetric_encrypt (
116{ 116{
117 if (size > crypto_secretbox_MESSAGEBYTES_MAX) 117 if (size > crypto_secretbox_MESSAGEBYTES_MAX)
118 return GNUNET_SYSERR; 118 return GNUNET_SYSERR;
119 crypto_secretbox_detached (result, // Ciphertext 119 crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext
120 result + size, // TAG 120 result, // TAG
121 block, size, nonce, key); 121 block, size, nonce, key);
122 return GNUNET_OK; 122 return GNUNET_OK;
123} 123}
@@ -180,6 +180,20 @@ GNR_derive_block_xsalsa_key (unsigned char *nonce,
180} 180}
181 181
182 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
183/** 197/**
184 * Sign name and records 198 * Sign name and records
185 * 199 *
@@ -189,20 +203,22 @@ GNR_derive_block_xsalsa_key (unsigned char *nonce,
189 * @param label the name for the records 203 * @param label the name for the records
190 * @param rd record data 204 * @param rd record data
191 * @param rd_count number of records 205 * @param rd_count number of records
192 * @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)
193 */ 208 */
194static struct GNUNET_GNSRECORD_Block * 209static enum GNUNET_GenericReturnValue
195block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, 210block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
196 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, 211 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
197 struct GNUNET_TIME_Absolute expire, 212 struct GNUNET_TIME_Absolute expire,
198 const char *label, 213 const char *label,
199 const struct GNUNET_GNSRECORD_Data *rd, 214 const struct GNUNET_GNSRECORD_Data *rd,
200 unsigned int rd_count) 215 unsigned int rd_count,
216 struct GNUNET_GNSRECORD_Block **block)
201{ 217{
202 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 218 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
203 rd); 219 rd);
204 struct GNUNET_GNSRECORD_Block *block;
205 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; 220 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
221 struct GNRBlockPS *gnr_block;
206 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; 222 struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
207 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; 223 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
208 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; 224 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
@@ -213,12 +229,12 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
213 if (payload_len < 0) 229 if (payload_len < 0)
214 { 230 {
215 GNUNET_break (0); 231 GNUNET_break (0);
216 return NULL; 232 return GNUNET_SYSERR;
217 } 233 }
218 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) 234 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
219 { 235 {
220 GNUNET_break (0); 236 GNUNET_break (0);
221 return NULL; 237 return GNUNET_SYSERR;
222 } 238 }
223 /* convert relative to absolute times */ 239 /* convert relative to absolute times */
224 now = GNUNET_TIME_absolute_get (); 240 now = GNUNET_TIME_absolute_get ();
@@ -236,31 +252,25 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
236 } 252 }
237 } 253 }
238 /* 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);
239 rd_count_nbo = htonl (rd_count); 257 rd_count_nbo = htonl (rd_count);
240 { 258 {
241 char payload[sizeof(uint32_t) + payload_len]; 259 char payload[payload_len];
242 260
243 GNUNET_memcpy (payload,
244 &rd_count_nbo,
245 sizeof(uint32_t));
246 GNUNET_assert (payload_len == 261 GNUNET_assert (payload_len ==
247 GNUNET_GNSRECORD_records_serialize (rd_count, 262 GNUNET_GNSRECORD_records_serialize (rd_count,
248 rdc, 263 rdc,
249 payload_len, 264 payload_len,
250 &payload[sizeof(uint32_t) 265 payload));
251 ])); 266 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
252 block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) 267 ecblock = &(*block)->ecdsa_block;
253 + sizeof(uint32_t) 268 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
254 + payload_len); 269 gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len);
255 ecblock = &block->ecdsa_block; 270 gnr_block->purpose.purpose =
256 block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); 271 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
257 ecblock->purpose.size = htonl (sizeof(uint32_t) 272 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
258 + payload_len 273 ecblock->expiration_time = gnr_block->expiration_time;
259 + sizeof(struct
260 GNUNET_CRYPTO_EccSignaturePurpose)
261 + sizeof(struct GNUNET_TIME_AbsoluteNBO));
262 ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
263 ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
264 /* encrypt and sign */ 274 /* encrypt and sign */
265 dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, 275 dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key,
266 label, 276 label,
@@ -272,26 +282,40 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
272 label, 282 label,
273 ecblock->expiration_time.abs_value_us__, 283 ecblock->expiration_time.abs_value_us__,
274 pkey); 284 pkey);
275 GNUNET_break (payload_len + sizeof(uint32_t) == 285 GNUNET_break (payload_len ==
276 ecdsa_symmetric_encrypt (payload, 286 ecdsa_symmetric_encrypt (payload,
277 payload_len 287 payload_len,
278 + sizeof(uint32_t),
279 skey, 288 skey,
280 ctr, 289 ctr,
281 &ecblock[1])); 290 &ecblock[1]));
291 GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
282 } 292 }
283 if (GNUNET_OK != 293 if (GNUNET_OK !=
284 GNUNET_CRYPTO_ecdsa_sign_ (dkey, 294 GNUNET_CRYPTO_ecdsa_sign_ (dkey,
285 &ecblock->purpose, 295 &gnr_block->purpose,
286 &ecblock->signature)) 296 &ecblock->signature))
287 { 297 {
288 GNUNET_break (0); 298 GNUNET_break (0);
299 GNUNET_free (*block);
289 GNUNET_free (dkey); 300 GNUNET_free (dkey);
290 GNUNET_free (block); 301 return GNUNET_SYSERR;
291 return NULL;
292 } 302 }
293 GNUNET_free (dkey); 303 GNUNET_free (dkey);
294 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;
295} 319}
296 320
297 321
@@ -304,20 +328,22 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
304 * @param label the name for the records 328 * @param label the name for the records
305 * @param rd record data 329 * @param rd record data
306 * @param rd_count number of records 330 * @param rd_count number of records
307 * @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)
308 */ 333 */
309static struct GNUNET_GNSRECORD_Block * 334enum GNUNET_GenericReturnValue
310block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, 335block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
311 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey, 336 const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
312 struct GNUNET_TIME_Absolute expire, 337 struct GNUNET_TIME_Absolute expire,
313 const char *label, 338 const char *label,
314 const struct GNUNET_GNSRECORD_Data *rd, 339 const struct GNUNET_GNSRECORD_Data *rd,
315 unsigned int rd_count) 340 unsigned int rd_count,
341 struct GNUNET_GNSRECORD_Block **block)
316{ 342{
317 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 343 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
318 rd); 344 rd);
319 struct GNUNET_GNSRECORD_Block *block;
320 struct GNUNET_GNSRECORD_EddsaBlock *edblock; 345 struct GNUNET_GNSRECORD_EddsaBlock *edblock;
346 struct GNRBlockPS *gnr_block;
321 struct GNUNET_CRYPTO_EddsaPrivateScalar dkey; 347 struct GNUNET_CRYPTO_EddsaPrivateScalar dkey;
322 unsigned char nonce[crypto_secretbox_NONCEBYTES]; 348 unsigned char nonce[crypto_secretbox_NONCEBYTES];
323 unsigned char skey[crypto_secretbox_KEYBYTES]; 349 unsigned char skey[crypto_secretbox_KEYBYTES];
@@ -328,12 +354,12 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
328 if (payload_len < 0) 354 if (payload_len < 0)
329 { 355 {
330 GNUNET_break (0); 356 GNUNET_break (0);
331 return NULL; 357 return GNUNET_SYSERR;
332 } 358 }
333 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) 359 if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
334 { 360 {
335 GNUNET_break (0); 361 GNUNET_break (0);
336 return NULL; 362 return GNUNET_SYSERR;
337 } 363 }
338 /* convert relative to absolute times */ 364 /* convert relative to absolute times */
339 now = GNUNET_TIME_absolute_get (); 365 now = GNUNET_TIME_absolute_get ();
@@ -351,33 +377,32 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
351 } 377 }
352 } 378 }
353 /* 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);
354 rd_count_nbo = htonl (rd_count); 384 rd_count_nbo = htonl (rd_count);
355 { 385 {
356 char payload[sizeof(uint32_t) + payload_len]; 386 char payload[payload_len];
357 387
358 GNUNET_memcpy (payload,
359 &rd_count_nbo,
360 sizeof(uint32_t));
361 GNUNET_assert (payload_len == 388 GNUNET_assert (payload_len ==
362 GNUNET_GNSRECORD_records_serialize (rd_count, 389 GNUNET_GNSRECORD_records_serialize (rd_count,
363 rdc, 390 rdc,
364 payload_len, 391 payload_len,
365 &payload[sizeof(uint32_t) 392 payload));
366 ])); 393 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
367 block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) 394 + payload_len
368 + sizeof(uint32_t) 395 + crypto_secretbox_MACBYTES);
369 + payload_len 396 edblock = &(*block)->eddsa_block;
370 + crypto_secretbox_MACBYTES); 397 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
371 edblock = &block->eddsa_block; 398 gnr_block->purpose.size =
372 block->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); 399 htonl (sizeof(struct GNRBlockPS)
373 edblock->purpose.size = htonl (sizeof(uint32_t) 400 + payload_len
374 + payload_len 401 + crypto_secretbox_MACBYTES);
375 + sizeof(struct 402 gnr_block->purpose.purpose =
376 GNUNET_CRYPTO_EccSignaturePurpose) 403 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
377 + sizeof(struct GNUNET_TIME_AbsoluteNBO) 404 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
378 + crypto_secretbox_MACBYTES); 405 edblock->expiration_time = gnr_block->expiration_time;
379 edblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
380 edblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
381 /* encrypt and sign */ 406 /* encrypt and sign */
382 GNUNET_CRYPTO_eddsa_private_key_derive (key, 407 GNUNET_CRYPTO_eddsa_private_key_derive (key,
383 label, 408 label,
@@ -392,38 +417,56 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
392 pkey); 417 pkey);
393 GNUNET_break (GNUNET_OK == 418 GNUNET_break (GNUNET_OK ==
394 eddsa_symmetric_encrypt (payload, 419 eddsa_symmetric_encrypt (payload,
395 payload_len 420 payload_len,
396 + sizeof(uint32_t),
397 skey, 421 skey,
398 nonce, 422 nonce,
399 &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);
400 } 430 }
401 GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey, 431 return GNUNET_OK;
402 &edblock->purpose,
403 &edblock->signature);
404 return block;
405} 432}
406 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;
407 442
408/** 443 GNUNET_IDENTITY_key_get_public (key,
409 * Sign name and records 444 &pkey);
410 * 445 switch (ntohl (key->type))
411 * @param key the private key 446 {
412 * @param expire block expiration 447 case GNUNET_GNSRECORD_TYPE_PKEY:
413 * @param label the name for the records 448 res = block_get_size_ecdsa (rd, rd_count);
414 * @param rd record data 449 break;
415 * @param rd_count number of records 450 case GNUNET_GNSRECORD_TYPE_EDKEY:
416 * @return NULL on error (block too large) 451 res = block_get_size_eddsa (rd, rd_count);
417 */ 452 break;
418struct GNUNET_GNSRECORD_Block * 453 default:
454 GNUNET_assert (0);
455 }
456 return -1;
457
458}
459
460enum GNUNET_GenericReturnValue
419GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, 461GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
420 struct GNUNET_TIME_Absolute expire, 462 struct GNUNET_TIME_Absolute expire,
421 const char *label, 463 const char *label,
422 const struct GNUNET_GNSRECORD_Data *rd, 464 const struct GNUNET_GNSRECORD_Data *rd,
423 unsigned int rd_count) 465 unsigned int rd_count,
466 struct GNUNET_GNSRECORD_Block **result)
424{ 467{
425 struct GNUNET_IDENTITY_PublicKey pkey; 468 struct GNUNET_IDENTITY_PublicKey pkey;
426 struct GNUNET_GNSRECORD_Block *res = NULL; 469 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
427 char *norm_label; 470 char *norm_label;
428 471
429 GNUNET_IDENTITY_key_get_public (key, 472 GNUNET_IDENTITY_key_get_public (key,
@@ -438,7 +481,8 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
438 expire, 481 expire,
439 norm_label, 482 norm_label,
440 rd, 483 rd,
441 rd_count); 484 rd_count,
485 result);
442 break; 486 break;
443 case GNUNET_GNSRECORD_TYPE_EDKEY: 487 case GNUNET_GNSRECORD_TYPE_EDKEY:
444 res = block_create_eddsa (&key->eddsa_key, 488 res = block_create_eddsa (&key->eddsa_key,
@@ -446,7 +490,8 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
446 expire, 490 expire,
447 norm_label, 491 norm_label,
448 rd, 492 rd,
449 rd_count); 493 rd_count,
494 result);
450 break; 495 break;
451 default: 496 default:
452 GNUNET_assert (0); 497 GNUNET_assert (0);
@@ -473,28 +518,17 @@ struct KeyCacheLine
473}; 518};
474 519
475 520
476/** 521enum GNUNET_GenericReturnValue
477 * Sign name and records, cache derived public key (also keeps the
478 * private key in static memory, so do not use this function if
479 * keeping the private key in the process'es RAM is a major issue).
480 *
481 * @param key the private key
482 * @param expire block expiration
483 * @param label the name for the records
484 * @param rd record data
485 * @param rd_count number of records
486 * @return NULL on error (block too large)
487 */
488struct GNUNET_GNSRECORD_Block *
489GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, 522GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
490 struct GNUNET_TIME_Absolute expire, 523 struct GNUNET_TIME_Absolute expire,
491 const char *label, 524 const char *label,
492 const struct GNUNET_GNSRECORD_Data *rd, 525 const struct GNUNET_GNSRECORD_Data *rd,
493 unsigned int rd_count) 526 unsigned int rd_count,
527 struct GNUNET_GNSRECORD_Block **result)
494{ 528{
495 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; 529 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
496 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey; 530 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
497 struct GNUNET_GNSRECORD_Block *res = NULL; 531 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
498 char *norm_label; 532 char *norm_label;
499 533
500 norm_label = GNUNET_GNSRECORD_string_normalize (label); 534 norm_label = GNUNET_GNSRECORD_string_normalize (label);
@@ -522,7 +556,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
522 expire, 556 expire,
523 norm_label, 557 norm_label,
524 rd, 558 rd,
525 rd_count); 559 rd_count,
560 result);
526 } 561 }
527 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type)) 562 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
528 { 563 {
@@ -533,7 +568,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
533 expire, 568 expire,
534 norm_label, 569 norm_label,
535 rd, 570 rd,
536 rd_count); 571 rd_count,
572 result);
537 } 573 }
538 GNUNET_free (norm_label); 574 GNUNET_free (norm_label);
539 return res; 575 return res;
@@ -550,41 +586,55 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
550enum GNUNET_GenericReturnValue 586enum GNUNET_GenericReturnValue
551GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) 587GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
552{ 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
553 switch (ntohl (block->type)) 598 switch (ntohl (block->type))
554 { 599 {
555 case GNUNET_GNSRECORD_TYPE_PKEY: 600 case GNUNET_GNSRECORD_TYPE_PKEY:
556 return GNUNET_CRYPTO_ecdsa_verify_ ( 601 purp->expiration_time = block->ecdsa_block.expiration_time;
602 res = GNUNET_CRYPTO_ecdsa_verify_ (
557 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, 603 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
558 &block->ecdsa_block.purpose, 604 &purp->purpose,
559 &block->ecdsa_block.signature, 605 &block->ecdsa_block.signature,
560 &block->ecdsa_block.derived_key); 606 &block->ecdsa_block.derived_key);
607 break;
561 case GNUNET_GNSRECORD_TYPE_EDKEY: 608 case GNUNET_GNSRECORD_TYPE_EDKEY:
562 return GNUNET_CRYPTO_eddsa_verify_ ( 609 purp->expiration_time = block->eddsa_block.expiration_time;
610 res = GNUNET_CRYPTO_eddsa_verify_ (
563 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, 611 GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
564 &block->eddsa_block.purpose, 612 &purp->purpose,
565 &block->eddsa_block.signature, 613 &block->eddsa_block.signature,
566 &block->eddsa_block.derived_key); 614 &block->eddsa_block.derived_key);
615 break;
567 default: 616 default:
568 return GNUNET_NO; 617 res = GNUNET_NO;
569 } 618 }
619 GNUNET_free (purp);
620 return res;
570} 621}
571 622
572 623
573enum GNUNET_GenericReturnValue 624enum GNUNET_GenericReturnValue
574block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, 625block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
575 const struct 626 const struct
576 GNUNET_CRYPTO_EcdsaPublicKey *zone_key, 627 GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
577 const char *label, 628 const char *label,
578 GNUNET_GNSRECORD_RecordCallback proc, 629 GNUNET_GNSRECORD_RecordCallback proc,
579 void *proc_cls) 630 void *proc_cls)
580{ 631{
581 size_t payload_len = ntohl (block->purpose.size) 632 size_t payload_len = ntohl (block->size) - sizeof (struct
582 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 633 GNUNET_GNSRECORD_Block);
583 - sizeof(struct GNUNET_TIME_AbsoluteNBO);
584 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; 634 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
585 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH]; 635 unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
586 636
587 if (ntohl (block->purpose.size) < 637 if (ntohl (block->size) <
588 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 638 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
589 + sizeof(struct GNUNET_TIME_AbsoluteNBO)) 639 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
590 { 640 {
@@ -594,20 +644,18 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
594 GNR_derive_block_aes_key (ctr, 644 GNR_derive_block_aes_key (ctr,
595 key, 645 key,
596 label, 646 label,
597 block->expiration_time.abs_value_us__, 647 block->ecdsa_block.expiration_time.abs_value_us__,
598 zone_key); 648 zone_key);
599 { 649 {
600 char payload[payload_len]; 650 char payload[payload_len];
601 uint32_t rd_count; 651 unsigned int rd_count;
602 652
603 GNUNET_break (payload_len == 653 GNUNET_break (payload_len ==
604 ecdsa_symmetric_decrypt (&block[1], payload_len, 654 ecdsa_symmetric_decrypt (&block[1], payload_len,
605 key, ctr, 655 key, ctr,
606 payload)); 656 payload));
607 GNUNET_memcpy (&rd_count, 657 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
608 payload, 658 payload);
609 sizeof(uint32_t));
610 rd_count = ntohl (rd_count);
611 if (rd_count > 2048) 659 if (rd_count > 2048)
612 { 660 {
613 /* limit to sane value */ 661 /* limit to sane value */
@@ -620,8 +668,8 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
620 struct GNUNET_TIME_Absolute now; 668 struct GNUNET_TIME_Absolute now;
621 669
622 if (GNUNET_OK != 670 if (GNUNET_OK !=
623 GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t), 671 GNUNET_GNSRECORD_records_deserialize (payload_len,
624 &payload[sizeof(uint32_t)], 672 payload,
625 rd_count, 673 rd_count,
626 rd)) 674 rd))
627 { 675 {
@@ -699,20 +747,20 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
699 747
700 748
701enum GNUNET_GenericReturnValue 749enum GNUNET_GenericReturnValue
702block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block, 750block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
703 const struct 751 const struct
704 GNUNET_CRYPTO_EddsaPublicKey *zone_key, 752 GNUNET_CRYPTO_EddsaPublicKey *zone_key,
705 const char *label, 753 const char *label,
706 GNUNET_GNSRECORD_RecordCallback proc, 754 GNUNET_GNSRECORD_RecordCallback proc,
707 void *proc_cls) 755 void *proc_cls)
708{ 756{
709 size_t payload_len = ntohl (block->purpose.size) 757 const struct GNUNET_GNSRECORD_EddsaBlock *edblock = &block->eddsa_block;
710 - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 758 size_t payload_len = ntohl (block->size) - sizeof (struct
711 - sizeof(struct GNUNET_TIME_AbsoluteNBO); 759 GNUNET_GNSRECORD_Block);
712 unsigned char nonce[crypto_secretbox_NONCEBYTES]; 760 unsigned char nonce[crypto_secretbox_NONCEBYTES];
713 unsigned char key[crypto_secretbox_KEYBYTES]; 761 unsigned char key[crypto_secretbox_KEYBYTES];
714 762
715 if (ntohl (block->purpose.size) < 763 if (ntohl (block->size) <
716 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 764 sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
717 + sizeof(struct GNUNET_TIME_AbsoluteNBO)) 765 + sizeof(struct GNUNET_TIME_AbsoluteNBO))
718 { 766 {
@@ -722,20 +770,19 @@ block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
722 GNR_derive_block_xsalsa_key (nonce, 770 GNR_derive_block_xsalsa_key (nonce,
723 key, 771 key,
724 label, 772 label,
725 block->expiration_time.abs_value_us__, 773 block->eddsa_block.expiration_time.abs_value_us__,
726 zone_key); 774 zone_key);
727 { 775 {
728 char payload[payload_len]; 776 char payload[payload_len];
729 uint32_t rd_count; 777 unsigned int rd_count;
730 778
731 GNUNET_break (GNUNET_OK == 779 GNUNET_break (GNUNET_OK ==
732 eddsa_symmetric_decrypt (&block[1], payload_len, 780 eddsa_symmetric_decrypt (&block[1], payload_len,
733 key, nonce, 781 key, nonce,
734 payload)); 782 payload));
735 GNUNET_memcpy (&rd_count, 783 payload_len -= crypto_secretbox_MACBYTES;
736 payload, 784 rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
737 sizeof(uint32_t)); 785 payload);
738 rd_count = ntohl (rd_count);
739 if (rd_count > 2048) 786 if (rd_count > 2048)
740 { 787 {
741 /* limit to sane value */ 788 /* limit to sane value */
@@ -748,8 +795,8 @@ block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
748 struct GNUNET_TIME_Absolute now; 795 struct GNUNET_TIME_Absolute now;
749 796
750 if (GNUNET_OK != 797 if (GNUNET_OK !=
751 GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t), 798 GNUNET_GNSRECORD_records_deserialize (payload_len,
752 &payload[sizeof(uint32_t)], 799 payload,
753 rd_count, 800 rd_count,
754 rd)) 801 rd))
755 { 802 {
@@ -852,12 +899,12 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
852 switch (ntohl (zone_key->type)) 899 switch (ntohl (zone_key->type))
853 { 900 {
854 case GNUNET_IDENTITY_TYPE_ECDSA: 901 case GNUNET_IDENTITY_TYPE_ECDSA:
855 res = block_decrypt_ecdsa (&block->ecdsa_block, 902 res = block_decrypt_ecdsa (block,
856 &zone_key->ecdsa_key, norm_label, proc, 903 &zone_key->ecdsa_key, norm_label, proc,
857 proc_cls); 904 proc_cls);
858 break; 905 break;
859 case GNUNET_IDENTITY_TYPE_EDDSA: 906 case GNUNET_IDENTITY_TYPE_EDDSA:
860 res = block_decrypt_eddsa (&block->eddsa_block, 907 res = block_decrypt_eddsa (block,
861 &zone_key->eddsa_key, norm_label, proc, 908 &zone_key->eddsa_key, norm_label, proc,
862 proc_cls); 909 proc_cls);
863 break; 910 break;