summaryrefslogtreecommitdiff
path: root/core/api-donau.rst
diff options
context:
space:
mode:
Diffstat (limited to 'core/api-donau.rst')
-rw-r--r--core/api-donau.rst615
1 files changed, 615 insertions, 0 deletions
diff --git a/core/api-donau.rst b/core/api-donau.rst
new file mode 100644
index 00000000..09f644ec
--- /dev/null
+++ b/core/api-donau.rst
@@ -0,0 +1,615 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2023 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Christian Grothoff
+ @author Pius Loosli
+ @author Lukas Matyja
+ @author Johannes Casaburi
+
+=====================
+The Donau RESTful API
+=====================
+
+The API specified here follows the :ref:`general conventions <http-common>`
+for all details not specified in the individual requests.
+The `glossary <https://docs.taler.net/glossary.html#glossary>`_
+defines all specific terms used in this section.
+
+.. contents:: Table of Contents
+ :local:
+
+.. _donau-overview:
+
+------------
+API Overview
+------------
+
+This is intended to provide a quick overview of the whole REST API. For a more detailed view of the protocol, see the protocol specification.
+
+The chapters group the families of requests frequently encountered when using the Donau API:
+
+* :ref:`Status information<donau_status>`: get the public signing keys of the Donau, the donation unit key, the Donaus config or some entropy
+* :ref:`Issue receipts<donau_issue>`: For use by charities: Issue receipts for blinded unique donor ids.
+* :ref:`Submit receipts<donau_submit>`: Receive the receipts and, if valid, add all of it's donation units to the donor total. Returns a signature on the total yearly donation amount, hash of taxid+salt and year.
+* :ref:`Charity administration and status information<donau_charity>`:
+
+ * For use by administrators to add/modify a charity
+ * For use by charities to get their remaining donation volume
+
+.. include:: tos.rst
+
+.. _donau_status:
+
+----------------------------------------
+Donau public keys and status information
+----------------------------------------
+
+This API is used by donors and charities to obtain global information about
+the Donau, such as online signing keys and available donation units. This is
+typically the first call any Donau client makes, as it returns information
+required to process all of the other interactions with the Donau. The
+returned information is secured by signature(s) from the Donau, especially the
+long-term offline signing key of the Donau, which clients should cache.
+
+.. http:get:: /keys
+
+ Get a list of all donation units keys offered by the Donau,
+ as well as the Donau's current online signing key (used for donation statements).
+
+ **Request:**
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The Donau responds with a `DonauKeysResponse` object. This request should
+ virtually always be successful. It only fails if the Donau is misconfigured.
+
+ **Details:**
+
+ .. ts:def:: DonauKeysResponse
+
+ interface DonauKeysResponse {
+ // libtool-style representation of the Donau protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+
+ // Financial domain this Donau operates for.
+ domain: string;
+
+ // The Donau's base URL.
+ base_url: string;
+
+ // The Donau's currency.
+ currency: string;
+
+ // How many digits should the amounts be rendered
+ // with by default. Small capitals should
+ // be used to render fractions beyond the number
+ // given here (like on gas stations).
+ currency_fraction_digits: Integer;
+
+ // Donation Units offered by this Donau
+ donation_units: DonationUnitKeyGroup[];
+
+ // The Donau's signing keys.
+ signkeys: SignKey[];
+
+ }
+
+ .. ts:def:: DonationUnitKeyGroup
+
+ type DonationUnitKeyGroup =
+ | DonationUnitKeyGroupRsa
+ | DonationUnitKeyGroupCs;
+
+ .. ts:def:: DonationUnitKeyGroupRsa
+
+ interface DonationUnitKeyGroupRsa extends DonationUnitKeyGroupCommon {
+ cipher: "RSA";
+
+ donation_units: ({
+ rsa_pub: RsaPublicKey;
+ } & DonationUnitKeyCommon)[];
+ }
+
+ .. ts:def:: DonationUnitKeyGroupCs
+
+ interface DonationUnitKeyGroupCs extends DonationUnitKeyGroupCommon {
+ cipher: "CS";
+
+ donation_units: ({
+ cs_pub: Cs25519Point;
+ } & DonationUnitKeyCommon)[];
+ }
+
+ .. ts:def:: DonationUnitKeyGroupCommon
+
+ // Common attributes for all donation unit groups
+ interface DonationUnitKeyGroupCommon {
+ // How much was donated based on this donation receipt.
+ value: Amount;
+
+ }
+
+ .. ts:def:: DonationUnitKeyCommon
+
+ interface DonationUnitKeyCommon {
+
+ // For which year is this donation unit key valid.
+ year: Integer;
+
+ // Set to 'true' if the Donau somehow "lost" the private key. The donation unit was not
+ // revoked, but still cannot be used to withdraw receipts at this time (theoretically,
+ // the private key could be recovered in the future; receipts signed with the private key
+ // remain valid).
+ lost?: boolean;
+ }
+
+ .. ts:def:: DonationUnitKey
+
+ type DonationUnitKey =
+ | RsaDonationUnitKey
+ | CSDonationUnitKey;
+
+ .. ts:def:: RsaDonationUnitKey
+
+ interface RsaDonationUnitKey {
+ cipher: "RSA";
+
+ // RSA public key
+ rsa_public_key: RsaPublicKey;
+ }
+
+ .. ts:def:: CSDonationUnitKey
+
+ interface CSDonationUnitKey {
+ cipher: "CS";
+
+ // Public key of the donation unit.
+ cs_public_key: Cs25519Point;
+
+ }
+
+ A signing key in the ``signkeys`` list is a JSON object with the following fields:
+
+ .. ts:def:: SignKey
+
+ interface SignKey {
+ // The actual Donau's EdDSA signing public key.
+ key: EddsaPublicKey;
+
+ // Initial validity date for the signing key.
+ year: Integer;
+
+ }
+
+
+ .. note::
+
+ Both the individual donation units *and* the donation units list is signed,
+ allowing customers to prove that they received an inconsistent list.
+
+.. http:get:: /seed
+
+ Return an entropy seed. The Donau will return a high-entropy
+ value that will differ for every call. The response is NOT in
+ JSON, but simply high-entropy binary data in the HTTP body.
+ This API should be used by wallets to guard themselves against
+ running on low-entropy (bad PRNG) hardware. Naturally, the entropy
+ returned MUST be mixed with locally generated entropy.
+
+.. http:get:: /config
+
+ Return the protocol version, financial domain and currency supported by this
+ Donau backend.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The body is a `DonauVersionResponse`.
+
+ .. ts:def:: DonauVersionResponse
+
+ interface DonauVersionResponse {
+ // libtool-style representation of the Donau protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+
+ // Name of the protocol.
+ name: "taler-donau";
+
+ // Currency supported by this Donau.
+ currency: string;
+
+ // Financial domain by this Donau.
+ domain: string;
+
+ }
+
+
+.. _donau_issue:
+
+--------------
+Issue receipts
+--------------
+
+Inspired by the Taler exchange :ref:`Withdrawal<exchange-withdrawal>`.
+
+This API is used by the charity to obtain valid, attested donation receipts from the Donau.
+Use the :ref:`charity GET route<donau_charity_get>` to see the remaining donation volume for the current year.
+
+
+All incoming `BDID` are recorded under the corresponding charity_id by the Donau.
+
+.. http:POST:: /batch-issue/$CHARITY_ID
+
+ Send in a `IssueReceiptsRequest` and ask the Donau to sign all it's contained `BDID`.
+
+ **Request:** `IssueReceiptsRequest`
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The request was successful, and the response is a `BSDonationReceipts`.
+ :http:statuscode:`403 Forbidden`:
+ The charity signature is invalid. This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`404 Not found`:
+ At least one of the donation unit keys is not known to the Donau. Comes with a `DonationUnitUnknownError`. This suggests a bug in the donor as it should have used current donation unit keys from :ref:`/keys<donau_status>`.
+ :http:statuscode:`409 Conflict`:
+ The donation volume of the charity is not sufficient to issue donation receipts vor all sent in blinded udids. The response is a `IssueError` object.
+ :http:statuscode:`410 Gone`:
+ The requested donation unit key is not yet or no longer valid. It either before the validity start, past the expiration or was revoked. The response is a `DonationUnitExpiredMessage`. Clients must evaluate the error code provided to understand which of the cases this is and handle it accordingly.
+
+ **Details:**
+
+ .. ts:def:: IssueReceiptsRequest
+
+ interface IssueReceiptsRequest {
+ charity_signature: EddsaSignature;
+ year: Integer;
+ bdids: BDID[];
+ }
+
+ .. ts:def:: BDID
+
+ interface BDID {
+ donau_pub_hash: HashCode;
+ taxpayer_blinded_id: BDIDEnvelope;
+ }
+
+ .. ts:def:: BDIDEnvelope
+
+ type BDIDEnvelope = RSABDIDEnvelope | CSBDIDEnvelope ;
+
+ .. ts:def:: RSABDIDEnvelope
+
+ interface RSABDIDEnvelope {
+ cipher: "RSA" | "RSA+age_restricted";
+ rsa_blinded_UDID: string; // Crockford Base32 encoded
+ }
+
+ .. ts:def:: CSBDIDEnvelope
+
+ // For donation unit signatures based on Blind Clause-Schnorr, the UDID
+ // consists of the public nonce and two Curve25519 scalars which are two
+ // blinded challenges in the Blinded Clause-Schnorr signature scheme.
+ // See https://taler.net/papers/cs-thesis.pdf for details.
+ interface CSBDIDEnvelope {
+ cipher: "CS" | "CS+age_restricted";
+ cs_nonce: string; // Crockford Base32 encoded
+ cs_blinded_c0: string; // Crockford Base32 encoded
+ cs_blinded_c1: string; // Crockford Base32 encoded
+ }
+
+ .. ts:def:: BDIDBlindingKeyP
+
+ // Secret for blinding/unblinding.
+ // An RSA blinding secret, which is basically
+ // a 256-bit nonce, converted to Crockford Base32.
+ type BDIDBlindingKeyP = string;
+
+ .. ts:def:: BSDonationReceipts
+
+ interface DonationReceipts {
+ blind_signed_receipt_signatures: DonationReceiptSignature[];
+ }
+
+ .. ts:def:: DonationReceiptSignature
+
+ .. ts:def:: BlindedDonationReceiptSignature
+
+ type BlindedDonationReceiptSignature =
+ | RSABlindedDonationReceiptSignature
+ | CSBlindedDonationReceiptSignature;
+
+ .. ts:def:: RSABlindedDonationReceiptSignature
+
+ interface RSABlindedDonationReceiptSignature {
+ cipher: "RSA";
+
+ // (blinded) RSA signature
+ blinded_rsa_signature: BlindedRsaSignature;
+ }
+
+ .. ts:def:: CSBlindedDonationReceiptSignature
+
+ interface CSBlindedDonationReceiptSignature {
+ type: "CS";
+
+ // Signer chosen bit value, 0 or 1, used
+ // in Clause Blind Schnorr to make the
+ // ROS problem harder.
+ b: Integer;
+
+ // Blinded scalar calculated from c_b.
+ s: Cs25519Scalar;
+ }
+
+
+ type DonationReceiptSignature = RSADonationReceiptSignature | CSDonationReceiptSignature ;
+
+ .. ts:def:: RSADonationReceiptSignature
+
+ interface RSADonationReceiptSignature {
+ cipher: "RSA";
+ rsa_blinded_donation_receipt_sig: string; // Crockford Base32 encoded
+ }
+
+ .. ts:def:: CSDonationReceiptSignature
+
+ interface CSDonationReceiptSignature {
+ cipher: "CS";
+ cs_nonce: string; // Crockford Base32 encoded
+ cs_blinded_c0: string; // Crockford Base32 encoded
+ cs_blinded_c1: string; // Crockford Base32 encoded
+ }
+
+ .. ts:def:: IssueError
+
+ interface IssueError{
+ max_per_year: Amount;
+ current_year: Amount;
+ }
+
+ .. ts:def:: DonationUnitUnknownError
+
+ interface DonationUnitUnknownError{
+ unknown_hash_pub_donation_unit: HashCode[];
+ donau_pub: EddsaPublicKey;
+ donau_sig: EddsaSignature;
+ }
+
+ .. ts:def:: DonationUnitExpiredMessage
+
+ interface DonationUnitExpiredMessage{
+ h_donation_unit_pub: HashCode;
+ donau_pub: EddsaPublicKey;
+ donau_sig: EddsaSignature;
+ }
+
+.. _donau_submit:
+
+---------------
+Submit receipts
+---------------
+
+Inspired by the Taler exchange :ref:`Deposit<deposit-par>`.
+
+.. http:POST:: /submit
+
+ Send in donation receipts for the past fiscal year, receive signed total back.
+
+ **Request:** `SubmitDonationReceiptsRequest`
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The request was successful, and the response is a `SubmitResponse`.
+ :http:statuscode:`403 Forbidden`:
+ One of the signatures is invalid. This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`404 Not found`:
+ At least one of the donation unit keys is not known to the Donau. Comes with a `DonationUnitUnknownError`.
+ :http:statuscode:`410 Gone`:
+ The requested donation unit key is not yet or no longer valid. It either before the validity start, past the expiration or was revoked. The response is a `DonationUnitExpiredMessage`. Clients must evaluate the error code provided to understand which of the cases this is and handle it accordingly. FIXME: text does not match our use case well.
+
+ **Details:**
+
+ .. ts:def:: SubmitDonationReceiptsRequest
+
+ interface SubmitDonationReceiptsRequest{
+ // hashed taxpayer ID plus salt
+ taxnr_hashed: HashCode;
+ // All donation receipts must be for this year.
+ year: Integer;
+ // Receipts should be sorted by amount.
+ donation_receipts: DonationReceipt[];
+ }
+
+ .. ts:def:: DonationReceipt
+
+ interface DonationReceipt{
+ donation_unit_pub_hash: HashCode;
+ nonce: string;
+ donau_sig: DonationSignature
+ }
+
+ .. ts:def:: DonationSignature
+
+ type DonationSignature =
+ RsaDonationSignature | CSDonationSignature;
+
+ .. ts:def:: RsaDonationSignature
+
+ interface RsaDonationSignature {
+ cipher: "RSA";
+
+ // RSA signature
+ rsa_signature: RsaSignature;
+ }
+
+ .. ts:def:: CSDonationSignature
+
+ interface CSDonationSignature {
+ type: "CS";
+
+ // R value component of the signature.
+ cs_signature_r: Cs25519Point;
+
+ // s value component of the signature.
+ cs_signature_s: Cs25519Scalar:
+ }
+
+
+
+ .. ts:def:: SubmitResponse
+
+ interface SubmitResponse{
+ // *accepted* total
+ total: Amount;
+ // signature over taxid_hashed, total, year
+ signature: EddsaSignature;
+ }
+
+.. _donau_charity:
+
+---------------------------------------------
+Charity administration and status information
+---------------------------------------------
+
+The administration requests require an authorized bearer token to be set in the HTTP "Authorization" Header. This token can be set by a proxy validating authentication/authorization (using e.g. LDAP).
+The GET status requests require an authorized bearer token as well.
+
+.. http:GET:: /charities
+
+ GET all charities. Only allowed if the request comes with the administration bearer token.
+
+ return all charities
+
+ **Request:**
+
+ **Reponse:**
+
+ :http:statuscode:`200 OK`:
+ The request was successful, and the response is a `Charities`.
+
+ **Details:**
+
+ .. ts:def:: Charities
+
+ interface Charities{
+ charities: CharitySummary[];
+ }
+
+ .. ts:def:: CharitySummary
+
+ interface CharitySummary{
+ charity_id: Integer;
+ name: string;
+ max_per_year: Amount;
+ receipts_to_date: Amount;
+ }
+
+.. _donau_charity_get:
+
+.. http:get:: /charities/$CHARITY_ID
+
+ GET a specific charity. Only allowed if the request comes with the charity or administration bearer token.
+
+ Request information about a charity.
+
+ **Request:**
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The Donau responds with a `Charity` object
+ :http:statuscode:`404 Not found`:
+ The charity id does not belong to a charity known to the Donau.
+
+ .. ts:def:: Charity
+
+ interface Charity {
+ charity_pub: EddsaPublicKey;
+ name: string;
+ url: string;
+ max_per_year: Amount;
+ receipts_to_date: Amount;
+ current_year: Integer;
+ }
+
+.. http:POST:: /charity
+
+ Add a charity. Only allowed if the request comes with the administrator bearer token.
+
+ **Request:** `CharityRequest`
+
+ **Response:**
+
+ **Details:**
+
+ :http:statuscode:`201 Created`:
+ The request was successful, and the response is a `CharityResponse`.
+
+ :http:statuscode:`403 Forbidden`:
+ The request did not contain an accepted administrator bearer token in it's header.
+
+ .. ts:def:: CharityRequest
+
+ interface CharityRequest{
+ charity_pub: EddsaPublicKey;
+ name: string;
+ url: string;
+ max_per_year: Amount;
+ receipts_to_date: Amount;
+ current_year: Integer;
+ }
+
+ .. ts:def:: CharityResponse
+
+ interface CharityResponse{
+ id: Integer;
+ }
+
+
+.. http:PATCH:: /charities/{id}
+
+ Modify a charity. Only allowed if the request comes with the administrator bearer token.
+
+ **Request:** `CharityRequest`
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The request was successful.
+
+ :http:statuscode:`403 Forbidden`:
+ The request did not contain an accepted administrator bearer token in it's header.
+
+
+.. http:DELETE:: /charities/{id}
+
+ Delete (or deactivate) a charity. Only allowed if the request comes with the administrator bearer token.
+
+ **Request:**
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The request was successful.
+
+ :http:statuscode:`403 Forbidden`:
+ The request did not contain an accepted administrator bearer token in it's header.