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.