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 @@ | |||
1 | .. | ||
2 | This file is part of Anastasis | ||
3 | Copyright (C) 2019-2021 Anastasis SARL | ||
4 | |||
5 | Anastasis is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU Affero General Public License as published by the Free Software | ||
7 | Foundation; either version 2.1, or (at your option) any later version. | ||
8 | |||
9 | Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU Affero General Public License along with | ||
14 | Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/> | ||
15 | |||
16 | @author Christian Grothoff | ||
17 | @author Dominik Meister | ||
18 | @author Dennis Neufeld | ||
19 | |||
20 | |||
21 | ======== | ||
22 | REST API | ||
23 | ======== | ||
24 | |||
25 | .. include:: core/api-common.rst | ||
26 | |||
27 | .. _salt: | ||
28 | .. _config: | ||
29 | |||
30 | |||
31 | Receiving Configuration | ||
32 | ^^^^^^^^^^^^^^^^^^^^^^^ | ||
33 | |||
34 | .. http:get:: /config | ||
35 | |||
36 | Obtain the configuration details of the escrow provider. | ||
37 | |||
38 | **Response:** | ||
39 | |||
40 | Returns an `EscrowConfigurationResponse`_. | ||
41 | |||
42 | |||
43 | .. _EscrowConfigurationResponse: | ||
44 | .. ts:def:: EscrowConfigurationResponse | ||
45 | |||
46 | interface EscrowConfigurationResponse { | ||
47 | |||
48 | // Protocol identifier, clarifies that this is an Anastasis provider. | ||
49 | name: "anastasis"; | ||
50 | |||
51 | // libtool-style representation of the Exchange protocol version, see | ||
52 | // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning | ||
53 | // The format is "current:revision:age". | ||
54 | version: string; | ||
55 | |||
56 | // Currency in which this provider processes payments. | ||
57 | currency: string; | ||
58 | |||
59 | // Supported authorization methods. | ||
60 | methods: AuthorizationMethodConfig[]; | ||
61 | |||
62 | // Maximum policy upload size supported. | ||
63 | storage_limit_in_megabytes: number; | ||
64 | |||
65 | // Payment required to maintain an account to store policy documents for a year. | ||
66 | // Users can pay more, in which case the storage time will go up proportionally. | ||
67 | annual_fee: Amount; | ||
68 | |||
69 | // Payment required to upload truth. To be paid per upload. | ||
70 | truth_upload_fee: Amount; | ||
71 | |||
72 | // Limit on the liability that the provider is offering with | ||
73 | // respect to the services provided. | ||
74 | liability_limit: Amount; | ||
75 | |||
76 | // Salt value with 128 bits of entropy. | ||
77 | // Different providers | ||
78 | // will use different high-entropy salt values. The resulting | ||
79 | // **provider salt** is then used in various operations to ensure | ||
80 | // cryptographic operations differ by provider. A provider must | ||
81 | // never change its salt value. | ||
82 | server_salt: string; | ||
83 | |||
84 | } | ||
85 | |||
86 | .. _AuthorizationMethodConfig: | ||
87 | .. ts:def:: AuthorizationMethodConfig | ||
88 | |||
89 | interface AuthorizationMethodConfig { | ||
90 | // Name of the authorization method. | ||
91 | type: string; | ||
92 | |||
93 | // Fee for accessing key share using this method. | ||
94 | cost: Amount; | ||
95 | |||
96 | } | ||
97 | |||
98 | .. _terms: | ||
99 | |||
100 | Receiving Terms of Service | ||
101 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
102 | |||
103 | .. http:get:: /terms | ||
104 | |||
105 | Obtain the terms of service provided by the escrow provider. | ||
106 | |||
107 | **Response:** | ||
108 | |||
109 | Returns the terms of service of the provider, in the best language | ||
110 | and format available based on the client's request. | ||
111 | |||
112 | .. http:get:: /privacy | ||
113 | |||
114 | Obtain the privacy policy of the service provided by the escrow provider. | ||
115 | |||
116 | **Response:** | ||
117 | |||
118 | Returns the privacy policy of the provider, in the best language | ||
119 | and format available based on the client's request. | ||
120 | |||
121 | |||
122 | .. _manage-policy: | ||
123 | |||
124 | |||
125 | Manage policy | ||
126 | ^^^^^^^^^^^^^ | ||
127 | |||
128 | This API is used by the Anastasis client to deposit or request encrypted | ||
129 | recovery documents with the escrow provider. Generally, a client will deposit | ||
130 | the same encrypted recovery document with each escrow provider, but provide | ||
131 | a different truth to each escrow provider. | ||
132 | |||
133 | Operations by the client are identified and authorized by ``$ACCOUNT_PUB``, which | ||
134 | should be kept secret from third parties. ``$ACCOUNT_PUB`` should be an account | ||
135 | public key using the Crockford base32-encoding. | ||
136 | |||
137 | In the following, UUID is always defined and used according to `RFC 4122`_. | ||
138 | |||
139 | .. _`RFC 4122`: https://tools.ietf.org/html/rfc4122 | ||
140 | |||
141 | .. http:get:: /policy/$ACCOUNT_PUB[?version=$NUMBER] | ||
142 | |||
143 | Get the customer's encrypted recovery document. If ``version`` | ||
144 | is not specified, the server returns the latest available version. If | ||
145 | ``version`` is specified, returns the policy with the respective | ||
146 | ``version``. The response must begin with the nonce and | ||
147 | an AES-GCM tag and continue with the ciphertext. Once decrypted, the | ||
148 | plaintext is expected to contain: | ||
149 | |||
150 | * the escrow policy | ||
151 | * the separately encrypted master public key | ||
152 | |||
153 | Note that the key shares required to decrypt the master public key are | ||
154 | not included, as for this the client needs to obtain authorization. | ||
155 | The policy does provide sufficient information for the client to determine | ||
156 | how to authorize requests for **truth**. | ||
157 | |||
158 | The client MAY provide an ``If-None-Match`` header with an Etag. | ||
159 | In that case, the server MUST additionally respond with an ``304`` status | ||
160 | code in case the resource matches the provided Etag. | ||
161 | |||
162 | **Response**: | ||
163 | |||
164 | :http:statuscode:`200 OK`: | ||
165 | The escrow provider responds with an EncryptedRecoveryDocument_ object. | ||
166 | :http:statuscode:`304 Not modified`: | ||
167 | The client requested the same resource it already knows. | ||
168 | :http:statuscode:`400 Bad request`: | ||
169 | The ``$ACCOUNT_PUB`` is not an EdDSA public key. | ||
170 | :http:statuscode:`402 Payment Required`: | ||
171 | The account's balance is too low for the specified operation. | ||
172 | See the Taler payment protocol specification for how to pay. | ||
173 | :http:statuscode:`403 Forbidden`: | ||
174 | The required account signature was invalid. | ||
175 | :http:statuscode:`404 Not found`: | ||
176 | The requested resource was not found. | ||
177 | |||
178 | *Anastasis-Version*: $NUMBER --- The server must return actual version of the encrypted recovery document via this header. | ||
179 | If the client specified a version number in the header of the request, the server must return that version. If the client | ||
180 | did not specify a version in the request, the server returns latest version of the EncryptedRecoveryDocument_. | ||
181 | |||
182 | *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``. | ||
183 | |||
184 | *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. | ||
185 | The client SHOULD send this header with every request (except for the first request) to avoid unnecessary downloads. | ||
186 | |||
187 | *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). | ||
188 | |||
189 | .. http:post:: /policy/$ACCOUNT_PUB | ||
190 | |||
191 | Upload a new version of the customer's encrypted recovery document. | ||
192 | While the document's structure is described in JSON below, the upload | ||
193 | should just be the bytestream of the raw data (i.e. 32-byte nonce followed | ||
194 | by 16-byte tag followed by the encrypted document). | ||
195 | If the request has been seen before, the server should do nothing, and otherwise store the new version. | ||
196 | The body must begin with a nonce, an AES-GCM tag and continue with the ciphertext. The format | ||
197 | is the same as specified for the response of the GET method. The | ||
198 | Anastasis server cannot fully validate the format, but MAY impose | ||
199 | minimum and maximum size limits. | ||
200 | |||
201 | **Request**: | ||
202 | |||
203 | :query storage_duration=YEARS: | ||
204 | For how many years from now would the client like us to | ||
205 | store the recovery document? Defaults to 0 (that is, do | ||
206 | not extend / prolong existing storage contract). | ||
207 | The server will respond with a ``402 Payment required``, but only | ||
208 | if the rest of the request is well-formed (account | ||
209 | signature must match). Clients that do not actually | ||
210 | intend to make a new upload but that only want to pay | ||
211 | may attempt to upload the latest backup again, as this | ||
212 | option will be checked before the ``304 Not modified`` | ||
213 | case. | ||
214 | :query timeout_ms=NUMBER: *Optional.* If specified, the Anastasis server will | ||
215 | wait up to ``timeout_ms`` milliseconds for completion of the payment before | ||
216 | sending the HTTP response. A client must never rely on this behavior, as the | ||
217 | backend may return a response immediately. | ||
218 | |||
219 | *If-None-Match*: This header MUST be present and set to the SHA512 hash (Etag) of the body by the client. | ||
220 | The client SHOULD also set the ``Expect: 100-Continue`` header and wait for ``100 continue`` | ||
221 | before uploading the body. The server MUST | ||
222 | use the Etag to check whether it already knows the encrypted recovery document that is about to be uploaded. | ||
223 | The server MUST refuse the upload with a ``304`` status code if the Etag matches | ||
224 | the latest version already known to the server. | ||
225 | |||
226 | *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. | ||
227 | |||
228 | *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. | ||
229 | |||
230 | **Response**: | ||
231 | |||
232 | :http:statuscode:`204 No content`: | ||
233 | The encrypted recovery document was accepted and stored. ``Anastasis-Version`` and ``Anastasis-UUID`` headers | ||
234 | indicate what version and UUID was assigned to this encrypted recovery document upload by the server. | ||
235 | :http:statuscode:`304 Not modified`: | ||
236 | The same encrypted recovery document was previously accepted and stored. ``Anastasis-Version`` header | ||
237 | indicates what version was previously assigned to this encrypted recovery document. | ||
238 | :http:statuscode:`400 Bad request`: | ||
239 | The ``$ACCOUNT_PUB`` is not an EdDSA public key or mandatory headers are missing. | ||
240 | The response body MUST elaborate on the error using a Taler error code in the typical JSON encoding. | ||
241 | :http:statuscode:`402 Payment required`: | ||
242 | The account's balance is too low for the specified operation. | ||
243 | See the Taler payment protocol specification for how to pay. | ||
244 | The response body MAY provide alternative means for payment. | ||
245 | :http:statuscode:`403 Forbidden`: | ||
246 | The required account signature was invalid. The response body may elaborate on the error. | ||
247 | :http:statuscode:`413 Request entity too large`: | ||
248 | The upload is too large *or* too small. The response body may elaborate on the error. | ||
249 | |||
250 | **Details:** | ||
251 | |||
252 | .. _EncryptedRecoveryDocument: | ||
253 | .. ts:def:: EncryptedRecoveryDocument | ||
254 | |||
255 | interface EncryptedRecoveryDocument { | ||
256 | // Nonce used to compute the (iv,key) pair for encryption of the | ||
257 | // encrypted_compressed_recovery_document. | ||
258 | nonce: [32]; //bytearray | ||
259 | |||
260 | // Authentication tag. | ||
261 | aes_gcm_tag: [16]; //bytearray | ||
262 | |||
263 | // Variable-size encrypted recovery document. After decryption, | ||
264 | // this contains a gzip compressed JSON-encoded `RecoveryDocument`. | ||
265 | // The nonce of the HKDF for this encryption must include the | ||
266 | // string "ERD". | ||
267 | encrypted_compressed_recovery_document: []; //bytearray of undefined length | ||
268 | |||
269 | } | ||
270 | |||
271 | .. _RecoveryDocument: | ||
272 | .. ts:def:: RecoveryDocument | ||
273 | |||
274 | interface RecoveryDocument { | ||
275 | // Account identifier at backup provider, AES-encrypted with | ||
276 | // the (symmetric) master_key, i.e. an URL | ||
277 | // https://sync.taler.net/$BACKUP_ID and | ||
278 | // a private key to decrypt the backup. Anastasis is oblivious | ||
279 | // to the details of how this is ultimately encoded. | ||
280 | backup_account: []; //bytearray of undefined length | ||
281 | |||
282 | // List of escrow providers and selected authentication method. | ||
283 | methods: EscrowMethod[]; | ||
284 | |||
285 | // List of possible decryption policies. | ||
286 | policy: DecryptionPolicy[]; | ||
287 | |||
288 | } | ||
289 | |||
290 | .. _EscrowMethod: | ||
291 | .. ts:def:: EscrowMethod | ||
292 | |||
293 | interface EscrowMethod { | ||
294 | // URL of the escrow provider (including possibly this Anastasis server). | ||
295 | provider_url : string; | ||
296 | |||
297 | // Type of the escrow method (e.g. security question, SMS etc.). | ||
298 | escrow_type: string; | ||
299 | |||
300 | // UUID of the escrow method (see /truth/ API below). | ||
301 | uuid: string; | ||
302 | |||
303 | // Key used to encrypt the `Truth` this `EscrowMethod` is related to. | ||
304 | // Client has to provide this key to the server when using ``/truth/``. | ||
305 | truth_encryption_key: [32]; //bytearray | ||
306 | |||
307 | // Salt used to encrypt the truth on the Anastasis server. | ||
308 | truth_salt: [32]; //bytearray | ||
309 | |||
310 | // The challenge to give to the user (i.e. the security question | ||
311 | // if this is challenge-response). | ||
312 | // (Q: as string in base32 encoding?) | ||
313 | // (Q: what is the mime-type of this value?) | ||
314 | // | ||
315 | // For some methods, this value may be absent. | ||
316 | // | ||
317 | // The plaintext challenge is not revealed to the | ||
318 | // Anastasis server. | ||
319 | challenge: []; //bytearray of undefined length | ||
320 | |||
321 | } | ||
322 | |||
323 | .. _DecryptionPolicy: | ||
324 | .. ts:def:: DecryptionPolicy | ||
325 | |||
326 | interface DecryptionPolicy { | ||
327 | // Salt included to encrypt master key share when | ||
328 | // using this decryption policy. | ||
329 | policy_salt: [32]; //bytearray | ||
330 | |||
331 | // Master key, AES-encrypted with key derived from | ||
332 | // salt and keyshares revealed by the following list of | ||
333 | // escrow methods identified by UUID. | ||
334 | encrypted_master_key: [32]; //bytearray | ||
335 | |||
336 | // List of escrow methods identified by their UUID. | ||
337 | uuid: string[]; | ||
338 | |||
339 | } | ||
340 | |||
341 | .. _Truth: | ||
342 | |||
343 | Managing truth | ||
344 | ^^^^^^^^^^^^^^ | ||
345 | |||
346 | This API is used by the Anastasis client to deposit **truth** or request a (encrypted) **key share** with | ||
347 | the escrow provider. | ||
348 | |||
349 | An **escrow method** specifies an Anastasis provider and how the user should | ||
350 | authorize themself. The **truth** API allows the user to provide the | ||
351 | (encrypted) key share to the respective escrow provider, as well as auxiliary | ||
352 | data required for such a respective escrow method. | ||
353 | |||
354 | An Anastasis-server may store truth for free for a certain time period, or | ||
355 | charge per truth operation using GNU Taler. | ||
356 | |||
357 | .. http:post:: /truth/$UUID | ||
358 | |||
359 | Upload a `TruthUploadRequest`_-Object according to the policy the client created before (see `RecoveryDocument`_). | ||
360 | If request has been seen before, the server should do nothing, and otherwise store the new object. | ||
361 | |||
362 | **Request:** | ||
363 | |||
364 | :query timeout_ms=NUMBER: *Optional.* If specified, the Anastasis server will | ||
365 | wait up to ``timeout_ms`` milliseconds for completion of the payment before | ||
366 | sending the HTTP response. A client must never rely on this behavior, as the | ||
367 | backend may return a response immediately. | ||
368 | |||
369 | **Response:** | ||
370 | |||
371 | :http:statuscode:`204 No content`: | ||
372 | Truth stored successfully. | ||
373 | :http:statuscode:`304 Not modified`: | ||
374 | The same truth was previously accepted and stored under this UUID. The | ||
375 | Anastasis server must still update the expiration time for the truth when returning | ||
376 | this response code. | ||
377 | :http:statuscode:`402 Payment required`: | ||
378 | This server requires payment to store truth per item. | ||
379 | See the Taler payment protocol specification for how to pay. | ||
380 | The response body MAY provide alternative means for payment. | ||
381 | :http:statuscode:`409 Conflict`: | ||
382 | The server already has some truth stored under this UUID. The client should check that it | ||
383 | is generating UUIDs with enough entropy. | ||
384 | :http:statuscode:`412 Precondition failed`: | ||
385 | The selected authentication method is not supported on this provider. | ||
386 | |||
387 | |||
388 | **Details:** | ||
389 | |||
390 | .. _TruthUploadRequest: | ||
391 | .. ts:def:: TruthUploadRequest | ||
392 | |||
393 | interface TruthUploadRequest { | ||
394 | // Contains the information of an interface `EncryptedKeyShare`, but simply | ||
395 | // as one binary block (in Crockford Base32 encoding for JSON). | ||
396 | key_share_data: []; //bytearray | ||
397 | |||
398 | // Key share method, i.e. "security question", "SMS", "e-mail", ... | ||
399 | type: string; | ||
400 | |||
401 | // Nonce used to compute the (iv,key) pair for encryption of the | ||
402 | // encrypted_truth. | ||
403 | nonce: [32]; //bytearray | ||
404 | |||
405 | // Authentication tag of ``encrypted_truth``. | ||
406 | aes_gcm_tag: [16]; //bytearray | ||
407 | |||
408 | // Variable-size truth. After decryption, | ||
409 | // this contains the ground truth, i.e. H(challenge answer), | ||
410 | // phone number, e-mail address, picture, fingerprint, ... | ||
411 | // **base32 encoded**. | ||
412 | // | ||
413 | // The nonce of the HKDF for this encryption must include the | ||
414 | // string "ECT". | ||
415 | encrypted_truth: [80]; //bytearray | ||
416 | |||
417 | // MIME type of truth, i.e. text/ascii, image/jpeg, etc. | ||
418 | truth_mime: string; | ||
419 | |||
420 | // For how many years from now would the client like us to | ||
421 | // store the truth? | ||
422 | storage_duration_years: Integer; | ||
423 | |||
424 | } | ||
425 | |||
426 | .. http:get:: /truth/$UUID[?response=$H_RESPONSE] | ||
427 | |||
428 | Get the stored encrypted key share. If ``$H_RESPONSE`` is specified by the client, the server checks | ||
429 | if ``$H_RESPONSE`` matches the expected response specified before within the `TruthUploadRequest`_ (see ``encrypted_truth``). | ||
430 | Also, the user has to provide the correct *truth_encryption_key* with every get request (see below). | ||
431 | When ``$H_RESPONSE`` is correct, the server responds with the encrypted key share. | ||
432 | The encrypted key share is returned simply as a byte array and not in JSON format. | ||
433 | |||
434 | **Response**: | ||
435 | |||
436 | :http:statuscode:`200 OK`: | ||
437 | `EncryptedKeyShare`_ is returned in body (in binary). | ||
438 | :http:statuscode:`202 Accepted`: | ||
439 | The escrow provider will respond out-of-band (i.e. SMS). | ||
440 | The body may contain human-readable instructions on next steps. | ||
441 | :http:statuscode:`208 Already Reported`: | ||
442 | An authentication challenge was recently send, client should | ||
443 | simply respond to the pending challenge. | ||
444 | :http:statuscode:`303 See other`: | ||
445 | The provider redirects for authentication (i.e. video identification/WebRTC). | ||
446 | If the client is not a browser, it should launch a browser at the URL | ||
447 | given in the ``Location`` header and allow the user to re-try the operation | ||
448 | after successful authorization. | ||
449 | :http:statuscode:`402 Payment required`: | ||
450 | The service requires payment for access to truth. | ||
451 | See the Taler payment protocol specification for how to pay. | ||
452 | The response body MAY provide alternative means for payment. | ||
453 | :http:statuscode:`403 Forbidden`: | ||
454 | The server requires a valid "response" to the challenge associated with the UUID. | ||
455 | :http:statuscode:`404 Not found`: | ||
456 | The server does not know any truth under the given UUID. | ||
457 | :http:statuscode:`410 Gone`: | ||
458 | The server has not (recently) issued a challenge under the given UUID, | ||
459 | but a reply was provided. (This does not apply for secure question.) | ||
460 | :http:statuscode:`417 Expectation Failed`: | ||
461 | The decrypted ``truth`` does not match the expectations of the authentication | ||
462 | backend, i.e. a phone number for sending an SMS is not a number, or | ||
463 | an e-mail address for sending an E-mail is not a valid e-mail address. | ||
464 | :http:statuscode:`503 Service Unavailable`: | ||
465 | Server is out of Service. | ||
466 | |||
467 | *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 | ||
468 | the according `EscrowMethod`_. The server needs this key to get the info out of `TruthUploadRequest`_ needed to verify the ``$RESPONSE``. | ||
469 | |||
470 | **Details:** | ||
471 | |||
472 | .. _EncryptedKeyShare: | ||
473 | .. ts:def:: EncryptedKeyShare | ||
474 | |||
475 | interface EncryptedKeyShare { | ||
476 | // Nonce used to compute the decryption (iv,key) pair. | ||
477 | nonce_i: [32]; //bytearray | ||
478 | |||
479 | // Authentication tag. | ||
480 | aes_gcm_tag_i: [16]; //bytearray | ||
481 | |||
482 | // Encrypted key-share in base32 encoding. | ||
483 | // After decryption, this yields a `KeyShare`. Note that | ||
484 | // the `KeyShare` MUST be encoded as a fixed-size binary | ||
485 | // block (instead of in JSON encoding). | ||
486 | // | ||
487 | // HKDF for the key generation must include the | ||
488 | // string "eks" as salt. | ||
489 | // Depending on the method, | ||
490 | // the HKDF may additionally include | ||
491 | // bits from the response (i.e. some hash over the | ||
492 | // answer to the security question). | ||
493 | encrypted_key_share_i: [32]; //bytearray | ||
494 | |||
495 | } | ||
496 | |||
497 | .. _KeyShare: | ||
498 | .. ts:def:: KeyShare | ||
499 | |||
500 | interface KeyShare { | ||
501 | // Key material to concatenate with policy_salt and KDF to derive | ||
502 | // the key to decrypt the master key. | ||
503 | key_share: [32]; //bytearray | ||
504 | |||
505 | // Signature over method, UUID, and ``key_share``. | ||
506 | account_sig: EddsaSignature; | ||
507 | |||
508 | } | ||