1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +03:00

ElementR: Stub CheckOwnCrossSigningTrust, import cross signing keys and verify local device in bootstrapCrossSigning (#3608)

This commit is contained in:
Florian Duros
2023-07-25 19:03:43 +02:00
committed by GitHub
parent 8a80886358
commit 79d4113a6b
9 changed files with 288 additions and 14 deletions

View File

@ -18,9 +18,22 @@ import fetchMock from "fetch-mock-jest";
import "fake-indexeddb/auto"; import "fake-indexeddb/auto";
import { IDBFactory } from "fake-indexeddb"; import { IDBFactory } from "fake-indexeddb";
import { CRYPTO_BACKENDS, InitCrypto } from "../../test-utils/test-utils"; import { CRYPTO_BACKENDS, InitCrypto, syncPromise } from "../../test-utils/test-utils";
import { createClient, IAuthDict, MatrixClient } from "../../../src"; import { AuthDict, createClient, CryptoEvent, MatrixClient } from "../../../src";
import { mockSetupCrossSigningRequests } from "../../test-utils/mockEndpoints"; import { mockInitialApiRequests, mockSetupCrossSigningRequests } from "../../test-utils/mockEndpoints";
import { encryptAES } from "../../../src/crypto/aes";
import { CryptoCallbacks } from "../../../src/crypto-api";
import { SECRET_STORAGE_ALGORITHM_V1_AES } from "../../../src/secret-storage";
import { ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder";
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
import {
MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64,
SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64,
SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64,
SIGNED_CROSS_SIGNING_KEYS_DATA,
USER_CROSS_SIGNING_PRIVATE_KEY_BASE64,
} from "../../test-utils/test-data";
import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder";
afterEach(() => { afterEach(() => {
// reset fake-indexeddb after each test, to make sure we don't leak connections // reset fake-indexeddb after each test, to make sure we don't leak connections
@ -39,8 +52,32 @@ const TEST_DEVICE_ID = "xzcvb";
* to provide the most effective integration tests possible. * to provide the most effective integration tests possible.
*/ */
describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: string, initCrypto: InitCrypto) => { describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: string, initCrypto: InitCrypto) => {
// newBackendOnly is the opposite to `oldBackendOnly`: it will skip the test if we are running against the legacy
// backend. Once we drop support for legacy crypto, it will go away.
const newBackendOnly = backend === "rust-sdk" ? test : test.skip;
let aliceClient: MatrixClient; let aliceClient: MatrixClient;
/** an object which intercepts `/sync` requests from {@link #aliceClient} */
let syncResponder: ISyncResponder;
/** an object which intercepts `/keys/query` requests on the test homeserver */
let e2eKeyResponder: E2EKeyResponder;
// Encryption key used to encrypt cross signing keys
const encryptionKey = new Uint8Array(32);
/**
* Create the {@link CryptoCallbacks}
*/
function createCryptoCallbacks(): CryptoCallbacks {
return {
getSecretStorageKey: (keys, name) => {
return Promise.resolve<[string, Uint8Array]>(["key_id", encryptionKey]);
},
};
}
beforeEach(async () => { beforeEach(async () => {
// anything that we don't have a specific matcher for silently returns a 404 // anything that we don't have a specific matcher for silently returns a 404
fetchMock.catch(404); fetchMock.catch(404);
@ -52,8 +89,14 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: s
userId: TEST_USER_ID, userId: TEST_USER_ID,
accessToken: "akjgkrgjs", accessToken: "akjgkrgjs",
deviceId: TEST_DEVICE_ID, deviceId: TEST_DEVICE_ID,
cryptoCallbacks: createCryptoCallbacks(),
}); });
syncResponder = new SyncResponder(homeserverUrl);
e2eKeyResponder = new E2EKeyResponder(homeserverUrl);
/** an object which intercepts `/keys/upload` requests on the test homeserver */
new E2EKeyReceiver(homeserverUrl);
await initCrypto(aliceClient); await initCrypto(aliceClient);
}); });
@ -68,7 +111,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: s
* @param authDict - The parameters to as the `auth` dict in the key upload request. * @param authDict - The parameters to as the `auth` dict in the key upload request.
* @see https://spec.matrix.org/v1.6/client-server-api/#authentication-types * @see https://spec.matrix.org/v1.6/client-server-api/#authentication-types
*/ */
async function bootstrapCrossSigning(authDict: IAuthDict): Promise<void> { async function bootstrapCrossSigning(authDict: AuthDict): Promise<void> {
await aliceClient.getCrypto()?.bootstrapCrossSigning({ await aliceClient.getCrypto()?.bootstrapCrossSigning({
authUploadDeviceSigningKeys: (makeRequest) => makeRequest(authDict).then(() => undefined), authUploadDeviceSigningKeys: (makeRequest) => makeRequest(authDict).then(() => undefined),
}); });
@ -105,6 +148,94 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("cross-signing (%s)", (backend: s
`[${TEST_USER_ID}].[${TEST_DEVICE_ID}].signatures.[${TEST_USER_ID}].[${sskId}]`, `[${TEST_USER_ID}].[${TEST_DEVICE_ID}].signatures.[${TEST_USER_ID}].[${sskId}]`,
); );
}); });
newBackendOnly("get cross signing keys from secret storage and import them", async () => {
// Return public cross signing keys
e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA);
mockInitialApiRequests(aliceClient.getHomeserverUrl());
// Encrypt the private keys and return them in the /sync response as if they are in Secret Storage
const masterKey = await encryptAES(
MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64,
encryptionKey,
"m.cross_signing.master",
);
const selfSigningKey = await encryptAES(
SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64,
encryptionKey,
"m.cross_signing.self_signing",
);
const userSigningKey = await encryptAES(
USER_CROSS_SIGNING_PRIVATE_KEY_BASE64,
encryptionKey,
"m.cross_signing.user_signing",
);
syncResponder.sendOrQueueSyncResponse({
next_batch: 1,
account_data: {
events: [
{
type: "m.cross_signing.master",
content: {
encrypted: {
key_id: masterKey,
},
},
},
{
type: "m.cross_signing.self_signing",
content: {
encrypted: {
key_id: selfSigningKey,
},
},
},
{
type: "m.cross_signing.user_signing",
content: {
encrypted: {
key_id: userSigningKey,
},
},
},
{
type: "m.secret_storage.key.key_id",
content: {
key: "key_id",
algorithm: SECRET_STORAGE_ALGORITHM_V1_AES,
},
},
],
},
});
await aliceClient.startClient();
await syncPromise(aliceClient);
// we expect a request to upload signatures for our device ...
fetchMock.post({ url: "path:/_matrix/client/v3/keys/signatures/upload", name: "upload-sigs" }, {});
// we expect the UserTrustStatusChanged event to be fired after the cross signing keys import
const userTrustStatusChangedPromise = new Promise<string>((resolve) =>
aliceClient.on(CryptoEvent.UserTrustStatusChanged, resolve),
);
const authDict = { type: "test" };
await bootstrapCrossSigning(authDict);
// Check if the UserTrustStatusChanged event was fired
expect(await userTrustStatusChangedPromise).toBe(aliceClient.getUserId());
// Expect the signature to be uploaded
expect(fetchMock.called("upload-sigs")).toBeTruthy();
const [, sigsOpts] = fetchMock.lastCall("upload-sigs")!;
const body = JSON.parse(sigsOpts!.body as string);
// the device should have a signature with the public self cross signing keys.
expect(body).toHaveProperty(
`[${TEST_USER_ID}].[${TEST_DEVICE_ID}].signatures.[${TEST_USER_ID}].[ed25519:${SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64}]`,
);
});
}); });
describe("getCrossSigningStatus()", () => { describe("getCrossSigningStatus()", () => {

View File

@ -32,13 +32,16 @@ export function mockInitialApiRequests(homeserverUrl: string) {
/** /**
* Mock the requests needed to set up cross signing * Mock the requests needed to set up cross signing
* *
* Return `{}` for `GET _matrix/client/r0/user/:userId/account_data/:type` request * Return 404 error for `GET _matrix/client/r0/user/:userId/account_data/:type` request
* Return `{}` for `POST _matrix/client/v3/keys/signatures/upload` request (named `upload-sigs` for fetchMock check) * Return `{}` for `POST _matrix/client/v3/keys/signatures/upload` request (named `upload-sigs` for fetchMock check)
* Return `{}` for `POST /_matrix/client/(unstable|v3)/keys/device_signing/upload` request (named `upload-keys` for fetchMock check) * Return `{}` for `POST /_matrix/client/(unstable|v3)/keys/device_signing/upload` request (named `upload-keys` for fetchMock check)
*/ */
export function mockSetupCrossSigningRequests(): void { export function mockSetupCrossSigningRequests(): void {
// have account_data requests return an empty object // have account_data requests return an empty object
fetchMock.get("express:/_matrix/client/r0/user/:userId/account_data/:type", {}); fetchMock.get("express:/_matrix/client/r0/user/:userId/account_data/:type", {
status: 404,
body: { errcode: "M_NOT_FOUND", error: "Account data not found." },
});
// we expect a request to upload signatures for our device ... // we expect a request to upload signatures for our device ...
fetchMock.post({ url: "path:/_matrix/client/v3/keys/signatures/upload", name: "upload-sigs" }, {}); fetchMock.post({ url: "path:/_matrix/client/v3/keys/signatures/upload", name: "upload-sigs" }, {});

View File

@ -71,6 +71,29 @@ def main() -> None:
b64_master_public_key = encode_base64( b64_master_public_key = encode_base64(
master_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw) master_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw)
) )
b64_master_private_key = encode_base64(
MASTER_CROSS_SIGNING_PRIVATE_KEY_BYTES
)
self_signing_private_key = ed25519.Ed25519PrivateKey.from_private_bytes(
SELF_CROSS_SIGNING_PRIVATE_KEY_BYTES
)
b64_self_signing_public_key = encode_base64(
self_signing_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw)
)
b64_self_signing_private_key = encode_base64(
SELF_CROSS_SIGNING_PRIVATE_KEY_BYTES
)
user_signing_private_key = ed25519.Ed25519PrivateKey.from_private_bytes(
USER_CROSS_SIGNING_PRIVATE_KEY_BYTES
)
b64_user_signing_public_key = encode_base64(
user_signing_private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw)
)
b64_user_signing_private_key = encode_base64(
USER_CROSS_SIGNING_PRIVATE_KEY_BYTES
)
print( print(
f"""\ f"""\
@ -96,6 +119,21 @@ export const SIGNED_TEST_DEVICE_DATA: IDeviceKeys = {json.dumps(device_data, ind
/** base64-encoded public master cross-signing key */ /** base64-encoded public master cross-signing key */
export const MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_master_public_key}"; export const MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_master_public_key}";
/** base64-encoded private master cross-signing key */
export const MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "{b64_master_private_key}";
/** base64-encoded public self cross-signing key */
export const SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_self_signing_public_key}";
/** base64-encoded private self signing cross-signing key */
export const SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "{b64_self_signing_private_key}";
/** base64-encoded public user cross-signing key */
export const USER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "{b64_user_signing_public_key}";
/** base64-encoded private user signing cross-signing key */
export const USER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "{b64_user_signing_private_key}";
/** Signed cross-signing keys data, also suitable for returning from a `/keys/query` call */ /** Signed cross-signing keys data, also suitable for returning from a `/keys/query` call */
export const SIGNED_CROSS_SIGNING_KEYS_DATA: Partial<IDownloadKeyResult> = { export const SIGNED_CROSS_SIGNING_KEYS_DATA: Partial<IDownloadKeyResult> = {
json.dumps(build_cross_signing_keys_data(), indent=4) json.dumps(build_cross_signing_keys_data(), indent=4)

View File

@ -36,6 +36,21 @@ export const SIGNED_TEST_DEVICE_DATA: IDeviceKeys = {
/** base64-encoded public master cross-signing key */ /** base64-encoded public master cross-signing key */
export const MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "J+5An10v1vzZpAXTYFokD1/PEVccFnLC61EfRXit0UY"; export const MASTER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "J+5An10v1vzZpAXTYFokD1/PEVccFnLC61EfRXit0UY";
/** base64-encoded private master cross-signing key */
export const MASTER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "ZG95b3VzcGVha3doYWFhYWFhYWFhYWFhYWFhYWFhbGU";
/** base64-encoded public self cross-signing key */
export const SELF_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "aU2+2CyXQTCuDcmWW0EL2bhJ6PdjFW2LbAsbHqf02AY";
/** base64-encoded private self signing cross-signing key */
export const SELF_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "c2VsZnNlbGZzZWxmc2VsZnNlbGZzZWxmc2VsZnNlbGY";
/** base64-encoded public user cross-signing key */
export const USER_CROSS_SIGNING_PUBLIC_KEY_BASE64 = "g5TC/zjQXyZYuDLZv7a41z5fFVrXpYPypG//AFQj8hY";
/** base64-encoded private user signing cross-signing key */
export const USER_CROSS_SIGNING_PRIVATE_KEY_BASE64 = "dXNlcnVzZXJ1c2VydXNlcnVzZXJ1c2VydXNlcnVzZXI";
/** Signed cross-signing keys data, also suitable for returning from a `/keys/query` call */ /** Signed cross-signing keys data, also suitable for returning from a `/keys/query` call */
export const SIGNED_CROSS_SIGNING_KEYS_DATA: Partial<IDownloadKeyResult> = { export const SIGNED_CROSS_SIGNING_KEYS_DATA: Partial<IDownloadKeyResult> = {
"master_keys": { "master_keys": {

View File

@ -19,6 +19,7 @@ import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
import { CrossSigningIdentity } from "../../../src/rust-crypto/CrossSigningIdentity"; import { CrossSigningIdentity } from "../../../src/rust-crypto/CrossSigningIdentity";
import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor"; import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
import { ServerSideSecretStorage } from "../../../src/secret-storage";
describe("CrossSigningIdentity", () => { describe("CrossSigningIdentity", () => {
describe("bootstrapCrossSigning", () => { describe("bootstrapCrossSigning", () => {
@ -31,6 +32,9 @@ describe("CrossSigningIdentity", () => {
/** A mock OutgoingRequestProcessor which crossSigning is connected to */ /** A mock OutgoingRequestProcessor which crossSigning is connected to */
let outgoingRequestProcessor: Mocked<OutgoingRequestProcessor>; let outgoingRequestProcessor: Mocked<OutgoingRequestProcessor>;
/** A mock ServerSideSecretStorage which crossSigning is connected to */
let secretStorage: Mocked<ServerSideSecretStorage>;
beforeEach(async () => { beforeEach(async () => {
await RustSdkCryptoJs.initAsync(); await RustSdkCryptoJs.initAsync();
@ -44,7 +48,11 @@ describe("CrossSigningIdentity", () => {
makeOutgoingRequest: jest.fn(), makeOutgoingRequest: jest.fn(),
} as unknown as Mocked<OutgoingRequestProcessor>; } as unknown as Mocked<OutgoingRequestProcessor>;
crossSigning = new CrossSigningIdentity(olmMachine, outgoingRequestProcessor); secretStorage = {
get: jest.fn(),
} as unknown as Mocked<ServerSideSecretStorage>;
crossSigning = new CrossSigningIdentity(olmMachine, outgoingRequestProcessor, secretStorage, jest.fn());
}); });
it("should do nothing if keys are present on-device and in secret storage", async () => { it("should do nothing if keys are present on-device and in secret storage", async () => {

View File

@ -2250,7 +2250,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
this.on(RoomMemberEvent.Membership, rustCrypto.onRoomMembership.bind(rustCrypto)); this.on(RoomMemberEvent.Membership, rustCrypto.onRoomMembership.bind(rustCrypto));
// re-emit the events emitted by the crypto impl // re-emit the events emitted by the crypto impl
this.reEmitter.reEmit(rustCrypto, [CryptoEvent.VerificationRequestReceived]); this.reEmitter.reEmit(rustCrypto, [
CryptoEvent.VerificationRequestReceived,
CryptoEvent.UserTrustStatusChanged,
]);
} }
/** /**
@ -2679,12 +2682,14 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Check the copy of our cross-signing key that we have in the device list and * Check the copy of our cross-signing key that we have in the device list and
* see if we can get the private key. If so, mark it as trusted. * see if we can get the private key. If so, mark it as trusted.
* @param opts - ICheckOwnCrossSigningTrustOpts object * @param opts - ICheckOwnCrossSigningTrustOpts object
*
* @deprecated Unneeded for the new crypto
*/ */
public checkOwnCrossSigningTrust(opts?: ICheckOwnCrossSigningTrustOpts): Promise<void> { public checkOwnCrossSigningTrust(opts?: ICheckOwnCrossSigningTrustOpts): Promise<void> {
if (!this.crypto) { if (!this.cryptoBackend) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
return this.crypto.checkOwnCrossSigningTrust(opts); return this.cryptoBackend.checkOwnCrossSigningTrust(opts);
} }
/** /**

View File

@ -90,6 +90,15 @@ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi {
* @returns the cross signing information for the user. * @returns the cross signing information for the user.
*/ */
getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null; getStoredCrossSigningForUser(userId: string): CrossSigningInfo | null;
/**
* Check the cross signing trust of the current user
*
* @param opts - Options object.
*
* @deprecated Unneeded for the new crypto
*/
checkOwnCrossSigningTrust(opts?: CheckOwnCrossSigningTrustOpts): Promise<void>;
} }
/** The methods which crypto implementations should expose to the Sync api /** The methods which crypto implementations should expose to the Sync api
@ -165,3 +174,10 @@ export interface OnSyncCompletedData {
*/ */
catchingUp?: boolean; catchingUp?: boolean;
} }
/**
* Options object for {@link CryptoBackend#checkOwnCrossSigningTrust}.
*/
export interface CheckOwnCrossSigningTrustOpts {
allowPrivateKeyRequests?: boolean;
}

View File

@ -15,11 +15,13 @@ limitations under the License.
*/ */
import { OlmMachine, CrossSigningStatus } from "@matrix-org/matrix-sdk-crypto-wasm"; import { OlmMachine, CrossSigningStatus } from "@matrix-org/matrix-sdk-crypto-wasm";
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
import { BootstrapCrossSigningOpts } from "../crypto-api"; import { BootstrapCrossSigningOpts } from "../crypto-api";
import { logger } from "../logger"; import { logger } from "../logger";
import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor";
import { UIAuthCallback } from "../interactive-auth"; import { UIAuthCallback } from "../interactive-auth";
import { ServerSideSecretStorage } from "../secret-storage";
/** Manages the cross-signing keys for our own user. /** Manages the cross-signing keys for our own user.
* *
@ -29,6 +31,9 @@ export class CrossSigningIdentity {
public constructor( public constructor(
private readonly olmMachine: OlmMachine, private readonly olmMachine: OlmMachine,
private readonly outgoingRequestProcessor: OutgoingRequestProcessor, private readonly outgoingRequestProcessor: OutgoingRequestProcessor,
private readonly secretStorage: ServerSideSecretStorage,
/** Called if the cross signing keys are imported from the secret storage */
private readonly onCrossSigningKeysImport: () => void,
) {} ) {}
/** /**
@ -41,7 +46,15 @@ export class CrossSigningIdentity {
} }
const olmDeviceStatus: CrossSigningStatus = await this.olmMachine.crossSigningStatus(); const olmDeviceStatus: CrossSigningStatus = await this.olmMachine.crossSigningStatus();
const privateKeysInSecretStorage = false; // TODO
// Try to fetch cross signing keys from the secret storage
const masterKeyFromSecretStorage = await this.secretStorage.get("m.cross_signing.master");
const selfSigningKeyFromSecretStorage = await this.secretStorage.get("m.cross_signing.self_signing");
const userSigningKeyFromSecretStorage = await this.secretStorage.get("m.cross_signing.user_signing");
const privateKeysInSecretStorage = Boolean(
masterKeyFromSecretStorage && selfSigningKeyFromSecretStorage && userSigningKeyFromSecretStorage,
);
const olmDeviceHasKeys = const olmDeviceHasKeys =
olmDeviceStatus.hasMaster && olmDeviceStatus.hasUserSigning && olmDeviceStatus.hasSelfSigning; olmDeviceStatus.hasMaster && olmDeviceStatus.hasUserSigning && olmDeviceStatus.hasSelfSigning;
@ -67,7 +80,23 @@ export class CrossSigningIdentity {
"bootStrapCrossSigning: Cross-signing private keys not found locally, but they are available " + "bootStrapCrossSigning: Cross-signing private keys not found locally, but they are available " +
"in secret storage, reading storage and caching locally", "in secret storage, reading storage and caching locally",
); );
throw new Error("TODO"); await this.olmMachine.importCrossSigningKeys(
masterKeyFromSecretStorage,
selfSigningKeyFromSecretStorage,
userSigningKeyFromSecretStorage,
);
// Get the current device
const device: RustSdkCryptoJs.Device = await this.olmMachine.getDevice(
this.olmMachine.userId,
this.olmMachine.deviceId,
);
// Sign the device with our cross-signing key and upload the signature
const request: RustSdkCryptoJs.SignatureUploadRequest = await device.verify();
await this.outgoingRequestProcessor.makeOutgoingRequest(request);
this.onCrossSigningKeysImport();
} }
// TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the // TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the

View File

@ -108,7 +108,17 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http); this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor); this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
this.eventDecryptor = new EventDecryptor(olmMachine); this.eventDecryptor = new EventDecryptor(olmMachine);
this.crossSigningIdentity = new CrossSigningIdentity(olmMachine, this.outgoingRequestProcessor);
// Fire if the cross signing keys are imported from the secret storage
const onCrossSigningKeysImport = (): void => {
this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(this.userId));
};
this.crossSigningIdentity = new CrossSigningIdentity(
olmMachine,
this.outgoingRequestProcessor,
secretStorage,
onCrossSigningKeysImport,
);
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -194,6 +204,20 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
return null; return null;
} }
/**
* This function is unneeded for the rust-crypto.
* The cross signing key import and the device verification are done in {@link CryptoApi#bootstrapCrossSigning}
*
* The function is stub to keep the compatibility with the old crypto.
* More information: https://github.com/vector-im/element-web/issues/25648
*
*
* Implementation of {@link CryptoBackend#checkOwnCrossSigningTrust}
*/
public async checkOwnCrossSigningTrust(): Promise<void> {
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// CryptoApi implementation // CryptoApi implementation
@ -1019,11 +1043,16 @@ class EventDecryptor {
} }
} }
type RustCryptoEvents = CryptoEvent.VerificationRequestReceived; type RustCryptoEvents = CryptoEvent.VerificationRequestReceived | CryptoEvent.UserTrustStatusChanged;
type RustCryptoEventMap = { type RustCryptoEventMap = {
/** /**
* Fires when a key verification request is received. * Fires when a key verification request is received.
*/ */
[CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void; [CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void;
/**
* Fires when the cross signing keys are imported during {@link CryptoApi#bootstrapCrossSigning}
*/
[CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserTrustLevel) => void;
}; };