summaryrefslogtreecommitdiff
path: root/taler-exchange-manual.rst
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-12-18 20:05:12 +0100
committerChristian Grothoff <christian@grothoff.org>2020-12-18 20:05:12 +0100
commit69d1c1a9510b7bbd5ef61f2fd9563ddab2c72433 (patch)
treede9d1342b65023dfeabdd338ff08190eaf6b5a11 /taler-exchange-manual.rst
parent0cc41c007f771f5bf8897e39565e426b44cfd7c1 (diff)
downloaddocs-69d1c1a9510b7bbd5ef61f2fd9563ddab2c72433.tar.gz
docs-69d1c1a9510b7bbd5ef61f2fd9563ddab2c72433.tar.bz2
docs-69d1c1a9510b7bbd5ef61f2fd9563ddab2c72433.zip
update exchange operator manual
Diffstat (limited to 'taler-exchange-manual.rst')
-rw-r--r--taler-exchange-manual.rst819
1 files changed, 456 insertions, 363 deletions
diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst
index 942fb14..0faa3ac 100644
--- a/taler-exchange-manual.rst
+++ b/taler-exchange-manual.rst
@@ -67,11 +67,8 @@ high-assurance) Postgres database. Furthermore, we expect some moderate
familiarity with the compilation and installation of free software
packages. You need to understand the cryptographic concepts of private
and public keys and must be able to protect private keys stored in files
-on disk. An exchange uses an *offline* master key as well as *online*
-keys. You are advised to secure your private master key and any copies
-on encrypted, always-offline computers. Again, we assume that you are
-familiar with good best practices in operational security, including
-securing key material. [2]_
+on disk.
+
Architecture overview
---------------------
@@ -113,6 +110,13 @@ components:
exchange’s bank account details, signing keys and fee structure. The
binary is the ``taler-exchange-httpd``.
+- Crypto-Helpers
+ The ``taler-exchange-helper-rsa`` and ``taler-exchange-helper-rsa``
+ are two programs that are responsible for managing the exchange's
+ online signing keys. They must run on the same machine as the
+ ``taler-exchange-httpd`` as the HTTP frontend communicates with the
+ crypto helpers using UNIX Domain Sockets.
+
- Aggregator
The aggregator combines multiple deposits made by the same merchant
and (eventually) triggers wire transfers for the aggregate amount.
@@ -121,12 +125,31 @@ components:
excessively frequent transfers. The binary is the
``taler-exchange-aggregator``.
-- Auditor
- The auditor verifies that the transactions performed by the exchange
- were done properly. It checks the various signatures, totals up the
- amounts and alerts the operator to any inconsistencies. It also
- computes the expected bank balance, revenue and risk exposure of the
- exchange operator. The main binary is the ``taler-auditor``.
+- Closer
+ The ``taler-exchange-closer`` tool check that reserves are properly
+ closed. If a customer wires funds to an exchange and then fails
+ to withdraw them, the closer will (eventually) trigger a wire
+ transfer that sends the customer's funds back to the originating
+ wire account.
+
+- Transfer
+ The ``taler-exchange-transfer`` tool is responsible for actually
+ executing the aggregated wire transfers. It is the only process
+ that needs to have the credentials to execute outgoing wire
+ transfers. The tool uses the Taler Wire REST API to execute
+ wire transfers. This API is provided by the Taler Python Bank
+ for stand-alone deployments (like those with ``KUDOS``) and
+ by LibEuFin. LibEuFin is an adapter which maps the Taler Wire
+ REST API to traditional banking protocols like EBICS and FinTS.
+
+- Wirewatch
+ The ``taler-exchange-wirewatch`` tool is responsible for observing
+ incoming wire transfers to the exchange. It needs to have the
+ credentials to obtain a list of incoming wire transfers.
+ The tool also uses the Taler Wire REST API to observe such
+ incoming transfers. It is possible that observing incoming and
+ making outgoing wire transfers is done via different bank accounts
+ and/or credentials.
- Wire adapter
A wire adapter is a component that enables exchange to talk to a bank.
@@ -145,24 +168,61 @@ components:
auditor to query bank transaction histories.
- DBMS
- Postgres
+.. index:: Postgres
The exchange requires a DBMS to stores the transaction history for
the Taler exchange and aggregator, and a (typically separate) DBMS
for the Taler auditor. For now, the GNU Taler reference implementation
only supports Postgres, but the code could be easily extended to
support another DBMS.
+- Auditor
+ The auditor verifies that the transactions performed by the exchange
+ were done properly. It checks the various signatures, totals up the
+ amounts and alerts the operator to any inconsistencies. It also
+ computes the expected bank balance, revenue and risk exposure of the
+ exchange operator. The main binary is the ``taler-auditor``.
+ Aside from the key setup procedures, the most critical setup for
+ deploying an auditor is providing the auditor with an up-to-date
+ copy of the database.
-Exchange online signing private key management (v0.9)
------------------------------------------------------
-The following text only applies starting with exchange version 0.9.
+Offline keys
+------------
-To provide an additional level of protection for the private online signing
+The exchange (and ideally also auditors) uses a long-term offline master
+siging key that identifies the operator and is used to authenticate critical
+information, such as the exchange's bank account and the actual keys the
+exchange uses online.
+
+Interactions with the offline system are performed using the
+``taler-exchange-offline`` tool. To use the offline system will require
+exchange operators to copy JSON files from or to the offline system (say using
+an USB stick). The offline system does not need any significant amount of
+computing power, a Raspberry-Pi is perfectly sufficient and the form-factor
+might be good for safe-keeping! (You should keep a copy of the (encrypted)
+private offline key on more than one physical medium though.)
+
+Exchange operators are strongly advised to secure your private master key and
+any copies on encrypted, always-offline computers. Again, we assume that you
+are familiar with good best practices in operational security, including
+securing key material. [2]_
+
+
+
+Online signing key security
+---------------------------
+
+To provide an additional level of protection for the private *online* signing
keys used by the exchange, the actual cryptographic signing operations are
performed by two helper processes, the ``taler-exchange-helper-rsa`` and the
``taler-exchange-helper-eddsa``.
+The current implementation does not yet support the use of a hardware security
+module (HSM). If you have such a device with adequate functionality and are
+interested in Taler supporting it, please contact the developers for HSM
+integration support.
+
+
Functionality
^^^^^^^^^^^^^
@@ -180,14 +240,17 @@ harder for an attacker who took control of the HTTP daemon's account to
extract the private keys, limiting the attackers ability to creating
signatures to the duration of their control of that account.
-In the future, the helper processes should additionally provide a mechanism to
-track the number of signatures they have made for the various keys.
+.. note::
+ In the future, the helper processes should additionally provide a mechanism
+ to track the total number of signatures they have made for the various keys.
Setup
^^^^^
The helper processes should be run under a user ID that is separate from that
-of the user running the main ``taler-exchange-httpd`` service. The
+of the user running the main ``taler-exchange-httpd`` service. For security,
+it is important that helpers run under a different user ID than the main HTTP
+frontend, in fact ideally each helper should run under its own user ID. The
``taler-exchange-httpd`` service's will securely communicate with the helpers
using UNIX domain sockets. To enable access to the keys, the service's user
must be in the group of the helper processes (and no other users should be in
@@ -204,6 +267,7 @@ system users. The configuration does not contain any sensitive information.
+
Installation
============
@@ -251,17 +315,28 @@ of some of the options.
Keying
------
-The exchange works with three types of keys:
+The exchange works with four types of keys:
+
+- master key (kept offline)
-- master key
+- sign keys (signs normal messages from the exchange)
-- sign keys
+- denomination keys (signs electronic coins, see section Coins)
-- denomination keys (see section Coins)
+- security module keys (signs sign keys and denomination keys)
-- MASTER_PRIV_FILE: Path to the exchange’s master private file.
+Additionally, the exchange is sometimes concerned with the auditor's public
+key (to verify messages signed by auditors approved by the exchange operator)
+and the merchant's public key (to verify refunds are authorized by the
+merchant).
+
+
+Key options include:
+
+- ``[exchange/MASTER_PRIV_FILE]``: Path to the exchange’s master private file. Only needs to be provided on the offline system where the ``taler-exchange-offline`` command is used.
+
+- ``[exchange/MASTER_PUBLIC_KEY]``: Must specify the exchange’s master public key. Needed for the exchange to verify information signed by the offline system.
-- MASTER_PUBLIC_KEY: Must specify the exchange’s master public key.
.. _Serving:
@@ -289,118 +364,15 @@ Currency
--------
The exchange supports only one currency. This data is set under the
-respective option currency in section [taler].
-
-.. _Bank-account:
-
-Bank account
-------------
-
-To configure a bank account in Taler, we need to furnish four pieces of
-information:
-
-- The ``payto://`` URI of the bank account, which uniquely idenfies the
- account. Examples for such URIs include
- ``payto://iban/CH9300762011623852957`` for a bank account with
- an IBAN or
- ``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a
- the Taler bank demonstrator running at ``localhost`` on port 8080.
- The first part of the URI following ``payto://`` (“iban” or
- “x-taler-bank”) is called the wire method.
-
-- A the name of a file containing the signed JSON-encoded bank account
- details for the /wire API. This is necessary as Taler supports offline
- signing for bank accounts for additional security.
-
-- Finally, the exchange needs to be provided resources for authentication
- to the respective banking service. The format in which the
- authentication information is currently a username and password
- for HTTP basic authentication, or nothing for the fakebank.
-
-You can configure multiple accounts for an exchange by creating sections
-starting with “exchange-account-” for the section name. You can ENABLE for
-each account whether it should be used, and for what (incoming or outgoing
-wire transfers):
-
-.. code-block:: ini
-
- [exchange-account-1]
- # With x-taler-bank (say for PyBank)
- PAYTO_URI = "payto://x-taler-bank/bank.demo.taler.net/Exchange"
-
- # Example using IBAN (for use with LibEuFin)
- # PAYTO_URI = "payto://iban/CH9300762011623852957"
-
- # Where the JSON with the signature is stored. Can be
- # generated using taler-exchange-wire tool using
- # this configuration on a system with the private master key.
- WIRE_RESPONSE = ${TALER_CONFIG_HOME}/account-1.json
-
- # URL for talking to the bank wire the wire API.
- WIRE_GATEWAY_URL = https://bank.demo.taler.net/taler-wire-gateway/Exchange
-
- # Use for exchange-aggregator (outgoing transfers)
- ENABLE_DEBIT = YES
- # Use for exchange-wirewatch (and listed in /wire)
- ENABLE_CREDIT = YES
-
- # Authentication options for exchange bank account go here.
- # (Next sections have examples of authentication mechanisms)
- WIRE_GATEWAY_AUTH_METHOD = basic
- USERNAME = exchange
- PASSWORD = super-secure
-
-
-The command line tool taler-exchange-wire is used to create the
-``account-1.json`` file. For example, the utility may be invoked as
-follows to create all of the WIRE_RESPONSE files (in the locations
-specified by the configuration):
-
-.. code-block:: console
-
- $ taler-exchange-wire
-
-The generated file will be echoed by the exchange when serving
-/wire [3]_ requests.
-
-.. _Wire-fee-structure:
-
-Wire fee structure
-^^^^^^^^^^^^^^^^^^
-
-.. index:: wire fee
-.. index:: fee
-
-For each wire method (“sepa” or “x-taler-wire”) the
-exchange configuration must specify applicable wire fees. This is done
-in configuration sections of the format ``fees-METHOD``. There are two
-types of fees, simple wire fees and closing fees. Wire fees apply
-whenever the aggregator transfers funds to a merchant. Closing fees
-apply whenever the exchange closes a reserve (sending back funds to the
-customer). The fees must be constant for a full year, which is specified
-as part of the name of the option.
-
-.. code-block:: ini
-
- [fees-iban]
- WIRE-FEE-2018 = EUR:0.01
- WIRE-FEE-2019 = EUR:0.01
- CLOSING-FEE-2018 = EUR:0.01
- CLOSING-FEE-2019 = EUR:0.01
-
- [fees-x-taler-bank]
- WIRE-FEE-2018 = KUDOS:0.01
- WIRE-FEE-2019 = KUDOS:0.01
- CLOSING-FEE-2018 = KUDOS:0.01
- CLOSING-FEE-2019 = KUDOS:0.01
+respective option ``CURRENCY`` in section [taler].
.. _Database:
Database
--------
-The option db under section [exchange] gets the DB backend’s name the
-exchange is going to use. So far, only db = postgres is supported. After
+The option ``DB`` in section ``[exchange]`` gets the database backend’s name the
+exchange is going to use. So far, only ``db = postgres`` is supported. After
choosing the backend, it is mandatory to supply the connection string
(namely, the database name). This is possible in two ways:
@@ -419,79 +391,111 @@ choosing the backend, it is mandatory to supply the connection string
[exchangedb-postgres]
CONFIG = postgres:///talerdemo
+
+Given this database configuration, the database can be initialized using:
+
+.. code-block:: console
+
+ $ taler-exchange-dbinit
+
+Note that to run this command, the user must have ``CREATE TABLE``, ``CREATE
+INDEX``, ``ALTER TABLE`` and (in the future possibly even) ``DROP TABLE``
+permissions. Those permissions are only required for this step (which may
+have to be repeated when upgrading a deployment). Afterwards, during normal
+operation, permissions to ``CREATE`` or ``ALTER`` tables are not required by
+any of the Taler exchange processes and thus should not be granted.
+
+
.. _Coins-denomination-keys:
Coins (denomination keys)
-------------------------
-Sections specifying denomination (coin) information start with ``coin_``.
-By convention, the name continues with "$CURRENCY_[$SUBUNIT]_$VALUE",
-i.e. ``[coin_eur_ct_10]`` for a 10 cent piece. However, only the ``coin_``
-prefix is mandatory. Each ``coin_``-section must then have the following
-options:
+Sections specifying denomination (coin) information start with ``coin_``. By
+convention, the name continues with ``$CURRENCY_[$SUBUNIT]_$VALUE_$REVISION``,
+i.e. ``[coin_eur_ct_10_0]`` for a 10 cent piece. However, only the ``coin_``
+prefix is mandatory. Once configured, these configuration values must not
+change. The ``$REVISION`` part of the section name should be incremented if
+any of the coin attributes in the section changes. Each ``coin_``-section
+must then have the following options:
-- value: How much is the coin worth, the format is
+- ``VALUE``: How much is the coin worth, the format is
CURRENCY:VALUE.FRACTION. For example, a 10 cent piece is "EUR:0.10".
-- duration_withdraw: How long can a coin of this type be withdrawn?
+- ``DURATION_WITHDRAW``: How long can a coin of this type be withdrawn?
This limits the losses incurred by the exchange when a denomination
key is compromised.
-- duration_overlap: What is the overlap of the withdrawal timespan for
- this coin type?
-
-- duration_spend: How long is a coin of the given type valid? Smaller
+- ``DURATION_SPEND``: How long is a coin of the given type valid? Smaller
values result in lower storage costs for the exchange.
-- fee_withdraw: What does it cost to withdraw this coin? Specified
+- ``FEE_WITHDRAW``: What does it cost to withdraw this coin? Specified
using the same format as value.
-- fee_deposit: What does it cost to deposit this coin? Specified using
+- ``FEE_DEPOSIT``: What does it cost to deposit this coin? Specified using
the same format as value.
-- fee_refresh: What does it cost to refresh this coin? Specified using
+- ``FEE_REFRESH``: What does it cost to refresh this coin? Specified using
the same format as value.
-- rsa_keysize: How many bits should the RSA modulus (product of the two
+- ``RSA_KEYSIZE``: How many bits should the RSA modulus (product of the two
primes) have for this type of coin.
-.. _Keys-duration:
-Keys duration
--------------
+Additionally, there are two global configuration options of note:
+
+- ``[taler-helper-crypto-rsa/OVERLAP_DURATION]``: What is the overlap of the
+ withdrawal timespan for denomination keys? The value given here must
+ be smaller than any of the ``DURATION_WITHDRAW`` values for any of the coins.
-Both signkeys and denom keys have a starting date. The option
-lookahead_provide, under section [exchange], is such that only keys
-whose starting date is younger than lookahead_provide will be issued by
-the exchange.
+- ``[taler-helper-crypto-rsa/LOOKAHEAD_SIGN]``: For how far into the future
+ should denomination keys be pre-generated? This allows the exchange and
+ auditor operators to download, offline-sign, and upload denomination key
+ signatures for denomination keys that will be used in the future by the
+ exchange.
-signkeys. The option lookahead_sign is such that, being t the time when
-taler-exchange-keyup is run, taler-exchange-keyup will generate n
-signkeys, where t + (n \* signkey_duration) = t + lookahead_sign. In
-other words, we generate a number of keys which is sufficient to cover a
-period of lookahead_sign. As for the starting date, the first generated
-key will get a starting time of t, and the j-th key will get a starting
-time of x + signkey_duration, where x is the starting time of the
-(j-1)-th key.
+.. index:: maintenance
+.. note::
+ We recommend setting the ``LOOKAHEAD_SIGN`` value to at least one year and
+ then to perform the offline-signing procedure at least once every 6 months
+ to ensure that there is sufficient time for wallets to learn the new keys
+ and to avoid unavailability in case this critical maintenance procedure is
+ delayed.
-denom keys. The option lookahead_sign is such that, being t the time
-when taler-exchange-keyup is run, taler-exchange-keyup will generate n
-denom keys for each denomination, where t + (n \* duration_withdraw) = t
-+ lookahead_sign. In other words, for each denomination, we generate a
-number of keys which is sufficient to cover a period of lookahead_sign.
-As for the starting date, the first generated key will get a starting
-time of t, and the j-th key will get a starting time of x +
-duration_withdraw, where x is the starting time of the (j-1)-th key.
+.. note::
+ It is crucial that the configuration provided in these sections is identical (!)
+ for the exchange and the crypto helpers. We recommend pointing both users
+ to the same configuration file!
-To change these settings, edit the following values in section
-[exchange]:
-- SIGNKEY_DURATION: How long should one signing key be used?
-- LOOKAHEAD_SIGN: How much time we want to cover with our signing keys?
- Note that if SIGNKEY_DURATION is bigger than LOOKAHEAD_SIGN,
- ``taler-exchange-keyup`` will generate a quantity of signing keys
- which is sufficient to cover all the gap.
+.. _Sign-keys:
+
+Sign keys
+---------
+
+There are three global configuration options of note for sign keys:
+
+- ``[taler-helper-crypto-eddsa/DURATION]``: How long are sign keys
+ used to sign messages? After this time interval expires, a fresh
+ sign key will be used (key rotation). We recommend using
+ a ``DURATION`` of a few weeks to a few months for sign keys.
+
+- ``[taler-helper-crypto-eddsa/OVERLAP_DURATION]``: What is the overlap of the
+ timespan for sign keys? We recommend a few minutes or hours. Must
+ be smaller than ``DURATION``.
+
+- ``[taler-helper-crypto-eddsa/LOOKAHEAD_SIGN]``: For how far into the future
+ should sign keys be pre-generated? This allows the exchange and
+ auditor operators to download, offline-sign, and upload sign key
+ signatures for sign keys that will be used in the future by the exchange.
+
+.. note::
+ We recommend setting the ``LOOKAHEAD_SIGN`` value to at least one year and
+ then to perform the offline-signing procedure at least once every 6 months
+ to ensure that there is sufficient time for wallets to learn the new keys
+ and to avoid unavailability in case this critical maintenance procedure is
+ delayed.
Terms of Service
@@ -548,13 +552,189 @@ the exchange would return "TERMS_DIR/en/v1.html" lacking an HTML version in
French.
+.. _Bank-account:
+
+Bank account
+------------
+
+To configure a bank account in Taler, we need to furnish two pieces of
+information:
+
+- The ``payto://`` URI of the bank account, which uniquely idenfies the
+ account. Examples for such URIs include
+ ``payto://iban/CH9300762011623852957`` for a bank account with
+ an IBAN or
+ ``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a
+ the Taler bank demonstrator running at ``localhost`` on port 8080.
+ The first part of the URI following ``payto://`` (“iban” or
+ “x-taler-bank”) is called the wire method.
+
+- The ``taler-exchange-wirewatch`` and ``taler-exchange-transfer``
+ tools needs to be provided resources for authentication
+ to the respective banking service. The format in which the
+ authentication information is currently a username and password
+ for HTTP basic authentication.
+
+You can configure multiple accounts for an exchange by creating sections
+starting with “exchange-account-” for the section name. You can ENABLE for
+each account whether it should be used, and for what (incoming or outgoing
+wire transfers):
+
+.. code-block:: ini
+
+ [exchange-account-1]
+ # With x-taler-bank (say for PyBank)
+ PAYTO_URI = "payto://x-taler-bank/bank.demo.taler.net/Exchange"
+
+ # Example using IBAN (for use with LibEuFin)
+ # PAYTO_URI = "payto://iban/CH9300762011623852957"
+
+ # URL for talking to the bank wire the wire API.
+ WIRE_GATEWAY_URL = https://bank.demo.taler.net/taler-wire-gateway/Exchange
+
+ # Use for exchange-aggregator (outgoing transfers)
+ ENABLE_DEBIT = YES
+ # Use for exchange-wirewatch (and listed in /wire)
+ ENABLE_CREDIT = YES
+
+ # Authentication options for exchange bank account go here.
+ # (Next sections have examples of authentication mechanisms)
+ WIRE_GATEWAY_AUTH_METHOD = basic
+ USERNAME = exchange
+ PASSWORD = super-secure
+
+
+The command line tool ``taler-exchange-offline`` must be used to
+sign the ``payto://`` URI in a way suitable to convince wallets that
+this is the correct address to wire funds to.
+For example, the utility may be invoked as
+follows to enable a wire account:
+
+.. code-block:: console
+
+ $ taler-exchange-offline enable-account payto://iban/CH9300762011623852957
+
+The resulting JSON output must be uploaded to the exchange using
+``taler-exchange-offline upload``. For details, see the man
+page on ``taler-exchange-offline``.
+ttn: please turn this into a link!
+
+
+.. _Wire-fee-structure:
+
+Wire fee structure
+^^^^^^^^^^^^^^^^^^
+
+.. index:: wire fee
+.. index:: fee
+
+For each wire method (“sepa” or “x-taler-wire”) the
+exchange must know about applicable wire fees. This is also done
+using the ``taler-exchange-offline`` tool:
+
+.. code-block:: console
+
+ $ taler-exchange-offline wire-fee iban 2040 EUR:0.05 EUR:0.10
+
+The above sets the wire fees for wire transfers involving ``iban`` accounts
+(in Euros) in the year 2040 to 5 cents (wire fee) and 10 cents (closing fee).
+The tool only supports setting fees that applies for the entire calendar year.
+
+We recommend provisioning an exchange with wire fees at least for the next two
+years. Note that once the fees have been set for a year, they cannot be
+changed (basically, by signing the fees the exchange makes a legally binding
+offer to the customers).
+
+.. index:: maintenance
+.. note::
+ Provisioning future wire fees, like provisioning future denomination
+ and signing keys, are key regular maintenance procedures for every
+ exchange operator. We recommend setting automated reminders for
+ this maintenance activity!
+
+
+.. _Auditor-configuration:
+
+Auditor configuration
+---------------------
+
+The exchange must be informed about any auditor that is expected to provision
+it with auditor signatures. This is also done using the
+``taler-exchange-offline`` tool on the offline system. First, the auditor
+must be configured and provide the exchange operator with its public key and
+the URL of it's REST API. The exchange operator also needs a human-readable
+name that may be shown to users to identify the auditor. Given this
+information, the exchange operator can enable the auditor:
+
+.. code-block:: console
+
+ $ taler-exchange-offline enable-auditor $PUB_KEY $REST_URL "$AUDITOR_NAME" > auditor.json
+
+As before, the *auditor.json* file must then be copied from the offline system
+to a system connected to the exchange and there ``uploaded`` to the exchange.
+
+
+
.. _Deployment:
Deployment
==========
This chapter describes how to deploy the exchange once it has been
-properly configured.
+configured.
+
+
+.. _Launch:
+
+Launching an exchange
+---------------------
+
+A running exchange requires starting the following processes:
+
+- ``taler-exchange-helper-rsa`` (as special user, sharing group with the HTTPD)
+- ``taler-exchange-helper-eddsa`` (as special user, sharing group with the HTTPD)
+- ``taler-exchange-helper-httpd`` (needs database access)
+- ``taler-exchange-aggregator`` (only needs database access)
+- ``taler-exchange-closer`` (only needs database access)
+- ``taler-exchange-wirewatch`` (needs bank account read credentials and database access)
+- ``taler-exchange-transfer`` (needs credentials to initiate outgoing wire transfers and database access)
+
+The crypto helpers must be started before the ``taler-exchange-httpd`` and
+they should use the same configuration file.
+
+For the most secure deployment, we recommend using separate users for each of
+these processes to minimize information disclosures should any of them be
+compromised. The helpers do not need access to the Postgres database (and
+thus also should not have it).
+
+The processes that require access to the bank account need to have a
+configuration file with the respective credentials in it. We recommend using a
+separate configuration at least for ``taler-exchange-transfer`` which is the
+*only* process that needs to know the credentials to execute outgoing wire
+transfers.
+
+All of these processes should also be started via a hypervisor like
+``systemd`` or ``gnunet-arm`` that automatically re-starts them should they
+terminated unexpectedly. If the bank is down (say for maintenance), it is
+*possible* to halt the ``taler-exchange-wirewatch`` and/or
+``taler-exchange-transfer`` processes (to avoid them making requests to the
+bank API that can only fail) without impacting other operations of the
+exchange. Naturally, incoming wire transfers will only be observed once
+``taler-exchange-wirewatch`` is resumed, and merchants may complain if the
+disabled ``taler-exchange-transfer`` process causes payment deadlines to be
+missed.
+
+.. note::
+ The ``taler-exchange-httpd`` does not ship with HTTPS enabled by default.
+ In production, it should be run behind an HTTPS reverse proxy that performs
+ TLS termination on the same system. Thus, it would typically be configured
+ to listen on a UNIX domain socket. The ``/management`` and ``/auditors``
+ APIs do technically not have to be exposed on the Internet (only to the
+ administrators running ``taler-exchange-offline``) and should be blocked
+ by the reverse proxy for requests originating from outside of the bank.
+ (However, this is not a strong security assumption: in principle having
+ these endpoints be available should do no harm. However, it increases the
+ attack surface.)
.. _Keys-generation:
@@ -562,52 +742,67 @@ properly configured.
Keys generation
---------------
-Once the configuration is properly set up, all the keys can be generated
-by the tool ``taler-exchange-keyup``. The following command generates
-denomkeys and signkeys, plus the "blob" that is to be signed by the
-auditor.
+Once the configuration is properly set up, all the keys can be signed using
+the offline key on the offline system by the tool ``taler-exchange-offline``.
+To do this, one must first start the crypto helpers and the ``taler-exchange-httpd``
+process (the tools for wire transfers may also be started, but do not have to
+run yet).
-.. code-block:: console
+Next, the *future* key material should be downloaded using:
- $ taler-exchange-keyup -o blob
+.. code-block:: console
-*blob* contains data about denomkeys that the exchange operator needs to
-get signed by every auditor he wishes (or is forced to) work with.
+ $ taler-exchange-offline download > future-keys.json
-In a normal scenario, an auditor must have some way of receiving the
-blob to sign (Website, manual delivery, ..). Nonetheless, the exchange
-admin can fake an auditor signature — for testing purposes — by running
-the following command
+Afterwards, *future-keys.json* contains data about denomination and
+online signing keys that the exchange operator needs to sign with
+the offline tool. The file should be copied to the offline system.
+There, the operator should run:
.. code-block:: console
- $ taler-auditor-sign -m EXCHANGE_MASTER_PUB -r BLOB -u AUDITOR_URL -o OUTPUT_FILE
+ $ taler-exchange-offline show < future-keys.json
-Those arguments are all mandatory.
+and verify that the output contains the fee structure and key lifetimes
+they expect to see. They should also note the public keys being shown
+and communicate those to the *auditors* over a secure channel. Once
+they are convinced the file is acceptable, they should run:
-- ``EXCHANGE_MASTER_PUB`` the base32 Crockford-encoded exchange’s
- master public key. Typically, this value lies in the configuration
- option ``[exchange]/master_public_key``.
+.. code-block:: console
-- ``BLOB`` the blob generated in the previous step.
+ $ taler-exchange-offline sign < future-keys.json > offline-sigs.json
-- ``AUDITOR_URL`` the URL that identifies the auditor.
+The *offline-sigs.json* file must then be copied to an online system
+that is able to again communicate with the exchange. On that system, run:
-- ``OUTPUT_FILE`` where on the disk the signed blob is to be saved.
+.. code-block:: console
+
+ $ taler-exchange-offline upload < offline-sigs.json
-``OUTPUT_FILE`` must then be copied into the directory specified by the
-option ``AUDITOR_BASE_DIR`` under the section ``[exchangedb]``. Assuming
-``AUDITOR_BASE_DIR = ${HOME}/.local/share/taler/auditors``, the
-following command will "add" the auditor identified by ``AUDITOR_URL``
-to the exchange.
+to provision the signatures to the exchange. At this point, the
+exchange will be able to use those keys, but wallets and merchants
+may not yet trust them! Thus, the next step is for the auditor
+to affirm that they are auditing this exchange. Details about
+this are described in the auditor manual (ttn: add link, please!).
+
+The simplistic (without using offline keys for the auditor) way
+to do this would be:
.. code-block:: console
- $ cp OUTPUT_FILE ${HOME}/.local/share/taler/auditors
+ $ taler-auditor-offline download sign upload
+
+
+Private key storage
+-------------------
+
+Keeping the private keys the helpers create secret is paramount. If the
+private keys are lost, it is easy to provision fresh keys (with the help of
+the auditor). Thus, we recommend that the private keys of the crypto helpers
+are *not* backed up: in the rare event of a disk failure, they can be
+regenerated. However, we do recommend using RAID (1+1 or 1+1+1) for all
+disks of the system.
-If the auditor has been correctly added, the exchange’s ``/keys``
-response must contain an entry in the ``auditors`` array mentioning the
-auditor’s URL.
.. _Database-upgrades:
@@ -628,97 +823,6 @@ being lost, which may result in significant financial liabilities as the
exchange can then not detect double-spending. Hence this operation must
not be performed in a production system.
-.. _Diagnostics:
-
-Diagnostics
-===========
-
-This chapter includes various (very unpolished) sections on specific
-topics that might be helpful to understand how the exchange operates,
-which files should be backed up. The information may also be helpful for
-diagnostics.
-
-.. _Reserve-management:
-
-Reserve management
-------------------
-
-Incoming transactions to the exchange’s provider result in the creation
-or update of reserves, identified by their reserve key. The command line
-tool taler-exchange-reservemod allows create and add money to reserves
-in the exchange’s database.
-
-.. _Database-Scheme:
-
-Database Scheme
----------------
-
-The exchange database must be initialized using taler-exchange-dbinit.
-This tool creates the tables required by the Taler exchange to operate.
-The tool also allows you to reset the Taler exchange database, which is
-useful for test cases but should never be used in production. Finally,
-taler-exchange-dbinit has a function to garbage collect a database,
-allowing administrators to purge records that are no longer required.
-
-The database scheme used by the exchange looks as follows:
-
-.. image:: exchange-db.png
-
-.. _Signing-key-storage:
-
-Signing key storage
--------------------
-
-The private online signing keys of the exchange are stored in a
-subdirectory "signkeys/" of the "KEYDIR" which is an option in the
-"[exchange]" section of the configuration file. The filename is the
-starting time at which the signing key can be used in microseconds since
-the Epoch. The file format is defined by the struct
-TALER_EXCHANGEDB_PrivateSigningKeyInformationP:
-
-.. code-block:: c
-
- struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP {
- struct TALER_ExchangePrivateKeyP signkey_priv;
- struct TALER_ExchangeSigningKeyValidityPS issue;
- };
-
-.. _Denomination-key-storage:
-
-Denomination key storage
-------------------------
-
-The private denomination keys of the exchange are store in a
-subdirectory "denomkeys/" of the "KEYDIR" which is an option in the
-"[exchange]" section of the configuration file. "denomkeys/" contains
-further subdirectories, one per denomination. The specific name of the
-subdirectory under "denomkeys/" is ignored by the exchange. However, the
-name is important for the "taler-exchange-keyup" tool that generates the
-keys. The tool combines a human-readable encoding of the denomination
-(i.e. for EUR:1.50 the prefix would be "EUR_1_5-", or for EUR:0.01 the
-name would be "EUR_0_01-") with a postfix that is a truncated
-Crockford32 encoded hash of the various attributes of the denomination
-key (relative validity periods, fee structure and key size). Thus, if
-any attributes of a coin change, the name of the subdirectory will also
-change, even if the denomination remains the same.
-
-Within this subdirectory, each file represents a particular denomination
-key. The filename is the starting time at which the signing key can be
-used in microseconds since the Epoch. The format on disk begins with a
-struct TALER_EXCHANGEDB_DenominationKeyInformationP giving the
-attributes of the denomination key and the associated signature with the
-exchange’s long-term offline key:
-
-.. code-block:: c
-
- struct TALER_EXCHANGEDB_DenominationKeyInformationP {
- struct TALER_MasterSignatureP signature;
- struct TALER_DenominationKeyValidityPS properties;
- };
-
-This is then followed by the variable-size RSA private key in
-libgcrypt’s S-expression format, which can be decoded using
-GNUNET_CRYPTO_rsa_private_key_decode().
.. _Revocations:
@@ -732,72 +836,51 @@ must be returned as part of the ``/keys`` response under “recoup”.
Wallets detect this, and then return unspent coins of the respective
denomination key using the ``/recoup`` API.
-When a denomination key is revoked, a revocation file is placed into the
-respective subdirectory of “denomkeys/”. The file has the same prefix as
-the file that stores the struct
-TALER_EXCHANGEDB_DenominationKeyInformationP information, but is
-followed by the “.rev” suffix. It contains a 64-byte EdDSA signature
-made with the master key of the exchange with purpose
-``TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED``. If such a file is
-present, the exchange must check the signature and if it is valid treat
-the respective denomination key as revoked.
-
-Revocation files can be generated using the ``taler-exchange-keyup``
-command-line tool using the ``-r`` option. The Taler auditor will
-instruct operators to generate revocations if it detects a key
-compromise (which is possible more coins of a particular denomination
-were deposited than issued).
-
-It should be noted that denomination key revocations should only happen
-under highly unusual (“emergency”) conditions and not under normal
-conditions.
-
-.. _Auditor-signature-storage:
-
-Auditor signature storage
--------------------------
+To revoke a denomination key, you need to know the hash of the denomination
+public key, ``$HDP``. The ``$HDP`` value is usually included in the security
+report that is generated when a compromise is detected). Given this
+value, the key revocation can be approved on the offline system:
+
+.. code-block:: console
-Signatures from auditors are stored in the directory specified in the
-exchange configuration section "exchangedb" under the option
-"AUDITOR_BASE_DIR". The exchange does not care about the specific names
-of the files in this directory.
+ $ taler-exchange-offline revoke-denominatin $HDP > revocation.json
-Each file must contain a header with the public key information of the
-auditor, the master public key of the exchange, and the number of signed
-denomination keys:
+The resulting *revocation.json* must be copied to a system connected to the
+exchange and uploaded to the exchange using the ``upload`` subcommand
+of ``taler-exchange-offline``.
-.. code-block:: c
+.. note::
+ Denomination key revocations should only happen
+ under highly unusual (“emergency”) conditions and not in normal
+ operation.
+
+
+
+.. _Diagnostics:
- struct AuditorFileHeaderP {
- struct TALER_AuditorPublicKeyP apub;
- struct TALER_MasterPublicKeyP mpub;
- uint32_t dki_len;
- };
+Diagnostics
+===========
-This is then followed by dki_len signatures of the auditor of type
-struct TALER_AuditorSignatureP, which are then followed by another
-dki_len blocks of type struct TALER_DenominationKeyValidityPS. The
-auditor’s signatures must be signatures over the information of the
-corresponding denomination key validity structures embedded in a struct
-TALER_ExchangeKeyValidityPS structure using the
-TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS purpose.
+This chapter includes various (very unpolished) sections on specific
+topics that might be helpful to understand how the exchange operates,
+which files should be backed up. The information may also be helpful for
+diagnostics.
+.. _Database-Scheme:
-.. [1]
- Naturally, you could operate a Taler exchange for a toy currency
- without any real value on low-cost setups like a Raspberry Pi, but we
- urge you to limit the use of such setups to research and education as
- with GNU Taler data loss instantly results in financial losses.
+Database Scheme
+---------------
-.. [2]
- The current implementation does not make provisions for secret
- splitting. Still, the use of a hardware security module (HSM) for
- protecting private keys is advisable, so please contact the
- developers for HSM integration support.
+The exchange database must be initialized using ``taler-exchange-dbinit``.
+This tool creates the tables required by the Taler exchange to operate.
+The tool also allows you to reset the Taler exchange database, which is
+useful for test cases but should never be used in production. Finally,
+``taler-exchange-dbinit`` has a function to garbage collect a database,
+allowing administrators to purge records that are no longer required.
-.. [3]
- https://api.taler.net/api-exchange.html#wire-req
+The database scheme used by the exchange looks as follows:
+.. image:: exchange-db.png
.. _ExchangeBenchmarking:
@@ -805,13 +888,13 @@ TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS purpose.
Benchmarking
============
-This chapter describes how to run the Taler exchange benchmark.
-The benchmark can be used to measure the performance of the exchange
-by running a (possibly large) number of simulated clients against one
-Taler deployment with a bank, exchange and auditor. For the bank, both
-a "fakebank" (``-f``) and a "Pythonbank" deployment are currently supported.
-The taler-exchange-benchmark program can launch all required services
-and clients, or only launch the parallel clients (``-m``), for example for
+This chapter describes how to run the Taler exchange benchmark. The benchmark
+can be used to measure the performance of the exchange by running a (possibly
+large) number of simulated clients against one Taler deployment with a bank,
+exchange and auditor. For the bank, both a "fakebank" (``-f``) and a
+"Pythonbank" deployment are currently supported. The
+``taler-exchange-benchmark`` program can launch all required services and
+clients, or only launch the parallel clients (``-m``), for example for
distributed testing over a network.
For each *parallel* (``-p``) client, a number of *reserves* (``-r``) is first established by
@@ -829,15 +912,25 @@ The existing ``benchmark.conf`` file in ``src/benchmark/`` can be used as a
starting point for a configuration to run the benchmark. The existing
configuration file only requires that the ``talercheck`` database already
exists and will launch all required services locally as needed.
-Note that by default the benchmark requires that the database is already
-initialized using ``taler-exchange-keyup``.
You can run a first simple benchmark using:
+.. note::
+ FIXME-TTN/CG: these instructions are incomplete and untested for the
+ current iteration of the code...
+
.. code-block:: console
$ createdb talercheck # if it does not yet exist
- $ taler-exchange-keyup -c benchmark.conf
+ $ taler-exchange-dbinit -c benchmark.conf
+ $ taler-exchange-httpd -c benchmark.conf &
+ $ HTTPD_PID=$!
+ $ taler-exchange-offline -c benchmark.conf \
+ download sign \
+ enable-account FIXME-DETAILS-MISING-HERE \
+ wire-fee FIXME-DETAILS-MISING-HERE \
+ upload
+ $ kill -TERM $HTTPD_PID
$ taler-exchange-benchmark -c benchmark.conf -p 4 -r 1 -n 10
This will run 4 parallel clients withdrawing 10 coins from 1 reserve and then