diff options
-rw-r--r-- | design-documents/009-backup.rst | 2 | ||||
-rw-r--r-- | design-documents/010-exchange-helpers.rst | 128 | ||||
-rw-r--r-- | design-documents/index.rst | 3 | ||||
-rw-r--r-- | taler-exchange-manual.rst | 54 |
4 files changed, 184 insertions, 3 deletions
diff --git a/design-documents/009-backup.rst b/design-documents/009-backup.rst index 0f2a434a..04ae628c 100644 --- a/design-documents/009-backup.rst +++ b/design-documents/009-backup.rst @@ -133,7 +133,7 @@ Open Questions .. Note:: CG would definitively solve this using a more complex format for the **master secret**, - basically serializing mutliple **root secret** values with meta data + basically serializing multiple **root secret** values with meta data (which wallet/device/name). diff --git a/design-documents/010-exchange-helpers.rst b/design-documents/010-exchange-helpers.rst new file mode 100644 index 00000000..cf7a4dff --- /dev/null +++ b/design-documents/010-exchange-helpers.rst @@ -0,0 +1,128 @@ +Exchange crypto helper design +############################# + +Summary +======= + +A way to minimize the attack surface for extraction of the private online +signing keys (RSA and EdDSA) from the exchange is described. + + +Motivation +========== + +We want to provide an additional layer of protection for the private online +signing keys used by the exchange. The exchange is network-facing, includes an +HTTP server, Postgres interaction, JSON parser and quite a bit of other logic +which may all be theoretically vulnerable to remote exploitation. Thus, it +would be good from a security perspective to protect the private online +signing keys via an additional layer of protection. + + +Requirements +============ + +* The solution should not result in a dramatic loss of performance. +* An attacker with a successful arbitrary code execution on the exchange + must not be able to extract the private keys. +* Ideally, we should be able to determine the number of signatures + obtained illicitly by the attacker. +* Key management for operators should be simplified to improve usability. +* Both RSA and EdDSA online signing keys need to be protected. + + +Proposed Solution +================= + +The private keys are to be created, used and deleted by two helper processes +running under a different user ID (UID). The exchange's HTTP process will be +required to interact with those helpers via a UNIX domain socket. + +Specific design details: + +* The helpers will process requests from the exchange to sign and revoke keys. +* The helpers will tell the exchange when keys are created or deleted/expired. +* SOCK_DGRAM will be used to avoid needing to parse a data stream. +* The helpers will only know about (private) key lifetime. They will not know about + details like currency, fee structure, master or auditor signatures. + Those will be managed by the HTTP process to keep the helpers minimal. +* The exchange will expose the corresponding public keys via a ``/keys?future`` + endpoint to the auditor and the offline signing process. Auditor and master + signatures will be POSTed to the exchange via the ``/keys`` endpoint. + The exchange will keep those signatures in the Postgres database. +* Each exchange thread will create its own connection to the helpers, and will + block while waiting on the helper to create a signature. This keeps the + exchange logic simple and similar to the existing in-line signing calls. + Suspending and resuming would be difficult as we currently do not have a + way to wait for a UNIX domain socket to resume the MHD logic. + If a signal is received while waiting for the helper, the signature operation + fails. Signature operations can also fail if the helper is not running or + responding with incorrect data. However, signature operations do NOT have a + timeout. +* The helpers will use a single-threaded, GNUnet-scheduler-driven event loop + to process incoming requests from the UNIX domain sockets. However, the + actual signing will be done by a thread pool of workers that only process + signing requests from a work queue. Reference counting is used to avoid + releasing private keys while workers are actively using them to sign requests. +* The work queue is managed via a pthread-style semaphore. +* The master thread is informed about completed work via an ``eventfd()``. +* The master thread is responsible for handling revocations, creating future + private keys and expiring old keys. + + +Alternatives +============ + +* The helpers could have been given the information to validate the signing + request. However, without database access, validating the reserve key + signature (and others) is pretty useless. Thus, this direction would only + complicate the helper (which we want to keep minimal to minimize attack + surface) without real benefits. Even validating revocation requests (checking + signatures by auditor or master public key) makes no sense, as if an attacker + triggers a revocation, we should probably be thankful: That's a white-hat + demonstrating that they got control in the least harmful way. +* Instead of two helpers, we could have just one helper. But there is limited + overlap between the (RSA) denomination key logic and the (EdDSA) signing + key logic. Separation may improve security. +* We could have proposed a helper per denomination. But as the code of all of + these helpers would be identical, this would have no security advantages. +* We could have implemented our own event loop and configuration parser, + instead of relying on libgnunetutil. But this part of GNUnet is very + robust. +* We could have had a thread pool reading requests from the exchange clients, + instead of a master thread doling out the work. But this would become really + complicted with key revocations, and as really only the cryptography should + be the bottleneck, performance advantages should be minimal. If IPC ever + becomes the issue, then the entire idea of moving signatures to another + process would be flawed. +* More portable mechanisms (like a ``pipe()``) could be used for signaling + instead of ``eventfd()``. But, this can always be implemented if we truly + ever have an exchange operator needing support for such a platform. +* We could have left the helper single-threaded, to avoid the complications + arising from the use of threads. However, given that signing is expected to + be a bottleneck of the exchange, this would have had serious performance + implications for the entire system. + + +Drawbacks +========= + +* Additional work to properly setup an exchange and to run + our automated tests. +* Slight (?) performance impact. +* UNIX only. Likely Linux-only for now (but fixable). +* If exchange receives ANY (not ignored) signal during signing + operation, a discrepancy in the number of signatures created + between exchange (DB) and the helper will arise. Thus, + auditors have to allow for small discrepancies (increasing + over time). Note that we only expect the exchange to receive + signals if the software is updated or the process is terminated. +* If helper is stopped (SIGSTOP), exchange HTTP will itself block + (no timeout!). Timeout-based mitigation would additionally increase + discrepancies in the count of the number of signatures created. + + +Discussion / Q&A +================ + +(This should be filled in with results from discussions on mailing lists / personal communication.) diff --git a/design-documents/index.rst b/design-documents/index.rst index 55dd8c1e..6b66dd24 100644 --- a/design-documents/index.rst +++ b/design-documents/index.rst @@ -10,7 +10,7 @@ and protocol. :glob: 000-template - 001-new-browser-integration + 001-new-browser-integration 002-wallet-exchange-management 003-tos-rendering 004-wallet-withdrawal-flow @@ -19,3 +19,4 @@ and protocol. 007-payment 008-fees 009-backup + 010-exchange-helpers diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst index b156eb90..74118a7a 100644 --- a/taler-exchange-manual.rst +++ b/taler-exchange-manual.rst @@ -152,6 +152,58 @@ components: only supports Postgres, but the code could be easily extended to support another DBMS. + +Exchange online signing private key management (v0.9) +----------------------------------------------------- + +The following text only applies starting with exchange version 0.9. + +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``. + +Functionality +^^^^^^^^^^^^^ + +The two helper processes will create the required private keys, and allow +anyone with access to the UNIX domain socket to sign arbitrary messages with +the keys or to inform them about a key being revoked. The helper processes +are also responsible for deleting the private keys if their validity period +expires or if they are informed about a key having been revoked. + +Security goals +^^^^^^^^^^^^^^ + +From a security point of view, the helpers are designed to *only* make it +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. + +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 +``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 +that group). + +Configuration +^^^^^^^^^^^^^ + +The helpers and the HTTP service need both access to the same configuration +information. Having divergent configurations may result in run-time failures. +It is recommended that the configuration file (``-c`` option) is simply shared +between all of the different processes, even though they run as different +system users. The configuration does not contain any sensitive information. + + + Installation ============ @@ -207,7 +259,7 @@ To download and install libgnunetutil, proceed as follows: :: - $ git clone https://git.gnunet.org/gnunet/ + $ git clone git://git.gnunet.org/gnunet $ cd gnunet/ $ ./bootstrap $ ./configure [--prefix=GNUNETPFX] |