exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler_json_lib.h (38125B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2025 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file include/taler/taler_json_lib.h
     18  * @brief helper functions for JSON processing using libjansson
     19  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
     20  * @author Christian Grothoff
     21  * @author Özgür Kesim
     22  */
     23 #ifndef TALER_JSON_LIB_H_
     24 #define TALER_JSON_LIB_H_
     25 
     26 #include <jansson.h>
     27 #include <gnunet/gnunet_json_lib.h>
     28 #include <gnunet/gnunet_curl_lib.h>
     29 #include <taler/taler_util.h>
     30 #include <taler/taler_error_codes.h>
     31 
     32 
     33 /**
     34  * Version of this API, for compatibility tests.
     35  */
     36 #define TALER_JSON_LIB_VERSION 0x00020000
     37 
     38 
     39 /**
     40  * Print JSON parsing related error information
     41  * @deprecated
     42  */
     43 #define TALER_json_warn(error)                                         \
     44         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,                                \
     45                     "JSON parsing failed at %s:%u: %s (%s)\n",                  \
     46                     __FILE__, __LINE__, error.text, error.source)
     47 
     48 
     49 /**
     50  * Generate packer instruction for a JSON field of type
     51  * absolute time creating a human-readable timestamp.
     52  *
     53  * @param name name of the field to add to the object
     54  * @param at absolute time to pack
     55  * @return json pack specification
     56  */
     57 struct GNUNET_JSON_PackSpec
     58 TALER_JSON_pack_time_abs_human (
     59   const char *name,
     60   struct GNUNET_TIME_Absolute at);
     61 
     62 
     63 /**
     64  * Put an error code into a JSON reply, including
     65  * both the numeric value and the hint.
     66  *
     67  * @param ec error code to encode using canonical field names
     68  */
     69 #define TALER_JSON_pack_ec(ec) \
     70         GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec)), \
     71         GNUNET_JSON_pack_uint64 ("code", ec)
     72 
     73 
     74 /**
     75  * Generate packer instruction for a JSON field of type
     76  * denomination public key.
     77  *
     78  * @param name name of the field to add to the object
     79  * @param pk public key
     80  * @return json pack specification
     81  */
     82 struct GNUNET_JSON_PackSpec
     83 TALER_JSON_pack_denom_pub (
     84   const char *name,
     85   const struct TALER_DenominationPublicKey *pk);
     86 
     87 
     88 /**
     89  * Generate packer instruction for a JSON field of type
     90  * denomination signature.
     91  *
     92  * @param name name of the field to add to the object
     93  * @param sig signature
     94  * @return json pack specification
     95  */
     96 struct GNUNET_JSON_PackSpec
     97 TALER_JSON_pack_denom_sig (
     98   const char *name,
     99   const struct TALER_DenominationSignature *sig);
    100 
    101 
    102 /**
    103  * Generate packer instruction for a JSON field of type
    104  * blinded denomination signature (that needs to be
    105  * unblinded before it becomes valid).
    106  *
    107  * @param name name of the field to add to the object
    108  * @param sig signature
    109  * @return json pack specification
    110  */
    111 struct GNUNET_JSON_PackSpec
    112 TALER_JSON_pack_blinded_denom_sig (
    113   const char *name,
    114   const struct TALER_BlindedDenominationSignature *sig);
    115 
    116 
    117 /**
    118  * Generate packer instruction for a JSON field of type
    119  * blinded planchet.
    120  *
    121  * @param name name of the field to add to the object
    122  * @param blinded_planchet blinded planchet
    123  * @return json pack specification
    124  */
    125 struct GNUNET_JSON_PackSpec
    126 TALER_JSON_pack_blinded_planchet (
    127   const char *name,
    128   const struct TALER_BlindedPlanchet *blinded_planchet);
    129 
    130 
    131 /**
    132   * Generate packer instruction for a JSON field of type
    133   * blinded token issue signature.
    134   *
    135   * @param name name of the field to add to the object
    136   * @param sig token issue signature
    137   * @return json pack specification
    138   */
    139 struct GNUNET_JSON_PackSpec
    140 TALER_JSON_pack_token_issue_sig (
    141   const char *name,
    142   const struct TALER_TokenIssueSignature *sig);
    143 
    144 
    145 /**
    146  * Generate packer instruction for a JSON field of type
    147  * token family public key.
    148  *
    149  * @param name name of the field to add to the object
    150  * @param pk public key
    151  * @return json pack specification
    152  */
    153 struct GNUNET_JSON_PackSpec
    154 TALER_JSON_pack_token_pub (
    155   const char *name,
    156   const struct TALER_TokenIssuePublicKey *pk);
    157 
    158 /**
    159   * Generate packer instruction for a JSON field of type token envelope.
    160   *
    161   * @param name name of the field to add to the object
    162   * @param envelope blinded token envelope
    163   * @return json pack specification
    164  */
    165 struct GNUNET_JSON_PackSpec
    166 TALER_JSON_pack_token_envelope (
    167   const char *name,
    168   const struct TALER_TokenEnvelope *envelope);
    169 
    170 
    171 /**
    172  * Generate packer instruction for a JSON field of type
    173  * exchange blinding values (/blinding-prepare).
    174  *
    175  * @param name name of the field to add to the object
    176  * @param ewv values to transmit
    177  * @return json pack specification
    178  */
    179 struct GNUNET_JSON_PackSpec
    180 TALER_JSON_pack_exchange_blinding_values (
    181   const char *name,
    182   const struct TALER_ExchangeBlindingValues *ewv);
    183 
    184 /**
    185  * Generate packer instruction for a JSON field of type
    186  * blinding prepare response (/blinding-prepare).
    187  *
    188  * @param name name of the field to add to the object
    189  * @param bpr blinding prepare response to transmit
    190  * @return json pack specification
    191  */
    192 struct GNUNET_JSON_PackSpec
    193 TALER_JSON_pack_blinding_prepare_response (
    194   const char *name,
    195   const struct TALER_BlindingPrepareResponse *bpr);
    196 
    197 
    198 /**
    199  * Generate packer instruction for a JSON field of type
    200  * amount.
    201  *
    202  * @param name name of the field to add to the object
    203  * @param amount valid amount to pack
    204  * @return json pack specification
    205  */
    206 struct GNUNET_JSON_PackSpec
    207 TALER_JSON_pack_amount (
    208   const char *name,
    209   const struct TALER_Amount *amount);
    210 
    211 
    212 /**
    213  * Generate packer instruction for a JSON field that contains an array of
    214  * amounts (as strings). If @a amounts is NULL, emits JSON null.
    215  *
    216  * @param name field name
    217  * @param len number of elements in @a amounts
    218  * @param amounts array to encode
    219  * @return json pack specification
    220  */
    221 struct GNUNET_JSON_PackSpec
    222 TALER_JSON_pack_amount_array (const char *name,
    223                               size_t len,
    224                               const struct TALER_Amount *amounts);
    225 
    226 
    227 /**
    228  * Generate packer instruction for a JSON field that contains a price
    229  * list (as an array of amount strings).  Unlike
    230  * #TALER_JSON_pack_amount_array(), an empty list is emitted as an
    231  * empty array and not as JSON null, because for a price list "empty"
    232  * is the meaningful value "free".
    233  *
    234  * @param name field name
    235  * @param al price list to encode
    236  * @return json pack specification
    237  */
    238 struct GNUNET_JSON_PackSpec
    239 TALER_JSON_pack_amount_list (const char *name,
    240                              const struct TALER_AmountList *al);
    241 
    242 
    243 /**
    244  * Generate packer instruction for a JSON field of type
    245  * full payto.
    246  *
    247  * @param name name of the field to add to the object
    248  * @param payto payto URI to pack
    249  * @return json pack specification
    250  */
    251 struct GNUNET_JSON_PackSpec
    252 TALER_JSON_pack_full_payto (
    253   const char *name,
    254   const struct TALER_FullPayto payto);
    255 
    256 
    257 /**
    258  * Generate packer instruction for a JSON field of type
    259  * normalized payto.
    260  *
    261  * @param name name of the field to add to the object
    262  * @param payto payto URI to pack
    263  * @return json pack specification
    264  */
    265 struct GNUNET_JSON_PackSpec
    266 TALER_JSON_pack_normalized_payto (
    267   const char *name,
    268   const struct TALER_NormalizedPayto payto);
    269 
    270 
    271 /**
    272  * Generate packer instruction for a JSON field of type
    273  * encrypted contract.
    274  *
    275  * @param name name of the field to add to the object
    276  * @param econtract the encrypted contract
    277  * @return json pack specification
    278  */
    279 struct GNUNET_JSON_PackSpec
    280 TALER_JSON_pack_econtract (
    281   const char *name,
    282   const struct TALER_EncryptedContract *econtract);
    283 
    284 /**
    285  * Generate packer instruction for a JSON field of type age_commitment
    286  *
    287  * @param name name of the field to add to the object
    288  * @param age_commitment age commitment to add
    289  * @return json pack specification
    290  */
    291 struct GNUNET_JSON_PackSpec
    292 TALER_JSON_pack_age_commitment (
    293   const char *name,
    294   const struct TALER_AgeCommitment *age_commitment);
    295 
    296 
    297 /**
    298  * Generate packer instruction of a KYC Trigger Event.
    299  *
    300  * @param name name of the field to add to the object
    301  * @param event event type to add
    302  * @return json pack specification
    303  */
    304 struct GNUNET_JSON_PackSpec
    305 TALER_JSON_pack_kycte (const char *name,
    306                        enum TALER_KYCLOGIC_KycTriggerEvent event);
    307 
    308 /**
    309  * Convert a TALER amount to a JSON object.
    310  *
    311  * @param amount the amount
    312  * @return a json object describing the amount
    313  */
    314 json_t *
    315 TALER_JSON_from_amount (const struct TALER_Amount *amount);
    316 
    317 
    318 /**
    319  * Convert a currency specification to the
    320  * respective JSON object.
    321  *
    322  * @param cspec currency specification
    323  * @return JSON object encoding @a cspec for `/config`.
    324  */
    325 json_t *
    326 TALER_JSON_currency_specs_to_json (
    327   const struct TALER_CurrencySpecification *cspec);
    328 
    329 
    330 /**
    331  * Generate packer for a fixed length array (tuple) of packers.
    332  * The packers should be build with GNUNET_JSON_PACK.
    333  *
    334  * @param name name of the field to add to the object
    335  * @param packers packers to take the values from, in order.
    336  * @return json pack specification
    337  */
    338 struct GNUNET_JSON_PackSpec
    339 TALER_JSON_pack_tuple (
    340   const char *name,
    341   const struct GNUNET_JSON_PackSpec packers[]);
    342 
    343 /**
    344  * Generate packer for an array of data of the same size,
    345  * encoded in Crockford base32-encoding.
    346  *
    347  * @param name name of the field to add to the object
    348  * @param num number of elements in the @a array
    349  * @param data pointer to the list of elements
    350  * @param size size of an individual element
    351  * @return json pack specification
    352  */
    353 struct GNUNET_JSON_PackSpec
    354 TALER_JSON_pack_array_of_data (
    355   const char *name,
    356   size_t num,
    357   const void *data,
    358   size_t size);
    359 
    360 /**
    361  * Generate packer for an array of data of the same size,
    362  * encoded in Crockford base32-encoding.
    363  * The size is taken via sizeof().
    364  *
    365  * @param name name of the field to add to the object
    366  * @param num number of elements in the @a array
    367  * @param data pointer to the list of elements
    368  * @return json pack specification
    369  */
    370 #define TALER_JSON_pack_array_of_data_auto(name,num,data) \
    371         TALER_JSON_pack_array_of_data ((name), \
    372                                        (num), \
    373                                        (data), \
    374                                        sizeof(*(data)))
    375 
    376 
    377 /******************  Specs For Parsing JSON  *********************/
    378 
    379 
    380 /**
    381  * Provide specification to parse given JSON object to an amount.
    382  * The @a currency must be a valid pointer while the
    383  * parsing is done, a copy is not made.
    384  *
    385  * @param name name of the amount field in the JSON
    386  * @param currency the currency the amount must be in
    387  * @param[out] r_amount where the amount has to be written
    388  * @return spec for parsing an amount
    389  */
    390 struct GNUNET_JSON_Specification
    391 TALER_JSON_spec_amount (const char *name,
    392                         const char *currency,
    393                         struct TALER_Amount *r_amount);
    394 
    395 
    396 /**
    397  * Result specification for an array of amounts. Elements must be strings in
    398  * the usual "CUR:VAL.FRAC" notation. Allocates *@a amounts and sets
    399  * @a amounts_len on success. Use GNUNET_JSON_parse_free() to release the array.
    400  *
    401  * @param field name of the field to parse
    402  * @param amounts_len where to store the array length
    403  * @param amounts where the allocated array pointer is written
    404  */
    405 struct GNUNET_JSON_Specification
    406 TALER_JSON_spec_amount_any_array (const char *field,
    407                                   size_t *amounts_len,
    408                                   struct TALER_Amount **amounts);
    409 
    410 
    411 /**
    412  * Result specification for a price list.  Elements must be strings in
    413  * the usual "CUR:VAL.FRAC" notation, and no currency may appear twice
    414  * --- otherwise a hostile peer could advertise a price twice and have
    415  * #TALER_amount_list_find() and a UI disagree about which one applies.
    416  * Use GNUNET_JSON_parse_free() to release the list.
    417  *
    418  * @param field name of the field to parse
    419  * @param[out] al where to store the price list
    420  */
    421 struct GNUNET_JSON_Specification
    422 TALER_JSON_spec_amount_list (const char *field,
    423                              struct TALER_AmountList *al);
    424 
    425 
    426 /**
    427  * Provide specification to parse given JSON object to
    428  * a currency specification.
    429  *
    430  * @param name name of the amount field in the JSON
    431  * @param currency_code currency code to parse
    432  * @param[out] r_cspec where the currency spec has to be written
    433  * @return spec for parsing an amount
    434  */
    435 struct GNUNET_JSON_Specification
    436 TALER_JSON_spec_currency_specification (
    437   const char *name,
    438   const char *currency_code,
    439   struct TALER_CurrencySpecification *r_cspec);
    440 
    441 
    442 /**
    443  * Provide specification to parse given JSON object to an amount
    444  * in any currency.
    445  *
    446  * @param name name of the amount field in the JSON
    447  * @param[out] r_amount where the amount has to be written
    448  * @return spec for parsing an amount
    449  */
    450 struct GNUNET_JSON_Specification
    451 TALER_JSON_spec_amount_any (const char *name,
    452                             struct TALER_Amount *r_amount);
    453 
    454 
    455 /**
    456  * Provide specification to parse given JSON object to an encrypted contract.
    457  *
    458  * @param name name of the amount field in the JSON
    459  * @param[out] econtract where to store the encrypted contract
    460  * @return spec for parsing an amount
    461  */
    462 struct GNUNET_JSON_Specification
    463 TALER_JSON_spec_econtract (const char *name,
    464                            struct TALER_EncryptedContract *econtract);
    465 
    466 
    467 /**
    468  * Provide specification to parse a given JSON object to an age commitment.
    469  *
    470  * @param name name of the age commitment field in the JSON
    471  * @param[out] age_commitment where to store the age commitment
    472  * @return spec for parsing an age commitment
    473  */
    474 struct GNUNET_JSON_Specification
    475 TALER_JSON_spec_age_commitment (const char *name,
    476                                 struct TALER_AgeCommitment *age_commitment);
    477 
    478 
    479 /**
    480  * Provide specification to parse an OTP key.
    481  * An OTP key must be an RFC 3548 base32-encoded
    482  * value (so NOT our usual Crockford-base32 encoding!).
    483  *
    484  * @param name name of the OTP key field in the JSON
    485  * @param[out] otp_key where to store the OTP key
    486  * @return spec for parsing an age commitment
    487  */
    488 struct GNUNET_JSON_Specification
    489 TALER_JSON_spec_otp_key (const char *name,
    490                          const char **otp_key);
    491 
    492 
    493 /**
    494  * Provide specification to parse an OTP method type.
    495  * The value could be provided as an integer or
    496  * as a descriptive string.
    497  *
    498  * @param name name of the OTP method type in the JSON
    499  * @param[out] mca where to store the method type
    500  * @return spec for parsing an age commitment
    501  */
    502 struct GNUNET_JSON_Specification
    503 TALER_JSON_spec_otp_type (const char *name,
    504                           enum TALER_MerchantConfirmationAlgorithm *mca);
    505 
    506 
    507 /**
    508  * Provide specification to parse a KYC trigger
    509  * event type.
    510  * The value could be provided as an integer or
    511  * as a descriptive string.
    512  *
    513  * @param name name of the KYC trigger event type in the JSON
    514  * @param[out] kte where to store the operation type
    515  * @return spec for parsing trigger event type
    516  */
    517 struct GNUNET_JSON_Specification
    518 TALER_JSON_spec_kycte (const char *name,
    519                        enum TALER_KYCLOGIC_KycTriggerEvent *kte);
    520 
    521 
    522 /**
    523  * Generate specification to parse all fees for
    524  * a denomination under a prefix @a pfx.
    525  *
    526  * @param pfx string prefix to use
    527  * @param currency which currency to expect
    528  * @param[out] dfs a `struct TALER_DenomFeeSet` to initialize
    529  */
    530 #define TALER_JSON_SPEC_DENOM_FEES(pfx,currency,dfs) \
    531         TALER_JSON_spec_amount (pfx "_withdraw", (currency), &(dfs)->withdraw), \
    532         TALER_JSON_spec_amount (pfx "_deposit", (currency), &(dfs)->deposit),   \
    533         TALER_JSON_spec_amount (pfx "_refresh", (currency), &(dfs)->refresh),   \
    534         TALER_JSON_spec_amount (pfx "_refund", (currency), &(dfs)->refund)
    535 
    536 
    537 /**
    538  * Macro to pack all of a denominations' fees under
    539  * a given @a pfx.
    540  *
    541  * @param pfx string prefix to use
    542  * @param dfs a `struct TALER_DenomFeeSet` to pack
    543  */
    544 #define TALER_JSON_PACK_DENOM_FEES(pfx, dfs) \
    545         TALER_JSON_pack_amount (pfx "_withdraw", &(dfs)->withdraw),   \
    546         TALER_JSON_pack_amount (pfx "_deposit", &(dfs)->deposit),     \
    547         TALER_JSON_pack_amount (pfx "_refresh", &(dfs)->refresh),     \
    548         TALER_JSON_pack_amount (pfx "_refund", &(dfs)->refund)
    549 
    550 
    551 /**
    552  * Generate specification to parse all global fees.
    553  *
    554  * @param currency which currency to expect
    555  * @param[out] gfs a `struct TALER_GlobalFeeSet` to initialize
    556  */
    557 #define TALER_JSON_SPEC_GLOBAL_FEES(currency,gfs) \
    558         TALER_JSON_spec_amount ("history_fee", (currency), &(gfs)->history),   \
    559         TALER_JSON_spec_amount ("account_fee", (currency), &(gfs)->account),   \
    560         TALER_JSON_spec_amount ("purse_fee", (currency), &(gfs)->purse)
    561 
    562 /**
    563  * Macro to pack all of the global fees.
    564  *
    565  * @param gfs a `struct TALER_GlobalFeeSet` to pack
    566  */
    567 #define TALER_JSON_PACK_GLOBAL_FEES(gfs) \
    568         TALER_JSON_pack_amount ("history_fee", &(gfs)->history),     \
    569         TALER_JSON_pack_amount ("account_fee", &(gfs)->account),     \
    570         TALER_JSON_pack_amount ("purse_fee", &(gfs)->purse)
    571 
    572 
    573 /**
    574  * Generate a parser for a group of denominations.
    575  *
    576  * @param[in] field name of the field, maybe NULL
    577  * @param[in] currency name of the currency
    578  * @param[out] group denomination group information
    579  * @return corresponding field spec
    580  */
    581 struct GNUNET_JSON_Specification
    582 TALER_JSON_spec_denomination_group (const char *field,
    583                                     const char *currency,
    584                                     struct TALER_DenominationGroup *group);
    585 
    586 /**
    587  * Generate line in parser specification for denomination public key.
    588  *
    589  * @param field name of the field
    590  * @param[out] pk key to initialize
    591  * @return corresponding field spec
    592  */
    593 struct GNUNET_JSON_Specification
    594 TALER_JSON_spec_denom_pub (const char *field,
    595                            struct TALER_DenominationPublicKey *pk);
    596 
    597 /**
    598  * Generate line in parser specification for token issue public key.
    599  *
    600  * @param field name of the field
    601  * @param[out] pk key to initialize
    602  * @return corresponding field spec
    603  */
    604 struct GNUNET_JSON_Specification
    605 TALER_JSON_spec_token_pub (const char *field,
    606                            struct TALER_TokenIssuePublicKey *pk);
    607 
    608 
    609 /**
    610  * Generate line in parser specification for error codes.
    611  *
    612  * @param field name of the field
    613  * @param[out] ec error code to initialize
    614  * @return corresponding field spec
    615  */
    616 struct GNUNET_JSON_Specification
    617 TALER_JSON_spec_ec (const char *field,
    618                     enum TALER_ErrorCode *ec);
    619 
    620 
    621 /**
    622  * Generate line in parser specification for
    623  * HTTP/HTTPS URLs.
    624  *
    625  * @param field name of the field
    626  * @param[out] url web URL to initialize
    627  * @return corresponding field spec
    628  */
    629 struct GNUNET_JSON_Specification
    630 TALER_JSON_spec_web_url (const char *field,
    631                          const char **url);
    632 
    633 
    634 /**
    635  * Generate line in parser specification for
    636  * HTTP/HTTPS URLs.  Creates a copy of the original string.
    637  *
    638  * @param field name of the field
    639  * @param[out] url web URL to initialize
    640  * @return corresponding field spec
    641  */
    642 struct GNUNET_JSON_Specification
    643 TALER_JSON_spec_web_url_copy (const char *field,
    644                               char **url);
    645 
    646 
    647 /**
    648  * Generate line in parser specification for slugs (URL-safe identifiers).
    649  *
    650  * @param field name of the field
    651  * @param[out] slug string to initialize
    652  * @return corresponding field spec
    653  */
    654 struct GNUNET_JSON_Specification
    655 TALER_JSON_spec_slug (const char *field,
    656                       const char **slug);
    657 
    658 
    659 /**
    660  * Generate line in parser specification for slugs (URL-safe identifiers).
    661  * Creates a copy of the original string.
    662  *
    663  * @param field name of the field
    664  * @param[out] slug string to initialize
    665  * @return corresponding field spec
    666  */
    667 struct GNUNET_JSON_Specification
    668 TALER_JSON_spec_slug_copy (const char *field,
    669                            char **slug);
    670 
    671 
    672 /**
    673  * Generate line in parser specification for session IDs
    674  * (see #TALER_is_session_id()).  The empty session ID is
    675  * allowed and is the canonical way for a client to say that
    676  * a payment is not bound to any session (wallets do send it
    677  * that way).
    678  *
    679  * @param field name of the field
    680  * @param[out] session_id string to initialize
    681  * @return corresponding field spec
    682  */
    683 struct GNUNET_JSON_Specification
    684 TALER_JSON_spec_session_id (const char *field,
    685                             const char **session_id);
    686 
    687 
    688 /**
    689  * Generate line in parser specification for session IDs that
    690  * must not be empty.  Same as #TALER_JSON_spec_session_id(),
    691  * except for requests that only make sense for an actual
    692  * session.
    693  *
    694  * @param field name of the field
    695  * @param[out] session_id string to initialize
    696  * @return corresponding field spec
    697  */
    698 struct GNUNET_JSON_Specification
    699 TALER_JSON_spec_nonempty_session_id (const char *field,
    700                                      const char **session_id);
    701 
    702 
    703 /**
    704  * Generate line in parser specification for full
    705  * "payto://" URIs.
    706  *
    707  * @param field name of the field
    708  * @param[out] payto_uri RFC 8905 URI to initialize
    709  * @return corresponding field spec
    710  */
    711 struct GNUNET_JSON_Specification
    712 TALER_JSON_spec_full_payto_uri (
    713   const char *field,
    714   struct TALER_FullPayto *payto_uri);
    715 
    716 
    717 /**
    718  * Generate line in parser specification for normalized
    719  * "payto://" URIs.
    720  *
    721  * @param field name of the field
    722  * @param[out] payto_uri RFC 8905 URI to initialize
    723  * @return corresponding field spec
    724  */
    725 struct GNUNET_JSON_Specification
    726 TALER_JSON_spec_normalized_payto_uri (
    727   const char *field,
    728   struct TALER_NormalizedPayto *payto_uri);
    729 
    730 
    731 /**
    732  * Representation of a protocol version.
    733  */
    734 struct TALER_JSON_ProtocolVersion
    735 {
    736   /**
    737    * Current version of the protocol.
    738    */
    739   unsigned int current;
    740 
    741   /**
    742    * Implementation revision for the @e current
    743    * version.
    744    */
    745   unsigned int revision;
    746 
    747   /**
    748    * Number of protocol versions this @e revision is
    749    * backwards-compatible with.  Subtract this number
    750    * from @e current to get the minimum protocol version
    751    * required from the client.
    752    */
    753   unsigned int age;
    754 };
    755 
    756 
    757 /**
    758  * Generate line in parser specification for protocol
    759  * versions (``/config``). The field must be a string
    760  * encoding the version as "$CURRENT:$REVISION:$AGE".
    761  *
    762  * @param field name of the field (usually "version")
    763  * @param[out] ver protocol versions to initialize
    764  * @return corresponding field spec
    765  */
    766 struct GNUNET_JSON_Specification
    767 TALER_JSON_spec_version (
    768   const char *field,
    769   struct TALER_JSON_ProtocolVersion *ver);
    770 
    771 
    772 /**
    773  * Generate a parser specification for a denomination public key of a given
    774  * cipher.
    775  *
    776  * @param field name of the field
    777  * @param cipher which cipher type to parse for
    778  * @param[out] pk key to fill
    779  * @return corresponding field spec
    780  */
    781 struct GNUNET_JSON_Specification
    782 TALER_JSON_spec_denom_pub_cipher (
    783   const char *field,
    784   enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher,
    785   struct TALER_DenominationPublicKey *pk);
    786 
    787 
    788 /**
    789  * Generate line in parser specification for denomination signature.
    790  *
    791  * @param field name of the field
    792  * @param[out] sig the signature to initialize
    793  * @return corresponding field spec
    794  */
    795 struct GNUNET_JSON_Specification
    796 TALER_JSON_spec_denom_sig (
    797   const char *field,
    798   struct TALER_DenominationSignature *sig);
    799 
    800 
    801 /**
    802  * Generate line in parser specification for a
    803  * blinded denomination signature.
    804  *
    805  * @param field name of the field
    806  * @param[out] sig the blinded signature to initialize
    807  * @return corresponding field spec
    808  */
    809 struct GNUNET_JSON_Specification
    810 TALER_JSON_spec_blinded_denom_sig (
    811   const char *field,
    812   struct TALER_BlindedDenominationSignature *sig);
    813 
    814 
    815 /**
    816  * Generate line in parser specification for
    817  * exchange blinding values (/blinding-prepare).
    818  *
    819  * @param field name of the field
    820  * @param[out] ewv the exchange blinding values to initialize
    821  * @return corresponding field spec
    822  */
    823 struct GNUNET_JSON_Specification
    824 TALER_JSON_spec_exchange_blinding_values (
    825   const char *field,
    826   struct TALER_ExchangeBlindingValues *ewv);
    827 
    828 
    829 /**
    830  * Generate line in parser specification for a
    831  * blinded planchet.
    832  *
    833  * @param field name of the field
    834  * @param[out] blinded_planchet the blinded planchet to initialize
    835  * @return corresponding field spec
    836  */
    837 struct GNUNET_JSON_Specification
    838 TALER_JSON_spec_blinded_planchet (
    839   const char *field,
    840   struct TALER_BlindedPlanchet *blinded_planchet);
    841 
    842 
    843 /**
    844  * The expected field stores a possibly internationalized string.
    845  * Internationalization means that there is another field "$name_i18n"
    846  * which is an object where the keys are languages.  If this is
    847  * present, and if @a language_pattern is non-NULL, this function
    848  * should return the best match from @a language pattern from the
    849  * "_i18n" field.  If no language matches, the normal field under
    850  * @a name is to be returned.
    851  *
    852  * The @a language_pattern is given using the format from
    853  * https://tools.ietf.org/html/rfc7231#section-5.3.1
    854  * so that #TALER_pattern_matches() can be used.
    855  *
    856  * @param name name of the JSON field
    857  * @param language_pattern language pattern to use to find best match, possibly NULL
    858  * @param[out] strptr where to store a pointer to the field with the best variant
    859  */
    860 struct GNUNET_JSON_Specification
    861 TALER_JSON_spec_i18n_string (
    862   const char *name,
    863   const char *language_pattern,
    864   const char **strptr);
    865 
    866 
    867 /**
    868  * The expected field stores a possibly internationalized string.
    869  * Internationalization means that there is another field "$name_i18n" which
    870  * is an object where the keys are languages.  If this is present, this
    871  * function should return the best match based on the locale from the "_i18n"
    872  * field.  If no language matches, the normal field under @a name is to be
    873  * returned.
    874  *
    875  * @param name name of the JSON field
    876  * @param[out] strptr where to store a pointer to the field with the best variant
    877  */
    878 struct GNUNET_JSON_Specification
    879 TALER_JSON_spec_i18n_str (
    880   const char *name,
    881   const char **strptr);
    882 
    883 
    884 /**
    885  * Generate line in parser specification for a
    886  * token issue signature.
    887  *
    888  * @param field name of the field
    889  * @param[out] sig the signature to initialize
    890  * @return corresponding field spec
    891  */
    892 struct GNUNET_JSON_Specification
    893 TALER_JSON_spec_token_issue_sig (
    894   const char *field,
    895   struct TALER_TokenIssueSignature *sig);
    896 
    897 
    898 /**
    899  * Generate line in parser specification for a
    900  * blinded token issue signature.
    901  *
    902  * @param field name of the field
    903  * @param[out] sig the blinded signature to initialize
    904  * @return corresponding field spec
    905  */
    906 struct GNUNET_JSON_Specification
    907 TALER_JSON_spec_blinded_token_issue_sig (
    908   const char *field,
    909   struct TALER_BlindedTokenIssueSignature *sig);
    910 
    911 /**
    912  * Generate line in parser specification for a
    913  * token envelope.
    914  *
    915  * @param field name of the field
    916  * @param[out] env the envelope to initialize
    917  * @return corresponding field spec
    918  */
    919 struct GNUNET_JSON_Specification
    920 TALER_JSON_spec_token_envelope (
    921   const char *field,
    922   struct TALER_TokenEnvelope *env);
    923 
    924 
    925 /**
    926   * Generate a parser for a tuple, i.e. fixed-length array,
    927   * of individual values, parsed with individual parsers.
    928   *
    929   * @param field name of the field, might be NULL
    930   * @param specs array of specs, must end with GNUNET_JSON_spec_end
    931   */
    932 struct GNUNET_JSON_Specification
    933 TALER_JSON_spec_tuple_of (
    934   const char *field,
    935   struct GNUNET_JSON_Specification specs[]);
    936 
    937 
    938 /**
    939  * Generate a parser for an array of fixed-size elements,
    940  * with given number of entries and sizes.
    941  *
    942  * @param field name of the field for the array, might be NULL
    943  * @param entry_size size of each of the @e num_entries entries in @e entries
    944  * @param[out] num_entries number of entries found in the array
    945  * @param[out] entries pointer to the beginning of @e num_entries continuous entries of size @e entry_size each
    946  */
    947 struct GNUNET_JSON_Specification
    948 TALER_JSON_spec_array_of_data (
    949   const char *field,
    950   size_t entry_size,
    951   size_t *num_entries,
    952   void **entries);
    953 
    954 
    955 /**
    956  * Generate a parser for an array of known length of
    957  * blinded signatures of denomination public keys.
    958  *
    959  * @param field name of the field for the array, might be NULL
    960  * @param[out] num_entries number of entries found in the array
    961  * @param[out] entries pointer to write where the allocated array of @e num_entries entries is
    962  */
    963 struct GNUNET_JSON_Specification
    964 TALER_JSON_spec_array_of_blinded_denom_sigs (
    965   const char *field,
    966   size_t num_entries,
    967   struct TALER_BlindedDenominationSignature *entries);
    968 
    969 
    970 /**
    971  * Generate a parser for an array of unknown length of
    972  * hashes of denomination public keys.
    973  *
    974  * @param field name of the field for the array, might be NULL
    975  * @param[out] num_entries number of entries found in the array
    976  * @param[out] entries pointer to write where the allocated array of @e num_entries entries is
    977  */
    978 struct GNUNET_JSON_Specification
    979 TALER_JSON_spec_array_of_denom_pub_h (
    980   const char *field,
    981   size_t *num_entries,
    982   struct TALER_DenominationHashP **entries);
    983 
    984 
    985 /**
    986  * Generate a parser for an array of fixed-size elements,
    987  * with an unknown number of entries.
    988  *
    989  * @param field name of the field for the array, might be NULL
    990  * @param num_entries number of entries to find in the array
    991  * @param entries pointer to the beginning of @e num_entries continuous entries of size @e entry_size each, must be preallocated
    992  * @param entry_size size of each of the @e num_entries entries in @e entries
    993  */
    994 struct GNUNET_JSON_Specification
    995 TALER_JSON_spec_array_fixed (
    996   const char *field,
    997   size_t num_entries,
    998   void *entries,
    999   size_t entry_size);
   1000 
   1001 
   1002 /**
   1003  * Hash a JSON for binary signing.
   1004  *
   1005  * See https://tools.ietf.org/html/draft-rundgren-json-canonicalization-scheme-15
   1006  * for fun JSON canonicalization problems.  Callers must ensure that
   1007  * those are avoided in the input. We will use libjanson's "JSON_COMPACT"
   1008  * encoding for whitespace and "JSON_SORT_KEYS" to canonicalize as best
   1009  * as we can.
   1010  *
   1011  * @param[in] json some JSON value to hash
   1012  * @param[out] hc resulting hash code
   1013  * @return #GNUNET_OK on success,
   1014  *         #GNUNET_NO if @a json was malformed
   1015  *         #GNUNET_SYSERR on internal error
   1016  */
   1017 enum GNUNET_GenericReturnValue
   1018 TALER_JSON_contract_hash (
   1019   const json_t *json,
   1020   struct TALER_PrivateContractHashP *hc);
   1021 
   1022 
   1023 /**
   1024  * Take a given @a contract with "forgettable" fields marked in the @a spec
   1025  * with 'True' instead of a real salt. Replaces all 'True' values with proper
   1026  * random salts in the actual @a contract.  Fails if any forgettable markers
   1027  * are neither 'True' nor valid salts.
   1028  *
   1029  * @param spec specification with forgettable fields
   1030  * @param[in,out] contract JSON contract to transform
   1031  * @return #GNUNET_OK on success
   1032  */
   1033 enum GNUNET_GenericReturnValue
   1034 TALER_JSON_contract_seed_forgettable (
   1035   const json_t *spec,
   1036   json_t *contract);
   1037 
   1038 
   1039 /**
   1040  * Mark part of a contract object as 'forgettable'.
   1041  *
   1042  * @param[in,out] json some JSON object to modify
   1043  * @param field name of the field to mark as forgettable
   1044  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
   1045  */
   1046 enum GNUNET_GenericReturnValue
   1047 TALER_JSON_contract_mark_forgettable (
   1048   json_t *json,
   1049   const char *field);
   1050 
   1051 
   1052 /**
   1053  * Forget part of a contract object.
   1054  *
   1055  * @param[in,out] json some JSON object to modify
   1056  * @param field name of the field to forget
   1057  * @return #GNUNET_OK on success,
   1058  *         #GNUNET_NO if the field was already forgotten before
   1059  *         #GNUNET_SYSERR on error
   1060  */
   1061 enum GNUNET_GenericReturnValue
   1062 TALER_JSON_contract_part_forget (
   1063   json_t *json,
   1064   const char *field);
   1065 
   1066 
   1067 /**
   1068  * Called for each path found after expanding a path.
   1069  *
   1070  * @param cls the closure.
   1071  * @param object_id the name of the object that is pointed to.
   1072  * @param parent the parent of the object at @e object_id.
   1073  */
   1074 typedef void
   1075 (*TALER_JSON_ExpandPathCallback) (
   1076   void *cls,
   1077   const char *object_id,
   1078   json_t *parent);
   1079 
   1080 
   1081 /**
   1082  * Expands a path for a json object. May call the callback several times
   1083  * if the path contains a wildcard.
   1084  *
   1085  * @param json the json object the path references.
   1086  * @param path the path to expand. Must begin with "$." and follow dot notation,
   1087  *        and may include array indices and wildcards.
   1088  * @param cb the callback.
   1089  * @param cb_cls closure for the callback.
   1090  * @return #GNUNET_OK on success, #GNUNET_SYSERR if @e path is invalid.
   1091  */
   1092 enum GNUNET_GenericReturnValue
   1093 TALER_JSON_expand_path (
   1094   json_t *json,
   1095   const char *path,
   1096   TALER_JSON_ExpandPathCallback cb,
   1097   void *cb_cls);
   1098 
   1099 
   1100 /**
   1101  * Extract the Taler error code from the given @a json object.
   1102  * Note that #TALER_EC_NONE is returned if no "code" is present.
   1103  *
   1104  * @param json response to extract the error code from
   1105  * @return the "code" value from @a json
   1106  */
   1107 enum TALER_ErrorCode
   1108 TALER_JSON_get_error_code (const json_t *json);
   1109 
   1110 
   1111 /**
   1112  * Extract the Taler error hint from the given @a json object.
   1113  * Note that NULL is returned if no "hint" is present.
   1114  *
   1115  * @param json response to extract the error hint from
   1116  * @return the "hint" value from @a json; only valid as long as @a json is valid
   1117  */
   1118 const char *
   1119 TALER_JSON_get_error_hint (const json_t *json);
   1120 
   1121 
   1122 /**
   1123  * Extract the Taler error code from the given @a data object, which is expected to be in JSON.
   1124  * Note that #TALER_EC_INVALID is returned if no "code" is present or if @a data is not in JSON.
   1125  *
   1126  * @param data response to extract the error code from
   1127  * @param data_size number of bytes in @a data
   1128  * @return the "code" value from @a json
   1129  */
   1130 enum TALER_ErrorCode
   1131 TALER_JSON_get_error_code2 (const void *data,
   1132                             size_t data_size);
   1133 
   1134 
   1135 /* **************** /wire account offline signing **************** */
   1136 
   1137 /**
   1138  * Compute the hash of the given wire details.   The resulting
   1139  * hash is what is put into the contract.  Also performs rudimentary
   1140  * checks on the account data *if* supported.
   1141  *
   1142  * @param wire_s wire details to hash
   1143  * @param[out] hc set to the hash
   1144  * @return #GNUNET_OK on success, #GNUNET_SYSERR if @a wire_s is malformed
   1145  */
   1146 enum GNUNET_GenericReturnValue
   1147 TALER_JSON_merchant_wire_signature_hash (
   1148   const json_t *wire_s,
   1149   struct TALER_MerchantWireHashP *hc);
   1150 
   1151 
   1152 /**
   1153  * Extract a string from @a object under the field @a field, but respecting
   1154  * the Taler i18n rules and the language preferences expressed in @a
   1155  * language_pattern.
   1156  *
   1157  * Basically, the @a object may optionally contain a sub-object
   1158  * "${field}_i18n" with a map from IETF BCP 47 language tags to a localized
   1159  * version of the string. If this map exists and contains an entry that
   1160  * matches the @a language pattern, that object (usually a string) is
   1161  * returned. If the @a language_pattern does not match any entry, or if the
   1162  * i18n sub-object does not exist, we simply return @a field of @a object
   1163  * (also usually a string).
   1164  *
   1165  * If @a object does not have a member @a field we return NULL (error).
   1166  *
   1167  * @param object the object to extract internationalized
   1168  *        content from
   1169  * @param language_pattern a language preferences string
   1170  *        like "fr-CH, fr;q=0.9, en;q=0.8, *;q=0.1", following
   1171  *        https://tools.ietf.org/html/rfc7231#section-5.3.1
   1172  * @param field name of the field to extract
   1173  * @return NULL on error, otherwise the member from
   1174  *        @a object. Note that the reference counter is
   1175  *        NOT incremented.
   1176  */
   1177 const json_t *
   1178 TALER_JSON_extract_i18n (
   1179   const json_t *object,
   1180   const char *language_pattern,
   1181   const char *field);
   1182 
   1183 
   1184 /**
   1185  * Check whether a given @a i18n object is wellformed.
   1186  *
   1187  * @param i18n object with internationalized content
   1188  * @return true if @a i18n is well-formed
   1189  */
   1190 bool
   1191 TALER_JSON_check_i18n (
   1192   const json_t *i18n);
   1193 
   1194 
   1195 /**
   1196  * Obtain the wire method associated with the given
   1197  * wire account details.  @a wire_s must contain a payto://-URL
   1198  * under 'url'.
   1199  *
   1200  * @return NULL on error
   1201  */
   1202 char *
   1203 TALER_JSON_wire_to_method (
   1204   const json_t *wire_s);
   1205 
   1206 
   1207 /**
   1208  * Obtain the payto://-URL associated with the given
   1209  * wire account details.  @a wire_s must contain a payto://-URL
   1210  * under 'payto_uri'.
   1211  *
   1212  * @return NULL on error
   1213  */
   1214 struct TALER_FullPayto
   1215 TALER_JSON_wire_to_payto (
   1216   const json_t *wire_s);
   1217 
   1218 
   1219 /**
   1220  * Hash @a policy extensions in deposits.
   1221  *
   1222  * @param policy contract policy extension to hash
   1223  * @param[out] ech where to write the policy hash
   1224  */
   1225 void
   1226 TALER_deposit_policy_hash (
   1227   const json_t *policy,
   1228   struct TALER_ExtensionPolicyHashP *ech);
   1229 
   1230 
   1231 /**
   1232  * Canonicalize a JSON input to a string according to RFC 8785.
   1233  */
   1234 char *
   1235 TALER_JSON_canonicalize (
   1236   const json_t *input);
   1237 
   1238 
   1239 /**
   1240  * Handle to an external process that will assist
   1241  * with some JSON-to-JSON conversion.
   1242  */
   1243 struct TALER_JSON_ExternalConversion;
   1244 
   1245 /**
   1246  * Type of a callback that receives a JSON @a result.
   1247  *
   1248  * @param cls closure
   1249  * @param status_type how did the process die
   1250  * @param code termination status code from the process
   1251  * @param result some JSON result, NULL if we failed to get an JSON output
   1252  */
   1253 typedef void
   1254 (*TALER_JSON_JsonCallback) (
   1255   void *cls,
   1256   enum GNUNET_OS_ProcessStatusType status_type,
   1257   unsigned long code,
   1258   const json_t *result);
   1259 
   1260 
   1261 /**
   1262  * Launch some external helper @a binary to convert some @a input
   1263  * and eventually call @a cb with the result.
   1264  *
   1265  * @param input JSON to serialize and pass to the helper process
   1266  * @param cb function to call on the result
   1267  * @param cb_cls closure for @a cb
   1268  * @param binary name of the binary to execute
   1269  * @param argv NULL-terminated list of arguments for the @a binary,
   1270  *        usually starting with again the name of the binary
   1271  * @return handle to cancel the operation (and kill the helper)
   1272  */
   1273 struct TALER_JSON_ExternalConversion *
   1274 TALER_JSON_external_conversion_start (
   1275   const json_t *input,
   1276   TALER_JSON_JsonCallback cb,
   1277   void *cb_cls,
   1278   const char *binary,
   1279   const char **argv);
   1280 
   1281 /**
   1282  * Abort external conversion, killing the process and preventing
   1283  * the callback from being called. Must not be called after the
   1284  * callback was invoked.
   1285  *
   1286  * @param[in] ec external conversion handle to cancel
   1287  */
   1288 void
   1289 TALER_JSON_external_conversion_stop (
   1290   struct TALER_JSON_ExternalConversion *ec);
   1291 
   1292 
   1293 #endif /* TALER_JSON_LIB_H_ */
   1294 
   1295 /* End of taler_json_lib.h */