taler-docs

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

006-extensions.rst (7693B)


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