summaryrefslogtreecommitdiff
path: root/design-documents/006-extensions.rst
blob: 576809ada2eec8290c19c25d0b461ad9aa479dab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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.