DD6: Extensions for GNU Taler ############################# Summary ======= This design document describes a generic framework for how extensions (i.e. optional features) to GNU Taler can be offered and used by the exchange, merchants and wallets. Motivation ========== GNU Taler's list of supported features evolves over time. For example, the following features are going to be designed and implemented during the course of 2021 and 2022: * Peer-to-peer payments * Anonymous age-restriction * Escrow service for anonymous auctions We call a feature an *extension* when it is *optional* for either the exchange, wallet or merchant to enable and support it. (However, enabling a feature might *require* the other parties to support the feature, too) For optional features we therefore need a mechanism to express the availability, version and configuration of a particular feature, f.e. p2p or age-restriction offered by an exchange, and make it verifiable by the other participants. Requirements ============ Proposed Solution ================= Exchange ^^^^^^^^ The exchange will add two new *optional* fields in response to ``/keys``: #. The field ``extensions`` which contains a dictionary of extension-names and their configuration, see below. #. The field ``extensions_sig`` that contains the EdDSA signature of the SHA256-hash of the normalized JSON-string of the ``extensions`` object. The necessary changes to ``ExchangeKeysResponse`` are highlighted here: .. ts:def:: ExchangeKeysResponse interface ExchangeKeysResponse { //... // Optional field with a dictionary of (name, object) pairs defining the // supported and enabled extensions. // The name MUST be non-empty and unique. extensions?: { name: Extension }; // Signature by the exchange master key of the SHA-256 hash of the // normalized JSON-object of field ``extensions``, if it was set. // The signature MUST have purpose ``TALER_SIGNATURE_MASTER_EXTENSIONS``. extensions_sig?: EddsaSignature; //... } Extension names --------------- The names of extensions MUST be unique. The full name MUST be registered with GANA_ along with a full description of the extension. .. _GANA: https://git.gnunet.org/gana.git (In the rare situation that the exchange might have to provide *multiple* versions of the "same" feature in parallel, multiple unique names MUST be used, f.e. ``age_restriction`` an ``age_restriction.v2``.) Extension object ---------------- The definition of ``Extension`` object itself is mostly up to the particular feature. **However**, it MUST have #. the boolean field ``critical`` that has the same semantics as as "critical" has for extensions in X.509_: if true, the client must "understand" the extension before proceeding, if "false" clients can safely skip extensions they do not understand. #. the field ``version`` of type `LibtoolVersion` which contains the version information of the extension in Taler's `protocol version ranges notation`_. .. _X.509: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2 .. _`protocol version ranges notation`: https://docs.taler.net/core/api-common.html#protocol-version-ranges .. ts:def:: Extension interface Extension { // The criticality of the extension MUST be provided. It has the same // semantics as "critical" has for extensions in X.509: // - if "true", the client must "understand" the extension before // proceeding, // - if "false", clients can safely skip extensions they do not // understand. // (see https://datatracker.ietf.org/doc/html/rfc5280#section-4.2) critical: boolean; // The version information MUST be provided in Taler's protocol version // ranges notation, see // https://docs.taler.net/core/api-common.html#protocol-version-ranges version: LibtoolVersion; // Optional configuration object, defined by the feature itself config?: object; } Configuration ------------- Extensions are *disabled* per default and must *explicetly* be enabled in the the TALER configuration manually. The configurations of all enabled extensions are signed with the master key and uploaded to the exchange with the tool ``taler-exchange-offline``. Each extension has its own section in the configuration, starting with the prefix ``exchange-extension-``, like ``[exchange-extension-age_restriction]``. The field ``ENABLED = YES|NO`` is used to enable or disable the corresponding extension. If the extension has its own configuration parameters, they MAY be optional, in which case the ``taler-exchange-offline`` tool MUST fill them with safe default values. The ``taler-exchange-offline`` tool MUST offer the subcommand ``extensions`` for showing and signing extensions. For this purpose, the following sub-subcommands MUST be available: * ``extensions show``: List all available extensions, their versions, criticality and whether they are enabled. * ``extensions sign``: Sign the configuration of all enabled extensions with the master key and prepare a JSON-object for the ``upload`` command. When extensions are offered and enabled by an exchange, the ``extensions`` object MUST be signed by the exchange's master signing key. Whenever extensions are enabled or disabled, the offline tool MUST sign the SHA256 hash of the normalized JSON-string of the ``extensions`` object, if it is not empty. In order to do so, the ``taler-exchange-offline`` tool MUST #. have the complete list of all available optional features/extensions and their versions builtin and #. understand them (including the version). For example, the extension for age-restriction will require the exchange to perform particular steps when this extension is enabled (i.e. signing denominations with support with age restriction *together* with the string of age groups). #. reject a configuration that refers to any extension that the tool does not know or understand. Similarly, the exchange MUST reject a signed configuration with extensions it does not know or understand. Examples -------- A configuration for age-restriction in the taler configuration would look like this: .. code:: none [exchange-extension-age_restriction] ENABLED = true # default: AGE_GROUPS = "8:10:12:14:16:18:21" * TODO: Add examples for p2p. Merchant ^^^^^^^^ TODO: * Needs to express support for particular extensions, too. F.e. age-restriction. Alternatives ============ TODO. None yet. Drawbacks ========= * We do not offer (yet) any lifetime cycle of a feature, that is: There are only two states that a feature can be in: "available" or "not-available". * The existing design for peer-to-peer payments must be adapted to this. Discussion / Q&A ================ The initial ideas presented here are based on discussions between Özgür Kesim and Christian Grothoff.