Skip to content

Commit aba4e69

Browse files
authored
Improve documentation on various secret-storage related methods (#4585)
* Improve documentation on various secret-storage related methods * fix link * Apply suggestions from code review
1 parent 693bb22 commit aba4e69

File tree

1 file changed

+86
-20
lines changed

1 file changed

+86
-20
lines changed

src/crypto-api/index.ts

Lines changed: 86 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type { ToDeviceBatch, ToDevicePayload } from "../models/ToDeviceMessage.t
2020
import { Room } from "../models/room.ts";
2121
import { DeviceMap } from "../models/device.ts";
2222
import { UIAuthCallback } from "../interactive-auth.ts";
23-
import { PassphraseInfo, SecretStorageCallbacks, SecretStorageKeyDescription } from "../secret-storage.ts";
23+
import { PassphraseInfo, SecretStorageKeyDescription } from "../secret-storage.ts";
2424
import { VerificationRequest } from "./verification.ts";
2525
import {
2626
BackupTrustInfo,
@@ -268,9 +268,9 @@ export interface CryptoApi {
268268
* - is enabled on this account and trusted by this device
269269
* - has private keys either cached locally or stored in secret storage
270270
*
271-
* If this function returns false, bootstrapCrossSigning() can be used
271+
* If this function returns false, {@link bootstrapCrossSigning()} can be used
272272
* to fix things such that it returns true. That is to say, after
273-
* bootstrapCrossSigning() completes successfully, this function should
273+
* `bootstrapCrossSigning()` completes successfully, this function should
274274
* return true.
275275
*
276276
* @returns True if cross-signing is ready to be used on this device
@@ -317,27 +317,30 @@ export interface CryptoApi {
317317
* - is storing cross-signing private keys
318318
* - is storing session backup key (if enabled)
319319
*
320-
* If this function returns false, bootstrapSecretStorage() can be used
320+
* If this function returns false, {@link bootstrapSecretStorage()} can be used
321321
* to fix things such that it returns true. That is to say, after
322-
* bootstrapSecretStorage() completes successfully, this function should
322+
* `bootstrapSecretStorage()` completes successfully, this function should
323323
* return true.
324324
*
325325
* @returns True if secret storage is ready to be used on this device
326326
*/
327327
isSecretStorageReady(): Promise<boolean>;
328328

329329
/**
330-
* Bootstrap the secret storage by creating a new secret storage key, add it in the secret storage and
331-
* store the cross signing keys in the secret storage.
330+
* Bootstrap [secret storage](https://spec.matrix.org/v1.12/client-server-api/#storage).
332331
*
333-
* - Generate a new key {@link GeneratedSecretStorageKey} with `createSecretStorageKey`.
334-
* Only if `setupNewSecretStorage` is set or if there is no AES key in the secret storage
335-
* - Store this key in the secret storage and set it as the default key.
336-
* - Call `cryptoCallbacks.cacheSecretStorageKey` if provided.
337-
* - Store the cross signing keys in the secret storage if
338-
* - the cross signing is ready
339-
* - a new key was created during the previous step
340-
* - or the secret storage already contains the cross signing keys
332+
* - If secret storage is not already set up, or {@link CreateSecretStorageOpts.setupNewSecretStorage} is set:
333+
* * Calls {@link CreateSecretStorageOpts.createSecretStorageKey} to generate a new key.
334+
* * Stores the metadata of the new key in account data and sets it as the default secret storage key.
335+
* * Calls {@link CryptoCallbacks.cacheSecretStorageKey} if provided.
336+
* - Stores the private cross signing keys in the secret storage if they are known, and they are not
337+
* already stored in secret storage.
338+
* - If {@link CreateSecretStorageOpts.setupNewKeyBackup} is set, calls {@link CryptoApi.resetKeyBackup}; otherwise,
339+
* stores the key backup decryption key in secret storage if it is known, and it is not
340+
* already stored in secret storage.
341+
*
342+
* Note that there may be multiple accesses to secret storage during the course of this call, each of which will
343+
* result in a call to {@link CryptoCallbacks.getSecretStorageKey}.
341344
*
342345
* @param opts - Options object.
343346
*/
@@ -562,9 +565,10 @@ export interface CryptoApi {
562565
*
563566
* If there are existing backups they will be replaced.
564567
*
565-
* The decryption key will be saved in Secret Storage (the {@link matrix.SecretStorage.SecretStorageCallbacks.getSecretStorageKey} Crypto
566-
* callback will be called)
567-
* and the backup engine will be started.
568+
* If secret storage is set up, the new decryption key will be saved (the {@link CryptoCallbacks.getSecretStorageKey}
569+
* callback will be called to obtain the secret storage key).
570+
*
571+
* The backup engine will be started using the new backup version (i.e., {@link checkKeyBackupAndEnable} is called).
568572
*/
569573
resetKeyBackup(): Promise<void>;
570574

@@ -995,15 +999,77 @@ export interface CrossSigningStatus {
995999
/**
9961000
* Crypto callbacks provided by the application
9971001
*/
998-
export interface CryptoCallbacks extends SecretStorageCallbacks {
1002+
export interface CryptoCallbacks {
1003+
/**
1004+
* Called to retrieve a secret storage encryption key.
1005+
*
1006+
* [Server-side secret storage](https://spec.matrix.org/v1.12/client-server-api/#key-storage)
1007+
* is, as the name implies, a mechanism for storing secrets which should be shared between
1008+
* clients on the server. For example, it is typically used for storing the
1009+
* [key backup decryption key](https://spec.matrix.org/v1.12/client-server-api/#decryption-key)
1010+
* and the private [cross-signing keys](https://spec.matrix.org/v1.12/client-server-api/#cross-signing).
1011+
*
1012+
* The secret storage mechanism encrypts the secrets before uploading them to the server using a
1013+
* secret storage key. The schema supports multiple keys, but in practice only one tends to be used
1014+
* at once; this is the "default secret storage key" and may be known as the "recovery key" (or, sometimes,
1015+
* the "security key").
1016+
*
1017+
* Secret storage can be set up by calling {@link CryptoApi.bootstrapSecretStorage}. Having done so, when
1018+
* the crypto stack needs to access secret storage (for example, when setting up a new device, or to
1019+
* store newly-generated secrets), it will use this callback (`getSecretStorageKey`).
1020+
*
1021+
* Note that the secret storage key may be needed several times in quick succession: it is recommended
1022+
* that applications use a temporary cache to avoid prompting the user multiple times for the key. See
1023+
* also {@link cacheSecretStorageKey} which is called when a new key is created.
1024+
*
1025+
* The helper method {@link deriveRecoveryKeyFromPassphrase} may be useful if the secret storage key
1026+
* was derived from a passphrase.
1027+
*
1028+
* @param opts - An options object.
1029+
*
1030+
* @param name - the name of the *secret* (NB: not the encryption key) being stored or retrieved.
1031+
* When the item is stored in account data, it will have this `type`.
1032+
*
1033+
* @returns a pair [`keyId`, `privateKey`], where `keyId` is one of the keys from the `keys` parameter,
1034+
* and `privateKey` is the raw private encryption key, as appropriate for the encryption algorithm.
1035+
* (For `m.secret_storage.v1.aes-hmac-sha2`, it is the input to an HKDF as defined in the
1036+
* [specification](https://spec.matrix.org/v1.6/client-server-api/#msecret_storagev1aes-hmac-sha2).)
1037+
*
1038+
* Alternatively, if none of the keys are known, may return `null` — in which case the original
1039+
* operation that requires access to a secret in secret storage may fail with an exception.
1040+
*/
1041+
getSecretStorageKey?: (
1042+
opts: {
1043+
/**
1044+
* Details of the secret storage keys required: a map from the key ID
1045+
* (excluding the `m.secret_storage.key.` prefix) to details of the key.
1046+
*
1047+
* When storing a secret, `keys` will contain exactly one entry.
1048+
*
1049+
* For secret retrieval, `keys` may contain several entries, and the application can return
1050+
* any one of the requested keys. Unless your application specifically wants to offer the
1051+
* user the ability to have more than one secret storage key active at a time, it is recommended
1052+
* to call {@link matrix.SecretStorage.ServerSideSecretStorage.getDefaultKeyId | ServerSideSecretStorage.getDefaultKeyId}
1053+
* to figure out which is the current default key, and to return `null` if the default key is not listed in `keys`.
1054+
*/
1055+
keys: Record<string, SecretStorageKeyDescription>;
1056+
},
1057+
name: string,
1058+
) => Promise<[string, Uint8Array] | null>;
1059+
9991060
/** @deprecated: unused with the Rust crypto stack. */
10001061
getCrossSigningKey?: (keyType: string, pubKey: string) => Promise<Uint8Array | null>;
10011062
/** @deprecated: unused with the Rust crypto stack. */
10021063
saveCrossSigningKeys?: (keys: Record<string, Uint8Array>) => void;
10031064
/** @deprecated: unused with the Rust crypto stack. */
10041065
shouldUpgradeDeviceVerifications?: (users: Record<string, any>) => Promise<string[]>;
1066+
10051067
/**
1006-
* Called by {@link CryptoApi#bootstrapSecretStorage}
1068+
* Called by {@link CryptoApi.bootstrapSecretStorage} when a new default secret storage key is created.
1069+
*
1070+
* Applications can use this to (temporarily) cache the secret storage key, for later return by
1071+
* {@link getSecretStorageKey}.
1072+
*
10071073
* @param keyId - secret storage key id
10081074
* @param keyInfo - secret storage key info
10091075
* @param key - private key to store

0 commit comments

Comments
 (0)