2
0

gnunet_gnsrecord_lib.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2012, 2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @author Christian Grothoff
  18. *
  19. * @file
  20. * API that can be used to manipulate GNS record data
  21. *
  22. * @defgroup gnsrecord GNS Record library
  23. * Manipulate GNS record data
  24. *
  25. * @see [Documentation](https://gnunet.org/gns-plugins)
  26. *
  27. * @{
  28. */
  29. #ifndef GNUNET_GNSRECORD_LIB_H
  30. #define GNUNET_GNSRECORD_LIB_H
  31. #ifdef __cplusplus
  32. extern "C" {
  33. #if 0 /* keep Emacsens' auto-indent happy */
  34. }
  35. #endif
  36. #endif
  37. /**
  38. * Maximum size of a value that can be stored in a GNS block.
  39. */
  40. #define GNUNET_GNSRECORD_MAX_BLOCK_SIZE (63 * 1024)
  41. /**
  42. * Record type indicating any record/'*'
  43. */
  44. #define GNUNET_GNSRECORD_TYPE_ANY 0
  45. /**
  46. * Record type for GNS zone transfer ("PKEY").
  47. */
  48. #define GNUNET_GNSRECORD_TYPE_PKEY 65536
  49. /**
  50. * Record type for GNS nick names ("NICK").
  51. */
  52. #define GNUNET_GNSRECORD_TYPE_NICK 65537
  53. /**
  54. * Record type for GNS legacy hostnames ("LEHO").
  55. */
  56. #define GNUNET_GNSRECORD_TYPE_LEHO 65538
  57. /**
  58. * Record type for VPN resolution
  59. */
  60. #define GNUNET_GNSRECORD_TYPE_VPN 65539
  61. /**
  62. * Record type for delegation to DNS.
  63. */
  64. #define GNUNET_GNSRECORD_TYPE_GNS2DNS 65540
  65. /**
  66. * Record type for a boxed record (see TLSA/SRV handling in GNS).
  67. */
  68. #define GNUNET_GNSRECORD_TYPE_BOX 65541
  69. /**
  70. * Record type for a social place.
  71. */
  72. #define GNUNET_GNSRECORD_TYPE_PLACE 65542
  73. /**
  74. * Record type for a phone (of CONVERSATION).
  75. */
  76. #define GNUNET_GNSRECORD_TYPE_PHONE 65543
  77. /**
  78. * Record type for identity attributes (of RECLAIM).
  79. */
  80. #define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR 65544
  81. /**
  82. * Record type for local ticket references
  83. */
  84. #define GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET 65545
  85. /**
  86. * 65546 reserved
  87. */
  88. /**
  89. * Record type for credential
  90. */
  91. #define GNUNET_GNSRECORD_TYPE_CREDENTIAL 65547
  92. /**
  93. * Record type for policies
  94. */
  95. #define GNUNET_GNSRECORD_TYPE_POLICY 65548
  96. /**
  97. * Record type for reverse lookups
  98. */
  99. #define GNUNET_GNSRECORD_TYPE_ATTRIBUTE 65549
  100. /**
  101. * Record type for reclaim records
  102. */
  103. #define GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF 65550
  104. /**
  105. * Record type for RECLAIM master
  106. */
  107. #define GNUNET_GNSRECORD_TYPE_RECLAIM_MASTER 65551
  108. /**
  109. * Record type for reclaim OIDC clients
  110. */
  111. #define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_CLIENT 65552
  112. /**
  113. * Record type for reclaim OIDC redirect URIs
  114. */
  115. #define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT 65553
  116. /**
  117. * Flags that can be set for a record.
  118. */
  119. enum GNUNET_GNSRECORD_Flags {
  120. /**
  121. * No special options.
  122. */
  123. GNUNET_GNSRECORD_RF_NONE = 0,
  124. /**
  125. * This is a private record of this peer and it should
  126. * thus not be handed out to other peers.
  127. */
  128. GNUNET_GNSRECORD_RF_PRIVATE = 2,
  129. /**
  130. * This flag is currently unused; former RF_PENDING flag
  131. *
  132. * GNUNET_GNSRECORD_RF_UNUSED = 4,
  133. */
  134. /**
  135. * This expiration time of the record is a relative
  136. * time (not an absolute time).
  137. */
  138. GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 8,
  139. /**
  140. * This record should not be used unless all (other) records with an absolute
  141. * expiration time have expired.
  142. */
  143. GNUNET_GNSRECORD_RF_SHADOW_RECORD = 16
  144. /**
  145. * When comparing flags for record equality for removal,
  146. * which flags should must match (in addition to the type,
  147. * name, expiration value and data of the record)? All flags
  148. * that are not listed here will be ignored for this purpose.
  149. * (for example, we don't expect that users will remember to
  150. * pass the '--private' option when removing a record from
  151. * the namestore, hence we don't require this particular option
  152. * to match upon removal). See also
  153. * #GNUNET_GNSRECORD_records_cmp.
  154. */
  155. #define GNUNET_GNSRECORD_RF_RCMP_FLAGS (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)
  156. };
  157. /**
  158. * A GNS record.
  159. */
  160. struct GNUNET_GNSRECORD_Data {
  161. /**
  162. * Binary value stored in the DNS record. Note: "data" must never
  163. * be individually 'malloc'ed, but instead always points into some
  164. * existing data area.
  165. */
  166. const void *data;
  167. /**
  168. * Expiration time for the DNS record. Can be relative
  169. * or absolute, depending on @e flags. Measured in the same
  170. * unit as GNUnet time (microseconds).
  171. */
  172. uint64_t expiration_time;
  173. /**
  174. * Number of bytes in @e data.
  175. */
  176. size_t data_size;
  177. /**
  178. * Type of the GNS/DNS record.
  179. */
  180. uint32_t record_type;
  181. /**
  182. * Flags for the record.
  183. */
  184. enum GNUNET_GNSRECORD_Flags flags;
  185. };
  186. GNUNET_NETWORK_STRUCT_BEGIN
  187. /**
  188. * Data stored in a PLACE record.
  189. */
  190. struct GNUNET_GNSRECORD_PlaceData {
  191. /**
  192. * Public key of the place.
  193. */
  194. struct GNUNET_CRYPTO_EddsaPublicKey place_pub_key;
  195. /**
  196. * Peer identity of the origin.
  197. */
  198. struct GNUNET_PeerIdentity origin;
  199. /**
  200. * Number of relays that follow.
  201. */
  202. uint32_t relay_count GNUNET_PACKED;
  203. /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */
  204. };
  205. /**
  206. * Information we have in an encrypted block with record data (i.e. in the DHT).
  207. */
  208. struct GNUNET_GNSRECORD_Block {
  209. /**
  210. * Signature of the block.
  211. */
  212. struct GNUNET_CRYPTO_EcdsaSignature signature;
  213. /**
  214. * Derived key used for signing; hash of this is the query.
  215. */
  216. struct GNUNET_CRYPTO_EcdsaPublicKey derived_key;
  217. /**
  218. * Number of bytes signed; also specifies the number of bytes
  219. * of encrypted data that follow.
  220. */
  221. struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  222. /**
  223. * Expiration time of the block.
  224. */
  225. struct GNUNET_TIME_AbsoluteNBO expiration_time;
  226. /* followed by encrypted data */
  227. };
  228. /**
  229. * Record type used to box up SRV and TLSA records. For example, a
  230. * TLSA record for "_https._tcp.foo.gnu" will be stored under
  231. * "foo.gnu" as a BOX record with service 443 (https) and protocol 6
  232. * (tcp) and record_type "TLSA". When a BOX record is received, GNS
  233. * unboxes it if the name contained "_SERVICE._PROTO", otherwise GNS
  234. * leaves it untouched. This is done to ensure that TLSA (and SRV)
  235. * records do not require a separate network request, thus making TLSA
  236. * records inseparable from the "main" A/AAAA/VPN/etc. records.
  237. */
  238. struct GNUNET_GNSRECORD_BoxRecord {
  239. /**
  240. * Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
  241. * Yes, in IP protocols are usually limited to 8 bits. In NBO.
  242. */
  243. uint16_t protocol GNUNET_PACKED;
  244. /**
  245. * Service of the boxed record (aka port number), in NBO.
  246. */
  247. uint16_t service GNUNET_PACKED;
  248. /**
  249. * GNS record type of the boxed record. In NBO.
  250. */
  251. uint32_t record_type GNUNET_PACKED;
  252. /* followed by the 'original' record */
  253. };
  254. /**
  255. * Record type used internally to keep track of reverse mappings into a
  256. * namespace.
  257. * The record contains data related to PKEY delegations from other namespaces to
  258. * the namespace the record belongs to.
  259. * It is exclusively found under the label ``+''.
  260. */
  261. struct GNUNET_GNSRECORD_ReverseRecord {
  262. /**
  263. * The public key of the namespace the is delegating to our namespace
  264. */
  265. struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
  266. /**
  267. * The expiration time of the delegation
  268. */
  269. struct GNUNET_TIME_Absolute expiration;
  270. /* followed by the name the delegator uses to refer to our namespace */
  271. };
  272. GNUNET_NETWORK_STRUCT_END
  273. /**
  274. * Process a records that were decrypted from a block.
  275. *
  276. * @param cls closure
  277. * @param rd_count number of entries in @a rd array
  278. * @param rd array of records with data to store
  279. */
  280. typedef void (*GNUNET_GNSRECORD_RecordCallback) (
  281. void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd);
  282. /* ***************** API related to GNSRECORD plugins ************** */
  283. /**
  284. * Convert the binary value @a data of a record of
  285. * type @a type to a human-readable string.
  286. *
  287. * @param type type of the record
  288. * @param data value in binary encoding
  289. * @param data_size number of bytes in @a data
  290. * @return NULL on error, otherwise human-readable representation of the value
  291. */
  292. char *
  293. GNUNET_GNSRECORD_value_to_string (uint32_t type, const void *data,
  294. size_t data_size);
  295. /**
  296. * Convert human-readable version of the value @a s of a record
  297. * of type @a type to the respective binary representation.
  298. *
  299. * @param type type of the record
  300. * @param s human-readable string
  301. * @param data set to value in binary encoding (will be allocated)
  302. * @param data_size set to number of bytes in @a data
  303. * @return #GNUNET_OK on success
  304. */
  305. int
  306. GNUNET_GNSRECORD_string_to_value (uint32_t type, const char *s, void **data,
  307. size_t *data_size);
  308. /**
  309. * Convert a type name (i.e. "AAAA") to the corresponding number.
  310. *
  311. * @param dns_typename name to convert
  312. * @return corresponding number, UINT32_MAX on error
  313. */
  314. uint32_t
  315. GNUNET_GNSRECORD_typename_to_number (const char *dns_typename);
  316. /**
  317. * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
  318. *
  319. * @param type number of a type to convert
  320. * @return corresponding typestring, NULL on error
  321. */
  322. const char *
  323. GNUNET_GNSRECORD_number_to_typename (uint32_t type);
  324. /* convenience APIs for serializing / deserializing GNS records */
  325. /**
  326. * Calculate how many bytes we will need to serialize the given
  327. * records.
  328. *
  329. * @param rd_count number of records in the @a rd array
  330. * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
  331. * @return the required size to serialize, -1 on error
  332. */
  333. ssize_t
  334. GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
  335. const struct GNUNET_GNSRECORD_Data *rd);
  336. /**
  337. * Serialize the given records to the given destination buffer.
  338. *
  339. * @param rd_count number of records in the @a rd array
  340. * @param rd array of #GNUNET_GNSRECORD_Data with @a rd_count elements
  341. * @param dest_size size of the destination array @a dst
  342. * @param dest where to write the result
  343. * @return the size of serialized records, -1 if records do not fit
  344. */
  345. ssize_t
  346. GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
  347. const struct GNUNET_GNSRECORD_Data *rd,
  348. size_t dest_size, char *dest);
  349. /**
  350. * Deserialize the given records to the given destination.
  351. *
  352. * @param len size of the serialized record data
  353. * @param src the serialized record data
  354. * @param rd_count number of records in the @a dest array
  355. * @param dest where to put the data
  356. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  357. */
  358. int
  359. GNUNET_GNSRECORD_records_deserialize (size_t len, const char *src,
  360. unsigned int rd_count,
  361. struct GNUNET_GNSRECORD_Data *dest);
  362. /* ******* general APIs relating to blocks, records and labels ******** */
  363. /**
  364. * Test if a given record is expired.
  365. *
  366. * @param rd record to test
  367. * @return #GNUNET_YES if the record is expired,
  368. * #GNUNET_NO if not
  369. */
  370. int
  371. GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd);
  372. /**
  373. * Convert a UTF-8 string to UTF-8 lowercase
  374. * @param src source string
  375. * @return converted result
  376. */
  377. char *
  378. GNUNET_GNSRECORD_string_to_lowercase (const char *src);
  379. /**
  380. * Convert a zone to a string (for printing debug messages).
  381. * This is one of the very few calls in the entire API that is
  382. * NOT reentrant!
  383. *
  384. * @param z public key of a zone
  385. * @return string form; will be overwritten by next call to
  386. * #GNUNET_GNSRECORD_z2s.
  387. */
  388. const char *
  389. GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z);
  390. /**
  391. * Convert public key to the respective absolute domain name in the
  392. * ".zkey" pTLD.
  393. * This is one of the very few calls in the entire API that is
  394. * NOT reentrant!
  395. *
  396. * @param pkey a public key with a point on the eliptic curve
  397. * @return string "X.zkey" where X is the coordinates of the public
  398. * key in an encoding suitable for DNS labels.
  399. */
  400. const char *
  401. GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey);
  402. /**
  403. * Convert an absolute domain name to the
  404. * respective public key.
  405. *
  406. * @param zkey string "X" where X is the public
  407. * key in an encoding suitable for DNS labels.
  408. * @param pkey set to a public key on the eliptic curve
  409. * @return #GNUNET_SYSERR if @a zkey has the wrong syntax
  410. */
  411. int
  412. GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey,
  413. struct GNUNET_CRYPTO_EcdsaPublicKey *pkey);
  414. /**
  415. * Calculate the DHT query for a given @a label in a given @a zone.
  416. *
  417. * @param zone private key of the zone
  418. * @param label label of the record
  419. * @param query hash to use for the query
  420. */
  421. void
  422. GNUNET_GNSRECORD_query_from_private_key (
  423. const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label,
  424. struct GNUNET_HashCode *query);
  425. /**
  426. * Calculate the DHT query for a given @a label in a given @a zone.
  427. *
  428. * @param pub public key of the zone
  429. * @param label label of the record
  430. * @param query hash to use for the query
  431. */
  432. void
  433. GNUNET_GNSRECORD_query_from_public_key (
  434. const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label,
  435. struct GNUNET_HashCode *query);
  436. /**
  437. * Sign name and records
  438. *
  439. * @param key the private key
  440. * @param expire block expiration
  441. * @param label the name for the records
  442. * @param rd record data
  443. * @param rd_count number of records in @a rd
  444. */
  445. struct GNUNET_GNSRECORD_Block *
  446. GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
  447. struct GNUNET_TIME_Absolute expire,
  448. const char *label,
  449. const struct GNUNET_GNSRECORD_Data *rd,
  450. unsigned int rd_count);
  451. /**
  452. * Sign name and records, cache derived public key (also keeps the
  453. * private key in static memory, so do not use this function if
  454. * keeping the private key in the process'es RAM is a major issue).
  455. *
  456. * @param key the private key
  457. * @param expire block expiration
  458. * @param label the name for the records
  459. * @param rd record data
  460. * @param rd_count number of records in @a rd
  461. */
  462. struct GNUNET_GNSRECORD_Block *
  463. GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
  464. struct GNUNET_TIME_Absolute expire,
  465. const char *label,
  466. const struct GNUNET_GNSRECORD_Data *rd,
  467. unsigned int rd_count);
  468. /**
  469. * Check if a signature is valid. This API is used by the GNS Block
  470. * to validate signatures received from the network.
  471. *
  472. * @param block block to verify
  473. * @return #GNUNET_OK if the signature is valid
  474. */
  475. int
  476. GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block);
  477. /**
  478. * Decrypt block.
  479. *
  480. * @param block block to decrypt
  481. * @param zone_key public key of the zone
  482. * @param label the name for the records
  483. * @param proc function to call with the result
  484. * @param proc_cls closure for @a proc
  485. * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was
  486. * not well-formed
  487. */
  488. int
  489. GNUNET_GNSRECORD_block_decrypt (
  490. const struct GNUNET_GNSRECORD_Block *block,
  491. const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label,
  492. GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls);
  493. /**
  494. * Compares if two records are equal
  495. *
  496. * @param a a record
  497. * @param b another record
  498. * @return #GNUNET_YES if the records are equal, or #GNUNET_NO if not.
  499. */
  500. int
  501. GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a,
  502. const struct GNUNET_GNSRECORD_Data *b);
  503. /**
  504. * Returns the expiration time of the given block of records. The block
  505. * expiration time is the expiration time of the record with smallest
  506. * expiration time.
  507. *
  508. * @param rd_count number of records given in @a rd
  509. * @param rd array of records
  510. * @return absolute expiration time
  511. */
  512. struct GNUNET_TIME_Absolute
  513. GNUNET_GNSRECORD_record_get_expiration_time (
  514. unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd);
  515. #if 0 /* keep Emacsens' auto-indent happy */
  516. {
  517. #endif
  518. #ifdef __cplusplus
  519. }
  520. #endif
  521. #endif
  522. /** @} */ /* end of group */