taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

006-extensions.rst (7377B)


      1 XX 06: Extensions for GNU Taler
      2 ###############################
      3 
      4 
      5 .. attention::
      6 
      7    As of 2026-07-28, the extension mechanism
      8    has been retired.
      9 
     10 Summary
     11 =======
     12 
     13 This design document describes a generic framework for how extensions (i.e.
     14 optional features) to GNU Taler can be offered and used by the exchange,
     15 merchants and wallets.
     16 
     17 Motivation
     18 ==========
     19 
     20 GNU Taler's list of supported features evolves over time.  For example, the
     21 following features are going to be designed and implemented during the course
     22 of 2021 and 2022:
     23 
     24 * Peer-to-peer payments
     25 * Anonymous age-restriction
     26 * Escrow service for anonymous auctions
     27 * A general escrow service
     28 
     29 We call a feature an *extension* when it is *optional* for either the
     30 exchange, wallet or merchant to enable and support it. (However, enabling
     31 a feature might *require* the other parties to support the feature, too)
     32 
     33 For optional features we therefore need a mechanism to express the
     34 availability, version and configuration of a particular feature, f.e. p2p or
     35 age-restriction offered by an exchange, and make it verifiable by the other
     36 participants.
     37 
     38 Requirements
     39 ============
     40 
     41 
     42 Proposed Solution
     43 =================
     44 
     45 Exchange
     46 ^^^^^^^^
     47 
     48 The exchange will add two new *optional* fields in response to ``/keys``:
     49 
     50 #. The field ``extensions`` which contains a dictionary of
     51    extension-names and their configuration, see below.
     52 
     53 #. The field ``extensions_sig`` that contains the EdDSA signature of the
     54    SHA256-hash of the normalized JSON-string of the ``extensions`` object.
     55 
     56 
     57 The necessary changes to ``ExtensionsManifestsResponse`` are highlighted here:
     58 
     59 .. ts:def:: ExtensionsManifestsResponse
     60 
     61    interface ExtensionsManifestsResponse {
     62    //...
     63 
     64    // Optional field with a dictionary of (name, object) pairs defining the
     65    // supported and enabled extensions.
     66    // The name MUST be non-empty and unique.
     67    extensions?: { name: ExtensionManifest };
     68 
     69    // Signature by the exchange master key of the SHA-256 hash of the
     70    // normalized JSON-object of field ``extensions``, if it was set.
     71    // The signature MUST have purpose ``TALER_SIGNATURE_MASTER_EXTENSIONS``.
     72    extensions_sig?: EddsaSignature;
     73 
     74    //...
     75    }
     76 
     77 
     78 Extension names
     79 ---------------
     80 
     81 The names of extensions MUST be unique.  The full name MUST be registered with
     82 GANA_ along with a full description of the extension.
     83 
     84 .. _GANA: https://git.gnunet.org/gana.git
     85 
     86 (In the rare situation that the exchange might have to provide *multiple*
     87 versions of the "same" feature in parallel, multiple unique names MUST be used,
     88 f.e. ``age_restriction`` an ``age_restriction.v2``.)
     89 
     90 ExtensionManifest object
     91 ---------------------------
     92 
     93 The definition of ``ExtensionManifest`` object itself is mostly up to the
     94 particular feature.  **However**, it MUST have
     95 
     96 #. the boolean field ``critical`` that has the same semantics as as "critical"
     97    has for extensions in X.509_: if true, the client must "understand" the
     98    extension before proceeding, if "false" clients can safely skip extensions
     99    they do not understand.
    100 
    101 #. the field ``version`` of type `LibtoolVersion` which contains the version
    102    information of the extension in Taler's `protocol version ranges notation`_.
    103 
    104 .. _X.509: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2
    105 
    106 .. _`protocol version ranges notation`: https://docs.taler.net/core/api-common.html#protocol-version-ranges
    107 
    108 .. ts:def:: ExtensionManifest
    109 
    110    interface ExtensionManifest {
    111      // The criticality of the extension MUST be provided.  It has the same
    112      // semantics as "critical" has for extensions in X.509:
    113      // - if "true", the client must "understand" the extension before
    114      //   proceeding,
    115      // - if "false", clients can safely skip extensions they do not
    116      //   understand.
    117      // (see https://datatracker.ietf.org/doc/html/rfc5280#section-4.2)
    118      critical: boolean;
    119 
    120      // The version information MUST be provided in Taler's protocol version
    121      // ranges notation, see
    122      // https://docs.taler.net/core/api-common.html#protocol-version-ranges
    123      version: LibtoolVersion;
    124 
    125      // Optional configuration object, defined by the feature itself
    126      config?: object;
    127    }
    128 
    129 
    130 Configuration
    131 -------------
    132 
    133 Extensions are *disabled* per default and must *explicetly* be enabled in the
    134 the TALER configuration manually.  The configurations of all enabled extensions
    135 are signed with the master key and uploaded to the exchange with the tool
    136 ``taler-exchange-offline``.
    137 
    138 Each extension has its own section in the configuration, starting with the
    139 prefix ``exchange-extension-``, like ``[exchange-extension-age_restriction]``.
    140 The field ``ENABLED = YES|NO`` is used to enable or disable the corresponding
    141 extension.  If the extension has its own configuration parameters, they MAY be
    142 optional, in which case the ``taler-exchange-offline`` tool MUST fill them with
    143 safe default values.
    144 
    145 The ``taler-exchange-offline`` tool MUST offer the subcommand ``extensions``
    146 for showing and signing extensions.  For this purpose, the following
    147 sub-subcommands MUST be available:
    148 
    149 * ``extensions show``: List all available extensions, their versions,
    150   criticality and whether they are enabled.
    151 * ``extensions sign``: Sign the configuration of all enabled extensions with
    152   the master key and prepare a JSON-object for the ``upload`` command.
    153 
    154 When extensions are offered and enabled by an exchange, the ``extensions``
    155 object MUST be signed by the exchange's master signing key.  Whenever
    156 extensions are enabled or disabled, the offline tool MUST sign the SHA256 hash
    157 of the normalized JSON-string of the ``extensions`` object, if it is not empty.
    158 
    159 In order to do so, the ``taler-exchange-offline`` tool MUST
    160 
    161 #. have the complete list of all available optional features/extensions and
    162    their versions builtin and
    163 
    164 #. understand them (including the version). For example, the extension for
    165    age-restriction will require the exchange to perform particular steps when
    166    this extension is enabled (i.e. signing denominations with support with age
    167    restriction *together* with the string of age groups).
    168 
    169 #. reject a configuration that refers to any extension that the tool does not
    170    know or understand.
    171 
    172 Similarly, the exchange MUST reject a signed configuration with extensions it
    173 does not know or understand.
    174 
    175 Examples
    176 --------
    177 
    178 A configuration for age-restriction in the taler configuration would look like
    179 this:
    180 
    181 .. code:: none
    182 
    183    [exchange-extension-age_restriction]
    184    ENABLED = true
    185    # default:
    186    AGE_GROUPS = "8:10:12:14:16:18:21"
    187 
    188 
    189    [exchange-extension-policy_brandt_vickery_auction]
    190    ENABLED = true
    191    REPLAY_PROGRAM = "/usr/local/bin/taler-exchange-auction_replay"
    192 
    193 
    194 Merchant
    195 ^^^^^^^^
    196 
    197 TODO:
    198 
    199 * Needs to express support for particular extensions, too.  F.e. age-restriction.
    200 
    201 Extension Plugins
    202 ==================
    203 
    204 TODO:
    205 
    206 * describe ``struct TALER_Extension``
    207 * describe the plugin loading mechanism for extensions
    208 * describe the various handlers
    209 
    210 
    211 Alternatives
    212 ============
    213 
    214 TODO.  None yet.
    215 
    216 
    217 Drawbacks
    218 =========
    219 
    220 * We do not offer (yet) any lifetime cycle of a feature, that is:  There are
    221   only two states that a feature can be in: "available" or "not-available".
    222 
    223 * The existing design for peer-to-peer payments must be adapted to this.
    224 
    225 Discussion / Q&A
    226 ================
    227 
    228 The initial ideas presented here are based on discussions between Özgür Kesim
    229 and Christian Grothoff.