exchange

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

taler_util.h (33244B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2024 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_util.h
     18  * @brief Interface for common utility functions
     19  *        This library is not thread-safe, all APIs must only be used from a single thread.
     20  *        This library calls abort() if it runs out of memory. Be aware of these limitations.
     21  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
     22  * @author Christian Grothoff
     23  */
     24 #ifndef TALER_UTIL_H
     25 #define TALER_UTIL_H
     26 
     27 #include <gnunet/gnunet_common.h>
     28 #define __TALER_UTIL_LIB_H_INSIDE__
     29 
     30 #include <gnunet/gnunet_util_lib.h>
     31 #include <taler/taler_amount_lib.h>
     32 #include <taler/taler_crypto_lib.h>
     33 
     34 
     35 /**
     36  * Version of the Taler API, in hex.
     37  * Thus 0.8.4-1 = 0x00080401.
     38  */
     39 #define TALER_API_VERSION 0x000D0000
     40 
     41 /**
     42  * Stringify operator.
     43  *
     44  * @param a some expression to stringify. Must NOT be a macro.
     45  * @return same expression as a constant string.
     46  */
     47 #define TALER_S(a) #a
     48 
     49 /**
     50  * Stringify operator.
     51  *
     52  * @param a some expression to stringify. Can be a macro.
     53  * @return macro-expanded expression as a constant string.
     54  */
     55 #define TALER_QUOTE(a) TALER_S (a)
     56 
     57 
     58 /* Define logging functions */
     59 #define TALER_LOG_DEBUG(...)                                  \
     60         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
     61 
     62 #define TALER_LOG_INFO(...)                                  \
     63         GNUNET_log (GNUNET_ERROR_TYPE_INFO, __VA_ARGS__)
     64 
     65 #define TALER_LOG_WARNING(...)                                \
     66         GNUNET_log (GNUNET_ERROR_TYPE_WARNING, __VA_ARGS__)
     67 
     68 #define TALER_LOG_ERROR(...)                                  \
     69         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, __VA_ARGS__)
     70 
     71 
     72 /**
     73  * Tests a given as assertion and if failed prints it as a warning with the
     74  * given reason
     75  *
     76  * @param EXP the expression to test as assertion
     77  * @param reason string to print as warning
     78  */
     79 #define TALER_assert_as(EXP, reason)                           \
     80         do {                                                          \
     81           if (EXP) break;                                             \
     82           TALER_LOG_ERROR ("%s at %s:%d\n", reason, __FILE__, __LINE__);       \
     83           abort ();                                                    \
     84         } while (0)
     85 
     86 
     87 /**
     88  * HTTP header with an AML officer signature to approve the inquiry.
     89  * Used only in GET Requests.
     90  */
     91 #define TALER_AML_OFFICER_SIGNATURE_HEADER "Taler-AML-Officer-Signature"
     92 
     93 /**
     94  * Header with signature for reserve history requests.
     95  */
     96 #define TALER_RESERVE_HISTORY_SIGNATURE_HEADER "Taler-Reserve-History-Signature"
     97 
     98 /**
     99  * Header with signature for coin history requests.
    100  */
    101 #define TALER_COIN_HISTORY_SIGNATURE_HEADER "Taler-Coin-History-Signature"
    102 
    103 /**
    104  * Log an error message at log-level 'level' that indicates
    105  * a failure of the command 'cmd' with the message given
    106  * by gcry_strerror(rc).
    107  */
    108 #define TALER_LOG_GCRY_ERROR(cmd, rc) do { TALER_LOG_ERROR ( \
    109                                              "`%s' failed at %s:%d with error: %s\n", \
    110                                              cmd, __FILE__, __LINE__, \
    111                                              gcry_strerror (rc)); } while (0)
    112 
    113 
    114 #define TALER_gcry_ok(cmd) \
    115         do {int rc; rc = cmd; if (! rc) break; \
    116             TALER_LOG_ERROR ("A Gcrypt call failed at %s:%d with error: %s\n", \
    117                              __FILE__, \
    118                              __LINE__, gcry_strerror (rc)); abort (); } while (0 \
    119                                                                                )
    120 
    121 
    122 /**
    123  * Initialize Gcrypt library.
    124  */
    125 void
    126 TALER_gcrypt_init (void);
    127 
    128 
    129 /**
    130  * Convert a buffer to an 8-character string
    131  * representative of the contents. This is used
    132  * for logging binary data when debugging.
    133  *
    134  * @param buf buffer to log
    135  * @param buf_size number of bytes in @a buf
    136  * @return text representation of buf, valid until next
    137  *         call to this function
    138  */
    139 const char *
    140 TALER_b2s (const void *buf,
    141            size_t buf_size);
    142 
    143 
    144 /**
    145  * Compare two NUL-terminated strings @a a and @a b in constant time
    146  * with respect to their contents.  Used for comparing secret/MAC
    147  * material (authorization codes, PKCE challenges) to avoid leaking
    148  * information via a timing oracle, as plain strcmp() short-circuits
    149  * at the first differing byte.  Note that the string lengths may
    150  * still leak, which is acceptable here as the token length is not
    151  * a secret at all.
    152  *
    153  * @param a first string
    154  * @param b second string
    155  * @return 0 if the strings are equal, non-zero otherwise
    156  */
    157 int
    158 TALER_strcmp_ct (const char *a,
    159                  const char *b);
    160 
    161 
    162 /**
    163  * Convert a fixed-sized object to a string using
    164  * #TALER_b2s().
    165  *
    166  * @param obj address of object to convert
    167  * @return string representing the binary obj buffer
    168  */
    169 #define TALER_B2S(obj) TALER_b2s ((obj), sizeof (*(obj)))
    170 
    171 
    172 /**
    173  * Obtain denomination amount from configuration file.
    174  *
    175  * @param cfg configuration to extract data from
    176  * @param section section of the configuration to access
    177  * @param option option of the configuration to access
    178  * @param[out] denom set to the amount found in configuration
    179  * @return #GNUNET_OK on success,
    180  *         #GNUNET_NO if not found,
    181  *         #GNUNET_SYSERR on error
    182  */
    183 enum GNUNET_GenericReturnValue
    184 TALER_config_get_amount (const struct GNUNET_CONFIGURATION_Handle *cfg,
    185                          const char *section,
    186                          const char *option,
    187                          struct TALER_Amount *denom);
    188 
    189 
    190 /**
    191  * Obtain a price list of the form "EUR:1.1;CHF:1;USD:2" from the
    192  * configuration file, for options where the same thing may be
    193  * priced in several currencies at once.
    194  *
    195  * A plain "EUR:1.1" is a valid one-element list, so options that
    196  * used to be read with #TALER_config_get_amount() can be moved to
    197  * this function without invalidating existing configurations.
    198  *
    199  * @param cfg configuration to extract data from
    200  * @param section section of the configuration to access
    201  * @param option option of the configuration to access
    202  * @param[out] al set to the price list found in the configuration;
    203  *             the caller must eventually free it using
    204  *             #TALER_amount_list_free()
    205  * @return #GNUNET_OK on success,
    206  *         #GNUNET_NO if not found (@a al is set to the empty list),
    207  *         #GNUNET_SYSERR on error
    208  */
    209 enum GNUNET_GenericReturnValue
    210 TALER_config_get_amount_list (const struct GNUNET_CONFIGURATION_Handle *cfg,
    211                               const char *section,
    212                               const char *option,
    213                               struct TALER_AmountList *al);
    214 
    215 
    216 /**
    217  * Obtain denomination fee structure of a
    218  * denomination from configuration file.  All
    219  * fee options must start with "fee_" and have
    220  * names typical for the respective fees.
    221  *
    222  * @param cfg configuration to extract data from
    223  * @param currency expected currency
    224  * @param section section of the configuration to access
    225  * @param[out] fees set to the denomination fees
    226  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
    227  */
    228 enum GNUNET_GenericReturnValue
    229 TALER_config_get_denom_fees (const struct GNUNET_CONFIGURATION_Handle *cfg,
    230                              const char *currency,
    231                              const char *section,
    232                              struct TALER_DenomFeeSet *fees);
    233 
    234 
    235 /**
    236  * Check that all denominations in @a fees use
    237  * @a currency
    238  *
    239  * @param currency desired currency
    240  * @param fees fee set to check
    241  * @return #GNUNET_OK on success
    242  */
    243 enum GNUNET_GenericReturnValue
    244 TALER_denom_fee_check_currency (
    245   const char *currency,
    246   const struct TALER_DenomFeeSet *fees);
    247 
    248 
    249 /**
    250  * Load our currency from the @a cfg in @a section
    251  * the option "CURRENCY".
    252  *
    253  * @param cfg configuration to use
    254  * @param section configuration section to inspect
    255  * @param[out] currency where to write the result
    256  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
    257  */
    258 enum GNUNET_GenericReturnValue
    259 TALER_config_get_currency (const struct GNUNET_CONFIGURATION_Handle *cfg,
    260                            const char *section,
    261                            char **currency);
    262 
    263 
    264 /**
    265  * Details about how to render a currency.
    266  */
    267 struct TALER_CurrencySpecification
    268 {
    269   /**
    270    * Currency code of the currency.
    271    */
    272   char currency[TALER_CURRENCY_LEN];
    273 
    274   /**
    275    * Human-readable long name of the currency, e.g.
    276    * "Japanese Yen".
    277    */
    278   char *name;
    279 
    280   /**
    281    * how many digits the user may enter at most after the @e decimal_separator
    282    */
    283   unsigned int num_fractional_input_digits;
    284 
    285   /**
    286    * how many digits we render in normal scale after the @e decimal_separator
    287    */
    288   unsigned int num_fractional_normal_digits;
    289 
    290   /**
    291    * how many digits we render in after the @e decimal_separator even if all
    292    * remaining digits are zero.
    293    */
    294   unsigned int num_fractional_trailing_zero_digits;
    295 
    296   /**
    297    * Mapping of powers of 10 to alternative currency names or symbols.
    298    * Keys are the decimal powers, values the currency symbol to use.
    299    * Map MUST contain an entry for "0" to the default currency symbol.
    300    */
    301   json_t *map_alt_unit_names;
    302 
    303   /**
    304    * Amounts wallet should display as short-cuts (for example,
    305    * in the withdraw dialog).
    306    */
    307   struct TALER_Amount *common_amounts;
    308 
    309   /**
    310    * Length of the @e common_amounts array.
    311    */
    312   unsigned int num_common_amounts;
    313 
    314 };
    315 
    316 
    317 /**
    318  * Parse information about supported currencies from
    319  * our configuration.
    320  *
    321  * @param cfg configuration to parse
    322  * @param main_currency main currency of the component
    323  * @param[out] num_currencies set to number of enabled currencies, length of @e cspecs
    324  * @param[out] cspecs set to currency specification array
    325  * @return #GNUNET_OK on success, #GNUNET_NO if zero
    326  *  currency specifications were enabled,
    327  *  #GNUNET_SYSERR if the configuration was malformed
    328  */
    329 enum GNUNET_GenericReturnValue
    330 TALER_CONFIG_parse_currencies (const struct GNUNET_CONFIGURATION_Handle *cfg,
    331                                const char *main_currency,
    332                                unsigned int *num_currencies,
    333                                struct TALER_CurrencySpecification **cspecs);
    334 
    335 
    336 /**
    337  * Free @a cspecs array.
    338  *
    339  * @param num_currencies length of @a cspecs array
    340  * @param[in] cspecs array to free
    341  */
    342 void
    343 TALER_CONFIG_free_currencies (
    344   unsigned int num_currencies,
    345   struct TALER_CurrencySpecification cspecs[static num_currencies]);
    346 
    347 
    348 /**
    349  * Check that @a map contains a valid currency scale
    350  * map that maps integers from [-12,24] to currency
    351  * symbols given as strings.
    352  *
    353  * @param map map to check
    354  * @return #GNUNET_OK if @a map is valid
    355  */
    356 enum GNUNET_GenericReturnValue
    357 TALER_check_currency_scale_map (const json_t *map);
    358 
    359 
    360 /**
    361  * Allow user to specify an amount on the command line.
    362  *
    363  * @param shortName short name of the option
    364  * @param name long name of the option
    365  * @param argumentHelp help text for the option argument
    366  * @param description long help text for the option
    367  * @param[out] amount set to the amount specified at the command line
    368  */
    369 struct GNUNET_GETOPT_CommandLineOption
    370 TALER_getopt_get_amount (char shortName,
    371                          const char *name,
    372                          const char *argumentHelp,
    373                          const char *description,
    374                          struct TALER_Amount *amount);
    375 
    376 
    377 /**
    378  * Return default project data used by Taler exchange.
    379  */
    380 const struct GNUNET_OS_ProjectData *
    381 TALER_EXCHANGE_project_data (void);
    382 
    383 
    384 /**
    385  * Return default project data used by Taler auditor.
    386  */
    387 const struct GNUNET_OS_ProjectData *
    388 TALER_AUDITOR_project_data (void);
    389 
    390 
    391 /**
    392  * Return default project data used by Taler fakebank.
    393  */
    394 const struct GNUNET_OS_ProjectData *
    395 TALER_FAKEBANK_project_data (void);
    396 
    397 
    398 /**
    399  * Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2).
    400  *
    401  * @param[in,out] inp pointer to string to re-encode
    402  * @return number of bytes in resulting @a inp
    403  */
    404 size_t
    405 TALER_rfc8785encode (char **inp);
    406 
    407 
    408 /**
    409  * URL-encode a string according to rfc3986.
    410  *
    411  * @param s string to encode
    412  * @returns the urlencoded string, the caller must free it with GNUNET_free()
    413  */
    414 char *
    415 TALER_urlencode (const char *s);
    416 
    417 
    418 /**
    419  * Test if all characters in @a url are valid for
    420  * a URL.
    421  *
    422  * @param url URL to sanity-check
    423  * @return true if @a url only contains valid characters
    424  */
    425 bool
    426 TALER_url_valid_charset (const char *url);
    427 
    428 
    429 /**
    430  * Compare two full payto URIs for equality.
    431  *
    432  * @param a a full payto URI, NULL is permitted
    433  * @param b a full payto URI, NULL is permitted
    434  * @return 0 if both are equal, otherwise -1 or 1
    435  */
    436 int
    437 TALER_full_payto_cmp (const struct TALER_FullPayto a,
    438                       const struct TALER_FullPayto b);
    439 
    440 /**
    441  * Compare two full payto URIs for equality in their normalized form.
    442  *
    443  * @param a a full payto URI, NULL is permitted
    444  * @param b a full payto URI, NULL is permitted
    445  * @return 0 if both are equal, otherwise -1 or 1
    446  */
    447 int
    448 TALER_full_payto_normalize_and_cmp (const struct TALER_FullPayto a,
    449                                     const struct TALER_FullPayto b);
    450 
    451 
    452 /**
    453  * Compare two normalized payto URIs for equality.
    454  *
    455  * @param a a full payto URI, NULL is permitted
    456  * @param b a full payto URI, NULL is permitted
    457  * @return 0 if both are equal, otherwise -1 or 1
    458  */
    459 int
    460 TALER_normalized_payto_cmp (const struct TALER_NormalizedPayto a,
    461                             const struct TALER_NormalizedPayto b);
    462 
    463 
    464 /**
    465  * Check if payto URI identifies a Taler wallet.
    466  *
    467  * @param payto_uri (full or normalized) to check
    468  * @return true if the payto URI is for a wallet
    469  */
    470 bool
    471 TALER_payto_is_wallet (const char *payto_uri);
    472 
    473 
    474 /**
    475  * Test if the URL is a valid "http" (or "https")
    476  * URL (includes test for #TALER_url_valid_charset()).
    477  *
    478  * @param url a string to test if it could be a valid URL
    479  * @return true if @a url is well-formed
    480  */
    481 bool
    482 TALER_is_web_url (const char *url);
    483 
    484 
    485 /**
    486  * Check if a character is reserved and should be urlencoded.
    487  *
    488  * Unreserved characters:
    489  *   - ASCII letters: a-z A-Z
    490  *   - Digits: 0-9
    491  *   - Hyphen: -
    492  *   - Underscore: _
    493  *   - Period: .
    494  *   - Tilde: ~
    495  *
    496  * @param c character to look at
    497  * @return true if @a c needs to be urlencoded,
    498  *         false otherwise (@a c in [a-zA-Z0-9_~.-])
    499  */
    500 bool
    501 TALER_url_is_reserved (char c);
    502 
    503 
    504 /**
    505  * Test if the URL is a valid slug (URL-safe string).
    506  *
    507  * Allowed characters:
    508  *   - ASCII letters: a-z A-Z
    509  *   - Digits: 0-9
    510  *   - Hyphen: -
    511  *   - Underscore: _
    512  *   - Period: .
    513  *   - Colon: :
    514  *   - Tilde: ~ (needed for core banking account usernames)
    515  *
    516  * Additional restrictions:
    517  *   - must not be empty
    518  *   - must not be "." or ".."
    519  *   - must not contain '/'
    520  *   - must not contain percent-encoding '%'
    521  *
    522  * @param slug a string to test if it could be a valid slug
    523  * @return true if @a slug is well-formed
    524  */
    525 bool
    526 TALER_is_slug (const char *slug);
    527 
    528 
    529 /**
    530  * Test if @a session_id is a valid session ID, as used for
    531  * session-based payments at a merchant.
    532  *
    533  * A session ID is deliberately *not* a slug: it may be empty, and it
    534  * may contain '=' as session IDs are frequently base64-encoded
    535  * identifiers (such as the Paivana IDs) that end in padding.
    536  *
    537  * Allowed characters:
    538  *   - ASCII letters: a-z A-Z
    539  *   - Digits: 0-9
    540  *   - Hyphen: -
    541  *   - Underscore: _
    542  *   - Period: .
    543  *   - Colon: :
    544  *   - Equals: = (needed for base64-encoded identifiers)
    545  *   - Tilde: ~
    546  *
    547  * Additional restrictions:
    548  *   - must not be "." or ".."
    549  *   - must not contain '/'
    550  *   - must not contain percent-encoding '%'
    551  *
    552  * The empty session ID is valid and means that a payment is not bound
    553  * to any session; it is also what the merchant stores in its database
    554  * in that case, and what it puts into the "taler://pay/" URI of an
    555  * order without a session.  Requests where only an actual session
    556  * makes sense must thus check for the empty string in addition to
    557  * calling this function.
    558  *
    559  * @param session_id a string to test if it could be a valid session ID
    560  * @return true if @a session_id is well-formed
    561  */
    562 bool
    563 TALER_is_session_id (const char *session_id);
    564 
    565 
    566 /**
    567  * Check if @a lang matches the @a language_pattern, and if so with
    568  * which preference.
    569  * See also: https://tools.ietf.org/html/rfc7231#section-5.3.1
    570  *
    571  * @param pattern a preferences string
    572  *        like "fr-CH, fr;q=0.9, en;q=0.8, *;q=0.1"
    573  * @param value the value to match
    574  * @return q-weight given for @a value in @a pattern, 1.0 if no weights are given;
    575  *         0 if @a value is not in @a pattern
    576  */
    577 double
    578 TALER_pattern_matches (const char *pattern,
    579                        const char *value);
    580 
    581 
    582 /**
    583  * Make an absolute URL with query parameters.
    584  *
    585  * If a 'value' is given as NULL, both the key and the value are skipped. Note
    586  * that a NULL value does not terminate the list, only a NULL key signals the
    587  * end of the list of arguments.
    588  *
    589  * @param base_url absolute base URL to use, must either
    590  *          end with '/' *or* @a path must be the empty string
    591  * @param path path of the url to append to the @a base_url
    592  * @param ... NULL-terminated key-value pairs (char *) for query parameters,
    593  *        only the value will be url-encoded
    594  * @returns the URL, must be freed with #GNUNET_free
    595  */
    596 char *
    597 TALER_url_join (const char *base_url,
    598                 const char *path,
    599                 ...);
    600 
    601 
    602 /**
    603  * Make an absolute URL for the given parameters.
    604  *
    605  * If a 'value' is given as NULL, both the key and the value are skipped. Note
    606  * that a NULL value does not terminate the list, only a NULL key signals the
    607  * end of the list of arguments.
    608  *
    609  * @param proto protocol for the URL (typically https)
    610  * @param host hostname for the URL
    611  * @param prefix prefix for the URL
    612  * @param path path for the URL
    613  * @param ... NULL-terminated key-value pairs (char *) for query parameters,
    614  *        the value will be url-encoded
    615  * @returns the URL, must be freed with #GNUNET_free
    616  */
    617 char *
    618 TALER_url_absolute_raw (const char *proto,
    619                         const char *host,
    620                         const char *prefix,
    621                         const char *path,
    622                         ...);
    623 
    624 
    625 /**
    626  * Make an absolute URL for the given parameters.
    627  *
    628  * If a 'value' is given as NULL, both the key and the value are skipped. Note
    629  * that a NULL value does not terminate the list, only a NULL key signals the
    630  * end of the list of arguments.
    631  *
    632  * @param proto protocol for the URL (typically https)
    633  * @param host hostname for the URL
    634  * @param prefix prefix for the URL
    635  * @param path path for the URL
    636  * @param args NULL-terminated key-value pairs (char *) for query parameters,
    637  *        the value will be url-encoded
    638  * @returns the URL, must be freed with #GNUNET_free
    639  */
    640 char *
    641 TALER_url_absolute_raw_va (const char *proto,
    642                            const char *host,
    643                            const char *prefix,
    644                            const char *path,
    645                            va_list args);
    646 
    647 
    648 /**
    649  * Obtain the payment method from a @a payto_uri
    650  *
    651  * @param payto_uri the URL to parse
    652  * @return NULL on error (malformed @a payto_uri)
    653  */
    654 char *
    655 TALER_payto_get_method (const char *payto_uri);
    656 
    657 
    658 /**
    659  * Normalize payto://-URI to make "strcmp()" sufficient
    660  * to check if two payto-URIs refer to the same bank
    661  * account. Removes optional arguments (everything after
    662  * "?") and applies method-specific normalizations to
    663  * the main part of the URI.
    664  *
    665  * @param input a payto://-URI
    666  * @return normalized URI, or NULL if @a input was not well-formed
    667  */
    668 struct TALER_NormalizedPayto
    669 TALER_payto_normalize (const struct TALER_FullPayto input);
    670 
    671 
    672 /**
    673  * Normalize the given full payto URI and hash it.
    674  *
    675  * @param in full payto URI
    676  * @param[out] out hash of the normalized payto URI
    677  */
    678 void
    679 TALER_full_payto_normalize_and_hash (
    680   const struct TALER_FullPayto in,
    681   struct TALER_NormalizedPaytoHashP *out);
    682 
    683 
    684 /**
    685  * Obtain the account name from a payto URL.
    686  *
    687  * @param payto an x-taler-bank payto URL
    688  * @return only the account name from the @a payto URL, NULL if not an x-taler-bank
    689  *   payto URL
    690  */
    691 char *
    692 TALER_xtalerbank_account_from_payto (const struct TALER_FullPayto payto);
    693 
    694 
    695 /**
    696  * Obtain the receiver name from a payto URL.
    697  *
    698  * @param fpayto a full payto URL
    699  * @return only the receiver name from the @a payto URL, NULL if not a full payto URL
    700  */
    701 char *
    702 TALER_payto_get_receiver_name (const struct TALER_FullPayto fpayto);
    703 
    704 
    705 /**
    706  * Extract the subject value from the URI parameters.
    707  *
    708  * @param payto_uri the full URL to parse
    709  * @return NULL if the subject parameter is not found.
    710  *         The caller should free the returned value.
    711  */
    712 char *
    713 TALER_payto_get_subject (const struct TALER_FullPayto payto_uri);
    714 
    715 
    716 /**
    717  * Check that a full payto:// URI is well-formed.
    718  *
    719  * @param fpayto_uri the full URL to check
    720  * @return NULL on success, otherwise an error
    721  *         message to be freed by the caller!
    722  */
    723 char *
    724 TALER_payto_validate (const struct TALER_FullPayto fpayto_uri);
    725 
    726 
    727 /**
    728  * Check that a normalized payto:// URI is well-formed.
    729  *
    730  * @param npayto_uri the normalized URL to check
    731  * @return NULL on success, otherwise an error
    732  *         message to be freed by the caller!
    733  */
    734 char *
    735 TALER_normalized_payto_validate (const struct TALER_NormalizedPayto npayto_uri);
    736 
    737 
    738 /**
    739  * Create payto://-URI for a given exchange base URL
    740  * and a @a reserve_pub.
    741  *
    742  * @param exchange_url the base URL of the exchange
    743  * @param reserve_pub the public key of the reserve
    744  * @return payto://-URI for the reserve (without receiver-name!)
    745  */
    746 struct TALER_NormalizedPayto
    747 TALER_reserve_make_payto (const char *exchange_url,
    748                           const struct TALER_ReservePublicKeyP *reserve_pub);
    749 
    750 
    751 /**
    752  * Check that an IBAN number is well-formed.
    753  *
    754  * Validates given IBAN according to the European Banking Standards.  See:
    755  * http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf
    756  *
    757  * @param iban the IBAN to check
    758  * @return NULL on success, otherwise an error
    759  *         message to be freed by the caller!
    760  */
    761 char *
    762 TALER_iban_validate (const char *iban);
    763 
    764 
    765 /**
    766  * Possible choices for long-polling for the deposit status.
    767  */
    768 enum TALER_DepositGetLongPollTarget
    769 {
    770   /**
    771    * No long-polling.
    772    */
    773   TALER_DGLPT_NONE = 0,
    774 
    775   /**
    776    * Wait for KYC required/ACCEPTED state *or* for
    777    * OK state.
    778    */
    779   TALER_DGLPT_KYC_REQUIRED_OR_OK = 1,
    780 
    781   /**
    782    * Wait for the OK-state only.
    783    */
    784   TALER_DGLPT_OK = 2,
    785 
    786   /**
    787    * Maximum allowed value.
    788    */
    789   TALER_DGLPT_MAX = 2
    790 };
    791 
    792 
    793 /**
    794  * Possible choices for long-polling for the KYC status.
    795  */
    796 enum TALER_EXCHANGE_KycLongPollTarget
    797 {
    798   /**
    799    * No long polling.
    800    */
    801   TALER_EXCHANGE_KLPT_NONE = 0,
    802 
    803   /**
    804    * Wait for KYC auth transfer to be complete.
    805    */
    806   TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER = 1,
    807 
    808   /**
    809    * Wait for AML investigation to be complete.
    810    */
    811   TALER_EXCHANGE_KLPT_INVESTIGATION_DONE = 2,
    812 
    813   /**
    814    * Wait for KYC status to be OK.
    815    */
    816   TALER_EXCHANGE_KLPT_KYC_OK = 3,
    817 
    818   /**
    819    * Maximum legal value in this enumeration.
    820    */
    821   TALER_EXCHANGE_KLPT_MAX = 3
    822 };
    823 
    824 
    825 /**
    826  * Enumeration of possible events that may trigger
    827  * KYC requirements.
    828  */
    829 enum TALER_KYCLOGIC_KycTriggerEvent
    830 {
    831 
    832   /**
    833    * Reserved value for invalid event types.
    834    */
    835   TALER_KYCLOGIC_KYC_TRIGGER_NONE = 0,
    836 
    837   /**
    838    * Customer withdraws coins.
    839    */
    840   TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW = 1,
    841 
    842   /**
    843    * Merchant deposits coins.
    844    */
    845   TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT = 2,
    846 
    847   /**
    848    * Wallet receives P2P payment.
    849    */
    850   TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 3,
    851 
    852   /**
    853    * Wallet balance exceeds threshold. The timeframe is
    854    * irrelevant for this limit.
    855    */
    856   TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 4,
    857 
    858   /**
    859    * Reserve is being closed by force.
    860    */
    861   TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE = 5,
    862 
    863   /**
    864    * Deposits have been aggregated, we are wiring a
    865    * certain amount into a (merchant) bank account.
    866    */
    867   TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6,
    868 
    869   /**
    870    * Limit per transaction.  The timeframe is
    871    * irrelevant for this limit.
    872    */
    873   TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION = 7,
    874 
    875   /**
    876    * Limit per refund.  The timeframe is
    877    * irrelevant for this limit.
    878    */
    879   TALER_KYCLOGIC_KYC_TRIGGER_REFUND = 8
    880 
    881 };
    882 
    883 
    884 /**
    885  * Types of KYC checks.
    886  */
    887 enum TALER_KYCLOGIC_CheckType
    888 {
    889   /**
    890    * Wait for staff or contact staff out-of-band.
    891    */
    892   TALER_KYCLOGIC_CT_INFO,
    893 
    894   /**
    895    * SPA should show an inline form.
    896    */
    897   TALER_KYCLOGIC_CT_FORM,
    898 
    899   /**
    900    * SPA may start external KYC process.
    901    */
    902   TALER_KYCLOGIC_CT_LINK
    903 };
    904 
    905 
    906 /**
    907  * Possible values for a binary filter.
    908  */
    909 enum TALER_EXCHANGE_YesNoAll
    910 {
    911   /**
    912    * If condition is yes.
    913    */
    914   TALER_EXCHANGE_YNA_YES = 1,
    915 
    916   /**
    917    * If condition is no.
    918    */
    919   TALER_EXCHANGE_YNA_NO = 2,
    920 
    921   /**
    922    * Condition disabled.
    923    */
    924   TALER_EXCHANGE_YNA_ALL = 3
    925 };
    926 
    927 
    928 /**
    929  * Convert YNA value to a string.
    930  *
    931  * @param yna value to convert
    932  * @return string representation ("yes"/"no"/"all").
    933  */
    934 const char *
    935 TALER_yna_to_string (enum TALER_EXCHANGE_YesNoAll yna);
    936 
    937 
    938 /**
    939  * Escape @a str for encoding in XML.
    940  *
    941  * @param str string to escape
    942  * @return XML-encoded @a str (caller must GNUNET_free())
    943  */
    944 char *
    945 TALER_escape_xml (const char *str);
    946 
    947 
    948 /**
    949  * Check if @a src matches ``[a-zA-Z0-9-.:]{1, 40}``
    950  *
    951  * @param src string to check
    952  * @return true if it is an allowed metadata string.
    953  */
    954 bool
    955 TALER_is_valid_subject_metadata_string (const char *src);
    956 
    957 
    958 #ifdef __APPLE__
    959 /**
    960  * Returns the first occurrence of `c` in `s`, or returns the null-byte
    961  * terminating the string if it does not occur.
    962  *
    963  * @param s the string to search in
    964  * @param c the character to search for
    965  * @return char* the first occurrence of `c` in `s`
    966  */
    967 char *strchrnul (const char *s, int c);
    968 
    969 #endif
    970 
    971 /**
    972  * @brief Parses a date information into days after 1970-01-01 (or 0)
    973  *
    974  * The input MUST be of the form
    975  *
    976  *   1) YYYY-MM-DD, representing a valid date
    977  *   2) YYYY-MM-00, representing a valid month in a particular year
    978  *   3) YYYY-00-00, representing a valid year.
    979  *
    980  * In the cases 2) and 3) the out parameter is set to the beginning of the
    981  * time, f.e. 1950-00-00 == 1950-01-01 and 1888-03-00 == 1888-03-01
    982  *
    983  * The output will set to the number of days after 1970-01-01 or 0, if the input
    984  * represents a date belonging to the largest allowed age group.
    985  *
    986  * @param in Input string representation of the date
    987  * @param mask Age mask
    988  * @param[out] out Where to write the result
    989  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
    990  */
    991 enum GNUNET_GenericReturnValue
    992 TALER_parse_coarse_date (
    993   const char *in,
    994   const struct TALER_AgeMask *mask,
    995   uint32_t *out);
    996 
    997 
    998 /**
    999  * @brief Parses a string as a list of age groups.
   1000  *
   1001  * The string must consist of a colon-separated list of increasing integers
   1002  * between 0 and 31.  Each entry represents the beginning of a new age group.
   1003  * F.e. the string
   1004  *
   1005  *  "8:10:12:14:16:18:21"
   1006  *
   1007  * represents the following list of eight age groups:
   1008  *
   1009  * | Group |    Ages       |
   1010  * | -----:|:------------- |
   1011  * |    0  |  0, 1, ..., 7 |
   1012  * |    1  |  8, 9         |
   1013  * |    2  | 10, 11        |
   1014  * |    3  | 12, 13        |
   1015  * |    4  | 14, 15        |
   1016  * |    5  | 16, 17        |
   1017  * |    6  | 18, 19, 20    |
   1018  * |    7  | 21, ...       |
   1019  *
   1020  * which is then encoded as a bit mask with the corresponding bits set:
   1021  *
   1022  *  31     24        16        8         0
   1023  *  |      |         |         |         |
   1024  *  oooooooo  oo1oo1o1  o1o1o1o1  ooooooo1
   1025  *
   1026  * @param groups String representation of age groups
   1027  * @param[out] mask Mask representation for age restriction.
   1028  * @return Error, if age groups were invalid, OK otherwise.
   1029  */
   1030 enum GNUNET_GenericReturnValue
   1031 TALER_parse_age_group_string (
   1032   const char *groups,
   1033   struct TALER_AgeMask *mask);
   1034 
   1035 
   1036 /**
   1037  * @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21"
   1038  *
   1039  * NOTE: This function uses a static buffer.  It is not safe to call this
   1040  * function concurrently.
   1041  *
   1042  * @param mask Age mask
   1043  * @return String representation of the age mask.
   1044  *         Can be used as value in the TALER config.
   1045  */
   1046 const char *
   1047 TALER_age_mask_to_string (
   1048   const struct TALER_AgeMask *mask);
   1049 
   1050 
   1051 /**
   1052  * @brief returns the age group of a given age for a given age mask
   1053  *
   1054  * @param mask Age mask
   1055  * @param age The given age
   1056  * @return age group
   1057  */
   1058 uint8_t
   1059 TALER_get_age_group (
   1060   const struct TALER_AgeMask *mask,
   1061   uint8_t age);
   1062 
   1063 
   1064 /**
   1065  * @brief Return the lowest age in the corresponding group for a given age
   1066  * according the given age mask.
   1067  *
   1068  * @param mask age mask
   1069  * @param age age to check
   1070  * @return lowest age in corresponding age group
   1071  */
   1072 uint8_t
   1073 TALER_get_lowest_age (
   1074   const struct TALER_AgeMask *mask,
   1075   uint8_t age);
   1076 
   1077 
   1078 /**
   1079  * @brief Get the lowest age for the largest age group
   1080  *
   1081  * @param mask the age mask
   1082  * @return lowest age for the largest age group
   1083  */
   1084 #define TALER_adult_age(mask) \
   1085         sizeof((mask)->bits) * 8 - __builtin_clz ((mask)->bits) - 1
   1086 
   1087 
   1088 /**
   1089  * Command-line options for various TALER_SECMOD_XXX_run() functions.
   1090  */
   1091 struct TALER_SECMOD_Options
   1092 {
   1093 
   1094   /**
   1095    * Number of workers to launch. Note that connections to
   1096    * exchanges are NOT workers.
   1097    */
   1098   unsigned int max_workers;
   1099 
   1100   /**
   1101    * Time when the key update is executed.
   1102    * Either the actual current time, or a pretended time.
   1103    */
   1104   struct GNUNET_TIME_Timestamp global_now;
   1105 
   1106   /**
   1107    * The time for the key update, as passed by the user
   1108    * on the command line.
   1109    */
   1110   struct GNUNET_TIME_Timestamp global_now_tmp;
   1111 
   1112   /**
   1113    * Configuration section name to use.
   1114    */
   1115   const char *section;
   1116 
   1117   /**
   1118    * Configuration section prefix to use for denomination settings.
   1119    * "coin_" for the exchange, "doco_" for Donau.
   1120    */
   1121   const char *cprefix;
   1122 
   1123   /**
   1124    * Return value from main().
   1125    */
   1126   int global_ret;
   1127 
   1128 
   1129 };
   1130 
   1131 #define TALER_SECMOD_OPTIONS(opt)                         \
   1132         GNUNET_GETOPT_option_timetravel ('T',                 \
   1133                                          "timetravel"),       \
   1134         GNUNET_GETOPT_option_timestamp ('t',                  \
   1135                                         "time",               \
   1136                                         "TIMESTAMP",          \
   1137                                         "pretend it is a different time for the update", \
   1138                                         &(opt)->global_now_tmp),        \
   1139         GNUNET_GETOPT_option_uint ('w',                       \
   1140                                    "workers",                 \
   1141                                    "COUNT",                   \
   1142                                    "use COUNT workers for parallel processing of batch requests", \
   1143                                    &(opt)->max_workers)
   1144 
   1145 
   1146 /**
   1147  * Main function of an EDDSA secmod that will be run under the GNUnet scheduler.
   1148  *
   1149  * @param cls must point to a `struct TALER_SECMOD_Options *`
   1150  * @param args remaining command-line arguments
   1151  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
   1152  * @param cfg configuration
   1153  */
   1154 void
   1155 TALER_SECMOD_eddsa_run (void *cls,
   1156                         char *const *args,
   1157                         const char *cfgfile,
   1158                         const struct GNUNET_CONFIGURATION_Handle *cfg);
   1159 
   1160 
   1161 /**
   1162  * Main function of a CS secmod that will be run under the GNUnet scheduler.
   1163  *
   1164  * @param cls must point to a `struct TALER_SECMOD_Options *`
   1165  * @param args remaining command-line arguments
   1166  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
   1167  * @param cfg configuration
   1168  */
   1169 void
   1170 TALER_SECMOD_cs_run (void *cls,
   1171                      char *const *args,
   1172                      const char *cfgfile,
   1173                      const struct GNUNET_CONFIGURATION_Handle *cfg);
   1174 
   1175 
   1176 /**
   1177  * Main function of an RSA secmod that will be run under the GNUnet scheduler.
   1178  *
   1179  * @param cls must point to a `struct TALER_SECMOD_Options *`
   1180  * @param args remaining command-line arguments
   1181  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
   1182  * @param cfg configuration
   1183  */
   1184 void
   1185 TALER_SECMOD_rsa_run (void *cls,
   1186                       char *const *args,
   1187                       const char *cfgfile,
   1188                       const struct GNUNET_CONFIGURATION_Handle *cfg);
   1189 
   1190 
   1191 /**
   1192  * Perform very primitive word splitting of a command.
   1193  * Primarily used to split helper commands from the configurations.
   1194  *
   1195  * @param command command to split
   1196  * @param extra_args extra arguments to append after the word
   1197  * @returns NULL-terminated array of words, free wiith TALER_words_destroy
   1198  */
   1199 char **
   1200 TALER_words_split (const char *command,
   1201                    const char **extra_args);
   1202 
   1203 
   1204 /**
   1205  * Free arguments allocated with split_words.
   1206  *
   1207  * @param args NULL-terminated array of strings to free.
   1208  */
   1209 void
   1210 TALER_words_destroy (char **args);
   1211 
   1212 #undef __TALER_UTIL_LIB_H_INSIDE__
   1213 
   1214 #endif