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.
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:
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.
The exchange will add two new optional fields in response to /keys
:
extensions
which contains a dictionary of
extension-names and their configuration, see below.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:
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;
//...
}
The names of extensions MUST be unique. The full name MUST be registered with GANA along with a full description of the extension.
(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
.)
The definition of Extension
object itself is mostly up to the particular
feature. However, it MUST have
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.version
of type LibtoolVersion which contains the version
information of the extension in Taler’s protocol version ranges notation.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;
}
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
Similarly, the exchange MUST reject a signed configuration with extensions it does not know or understand.
A configuration for age-restriction in the taler configuration would look like this:
[exchange-extension-age_restriction]
ENABLED = true
# default:
AGE_GROUPS = "8:10:12:14:16:18:21"
TODO. None yet.
The initial ideas presented here are based on discussions between Özgür Kesim and Christian Grothoff.