diff options
Diffstat (limited to 'doc/sphinx/rest.rst')
-rw-r--r-- | doc/sphinx/rest.rst | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/doc/sphinx/rest.rst b/doc/sphinx/rest.rst new file mode 100644 index 0000000..ba9d768 --- /dev/null +++ b/doc/sphinx/rest.rst @@ -0,0 +1,508 @@ +.. + This file is part of Anastasis + Copyright (C) 2019-2021 Anastasis SARL + + Anastasis 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. + + Anastasis 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 + Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + + @author Christian Grothoff + @author Dominik Meister + @author Dennis Neufeld + + +======== +REST API +======== + +.. include:: core/api-common.rst + +.. _salt: +.. _config: + + +Receiving Configuration +^^^^^^^^^^^^^^^^^^^^^^^ + +.. http:get:: /config + + Obtain the configuration details of the escrow provider. + + **Response:** + + Returns an `EscrowConfigurationResponse`_. + + + .. _EscrowConfigurationResponse: + .. ts:def:: EscrowConfigurationResponse + + interface EscrowConfigurationResponse { + + // Protocol identifier, clarifies that this is an Anastasis provider. + name: "anastasis"; + + // libtool-style representation of the Exchange protocol version, see + // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning + // The format is "current:revision:age". + version: string; + + // Currency in which this provider processes payments. + currency: string; + + // Supported authorization methods. + methods: AuthorizationMethodConfig[]; + + // Maximum policy upload size supported. + storage_limit_in_megabytes: number; + + // Payment required to maintain an account to store policy documents for a year. + // Users can pay more, in which case the storage time will go up proportionally. + annual_fee: Amount; + + // Payment required to upload truth. To be paid per upload. + truth_upload_fee: Amount; + + // Limit on the liability that the provider is offering with + // respect to the services provided. + liability_limit: Amount; + + // Salt value with 128 bits of entropy. + // Different providers + // will use different high-entropy salt values. The resulting + // **provider salt** is then used in various operations to ensure + // cryptographic operations differ by provider. A provider must + // never change its salt value. + server_salt: string; + + } + + .. _AuthorizationMethodConfig: + .. ts:def:: AuthorizationMethodConfig + + interface AuthorizationMethodConfig { + // Name of the authorization method. + type: string; + + // Fee for accessing key share using this method. + cost: Amount; + + } + +.. _terms: + +Receiving Terms of Service +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. http:get:: /terms + + Obtain the terms of service provided by the escrow provider. + + **Response:** + + Returns the terms of service of the provider, in the best language + and format available based on the client's request. + +.. http:get:: /privacy + + Obtain the privacy policy of the service provided by the escrow provider. + + **Response:** + + Returns the privacy policy of the provider, in the best language + and format available based on the client's request. + + +.. _manage-policy: + + +Manage policy +^^^^^^^^^^^^^ + +This API is used by the Anastasis client to deposit or request encrypted +recovery documents with the escrow provider. Generally, a client will deposit +the same encrypted recovery document with each escrow provider, but provide +a different truth to each escrow provider. + +Operations by the client are identified and authorized by ``$ACCOUNT_PUB``, which +should be kept secret from third parties. ``$ACCOUNT_PUB`` should be an account +public key using the Crockford base32-encoding. + +In the following, UUID is always defined and used according to `RFC 4122`_. + +.. _`RFC 4122`: https://tools.ietf.org/html/rfc4122 + +.. http:get:: /policy/$ACCOUNT_PUB[?version=$NUMBER] + + Get the customer's encrypted recovery document. If ``version`` + is not specified, the server returns the latest available version. If + ``version`` is specified, returns the policy with the respective + ``version``. The response must begin with the nonce and + an AES-GCM tag and continue with the ciphertext. Once decrypted, the + plaintext is expected to contain: + + * the escrow policy + * the separately encrypted master public key + + Note that the key shares required to decrypt the master public key are + not included, as for this the client needs to obtain authorization. + The policy does provide sufficient information for the client to determine + how to authorize requests for **truth**. + + The client MAY provide an ``If-None-Match`` header with an Etag. + In that case, the server MUST additionally respond with an ``304`` status + code in case the resource matches the provided Etag. + + **Response**: + + :http:statuscode:`200 OK`: + The escrow provider responds with an EncryptedRecoveryDocument_ object. + :http:statuscode:`304 Not modified`: + The client requested the same resource it already knows. + :http:statuscode:`400 Bad request`: + The ``$ACCOUNT_PUB`` is not an EdDSA public key. + :http:statuscode:`402 Payment Required`: + The account's balance is too low for the specified operation. + See the Taler payment protocol specification for how to pay. + :http:statuscode:`403 Forbidden`: + The required account signature was invalid. + :http:statuscode:`404 Not found`: + The requested resource was not found. + + *Anastasis-Version*: $NUMBER --- The server must return actual version of the encrypted recovery document via this header. + If the client specified a version number in the header of the request, the server must return that version. If the client + did not specify a version in the request, the server returns latest version of the EncryptedRecoveryDocument_. + + *Etag*: Set by the server to the Base32-encoded SHA512 hash of the body. Used for caching and to prevent redundancies. The server MUST send the Etag if the status code is ``200 OK``. + + *If-None-Match*: If this is not the very first request of the client, this contains the Etag-value which the client has received before from the server. + The client SHOULD send this header with every request (except for the first request) to avoid unnecessary downloads. + + *Anastasis-Account-Signature*: The client must provide Base-32 encoded EdDSA signature over hash of body with ``$ACCOUNT_PRIV``, affirming desire to download the requested encrypted recovery document. The purpose used MUST be ``TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD`` (1401). + +.. http:post:: /policy/$ACCOUNT_PUB + + Upload a new version of the customer's encrypted recovery document. + While the document's structure is described in JSON below, the upload + should just be the bytestream of the raw data (i.e. 32-byte nonce followed + by 16-byte tag followed by the encrypted document). + If the request has been seen before, the server should do nothing, and otherwise store the new version. + The body must begin with a nonce, an AES-GCM tag and continue with the ciphertext. The format + is the same as specified for the response of the GET method. The + Anastasis server cannot fully validate the format, but MAY impose + minimum and maximum size limits. + + **Request**: + + :query storage_duration=YEARS: + For how many years from now would the client like us to + store the recovery document? Defaults to 0 (that is, do + not extend / prolong existing storage contract). + The server will respond with a ``402 Payment required``, but only + if the rest of the request is well-formed (account + signature must match). Clients that do not actually + intend to make a new upload but that only want to pay + may attempt to upload the latest backup again, as this + option will be checked before the ``304 Not modified`` + case. + :query timeout_ms=NUMBER: *Optional.* If specified, the Anastasis server will + wait up to ``timeout_ms`` milliseconds for completion of the payment before + sending the HTTP response. A client must never rely on this behavior, as the + backend may return a response immediately. + + *If-None-Match*: This header MUST be present and set to the SHA512 hash (Etag) of the body by the client. + The client SHOULD also set the ``Expect: 100-Continue`` header and wait for ``100 continue`` + before uploading the body. The server MUST + use the Etag to check whether it already knows the encrypted recovery document that is about to be uploaded. + The server MUST refuse the upload with a ``304`` status code if the Etag matches + the latest version already known to the server. + + *Anastasis-Policy-Signature*: The client must provide Base-32 encoded EdDSA signature over hash of body with ``$ACCOUNT_PRIV``, affirming desire to upload an encrypted recovery document. + + *Payment-Identifier*: Base-32 encoded 32-byte payment identifier that was included in a previous payment (see ``402`` status code). Used to allow the server to check that the client paid for the upload (to protect the server against DoS attacks) and that the client knows a real secret of financial value (as the **kdf_id** might be known to an attacker). If this header is missing in the client's request (or the associated payment has exceeded the upload limit), the server must return a ``402`` response. When making payments, the server must include a fresh, randomly-generated payment-identifier in the payment request. + + **Response**: + + :http:statuscode:`204 No content`: + The encrypted recovery document was accepted and stored. ``Anastasis-Version`` and ``Anastasis-UUID`` headers + indicate what version and UUID was assigned to this encrypted recovery document upload by the server. + :http:statuscode:`304 Not modified`: + The same encrypted recovery document was previously accepted and stored. ``Anastasis-Version`` header + indicates what version was previously assigned to this encrypted recovery document. + :http:statuscode:`400 Bad request`: + The ``$ACCOUNT_PUB`` is not an EdDSA public key or mandatory headers are missing. + The response body MUST elaborate on the error using a Taler error code in the typical JSON encoding. + :http:statuscode:`402 Payment required`: + The account's balance is too low for the specified operation. + See the Taler payment protocol specification for how to pay. + The response body MAY provide alternative means for payment. + :http:statuscode:`403 Forbidden`: + The required account signature was invalid. The response body may elaborate on the error. + :http:statuscode:`413 Request entity too large`: + The upload is too large *or* too small. The response body may elaborate on the error. + + **Details:** + + .. _EncryptedRecoveryDocument: + .. ts:def:: EncryptedRecoveryDocument + + interface EncryptedRecoveryDocument { + // Nonce used to compute the (iv,key) pair for encryption of the + // encrypted_compressed_recovery_document. + nonce: [32]; //bytearray + + // Authentication tag. + aes_gcm_tag: [16]; //bytearray + + // Variable-size encrypted recovery document. After decryption, + // this contains a gzip compressed JSON-encoded `RecoveryDocument`. + // The nonce of the HKDF for this encryption must include the + // string "ERD". + encrypted_compressed_recovery_document: []; //bytearray of undefined length + + } + + .. _RecoveryDocument: + .. ts:def:: RecoveryDocument + + interface RecoveryDocument { + // Account identifier at backup provider, AES-encrypted with + // the (symmetric) master_key, i.e. an URL + // https://sync.taler.net/$BACKUP_ID and + // a private key to decrypt the backup. Anastasis is oblivious + // to the details of how this is ultimately encoded. + backup_account: []; //bytearray of undefined length + + // List of escrow providers and selected authentication method. + methods: EscrowMethod[]; + + // List of possible decryption policies. + policy: DecryptionPolicy[]; + + } + + .. _EscrowMethod: + .. ts:def:: EscrowMethod + + interface EscrowMethod { + // URL of the escrow provider (including possibly this Anastasis server). + provider_url : string; + + // Type of the escrow method (e.g. security question, SMS etc.). + escrow_type: string; + + // UUID of the escrow method (see /truth/ API below). + uuid: string; + + // Key used to encrypt the `Truth` this `EscrowMethod` is related to. + // Client has to provide this key to the server when using ``/truth/``. + truth_encryption_key: [32]; //bytearray + + // Salt used to encrypt the truth on the Anastasis server. + truth_salt: [32]; //bytearray + + // The challenge to give to the user (i.e. the security question + // if this is challenge-response). + // (Q: as string in base32 encoding?) + // (Q: what is the mime-type of this value?) + // + // For some methods, this value may be absent. + // + // The plaintext challenge is not revealed to the + // Anastasis server. + challenge: []; //bytearray of undefined length + + } + + .. _DecryptionPolicy: + .. ts:def:: DecryptionPolicy + + interface DecryptionPolicy { + // Salt included to encrypt master key share when + // using this decryption policy. + policy_salt: [32]; //bytearray + + // Master key, AES-encrypted with key derived from + // salt and keyshares revealed by the following list of + // escrow methods identified by UUID. + encrypted_master_key: [32]; //bytearray + + // List of escrow methods identified by their UUID. + uuid: string[]; + + } + +.. _Truth: + +Managing truth +^^^^^^^^^^^^^^ + +This API is used by the Anastasis client to deposit **truth** or request a (encrypted) **key share** with +the escrow provider. + +An **escrow method** specifies an Anastasis provider and how the user should +authorize themself. The **truth** API allows the user to provide the +(encrypted) key share to the respective escrow provider, as well as auxiliary +data required for such a respective escrow method. + +An Anastasis-server may store truth for free for a certain time period, or +charge per truth operation using GNU Taler. + +.. http:post:: /truth/$UUID + + Upload a `TruthUploadRequest`_-Object according to the policy the client created before (see `RecoveryDocument`_). + If request has been seen before, the server should do nothing, and otherwise store the new object. + + **Request:** + + :query timeout_ms=NUMBER: *Optional.* If specified, the Anastasis server will + wait up to ``timeout_ms`` milliseconds for completion of the payment before + sending the HTTP response. A client must never rely on this behavior, as the + backend may return a response immediately. + + **Response:** + + :http:statuscode:`204 No content`: + Truth stored successfully. + :http:statuscode:`304 Not modified`: + The same truth was previously accepted and stored under this UUID. The + Anastasis server must still update the expiration time for the truth when returning + this response code. + :http:statuscode:`402 Payment required`: + This server requires payment to store truth per item. + See the Taler payment protocol specification for how to pay. + The response body MAY provide alternative means for payment. + :http:statuscode:`409 Conflict`: + The server already has some truth stored under this UUID. The client should check that it + is generating UUIDs with enough entropy. + :http:statuscode:`412 Precondition failed`: + The selected authentication method is not supported on this provider. + + + **Details:** + + .. _TruthUploadRequest: + .. ts:def:: TruthUploadRequest + + interface TruthUploadRequest { + // Contains the information of an interface `EncryptedKeyShare`, but simply + // as one binary block (in Crockford Base32 encoding for JSON). + key_share_data: []; //bytearray + + // Key share method, i.e. "security question", "SMS", "e-mail", ... + type: string; + + // Nonce used to compute the (iv,key) pair for encryption of the + // encrypted_truth. + nonce: [32]; //bytearray + + // Authentication tag of ``encrypted_truth``. + aes_gcm_tag: [16]; //bytearray + + // Variable-size truth. After decryption, + // this contains the ground truth, i.e. H(challenge answer), + // phone number, e-mail address, picture, fingerprint, ... + // **base32 encoded**. + // + // The nonce of the HKDF for this encryption must include the + // string "ECT". + encrypted_truth: [80]; //bytearray + + // MIME type of truth, i.e. text/ascii, image/jpeg, etc. + truth_mime: string; + + // For how many years from now would the client like us to + // store the truth? + storage_duration_years: Integer; + + } + +.. http:get:: /truth/$UUID[?response=$H_RESPONSE] + + Get the stored encrypted key share. If ``$H_RESPONSE`` is specified by the client, the server checks + if ``$H_RESPONSE`` matches the expected response specified before within the `TruthUploadRequest`_ (see ``encrypted_truth``). + Also, the user has to provide the correct *truth_encryption_key* with every get request (see below). + When ``$H_RESPONSE`` is correct, the server responds with the encrypted key share. + The encrypted key share is returned simply as a byte array and not in JSON format. + + **Response**: + + :http:statuscode:`200 OK`: + `EncryptedKeyShare`_ is returned in body (in binary). + :http:statuscode:`202 Accepted`: + The escrow provider will respond out-of-band (i.e. SMS). + The body may contain human-readable instructions on next steps. + :http:statuscode:`208 Already Reported`: + An authentication challenge was recently send, client should + simply respond to the pending challenge. + :http:statuscode:`303 See other`: + The provider redirects for authentication (i.e. video identification/WebRTC). + If the client is not a browser, it should launch a browser at the URL + given in the ``Location`` header and allow the user to re-try the operation + after successful authorization. + :http:statuscode:`402 Payment required`: + The service requires payment for access to truth. + See the Taler payment protocol specification for how to pay. + The response body MAY provide alternative means for payment. + :http:statuscode:`403 Forbidden`: + The server requires a valid "response" to the challenge associated with the UUID. + :http:statuscode:`404 Not found`: + The server does not know any truth under the given UUID. + :http:statuscode:`410 Gone`: + The server has not (recently) issued a challenge under the given UUID, + but a reply was provided. (This does not apply for secure question.) + :http:statuscode:`417 Expectation Failed`: + The decrypted ``truth`` does not match the expectations of the authentication + backend, i.e. a phone number for sending an SMS is not a number, or + an e-mail address for sending an E-mail is not a valid e-mail address. + :http:statuscode:`503 Service Unavailable`: + Server is out of Service. + + *Truth-Decryption-Key*: Key used to encrypt the **truth** (see encrypted_truth within `TruthUploadRequest`_) and which has to provided by the user. The key is stored with + the according `EscrowMethod`_. The server needs this key to get the info out of `TruthUploadRequest`_ needed to verify the ``$RESPONSE``. + + **Details:** + + .. _EncryptedKeyShare: + .. ts:def:: EncryptedKeyShare + + interface EncryptedKeyShare { + // Nonce used to compute the decryption (iv,key) pair. + nonce_i: [32]; //bytearray + + // Authentication tag. + aes_gcm_tag_i: [16]; //bytearray + + // Encrypted key-share in base32 encoding. + // After decryption, this yields a `KeyShare`. Note that + // the `KeyShare` MUST be encoded as a fixed-size binary + // block (instead of in JSON encoding). + // + // HKDF for the key generation must include the + // string "eks" as salt. + // Depending on the method, + // the HKDF may additionally include + // bits from the response (i.e. some hash over the + // answer to the security question). + encrypted_key_share_i: [32]; //bytearray + + } + + .. _KeyShare: + .. ts:def:: KeyShare + + interface KeyShare { + // Key material to concatenate with policy_salt and KDF to derive + // the key to decrypt the master key. + key_share: [32]; //bytearray + + // Signature over method, UUID, and ``key_share``. + account_sig: EddsaSignature; + + } |