diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-20 17:01:48 +0900 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-20 17:01:48 +0900 |
commit | 64aefd7b6fb27b8625af12783201f3c87da41f47 (patch) | |
tree | 77b582d595b498909df446b3dd7ab326053b9a36 /src/gnsrecord | |
parent | 3d7d23db1764973179fe9fc0013b942692c47df5 (diff) | |
download | gnunet-64aefd7b6fb27b8625af12783201f3c87da41f47.tar.gz gnunet-64aefd7b6fb27b8625af12783201f3c87da41f47.zip |
ZONEMASTER: Use parallel worker thread for GNS block signing
Diffstat (limited to 'src/gnsrecord')
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 233 |
1 files changed, 171 insertions, 62 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index 6c1bc6045..d794c9cb4 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -95,7 +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 | ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext | 98 | ((unsigned char*) block) |
99 | + crypto_secretbox_MACBYTES, // Ciphertext | ||
99 | block, // Tag | 100 | block, // Tag |
100 | ctlen, | 101 | ctlen, |
101 | nonce, key)) | 102 | nonce, key)) |
@@ -193,6 +194,116 @@ block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd, | |||
193 | return len; | 194 | return len; |
194 | } | 195 | } |
195 | 196 | ||
197 | enum GNUNET_GenericReturnValue | ||
198 | block_sign_ecdsa (const struct | ||
199 | GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
200 | const struct | ||
201 | GNUNET_CRYPTO_EcdsaPublicKey *pkey, | ||
202 | const char *label, | ||
203 | struct GNUNET_GNSRECORD_Block *block) | ||
204 | { | ||
205 | struct GNRBlockPS *gnr_block; | ||
206 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | ||
207 | size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block); | ||
208 | |||
209 | gnr_block = GNUNET_malloc (size); | ||
210 | ecblock = &(block)->ecdsa_block; | ||
211 | gnr_block->purpose.size = htonl (size); | ||
212 | gnr_block->purpose.purpose = | ||
213 | htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
214 | gnr_block->expiration_time = ecblock->expiration_time; | ||
215 | /* encrypt and sign */ | ||
216 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], | ||
217 | size - sizeof (*gnr_block)); | ||
218 | GNUNET_CRYPTO_ecdsa_public_key_derive (pkey, | ||
219 | label, | ||
220 | "gns", | ||
221 | &ecblock->derived_key); | ||
222 | if (GNUNET_OK != | ||
223 | GNUNET_CRYPTO_ecdsa_sign_derived (key, | ||
224 | label, | ||
225 | "gns", | ||
226 | &gnr_block->purpose, | ||
227 | &ecblock->signature)) | ||
228 | { | ||
229 | GNUNET_break (0); | ||
230 | GNUNET_free (gnr_block); | ||
231 | return GNUNET_SYSERR; | ||
232 | } | ||
233 | GNUNET_free (gnr_block); | ||
234 | return GNUNET_OK; | ||
235 | } | ||
236 | |||
237 | |||
238 | enum GNUNET_GenericReturnValue | ||
239 | block_sign_eddsa (const struct | ||
240 | GNUNET_CRYPTO_EddsaPrivateKey *key, | ||
241 | const struct | ||
242 | GNUNET_CRYPTO_EddsaPublicKey *pkey, | ||
243 | const char *label, | ||
244 | struct GNUNET_GNSRECORD_Block *block) | ||
245 | { | ||
246 | struct GNRBlockPS *gnr_block; | ||
247 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; | ||
248 | size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block); | ||
249 | gnr_block = GNUNET_malloc (size); | ||
250 | edblock = &(block)->eddsa_block; | ||
251 | gnr_block->purpose.size = htonl (size); | ||
252 | gnr_block->purpose.purpose = | ||
253 | htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
254 | gnr_block->expiration_time = edblock->expiration_time; | ||
255 | GNUNET_memcpy (&gnr_block[1], &edblock[1], | ||
256 | size - sizeof (*gnr_block)); | ||
257 | /* encrypt and sign */ | ||
258 | GNUNET_CRYPTO_eddsa_public_key_derive (pkey, | ||
259 | label, | ||
260 | "gns", | ||
261 | &edblock->derived_key); | ||
262 | GNUNET_CRYPTO_eddsa_sign_derived (key, | ||
263 | label, | ||
264 | "gns", | ||
265 | &gnr_block->purpose, | ||
266 | &edblock->signature); | ||
267 | GNUNET_free (gnr_block); | ||
268 | return GNUNET_OK; | ||
269 | } | ||
270 | |||
271 | |||
272 | enum GNUNET_GenericReturnValue | ||
273 | GNUNET_GNSRECORD_block_sign (const struct | ||
274 | GNUNET_IDENTITY_PrivateKey *key, | ||
275 | const char *label, | ||
276 | struct GNUNET_GNSRECORD_Block *block) | ||
277 | { | ||
278 | struct GNUNET_IDENTITY_PublicKey pkey; | ||
279 | enum GNUNET_GenericReturnValue res = GNUNET_SYSERR; | ||
280 | char *norm_label; | ||
281 | |||
282 | GNUNET_IDENTITY_key_get_public (key, | ||
283 | &pkey); | ||
284 | norm_label = GNUNET_GNSRECORD_string_normalize (label); | ||
285 | |||
286 | switch (ntohl (key->type)) | ||
287 | { | ||
288 | case GNUNET_GNSRECORD_TYPE_PKEY: | ||
289 | res = block_sign_ecdsa (&key->ecdsa_key, | ||
290 | &pkey.ecdsa_key, | ||
291 | norm_label, | ||
292 | block); | ||
293 | break; | ||
294 | case GNUNET_GNSRECORD_TYPE_EDKEY: | ||
295 | res = block_sign_eddsa (&key->eddsa_key, | ||
296 | &pkey.eddsa_key, | ||
297 | norm_label, | ||
298 | block); | ||
299 | break; | ||
300 | default: | ||
301 | GNUNET_assert (0); | ||
302 | } | ||
303 | GNUNET_free (norm_label); | ||
304 | return res; | ||
305 | } | ||
306 | |||
196 | 307 | ||
197 | /** | 308 | /** |
198 | * Sign name and records | 309 | * Sign name and records |
@@ -204,6 +315,7 @@ block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd, | |||
204 | * @param rd record data | 315 | * @param rd record data |
205 | * @param rd_count number of records | 316 | * @param rd_count number of records |
206 | * @param block the block result. Must be allocated sufficiently. | 317 | * @param block the block result. Must be allocated sufficiently. |
318 | * @param sign sign the block GNUNET_NO if block will be signed later. | ||
207 | * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) | 319 | * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) |
208 | */ | 320 | */ |
209 | static enum GNUNET_GenericReturnValue | 321 | static enum GNUNET_GenericReturnValue |
@@ -213,12 +325,12 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
213 | const char *label, | 325 | const char *label, |
214 | const struct GNUNET_GNSRECORD_Data *rd, | 326 | const struct GNUNET_GNSRECORD_Data *rd, |
215 | unsigned int rd_count, | 327 | unsigned int rd_count, |
216 | struct GNUNET_GNSRECORD_Block **block) | 328 | struct GNUNET_GNSRECORD_Block **block, |
329 | int sign) | ||
217 | { | 330 | { |
218 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, | 331 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, |
219 | rd); | 332 | rd); |
220 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | 333 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; |
221 | struct GNRBlockPS *gnr_block; | ||
222 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | 334 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
223 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; | 335 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
224 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 336 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
@@ -251,7 +363,7 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
251 | } | 363 | } |
252 | /* serialize */ | 364 | /* serialize */ |
253 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); | 365 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); |
254 | (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); | 366 | (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); |
255 | { | 367 | { |
256 | char payload[payload_len]; | 368 | char payload[payload_len]; |
257 | 369 | ||
@@ -260,19 +372,9 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
260 | rdc, | 372 | rdc, |
261 | payload_len, | 373 | payload_len, |
262 | payload)); | 374 | payload)); |
263 | gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len); | ||
264 | ecblock = &(*block)->ecdsa_block; | 375 | ecblock = &(*block)->ecdsa_block; |
265 | (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | 376 | (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
266 | gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len); | 377 | ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire); |
267 | gnr_block->purpose.purpose = | ||
268 | htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
269 | gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire); | ||
270 | ecblock->expiration_time = gnr_block->expiration_time; | ||
271 | /* encrypt and sign */ | ||
272 | GNUNET_CRYPTO_ecdsa_public_key_derive (pkey, | ||
273 | label, | ||
274 | "gns", | ||
275 | &ecblock->derived_key); | ||
276 | GNR_derive_block_aes_key (ctr, | 378 | GNR_derive_block_aes_key (ctr, |
277 | skey, | 379 | skey, |
278 | label, | 380 | label, |
@@ -284,21 +386,16 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
284 | skey, | 386 | skey, |
285 | ctr, | 387 | ctr, |
286 | &ecblock[1])); | 388 | &ecblock[1])); |
287 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len); | ||
288 | } | 389 | } |
390 | if (GNUNET_YES != sign) | ||
391 | return GNUNET_OK; | ||
289 | if (GNUNET_OK != | 392 | if (GNUNET_OK != |
290 | GNUNET_CRYPTO_ecdsa_sign_derived (key, | 393 | block_sign_ecdsa (key, pkey, label, *block)) |
291 | label, | ||
292 | "gns", | ||
293 | &gnr_block->purpose, | ||
294 | &ecblock->signature)) | ||
295 | { | 394 | { |
296 | GNUNET_break (0); | 395 | GNUNET_break (0); |
297 | GNUNET_free (*block); | 396 | GNUNET_free (*block); |
298 | GNUNET_free (gnr_block); | ||
299 | return GNUNET_SYSERR; | 397 | return GNUNET_SYSERR; |
300 | } | 398 | } |
301 | GNUNET_free (gnr_block); | ||
302 | return GNUNET_OK; | 399 | return GNUNET_OK; |
303 | } | 400 | } |
304 | 401 | ||
@@ -327,6 +424,7 @@ block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd, | |||
327 | * @param rd record data | 424 | * @param rd record data |
328 | * @param rd_count number of records | 425 | * @param rd_count number of records |
329 | * @param block where to store the block. Must be allocated sufficiently. | 426 | * @param block where to store the block. Must be allocated sufficiently. |
427 | * @param sign GNUNET_YES if block shall be signed as well | ||
330 | * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) | 428 | * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) |
331 | */ | 429 | */ |
332 | enum GNUNET_GenericReturnValue | 430 | enum GNUNET_GenericReturnValue |
@@ -336,12 +434,12 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
336 | const char *label, | 434 | const char *label, |
337 | const struct GNUNET_GNSRECORD_Data *rd, | 435 | const struct GNUNET_GNSRECORD_Data *rd, |
338 | unsigned int rd_count, | 436 | unsigned int rd_count, |
339 | struct GNUNET_GNSRECORD_Block **block) | 437 | struct GNUNET_GNSRECORD_Block **block, |
438 | int sign) | ||
340 | { | 439 | { |
341 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, | 440 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, |
342 | rd); | 441 | rd); |
343 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; | 442 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; |
344 | struct GNRBlockPS *gnr_block; | ||
345 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | 443 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; |
346 | unsigned char skey[crypto_secretbox_KEYBYTES]; | 444 | unsigned char skey[crypto_secretbox_KEYBYTES]; |
347 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 445 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
@@ -375,8 +473,8 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
375 | /* serialize */ | 473 | /* serialize */ |
376 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) | 474 | *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) |
377 | + payload_len + crypto_secretbox_MACBYTES); | 475 | + payload_len + crypto_secretbox_MACBYTES); |
378 | (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) | 476 | (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) |
379 | + payload_len + crypto_secretbox_MACBYTES); | 477 | + payload_len + crypto_secretbox_MACBYTES); |
380 | { | 478 | { |
381 | char payload[payload_len]; | 479 | char payload[payload_len]; |
382 | 480 | ||
@@ -385,24 +483,9 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
385 | rdc, | 483 | rdc, |
386 | payload_len, | 484 | payload_len, |
387 | payload)); | 485 | payload)); |
388 | gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) | ||
389 | + payload_len | ||
390 | + crypto_secretbox_MACBYTES); | ||
391 | edblock = &(*block)->eddsa_block; | 486 | edblock = &(*block)->eddsa_block; |
392 | (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); | 487 | (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); |
393 | gnr_block->purpose.size = | 488 | edblock->expiration_time = GNUNET_TIME_absolute_hton (expire); |
394 | htonl (sizeof(struct GNRBlockPS) | ||
395 | + payload_len | ||
396 | + crypto_secretbox_MACBYTES); | ||
397 | gnr_block->purpose.purpose = | ||
398 | htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
399 | gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire); | ||
400 | edblock->expiration_time = gnr_block->expiration_time; | ||
401 | /* encrypt and sign */ | ||
402 | GNUNET_CRYPTO_eddsa_public_key_derive (pkey, | ||
403 | label, | ||
404 | "gns", | ||
405 | &edblock->derived_key); | ||
406 | GNR_derive_block_xsalsa_key (nonce, | 489 | GNR_derive_block_xsalsa_key (nonce, |
407 | skey, | 490 | skey, |
408 | label, | 491 | label, |
@@ -414,14 +497,9 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
414 | skey, | 497 | skey, |
415 | nonce, | 498 | nonce, |
416 | &edblock[1])); | 499 | &edblock[1])); |
417 | GNUNET_memcpy (&gnr_block[1], &edblock[1], | 500 | if (GNUNET_YES != sign) |
418 | payload_len + crypto_secretbox_MACBYTES); | 501 | return GNUNET_OK; |
419 | 502 | block_sign_eddsa (key, pkey, label, *block); | |
420 | GNUNET_CRYPTO_eddsa_sign_derived (key, | ||
421 | label, | ||
422 | "gns", | ||
423 | &gnr_block->purpose, | ||
424 | &edblock->signature); | ||
425 | } | 503 | } |
426 | return GNUNET_OK; | 504 | return GNUNET_OK; |
427 | } | 505 | } |
@@ -477,7 +555,8 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
477 | norm_label, | 555 | norm_label, |
478 | rd, | 556 | rd, |
479 | rd_count, | 557 | rd_count, |
480 | result); | 558 | result, |
559 | GNUNET_YES); | ||
481 | break; | 560 | break; |
482 | case GNUNET_GNSRECORD_TYPE_EDKEY: | 561 | case GNUNET_GNSRECORD_TYPE_EDKEY: |
483 | res = block_create_eddsa (&key->eddsa_key, | 562 | res = block_create_eddsa (&key->eddsa_key, |
@@ -486,7 +565,8 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
486 | norm_label, | 565 | norm_label, |
487 | rd, | 566 | rd, |
488 | rd_count, | 567 | rd_count, |
489 | result); | 568 | result, |
569 | GNUNET_YES); | ||
490 | break; | 570 | break; |
491 | default: | 571 | default: |
492 | GNUNET_assert (0); | 572 | GNUNET_assert (0); |
@@ -513,13 +593,14 @@ struct KeyCacheLine | |||
513 | }; | 593 | }; |
514 | 594 | ||
515 | 595 | ||
516 | enum GNUNET_GenericReturnValue | 596 | static enum GNUNET_GenericReturnValue |
517 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | 597 | block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, |
518 | struct GNUNET_TIME_Absolute expire, | 598 | struct GNUNET_TIME_Absolute expire, |
519 | const char *label, | 599 | const char *label, |
520 | const struct GNUNET_GNSRECORD_Data *rd, | 600 | const struct GNUNET_GNSRECORD_Data *rd, |
521 | unsigned int rd_count, | 601 | unsigned int rd_count, |
522 | struct GNUNET_GNSRECORD_Block **result) | 602 | struct GNUNET_GNSRECORD_Block **result, |
603 | int sign) | ||
523 | { | 604 | { |
524 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; | 605 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; |
525 | struct GNUNET_CRYPTO_EddsaPublicKey edpubkey; | 606 | struct GNUNET_CRYPTO_EddsaPublicKey edpubkey; |
@@ -552,7 +633,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | |||
552 | norm_label, | 633 | norm_label, |
553 | rd, | 634 | rd, |
554 | rd_count, | 635 | rd_count, |
555 | result); | 636 | result, |
637 | sign); | ||
556 | } | 638 | } |
557 | else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type)) | 639 | else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type)) |
558 | { | 640 | { |
@@ -564,13 +646,40 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | |||
564 | norm_label, | 646 | norm_label, |
565 | rd, | 647 | rd, |
566 | rd_count, | 648 | rd_count, |
567 | result); | 649 | result, |
650 | sign); | ||
568 | } | 651 | } |
569 | GNUNET_free (norm_label); | 652 | GNUNET_free (norm_label); |
570 | return res; | 653 | return res; |
571 | } | 654 | } |
572 | 655 | ||
573 | 656 | ||
657 | |||
658 | enum GNUNET_GenericReturnValue | ||
659 | GNUNET_GNSRECORD_block_create_unsigned (const struct | ||
660 | GNUNET_IDENTITY_PrivateKey *pkey, | ||
661 | struct GNUNET_TIME_Absolute expire, | ||
662 | const char *label, | ||
663 | const struct GNUNET_GNSRECORD_Data *rd, | ||
664 | unsigned int rd_count, | ||
665 | struct GNUNET_GNSRECORD_Block **result) | ||
666 | { | ||
667 | return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_NO); | ||
668 | } | ||
669 | |||
670 | |||
671 | |||
672 | enum GNUNET_GenericReturnValue | ||
673 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
674 | struct GNUNET_TIME_Absolute expire, | ||
675 | const char *label, | ||
676 | const struct GNUNET_GNSRECORD_Data *rd, | ||
677 | unsigned int rd_count, | ||
678 | struct GNUNET_GNSRECORD_Block **result) | ||
679 | { | ||
680 | return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_YES); | ||
681 | } | ||
682 | |||
574 | /** | 683 | /** |
575 | * Check if a signature is valid. This API is used by the GNS Block | 684 | * Check if a signature is valid. This API is used by the GNS Block |
576 | * to validate signatures received from the network. | 685 | * to validate signatures received from the network. |