diff options
Diffstat (limited to 'doc/sphinx/core/api-common.rst')
-rw-r--r-- | doc/sphinx/core/api-common.rst | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/doc/sphinx/core/api-common.rst b/doc/sphinx/core/api-common.rst new file mode 100644 index 0000000..a7d77ba --- /dev/null +++ b/doc/sphinx/core/api-common.rst | |||
@@ -0,0 +1,360 @@ | |||
1 | .. | ||
2 | This file is part of Anastasis | ||
3 | |||
4 | Copyright (C) 2014-2021 Anastasis SARL | ||
5 | |||
6 | Anastasis is free software; you can redistribute it and/or modify it under the | ||
7 | terms of the GNU Affero Public License as published by the Free Software | ||
8 | Foundation; either version 2.1, or (at your option) any later version. | ||
9 | |||
10 | Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY | ||
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
12 | A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Affero General Public License along with | ||
15 | Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> | ||
16 | |||
17 | @author Christian Grothoff | ||
18 | |||
19 | .. _http-common: | ||
20 | |||
21 | |||
22 | ------------------------- | ||
23 | HTTP Request and Response | ||
24 | ------------------------- | ||
25 | |||
26 | Certain response formats are common for all requests. They are documented here | ||
27 | instead of with each individual request. Furthermore, we note that clients may | ||
28 | theoretically fail to receive any response. In this case, the client should | ||
29 | verify that the Internet connection is working properly, and then proceed to | ||
30 | handle the error as if an internal error (500) had been returned. | ||
31 | |||
32 | .. http:any:: /* | ||
33 | |||
34 | |||
35 | **Request:** | ||
36 | |||
37 | Unless specified otherwise, HTTP requests that carry a message body must | ||
38 | have the content type ``application/json``. | ||
39 | |||
40 | :reqheader Content-Type: application/json | ||
41 | |||
42 | **Response:** | ||
43 | |||
44 | :resheader Content-Type: application/json | ||
45 | |||
46 | :http:statuscode:`200 Ok`: | ||
47 | The request was successful. | ||
48 | :http:statuscode:`400 Bad request`: | ||
49 | One of the arguments to the request is missing or malformed. | ||
50 | :http:statuscode:`500 Internal server error`: | ||
51 | This always indicates some serious internal operational error of the Anastasis | ||
52 | provider, such as a program bug, database problems, etc., and must not be used for | ||
53 | client-side problems. When facing an internal server error, clients should | ||
54 | retry their request after some delay. We recommended initially trying after | ||
55 | 1s, twice more at randomized times within 1 minute, then the user should be | ||
56 | informed and another three retries should be scheduled within the next 24h. | ||
57 | If the error persists, a report should ultimately be made to the auditor, | ||
58 | although the auditor API for this is not yet specified. However, as internal | ||
59 | server errors are always reported to the exchange operator, a good operator | ||
60 | should naturally be able to address them in a timely fashion, especially | ||
61 | within 24h. | ||
62 | |||
63 | Unless specified otherwise, all error status codes (4xx and 5xx) have a message | ||
64 | body with an `ErrorDetail` JSON object. | ||
65 | |||
66 | **Details:** | ||
67 | |||
68 | .. ts:def:: ErrorDetail | ||
69 | |||
70 | interface ErrorDetail { | ||
71 | |||
72 | // Numeric error code unique to the condition, see ``gnu-taler-error-codes`` in GANA. | ||
73 | // The other arguments are specific to the error value reported here. | ||
74 | code: number; | ||
75 | |||
76 | // Human-readable description of the error, i.e. "missing parameter", "commitment violation", ... | ||
77 | // Should give a human-readable hint about the error's nature. Optional, may change without notice! | ||
78 | hint?: string; | ||
79 | |||
80 | } | ||
81 | |||
82 | ----------------------- | ||
83 | Protocol Version Ranges | ||
84 | ----------------------- | ||
85 | |||
86 | Anastasis services expose the range of API versions they support. Clients in | ||
87 | turn have an API version range they support. These version ranges are written | ||
88 | down in the `libtool version format | ||
89 | <https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html>`__. | ||
90 | |||
91 | A protocol version is a positive, non-zero integer. A protocol version range consists of three components: | ||
92 | |||
93 | 1. The ``current`` version. This is the latest version of the protocol supported by the client or service. | ||
94 | 2. The ``revision`` number. This value should usually not be interpreted by the client/server, but serves | ||
95 | purely as a comment. Each time a service/client for a protocol is updated while supporting the same | ||
96 | set of protocol versions, the revision should be increased. | ||
97 | In rare cases, the revision number can be used to work around unintended breakage in deployed | ||
98 | versions of a service. This is discouraged and should only be used in exceptional situations. | ||
99 | 3. The ``age`` number. This non-zero integer identifies with how many previous protocol versions this | ||
100 | implementation is compatible. An ``age`` of 0 implies that the implementation only supports | ||
101 | the ``current`` protocol version. The ``age`` must be less or equal than the ``current`` protocol version. | ||
102 | |||
103 | To avoid confusion with semantic versions, the protocol version range is written down in the following format: | ||
104 | |||
105 | .. code:: none | ||
106 | |||
107 | current[:revision[:age]] | ||
108 | |||
109 | The angle brackets mark optional components. If either ``revision`` or ``age`` are omitted, they default to 0. | ||
110 | |||
111 | Examples: | ||
112 | |||
113 | * "1" and "1" are compatible | ||
114 | * "1" and "2" are **incompatible** | ||
115 | * "2:0:1" and "1:0:0" are compatible | ||
116 | * "2:5:1" and "1:10:0" are compatible | ||
117 | * "4:0:1" and "2:0:0" are **incompatible** | ||
118 | * "4:0:1" and "3:0:0" are compatible | ||
119 | |||
120 | .. note:: | ||
121 | |||
122 | `Semantic versions <https://semver.org/>`__ are not a good tool for this job, as we concisely want to express | ||
123 | that the client/server supports the last ``n`` versions of the protocol. | ||
124 | Semantic versions don't support this, and semantic version ranges are too complex for this. | ||
125 | |||
126 | .. warning:: | ||
127 | |||
128 | A client doesn't have one single protocol version range. Instead, it has | ||
129 | a protocol version range for each type of service it talks to. | ||
130 | |||
131 | .. warning:: | ||
132 | |||
133 | For privacy reasons, the protocol version range of a client should not be | ||
134 | sent to the service. Instead, the client should just use the two version ranges | ||
135 | to decide whether it will talk to the service. | ||
136 | |||
137 | |||
138 | .. _encodings-ref: | ||
139 | |||
140 | ---------------- | ||
141 | Common encodings | ||
142 | ---------------- | ||
143 | |||
144 | This section describes how certain types of values are represented throughout the API. | ||
145 | |||
146 | .. _base32: | ||
147 | |||
148 | Binary Data | ||
149 | ^^^^^^^^^^^ | ||
150 | |||
151 | .. ts:def:: foobase | ||
152 | |||
153 | type Base32 = string; | ||
154 | |||
155 | Binary data is generally encoded using Crockford's variant of Base32 | ||
156 | (http://www.crockford.com/wrmg/base32.html), except that "U" is not excluded | ||
157 | but also decodes to "V" to make OCR easy. We will still simply use the JSON | ||
158 | type "base32" and the term "Crockford Base32" in the text to refer to the | ||
159 | resulting encoding. | ||
160 | |||
161 | |||
162 | Hash codes | ||
163 | ^^^^^^^^^^ | ||
164 | Hash codes are strings representing base32 encoding of the respective | ||
165 | hashed data. See `base32`_. | ||
166 | |||
167 | .. ts:def:: HashCode | ||
168 | |||
169 | // 64-byte hash code. | ||
170 | type HashCode = string; | ||
171 | |||
172 | .. ts:def:: ShortHashCode | ||
173 | |||
174 | // 32-byte hash code. | ||
175 | type ShortHashCode = string; | ||
176 | |||
177 | |||
178 | |||
179 | Large numbers | ||
180 | ^^^^^^^^^^^^^ | ||
181 | |||
182 | Large numbers such as 256 bit keys, are transmitted as other binary data in | ||
183 | Crockford Base32 encoding. | ||
184 | |||
185 | |||
186 | Timestamps | ||
187 | ^^^^^^^^^^ | ||
188 | |||
189 | Timestamps are represented by the following structure: | ||
190 | |||
191 | .. ts:def:: Timestamp | ||
192 | |||
193 | interface Timestamp { | ||
194 | // Milliseconds since epoch, or the special | ||
195 | // value "never" to represent an event that will | ||
196 | // never happen. | ||
197 | t_ms: number | "never"; | ||
198 | } | ||
199 | |||
200 | .. ts:def:: RelativeTime | ||
201 | |||
202 | interface Duration { | ||
203 | // Duration in milliseconds or "forever" | ||
204 | // to represent an infinite duration. | ||
205 | d_ms: number | "forever"; | ||
206 | } | ||
207 | |||
208 | |||
209 | .. _public\ key: | ||
210 | |||
211 | |||
212 | Integers | ||
213 | ^^^^^^^^ | ||
214 | |||
215 | .. ts:def:: Integer | ||
216 | |||
217 | // JavaScript numbers restricted to integers. | ||
218 | type Integer = number; | ||
219 | |||
220 | Objects | ||
221 | ^^^^^^^ | ||
222 | |||
223 | .. ts:def:: Object | ||
224 | |||
225 | // JavaScript objects, no further restrictions. | ||
226 | type Object = object; | ||
227 | |||
228 | Keys | ||
229 | ^^^^ | ||
230 | |||
231 | .. ts:def:: EddsaPublicKey | ||
232 | |||
233 | // EdDSA and ECDHE public keys always point on Curve25519 | ||
234 | // and represented using the standard 256 bits Ed25519 compact format, | ||
235 | // converted to Crockford `Base32`. | ||
236 | type EddsaPublicKey = string; | ||
237 | |||
238 | .. ts:def:: EddsaPrivateKey | ||
239 | |||
240 | // EdDSA and ECDHE public keys always point on Curve25519 | ||
241 | // and represented using the standard 256 bits Ed25519 compact format, | ||
242 | // converted to Crockford `Base32`. | ||
243 | type EddsaPrivateKey = string; | ||
244 | |||
245 | .. _signature: | ||
246 | |||
247 | Signatures | ||
248 | ^^^^^^^^^^ | ||
249 | |||
250 | |||
251 | .. ts:def:: EddsaSignature | ||
252 | |||
253 | // EdDSA signatures are transmitted as 64-bytes `base32` | ||
254 | // binary-encoded objects with just the R and S values (base32_ binary-only). | ||
255 | type EddsaSignature = string; | ||
256 | |||
257 | .. _amount: | ||
258 | |||
259 | Amounts | ||
260 | ^^^^^^^ | ||
261 | |||
262 | .. ts:def:: Amount | ||
263 | |||
264 | type Amount = string; | ||
265 | |||
266 | Amounts of currency are serialized as a string of the format | ||
267 | ``<Currency>:<DecimalAmount>``. Taler treats monetary amounts as | ||
268 | fixed-precision numbers, with 8 decimal places. Unlike floating point numbers, | ||
269 | this allows accurate representation of monetary amounts. | ||
270 | |||
271 | The following constrains apply for a valid amount: | ||
272 | |||
273 | 1. The ``<Currency>`` part must be at most 11 characters long and may only consist | ||
274 | of ASCII letters (``a-zA-Z``). | ||
275 | 2. The integer part of ``<DecimalAmount>`` may be at most 2^52. | ||
276 | 3. The fractional part of ``<DecimalAmount>`` may contain at most 8 decimal digits. | ||
277 | |||
278 | .. note:: | ||
279 | |||
280 | "EUR:1.50" and "EUR:10" are valid amounts. These are all invalid amounts: "A:B:1.5", "EUR:4503599627370501.0", "EUR:1.", "EUR:.1". | ||
281 | |||
282 | An amount that is prefixed with a ``+`` or ``-`` character is also used in certain contexts. | ||
283 | When no sign is present, the amount is assumed to be positive. | ||
284 | |||
285 | |||
286 | Time | ||
287 | ^^^^ | ||
288 | |||
289 | In signed messages, time is represented using 64-bit big-endian values, | ||
290 | denoting microseconds since the UNIX Epoch. ``UINT64_MAX`` represents "never". | ||
291 | |||
292 | .. sourcecode:: c | ||
293 | |||
294 | struct GNUNET_TIME_Absolute { | ||
295 | uint64_t timestamp_us; | ||
296 | }; | ||
297 | struct GNUNET_TIME_AbsoluteNBO { | ||
298 | uint64_t abs_value_us__; // in network byte order | ||
299 | }; | ||
300 | |||
301 | Cryptographic primitives | ||
302 | ^^^^^^^^^^^^^^^^^^^^^^^^ | ||
303 | |||
304 | All elliptic curve operations are on Curve25519. Public and private keys are | ||
305 | thus 32 bytes, and signatures 64 bytes. For hashing, including HKDFs, Taler | ||
306 | uses 512-bit hash codes (64 bytes). | ||
307 | |||
308 | .. sourcecode:: c | ||
309 | |||
310 | struct GNUNET_HashCode { | ||
311 | uint8_t hash[64]; // usually SHA-512 | ||
312 | }; | ||
313 | |||
314 | .. _TALER_EcdhEphemeralPublicKeyP: | ||
315 | .. sourcecode:: c | ||
316 | |||
317 | struct TALER_EcdhEphemeralPublicKeyP { | ||
318 | uint8_t ecdh_pub[32]; | ||
319 | }; | ||
320 | |||
321 | .. sourcecode:: c | ||
322 | |||
323 | struct UUID { | ||
324 | uint32_t value[4]; | ||
325 | }; | ||
326 | |||
327 | .. _Signatures: | ||
328 | |||
329 | Signatures | ||
330 | ^^^^^^^^^^ | ||
331 | Any piece of signed data, complies to the abstract data structure given below. | ||
332 | |||
333 | .. sourcecode:: c | ||
334 | |||
335 | struct Data { | ||
336 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
337 | type1_t payload1; | ||
338 | type2_t payload2; | ||
339 | ... | ||
340 | }; | ||
341 | |||
342 | /*From gnunet_crypto_lib.h*/ | ||
343 | struct GNUNET_CRYPTO_EccSignaturePurpose { | ||
344 | /** | ||
345 | |||
346 | The following constraints apply for a valid amount: | ||
347 | |||
348 | * This field is used to express the context in | ||
349 | * which the signature is made, ensuring that a | ||
350 | * signature cannot be lifted from one part of the protocol | ||
351 | * to another. See `src/include/taler_signatures.h` within the | ||
352 | * exchange's codebase (git://taler.net/exchange). | ||
353 | */ | ||
354 | uint32_t purpose; | ||
355 | /** | ||
356 | * This field equals the number of bytes being signed, | ||
357 | * namely 'sizeof (struct Data)'. | ||
358 | */ | ||
359 | uint32_t size; | ||
360 | }; | ||