gnunet-android

GNUnet for Android
Log | Files | Refs | README

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 */