gnunet_gnsrecord_lib.h (28820B)
1 /* 2 This file is part of GNUnet 3 Copyright (C) 2012, 2013 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 21 /** 22 * @addtogroup GNS 23 * @{ 24 * 25 * @author Christian Grothoff 26 * 27 * @file 28 * API that can be used to manipulate GNS record data 29 * 30 * @defgroup gnsrecord GNS Record library 31 * Manipulate GNS record data 32 * 33 * @see [Documentation](https://gnunet.org/gns-plugins) 34 * 35 * @{ 36 */ 37 #ifndef GNUNET_GNSRECORD_LIB_H 38 #define GNUNET_GNSRECORD_LIB_H 39 40 41 #include "gnunet_common.h" 42 #include "gnunet_identity_service.h" 43 44 #ifdef __cplusplus 45 extern "C" { 46 #if 0 /* keep Emacsens' auto-indent happy */ 47 } 48 #endif 49 #endif 50 51 /** 52 * String we use to indicate an empty label (top-level 53 * entry in the zone). DNS uses "@", so do we. 54 */ 55 #define GNUNET_GNS_EMPTY_LABEL_AT "@" 56 57 /** 58 * Maximum size of a value that can be stored in a GNS block. 59 */ 60 #define GNUNET_GNSRECORD_MAX_BLOCK_SIZE (63 * 1024) 61 62 63 /** 64 * Record type indicating any record/'*' 65 */ 66 #define GNUNET_GNSRECORD_TYPE_ANY 0 67 68 /** 69 * Include the record types generated from GANA 70 */ 71 #include "gnu_name_system_record_types.h" 72 73 /** 74 * When comparing flags for record equality for removal, 75 * which flags should must match (in addition to the type, 76 * name, expiration value and data of the record)? All flags 77 * that are not listed here will be ignored for this purpose. 78 * (for example, we don't expect that users will remember to 79 * pass the '--private' option when removing a record from 80 * the namestore, hence we don't require this particular option 81 * to match upon removal). See also 82 * #GNUNET_GNSRECORD_records_cmp. 83 */ 84 #define GNUNET_GNSRECORD_RF_RCMP_FLAGS (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION) 85 86 87 /** 88 * Flags that can be set for a record. 89 * The numbers in the registry correspond to the bit index as specified in 90 * LSD0001 Chapter "Resource Records". 91 * Each enum member represents the 16-bit integer value of the flags field if 92 * only that particular flag was set. 93 * The value can be used to efficiently compare the bitmask setting for the 94 * record flag in C. 95 * WARNING: The values are in host byte order! In order to correctly check 96 * against the flags field a record, the respective fields must 97 * also be converted to HBO (or the enum value to NBO). 98 */ 99 enum GNUNET_GNSRECORD_Flags 100 { 101 /** 102 * Entry for no flags / cleared flags. 103 */ 104 GNUNET_GNSRECORD_RF_NONE = 0, 105 106 107 /** 108 * This record is critical. If it cannot be processed (for example because the record type is unknown) resolution MUST fail 109 */ 110 GNUNET_GNSRECORD_RF_CRITICAL = 1 << (15 - 15), 111 112 113 /** 114 * This record should not be used unless all (other) records in the set with an absolute expiration time have expired. 115 */ 116 GNUNET_GNSRECORD_RF_SHADOW = 1 << (15 - 14), 117 118 119 /** 120 * This is a supplemental record. 121 */ 122 GNUNET_GNSRECORD_RF_SUPPLEMENTAL = 1 << (15 - 13), 123 124 /** 125 * Maintenance records. E.g. TOMBSTONEs 126 */ 127 GNUNET_GNSRECORD_RF_MAINTENANCE = 1 << (15 - 2), 128 129 /** 130 * This expiration time of the record is a relative time (not an absolute time). Used in GNUnet implementation. 131 */ 132 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 1 << (15 - 1), 133 134 135 /** 136 * This is a private record of this peer and it should thus not be published. 137 */ 138 GNUNET_GNSRECORD_RF_PRIVATE = 1 << (15 - 0), 139 140 }; 141 142 143 /** 144 * Filter for GNUNET_GNSRECORD_normalize_record_set(). 145 */ 146 enum GNUNET_GNSRECORD_Filter 147 { 148 /** 149 * No filter flags set. 150 * Private and public records are returned, 151 * maintenance records (TOMBSTONE etc) are not. 152 */ 153 GNUNET_GNSRECORD_FILTER_NONE = 0, 154 155 /** 156 * Include maintenance records (TOMBSTONE etc). 157 */ 158 GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE = 1, 159 160 /** 161 * Filter private records 162 */ 163 GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE = 2, 164 165 /** 166 * Filter public records. 167 * FIXME: Not implemented 168 */ 169 // GNUNET_NAMESTORE_FILTER_OMIT_PUBLIC = 4, 170 }; 171 172 173 /** 174 * A GNS record. 175 */ 176 struct GNUNET_GNSRECORD_Data 177 { 178 /** 179 * Binary value stored in the DNS record. Note: "data" must never 180 * be individually 'malloc'ed, but instead always points into some 181 * existing data area. 182 */ 183 const void *data; 184 185 /** 186 * Expiration time for the DNS record. Can be relative 187 * or absolute, depending on @e flags. Measured in the same 188 * unit as GNUnet time (microseconds). 189 */ 190 uint64_t expiration_time; 191 192 /** 193 * Number of bytes in @e data. 194 */ 195 size_t data_size; 196 197 /** 198 * Type of the GNS/DNS record. 199 */ 200 uint32_t record_type; 201 202 /** 203 * Flags for the record. 204 */ 205 enum GNUNET_GNSRECORD_Flags flags; 206 }; 207 208 209 GNUNET_NETWORK_STRUCT_BEGIN 210 211 /** 212 * Data stored in a PLACE record. 213 */ 214 struct GNUNET_GNSRECORD_PlaceData 215 { 216 /** 217 * Public key of the place. 218 */ 219 struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key; 220 221 /** 222 * Peer identity of the origin. 223 */ 224 struct GNUNET_PeerIdentity origin; 225 226 /** 227 * Number of relays that follow. 228 */ 229 uint32_t relay_count GNUNET_PACKED; 230 231 /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */ 232 }; 233 234 /** 235 * Information we have in an encrypted block with record data (i.e. in the DHT). 236 */ 237 struct GNUNET_GNSRECORD_EcdsaBlock 238 { 239 /** 240 * Derived key used for signing; hash of this is the query. 241 */ 242 struct GNUNET_CRYPTO_EcdsaPublicKey derived_key; 243 244 /** 245 * Signature of the block. 246 */ 247 struct GNUNET_CRYPTO_EcdsaSignature signature; 248 249 /** 250 * Expiration time of the block. 251 */ 252 struct GNUNET_TIME_AbsoluteNBO expiration_time; 253 254 /* followed by encrypted data */ 255 }; 256 257 258 /** 259 * Information we have in an encrypted block with record data (i.e. in the DHT). 260 */ 261 struct GNUNET_GNSRECORD_EddsaBlock 262 { 263 /** 264 * Derived key used for signing; hash of this is the query. 265 */ 266 struct GNUNET_CRYPTO_EddsaPublicKey derived_key; 267 268 /** 269 * Signature of the block. 270 */ 271 struct GNUNET_CRYPTO_EddsaSignature signature; 272 273 /** 274 * Expiration time of the block. 275 */ 276 struct GNUNET_TIME_AbsoluteNBO expiration_time; 277 278 279 /* followed by encrypted data */ 280 }; 281 282 283 struct GNUNET_GNSRECORD_Block 284 { 285 /** 286 * Size of the block. 287 */ 288 uint32_t size; 289 290 /** 291 * The zone type (GNUNET_GNSRECORD_TYPE_PKEY) 292 */ 293 uint32_t type; 294 295 union 296 { 297 struct GNUNET_GNSRECORD_EcdsaBlock ecdsa_block; 298 struct GNUNET_GNSRECORD_EddsaBlock eddsa_block; 299 }; 300 }; 301 302 303 /** 304 * Record type used to box up SRV and TLSA records. For example, a 305 * TLSA record for "_https._tcp.foo.gnu" will be stored under 306 * "foo.gnu" as a BOX record with service 443 (https) and protocol 6 307 * (tcp) and record_type "TLSA". When a BOX record is received, GNS 308 * unboxes it if the name contained "_SERVICE._PROTO", otherwise GNS 309 * leaves it untouched. This is done to ensure that TLSA (and SRV) 310 * records do not require a separate network request, thus making TLSA 311 * records inseparable from the "main" A/AAAA/VPN/etc. records. 312 */ 313 struct GNUNET_GNSRECORD_BoxRecord 314 { 315 /** 316 * Protocol of the boxed record (6 = TCP, 17 = UDP, etc.). 317 * Yes, in IP protocols are usually limited to 8 bits. In NBO. 318 */ 319 uint16_t protocol GNUNET_PACKED; 320 321 /** 322 * Service of the boxed record (aka port number), in NBO. 323 */ 324 uint16_t service GNUNET_PACKED; 325 326 /** 327 * GNS record type of the boxed record. In NBO. 328 */ 329 uint32_t record_type GNUNET_PACKED; 330 331 /* followed by the 'original' record */ 332 }; 333 334 335 /** 336 * Record type used to box up SMIMEA records. For example, a 337 * SMIMEA record for "c93f1e400f26708f98cb19d936620da35eec8f72e57 338 * f9eec01c1afd6._smimecert.foo.gnu" will be stored under 339 * "foo.gnu" as a SBOX record with the local-path of the associated 340 * e-mails hash turnicated to 28 octets encoded as hex and protocol _smimecert 341 * and record_type "SMIMEA". When a BOX record is received, GNS 342 * unboxes it if the name contained "hash._PROTO", otherwise GNS 343 * leaves it untouched. This is done to ensure that SMIMEA 344 * records do not require a separate network request, thus making SMIMEA 345 * records inseparable from the "main" A/AAAA/VPN/etc. records. 346 */ 347 struct GNUNET_GNSRECORD_SBoxRecord 348 { 349 /** 350 * GNS record type of the boxed record. In NBO. 351 */ 352 uint32_t record_type GNUNET_PACKED; 353 354 /* followed by the zero terminated hostname prefix */ 355 /* followed by the 'original' record */ 356 }; 357 358 359 /** 360 * Record type used internally to keep track of reverse mappings into a 361 * namespace. 362 * The record contains data related to PKEY delegations from other namespaces to 363 * the namespace the record belongs to. 364 * It is exclusively found under the label ``+''. 365 */ 366 struct GNUNET_GNSRECORD_ReverseRecord 367 { 368 /** 369 * The public key of the namespace the is delegating to our namespace 370 */ 371 struct GNUNET_CRYPTO_BlindablePublicKey pkey; 372 373 /** 374 * The expiration time of the delegation 375 */ 376 struct GNUNET_TIME_Absolute expiration; 377 378 /* followed by the name the delegator uses to refer to our namespace */ 379 }; 380 381 382 /** 383 * Process a records that were decrypted from a block. 384 * 385 * @param cls closure 386 * @param rd_count number of entries in @a rd array 387 * @param rd array of records with data to store 388 */ 389 typedef void (*GNUNET_GNSRECORD_RecordCallback) ( 390 void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); 391 392 393 /* ***************** API related to GNSRECORD plugins ************** */ 394 395 /** 396 * Convert the binary value @a data of a record of 397 * type @a type to a human-readable string. 398 * 399 * @param type type of the record 400 * @param data value in binary encoding 401 * @param data_size number of bytes in @a data 402 * @return NULL on error, otherwise human-readable representation of the value 403 */ 404 char * 405 GNUNET_GNSRECORD_value_to_string (uint32_t type, const void *data, 406 size_t data_size); 407 408 409 /** 410 * Convert human-readable version of the value @a s of a record 411 * of type @a type to the respective binary representation. 412 * 413 * @param type type of the record 414 * @param s human-readable string 415 * @param data set to value in binary encoding (will be allocated) 416 * @param data_size set to number of bytes in @a data 417 * @return #GNUNET_OK on success 418 */ 419 int 420 GNUNET_GNSRECORD_string_to_value (uint32_t type, const char *s, void **data, 421 size_t *data_size); 422 423 424 /** 425 * Convert a type name (e.g. "AAAA") to the corresponding number. 426 * 427 * @param dns_typename name to convert 428 * @return corresponding number, UINT32_MAX on error 429 */ 430 uint32_t 431 GNUNET_GNSRECORD_typename_to_number (const char *dns_typename); 432 433 434 /** 435 * Convert a type number to the corresponding type string (e.g. 1 to "A") 436 * 437 * @param type number of a type to convert 438 * @return corresponding typestring, NULL on error 439 */ 440 const char * 441 GNUNET_GNSRECORD_number_to_typename (uint32_t type); 442 443 444 /* convenience APIs for serializing / deserializing GNS records */ 445 446 /** 447 * Calculate how many bytes we will need to serialize the given 448 * records. 449 * 450 * @param rd_count number of records in the @a rd array 451 * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements 452 * @return the required size to serialize, -1 on error 453 */ 454 ssize_t 455 GNUNET_GNSRECORD_records_get_size (unsigned int rd_count, 456 const struct GNUNET_GNSRECORD_Data *rd); 457 458 459 /** 460 * Serialize the given records to the given destination buffer. 461 * 462 * @param rd_count number of records in the @a rd array 463 * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements 464 * @param dest_size size of the destination array @a dst 465 * @param dest where to write the result 466 * @return the size of serialized records, -1 if records do not fit 467 */ 468 ssize_t 469 GNUNET_GNSRECORD_records_serialize (unsigned int rd_count, 470 const struct GNUNET_GNSRECORD_Data *rd, 471 size_t dest_size, char *dest); 472 473 unsigned int 474 GNUNET_GNSRECORD_records_deserialize_get_size (size_t len, 475 const char *src); 476 477 /** 478 * Deserialize the given records to the given destination. 479 * 480 * @param len size of the serialized record data 481 * @param src the serialized record data 482 * @param rd_count number of records in the @a dest array 483 * @param dest where to put the data 484 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 485 */ 486 int 487 GNUNET_GNSRECORD_records_deserialize (size_t len, const char *src, 488 unsigned int rd_count, 489 struct GNUNET_GNSRECORD_Data *dest); 490 491 492 /* ******* general APIs relating to blocks, records and labels ******** */ 493 494 495 /** 496 * Test if a given record is expired. 497 * 498 * @param rd record to test 499 * @return #GNUNET_YES if the record is expired, 500 * #GNUNET_NO if not 501 */ 502 int 503 GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd); 504 505 506 /** 507 * Normalize a UTF-8 string to a GNS name 508 * 509 * @param src source string 510 * @return converted result 511 */ 512 char * 513 GNUNET_GNSRECORD_string_normalize (const char *src); 514 515 516 /** 517 * Convert a zone to a string (for printing debug messages). 518 * This is one of the very few calls in the entire API that is 519 * NOT reentrant! 520 * 521 * @param z public key of a zone 522 * @return string form; will be overwritten by next call to 523 * #GNUNET_GNSRECORD_z2s. 524 */ 525 const char * 526 GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_BlindablePublicKey *z); 527 528 529 /** 530 * Convert public key to the respective absolute domain name in the 531 * ".zkey" pTLD. 532 * This is one of the very few calls in the entire API that is 533 * NOT reentrant! 534 * 535 * @param pkey a public key with a point on the elliptic curve 536 * @return string "X.zkey" where X is the coordinates of the public 537 * key in an encoding suitable for DNS labels. 538 */ 539 const char * 540 GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_BlindablePublicKey * 541 pkey); 542 543 544 /** 545 * Convert an absolute domain name to the 546 * respective public key. 547 * 548 * @param zkey string "X" where X is the public 549 * key in an encoding suitable for DNS labels. 550 * @param pkey set to a public key on the elliptic curve 551 * @return #GNUNET_SYSERR if @a zkey has the wrong syntax 552 */ 553 int 554 GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, 555 struct GNUNET_CRYPTO_BlindablePublicKey *pkey); 556 557 558 /** 559 * Calculate the DHT query for a given @a label in a given @a zone. 560 * 561 * @param zone private key of the zone 562 * @param label label of the record 563 * @param query hash to use for the query 564 */ 565 void 566 GNUNET_GNSRECORD_query_from_private_key ( 567 const struct GNUNET_CRYPTO_BlindablePrivateKey *zone, const char *label, 568 struct GNUNET_HashCode *query); 569 570 571 /** 572 * Calculate the DHT query for a given @a label in a given @a zone. 573 * FIXME: We may want to plugin-ize this at some point. 574 * 575 * @param pub public key of the zone 576 * @param label label of the record 577 * @param query hash to use for the query 578 */ 579 void 580 GNUNET_GNSRECORD_query_from_public_key ( 581 const struct GNUNET_CRYPTO_BlindablePublicKey *pub, const char *label, 582 struct GNUNET_HashCode *query); 583 584 585 /** 586 * Get size of buffer for block creation. 587 * 588 * @param key the zone key 589 * @param rd record data 590 * @param rd_count number of records 591 * @return -1 on error (otherwise the length of the block) 592 */ 593 ssize_t 594 GNUNET_GNSRECORD_block_calculate_size (const struct 595 GNUNET_CRYPTO_BlindablePrivateKey *key, 596 const struct GNUNET_GNSRECORD_Data *rd, 597 unsigned int rd_count); 598 599 /** 600 * Sign a block create with #GNUNET_GNSRECORD_block_create_unsigned 601 * 602 * @param key the private key 603 * @param label the label of the block 604 * @param block the unsigned block 605 * @return GNUNET_OK on success 606 */ 607 enum GNUNET_GenericReturnValue 608 GNUNET_GNSRECORD_block_sign (const struct 609 GNUNET_CRYPTO_BlindablePrivateKey *key, 610 const char *label, 611 struct GNUNET_GNSRECORD_Block *block); 612 613 /** 614 * Sign name and records 615 * 616 * @param key the private key 617 * @param expire block expiration 618 * @param label the name for the records 619 * @param rd record data 620 * @param rd_count number of records in @a rd 621 * @param result the block buffer. Will be allocated. 622 * @return GNUNET_OK on success 623 */ 624 enum GNUNET_GenericReturnValue 625 GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_BlindablePrivateKey * 626 key, 627 struct GNUNET_TIME_Absolute expire, 628 const char *label, 629 const struct GNUNET_GNSRECORD_Data *rd, 630 unsigned int rd_count, 631 struct GNUNET_GNSRECORD_Block **block); 632 633 634 /** 635 * Create name and records but do not sign! 636 * Sign later with #GNUNET_GNSRECORD_block_sign(). 637 * Cache derived public key (also keeps the 638 * private key in static memory, so do not use this function if 639 * keeping the private key in the process'es RAM is a major issue). 640 * 641 * @param key the private key 642 * @param expire block expiration 643 * @param label the name for the records 644 * @param rd record data 645 * @param rd_count number of records in @a rd 646 * @param result the block buffer. Will be allocated. 647 * @return GNUNET_OK on success. 648 */ 649 enum GNUNET_GenericReturnValue 650 GNUNET_GNSRECORD_block_create_unsigned (const struct 651 GNUNET_CRYPTO_BlindablePrivateKey *key, 652 struct GNUNET_TIME_Absolute expire, 653 const char *label, 654 const struct GNUNET_GNSRECORD_Data *rd, 655 unsigned int rd_count, 656 struct GNUNET_GNSRECORD_Block **result); 657 658 659 /** 660 * Sign name and records, cache derived public key (also keeps the 661 * private key in static memory, so do not use this function if 662 * keeping the private key in the process'es RAM is a major issue). 663 * 664 * @param key the private key 665 * @param expire block expiration 666 * @param label the name for the records 667 * @param rd record data 668 * @param rd_count number of records in @a rd 669 * @param result the block buffer. Will be allocated. 670 * @return GNUNET_OK on success. 671 */ 672 enum GNUNET_GenericReturnValue 673 GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_BlindablePrivateKey * 674 key, 675 struct GNUNET_TIME_Absolute expire, 676 const char *label, 677 const struct GNUNET_GNSRECORD_Data *rd, 678 unsigned int rd_count, 679 struct GNUNET_GNSRECORD_Block **result); 680 681 682 /** 683 * Check if a signature is valid. This API is used by the GNS Block 684 * to validate signatures received from the network. 685 * 686 * @param block block to verify 687 * @return #GNUNET_OK if the signature is valid 688 */ 689 enum GNUNET_GenericReturnValue 690 GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block); 691 692 693 /** 694 * Decrypt block. 695 * 696 * @param block block to decrypt 697 * @param zone_key public key of the zone 698 * @param label the name for the records 699 * @param proc function to call with the result 700 * @param proc_cls closure for @a proc 701 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was 702 * not well-formed 703 */ 704 enum GNUNET_GenericReturnValue 705 GNUNET_GNSRECORD_block_decrypt ( 706 const struct GNUNET_GNSRECORD_Block *block, 707 const struct GNUNET_CRYPTO_BlindablePublicKey *zone_key, const char *label, 708 GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls); 709 710 711 /** 712 * Compares if two records are equal 713 * 714 * @param a a record 715 * @param b another record 716 * @return #GNUNET_YES if the records are equal, or #GNUNET_NO if not. 717 */ 718 enum GNUNET_GenericReturnValue 719 GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, 720 const struct GNUNET_GNSRECORD_Data *b); 721 722 723 /** 724 * Returns the expiration time of the given block of records. The block 725 * expiration time is the expiration time of the record with smallest 726 * expiration time. 727 * 728 * @param rd_count number of records given in @a rd 729 * @param rd array of records 730 * @param min minimum expiration time 731 * @return absolute expiration time 732 */ 733 struct GNUNET_TIME_Absolute 734 GNUNET_GNSRECORD_record_get_expiration_time (unsigned int rd_count, 735 const struct 736 GNUNET_GNSRECORD_Data *rd, 737 struct GNUNET_TIME_Absolute min); 738 739 740 /** 741 * Returns the length of this block in bytes. 742 * Block length strongly depends on the zone type. 743 * 744 * @param block the block. 745 * @return the length of this block in bytes 746 */ 747 size_t 748 GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block); 749 750 /** 751 * Returns the expiration of a block. 752 * 753 * @param block the block. 754 * @return the block expiration. 755 */ 756 struct GNUNET_TIME_Absolute 757 GNUNET_GNSRECORD_block_get_expiration (const struct 758 GNUNET_GNSRECORD_Block *block); 759 760 761 /** 762 * Builds the query hash from a block. 763 * 764 * @param block the block. 765 * @param query where to write the query hash. 766 * @return GNUNET_SYSERR on error. 767 */ 768 enum GNUNET_GenericReturnValue 769 GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block, 770 struct GNUNET_HashCode *query); 771 772 773 /** 774 * Build a #GNUNET_GNSRECORD_PublicKey from 775 * zone delegation resource record data. 776 * 777 * @param data the record data- 778 * @param data_size the data size. 779 * @param type the record type 780 * @param key the identity key to store the data in (must be allocated). 781 * @return GNUNET_OK if successful. 782 */ 783 enum GNUNET_GenericReturnValue 784 GNUNET_GNSRECORD_identity_from_data (const char *data, 785 size_t data_size, 786 uint32_t type, 787 struct GNUNET_CRYPTO_BlindablePublicKey * 788 key); 789 790 791 /** 792 * Create record data and size from an identity key. 793 * 794 * @param key the identity key to use. 795 * @param data the record data (will be allocated) 796 * @param data_size the allocated data size. 797 * @param type the resulting record type 798 * @return GNUNET_OK if successful. 799 */ 800 enum GNUNET_GenericReturnValue 801 GNUNET_GNSRECORD_data_from_identity (const struct 802 GNUNET_CRYPTO_BlindablePublicKey *key, 803 char **data, 804 size_t *data_size, 805 uint32_t *type); 806 807 808 /** 809 * Check if this type is one of the supported GNS zone 810 * types. 811 * 812 * @param type the type to check 813 * @return GNUNET_YES if it is one of the supported types. 814 */ 815 enum GNUNET_GenericReturnValue 816 GNUNET_GNSRECORD_is_zonekey_type (uint32_t type); 817 818 /** 819 * Check if this type is a critical record. 820 * 821 * @param type the type to check 822 * @return GNUNET_YES if it is critical. 823 */ 824 enum GNUNET_GenericReturnValue 825 GNUNET_GNSRECORD_is_critical (uint32_t type); 826 827 /** 828 * Normalize namestore records: Check for consistency and 829 * expirations. Purge expired records. Returns a "clean" record set. 830 * Also returns the minimum expiration time this block should be 831 * published under. 832 * Also checks rules with respect to labels (e.g. no delegations under 833 * the empty label) 834 * 835 * @param label the label under which this set (supposed to be) stored. 836 * @param rd input records 837 * @param rd_count size of the @a rd and @a rd_public arrays 838 * @param rd_public where to write the converted records 839 * @param rd_count_public number of records written to @a rd_public 840 * @param min_expiry the minimum expiration of this set 841 * @param filter the record set filter, see GNUNET_GNSRECORD_Filter. 842 * @param emsg the error message if something went wrong 843 * @return GNUNET_OK if set could be normalized and is consistent 844 */ 845 enum GNUNET_GenericReturnValue 846 GNUNET_GNSRECORD_normalize_record_set (const char *label, 847 const struct GNUNET_GNSRECORD_Data *rd, 848 unsigned int rd_count, 849 struct GNUNET_GNSRECORD_Data *rd_public, 850 unsigned int *rd_count_public, 851 struct GNUNET_TIME_Absolute *min_expiry, 852 enum GNUNET_GNSRECORD_Filter filter, 853 char **emsg); 854 855 /** 856 * Check label for invalid characters. 857 * 858 * @param label the label to check 859 * @param emsg an error message (NULL if label is valid). Will be allocated. 860 * @return GNUNET_OK if label is valid. 861 */ 862 enum GNUNET_GenericReturnValue 863 GNUNET_GNSRECORD_label_check (const char*label, char **emsg); 864 865 /** 866 * Maximum length of a revocation 867 */ 868 #define GNUNET_MAX_POW_SIZE sizeof(struct GNUNET_GNSRECORD_PowP) \ 869 + sizeof(struct GNUNET_CRYPTO_BlindablePublicKey) \ 870 + 1024 // FIXME max sig_len 871 872 /** 873 * The proof-of-work narrowing factor. 874 * The number of PoWs that are calculates as part of revocation. 875 */ 876 #define POW_COUNT 32 877 878 879 GNUNET_NETWORK_STRUCT_BEGIN 880 881 /** 882 * Struct for a proof of work as part of the revocation. 883 */ 884 struct GNUNET_GNSRECORD_PowP 885 { 886 /** 887 * The timestamp of the revocation 888 */ 889 struct GNUNET_TIME_AbsoluteNBO timestamp; 890 891 /** 892 * The TTL of this revocation (purely informational) 893 */ 894 struct GNUNET_TIME_RelativeNBO ttl; 895 896 /** 897 * The PoWs 898 */ 899 uint64_t pow[POW_COUNT] GNUNET_PACKED; 900 901 /** followed by the public key type, the key and a signature **/ 902 }; 903 904 905 /** 906 * The signature object we use for the PoW 907 */ 908 struct GNUNET_GNSRECORD_SignaturePurposePS 909 { 910 /** 911 * The signature purpose 912 */ 913 struct GNUNET_CRYPTO_SignaturePurpose purpose; 914 915 /** 916 * The timestamp of the revocation 917 */ 918 struct GNUNET_TIME_AbsoluteNBO timestamp; 919 920 /** Followed by the zone public key type and key **/ 921 }; 922 923 GNUNET_NETWORK_STRUCT_END 924 925 926 /** 927 * Handle to a running proof-of-work calculation. 928 */ 929 struct GNUNET_GNSRECORD_PowCalculationHandle; 930 931 932 /** 933 * Check if the given proof-of-work is valid. 934 * 935 * @param pow proof of work 936 * @param matching_bits how many bits must match (configuration) 937 * @param epoch_duration length of single epoch in configuration 938 * @return #GNUNET_YES if the @a pow is acceptable, #GNUNET_NO if not 939 */ 940 enum GNUNET_GenericReturnValue 941 GNUNET_GNSRECORD_check_pow (const struct GNUNET_GNSRECORD_PowP *pow, 942 unsigned int matching_bits, 943 struct GNUNET_TIME_Relative epoch_duration); 944 945 946 /** 947 * Initializes a fresh PoW computation. 948 * 949 * @param key the key to calculate the PoW for. 950 * @param pow the pow object to work with in the calculation. 951 */ 952 void 953 GNUNET_GNSRECORD_pow_init (const struct GNUNET_CRYPTO_BlindablePrivateKey *key, 954 struct GNUNET_GNSRECORD_PowP *pow); 955 956 957 /** 958 * Starts a proof-of-work calculation given the pow object as well as 959 * target epochs and difficulty. 960 * 961 * @param pow the PoW to based calculations on. 962 * @param epochs the number of epochs for which the PoW must be valid. 963 * @param difficulty the base difficulty of the PoW. 964 * @return a handle for use in PoW rounds 965 */ 966 struct GNUNET_GNSRECORD_PowCalculationHandle* 967 GNUNET_GNSRECORD_pow_start (struct GNUNET_GNSRECORD_PowP *pow, 968 int epochs, 969 unsigned int difficulty); 970 971 972 /** 973 * Calculate a single round in the key revocation PoW. 974 * 975 * @param pc handle to the PoW, initially called with NULL. 976 * @return GNUNET_YES if the @a pow is acceptable, GNUNET_NO if not 977 */ 978 enum GNUNET_GenericReturnValue 979 GNUNET_GNSRECORD_pow_round (struct GNUNET_GNSRECORD_PowCalculationHandle *pc); 980 981 size_t 982 GNUNET_GNSRECORD_proof_get_size (const struct GNUNET_GNSRECORD_PowP *pow); 983 984 /** 985 * Stop a PoW calculation 986 * 987 * @param pc the calculation to clean up 988 * @return #GNUNET_YES if pow valid, #GNUNET_NO if pow was set but is not 989 * valid 990 */ 991 void 992 GNUNET_GNSRECORD_pow_stop (struct GNUNET_GNSRECORD_PowCalculationHandle *pc); 993 994 #if 0 /* keep Emacsens' auto-indent happy */ 995 { 996 #endif 997 #ifdef __cplusplus 998 } 999 #endif 1000 1001 #endif 1002 1003 /** @} */ /* end of group */ 1004 1005 /** @} */ /* end of group addition */