You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-23 17:02:25 +03:00
Add crypto methods for export and import of secrets bundle (#4227)
* Add crypto methods for OIDC QR code login Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Revert test due to hang inside Rust. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update test name Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update test name Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
c88487da07
commit
a3cea8ce7d
@@ -1515,6 +1515,44 @@ describe("RustCrypto", () => {
|
|||||||
expect(await rustCrypto.isDehydrationSupported()).toBe(true);
|
expect(await rustCrypto.isDehydrationSupported()).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("import & export secrets bundle", () => {
|
||||||
|
let rustCrypto: RustCrypto;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
rustCrypto = await makeTestRustCrypto(
|
||||||
|
new MatrixHttpApi(new TypedEventEmitter<HttpApiEvent, HttpApiEventHandlerMap>(), {
|
||||||
|
baseUrl: "http://server/",
|
||||||
|
prefix: "",
|
||||||
|
onlyData: true,
|
||||||
|
}),
|
||||||
|
testData.TEST_USER_ID,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an error if there is nothing to export", async () => {
|
||||||
|
await expect(rustCrypto.exportsSecretsBundle()).rejects.toThrow(
|
||||||
|
"The store doesn't contain any cross-signing keys",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should correctly import & export a secrets bundle", async () => {
|
||||||
|
const bundle = {
|
||||||
|
cross_signing: {
|
||||||
|
master_key: "bMnVpkHI4S2wXRxy+IpaKM5PIAUUkl6DE+n0YLIW/qs",
|
||||||
|
user_signing_key: "8tlgLjUrrb/zGJo4YKGhDTIDCEjtJTAS/Sh2AGNLuIo",
|
||||||
|
self_signing_key: "pfDknmP5a0fVVRE54zhkUgJfzbNmvKcNfIWEW796bQs",
|
||||||
|
},
|
||||||
|
backup: {
|
||||||
|
algorithm: "m.megolm_backup.v1.curve25519-aes-sha2",
|
||||||
|
key: "bYYv3aFLQ49jMNcOjuTtBY9EKDby2x1m3gfX81nIKRQ",
|
||||||
|
backup_version: "9",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await rustCrypto.importSecretsBundle(bundle);
|
||||||
|
await expect(rustCrypto.exportsSecretsBundle()).resolves.toEqual(expect.objectContaining(bundle));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Build a MatrixHttpApi instance */
|
/** Build a MatrixHttpApi instance */
|
||||||
|
|||||||
40
src/@types/matrix-sdk-crypto-wasm.d.ts
vendored
Normal file
40
src/@types/matrix-sdk-crypto-wasm.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
|
||||||
|
|
||||||
|
declare module "@matrix-org/matrix-sdk-crypto-wasm" {
|
||||||
|
interface OlmMachine {
|
||||||
|
importSecretsBundle(bundle: RustSdkCryptoJs.SecretsBundle): Promise<void>;
|
||||||
|
exportSecretsBundle(): Promise<RustSdkCryptoJs.SecretsBundle>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SecretsBundle {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
to_json(): Promise<{
|
||||||
|
cross_signing: {
|
||||||
|
master_key: string;
|
||||||
|
self_signing_key: string;
|
||||||
|
user_signing_key: string;
|
||||||
|
};
|
||||||
|
backup?: {
|
||||||
|
algorithm: string;
|
||||||
|
key: string;
|
||||||
|
backup_version: string;
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { SecretsBundle } from "@matrix-org/matrix-sdk-crypto-wasm";
|
||||||
import type { IMegolmSessionData } from "./@types/crypto";
|
import type { IMegolmSessionData } from "./@types/crypto";
|
||||||
import { Room } from "./models/room";
|
import { Room } from "./models/room";
|
||||||
import { DeviceMap } from "./models/device";
|
import { DeviceMap } from "./models/device";
|
||||||
@@ -532,6 +533,23 @@ export interface CryptoApi {
|
|||||||
* to false.
|
* to false.
|
||||||
*/
|
*/
|
||||||
startDehydration(createNewKey?: boolean): Promise<void>;
|
startDehydration(createNewKey?: boolean): Promise<void>;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Import/export of secret keys
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export secrets bundle for transmitting to another device as part of OIDC QR login
|
||||||
|
*/
|
||||||
|
exportSecretsBundle?(): Promise<Awaited<ReturnType<SecretsBundle["to_json"]>>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import secrets bundle transmitted from another device.
|
||||||
|
* @param secrets - The secrets bundle received from the other device
|
||||||
|
*/
|
||||||
|
importSecretsBundle?(secrets: Awaited<ReturnType<SecretsBundle["to_json"]>>): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A reason code for a failure to decrypt an event. */
|
/** A reason code for a failure to decrypt an event. */
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import {
|
|||||||
CrossSigningKey,
|
CrossSigningKey,
|
||||||
CrossSigningKeyInfo,
|
CrossSigningKeyInfo,
|
||||||
CrossSigningStatus,
|
CrossSigningStatus,
|
||||||
|
CryptoApi,
|
||||||
CryptoCallbacks,
|
CryptoCallbacks,
|
||||||
Curve25519AuthData,
|
Curve25519AuthData,
|
||||||
DecryptionFailureCode,
|
DecryptionFailureCode,
|
||||||
@@ -1165,6 +1166,26 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
this.checkKeyBackupAndEnable();
|
this.checkKeyBackupAndEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link CryptoApi#importSecretsBundle}.
|
||||||
|
*/
|
||||||
|
public async importSecretsBundle(
|
||||||
|
secrets: Parameters<NonNullable<CryptoApi["importSecretsBundle"]>>[0],
|
||||||
|
): Promise<void> {
|
||||||
|
const secretsBundle = RustSdkCryptoJs.SecretsBundle.from_json(secrets);
|
||||||
|
await this.getOlmMachineOrThrow().importSecretsBundle(secretsBundle); // this method frees the SecretsBundle
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link CryptoApi#exportSecretsBundle}.
|
||||||
|
*/
|
||||||
|
public async exportsSecretsBundle(): ReturnType<NonNullable<CryptoApi["exportSecretsBundle"]>> {
|
||||||
|
const secretsBundle = await this.getOlmMachineOrThrow().exportSecretsBundle();
|
||||||
|
const secrets = secretsBundle.to_json();
|
||||||
|
secretsBundle.free();
|
||||||
|
return secrets;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signs the given object with the current device and current identity (if available).
|
* Signs the given object with the current device and current identity (if available).
|
||||||
* As defined in {@link https://spec.matrix.org/v1.8/appendices/#signing-json | Signing JSON}.
|
* As defined in {@link https://spec.matrix.org/v1.8/appendices/#signing-json | Signing JSON}.
|
||||||
|
|||||||
Reference in New Issue
Block a user