diff options
Diffstat (limited to 'src/gnsrecord/gnsrecord_crypto.c')
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 311 |
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 | ||
183 | static ssize_t | ||
184 | block_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 | */ |
194 | static struct GNUNET_GNSRECORD_Block * | 209 | static enum GNUNET_GenericReturnValue |
195 | block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 210 | block_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 | |||
307 | static ssize_t | ||
308 | block_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 | */ |
309 | static struct GNUNET_GNSRECORD_Block * | 334 | enum GNUNET_GenericReturnValue |
310 | block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | 335 | block_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 | ||
434 | ssize_t | ||
435 | GNUNET_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; |
418 | struct GNUNET_GNSRECORD_Block * | 453 | default: |
454 | GNUNET_assert (0); | ||
455 | } | ||
456 | return -1; | ||
457 | |||
458 | } | ||
459 | |||
460 | enum GNUNET_GenericReturnValue | ||
419 | GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, | 461 | GNUNET_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 | /** | 521 | enum 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 | */ | ||
488 | struct GNUNET_GNSRECORD_Block * | ||
489 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | 522 | GNUNET_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, | |||
550 | enum GNUNET_GenericReturnValue | 586 | enum GNUNET_GenericReturnValue |
551 | GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) | 587 | GNUNET_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 | ||
573 | enum GNUNET_GenericReturnValue | 624 | enum GNUNET_GenericReturnValue |
574 | block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, | 625 | block_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 | ||
701 | enum GNUNET_GenericReturnValue | 749 | enum GNUNET_GenericReturnValue |
702 | block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block, | 750 | block_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; |