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.