@@ -20,7 +20,7 @@ import type { ToDeviceBatch, ToDevicePayload } from "../models/ToDeviceMessage.t
2020import { Room } from "../models/room.ts" ;
2121import { DeviceMap } from "../models/device.ts" ;
2222import { UIAuthCallback } from "../interactive-auth.ts" ;
23- import { PassphraseInfo , SecretStorageCallbacks , SecretStorageKeyDescription } from "../secret-storage.ts" ;
23+ import { PassphraseInfo , SecretStorageKeyDescription } from "../secret-storage.ts" ;
2424import { VerificationRequest } from "./verification.ts" ;
2525import {
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