diff options
Diffstat (limited to 'core/api-donau.rst')
-rw-r--r-- | core/api-donau.rst | 615 |
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. |