1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2026-01-03 23:22:30 +03:00

Use client logger in more places (crypto code) (#4900)

* Use client logger for `RustBackupManager`

* use client logger in `CrossSigningIdentity`

* use client logger in `OutgoingRequestProcessor`

* RoomEncryptor: use correct logger for logDuration

use the logger for this specific event, rather than the more general one for the room

* Use client logger in `RoomEncryptor`
This commit is contained in:
Richard van der Hoff
2025-07-04 08:35:42 +01:00
committed by GitHub
parent 70257e0ab4
commit 6e9740d787
10 changed files with 107 additions and 89 deletions

View File

@@ -20,6 +20,7 @@ import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
import { CrossSigningIdentity } from "../../../src/rust-crypto/CrossSigningIdentity";
import { type OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
import { type ServerSideSecretStorage } from "../../../src/secret-storage";
import { logger } from "../../../src/logger.ts";
describe("CrossSigningIdentity", () => {
describe("bootstrapCrossSigning", () => {
@@ -55,7 +56,7 @@ describe("CrossSigningIdentity", () => {
store: jest.fn(),
} as unknown as Mocked<ServerSideSecretStorage>;
crossSigning = new CrossSigningIdentity(olmMachine, outgoingRequestProcessor, secretStorage);
crossSigning = new CrossSigningIdentity(logger, olmMachine, outgoingRequestProcessor, secretStorage);
});
it("should do nothing if keys are present on-device and in secret storage", async () => {

View File

@@ -53,7 +53,7 @@ describe("KeyClaimManager", () => {
markRequestAsSent: jest.fn(),
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
const outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, httpApi);
const outgoingRequestProcessor = new OutgoingRequestProcessor(logger, olmMachine, httpApi);
keyClaimManager = new KeyClaimManager(olmMachine, outgoingRequestProcessor);
});

View File

@@ -40,6 +40,7 @@ import {
type UIAuthCallback,
} from "../../../src";
import { OutgoingRequestProcessor } from "../../../src/rust-crypto/OutgoingRequestProcessor";
import { logger } from "../../../src/logger.ts";
describe("OutgoingRequestProcessor", () => {
/** the OutgoingRequestProcessor implementation under test */
@@ -76,7 +77,7 @@ describe("OutgoingRequestProcessor", () => {
markRequestAsSent: jest.fn(),
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
processor = new OutgoingRequestProcessor(olmMachine, httpApi);
processor = new OutgoingRequestProcessor(logger, olmMachine, httpApi);
});
/* simple requests that map directly to the request body */
@@ -293,7 +294,7 @@ describe("OutgoingRequestProcessor", () => {
return await authRequestResultResolvers.promise;
},
} as unknown as Mocked<MatrixHttpApi<IHttpOpts & { onlyData: true }>>;
processor = new OutgoingRequestProcessor(olmMachine, mockHttpApi);
processor = new OutgoingRequestProcessor(logger, olmMachine, mockHttpApi);
});
// build a request
@@ -325,7 +326,7 @@ describe("OutgoingRequestProcessor", () => {
onlyData: true,
});
processor = new OutgoingRequestProcessor(olmMachine, httpApi);
processor = new OutgoingRequestProcessor(logger, olmMachine, httpApi);
});
afterEach(() => {

View File

@@ -36,6 +36,7 @@ import {
AllDevicesIsolationMode,
OnlySignedDevicesIsolationMode,
} from "../../../src/crypto-api";
import { logger } from "../../../src/logger.ts";
describe("RoomEncryptor", () => {
describe("History Visibility", () => {
@@ -108,6 +109,7 @@ describe("RoomEncryptor", () => {
} as unknown as Mocked<Room>;
roomEncryptor = new RoomEncryptor(
logger,
mockOlmMachine,
mockKeyClaimManager,
mockOutgoingRequestManager,

View File

@@ -8,6 +8,7 @@ import { type OutgoingRequestProcessor } from "../../../src/rust-crypto/Outgoing
import * as testData from "../../test-utils/test-data";
import * as TestData from "../../test-utils/test-data";
import { RustBackupManager, type KeyBackup } from "../../../src/rust-crypto/backup";
import { logger } from "../../../src/logger.ts";
describe("Upload keys to backup", () => {
/** The backup manager under test */
@@ -63,7 +64,7 @@ describe("Upload keys to backup", () => {
makeOutgoingRequest: jest.fn(),
} as unknown as Mocked<OutgoingRequestProcessor>;
rustBackupManager = new RustBackupManager(mockOlmMachine, httpAPi, outgoingRequestProcessor);
rustBackupManager = new RustBackupManager(logger, mockOlmMachine, httpAPi, outgoingRequestProcessor);
fetchMock.get("path:/_matrix/client/v3/room_keys/version", testData.SIGNED_BACKUP_DATA);
});

View File

@@ -22,7 +22,7 @@ import {
import type * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
import { type BootstrapCrossSigningOpts } from "../crypto-api/index.ts";
import { logger } from "../logger.ts";
import { type Logger } from "../logger.ts";
import { type OutgoingRequestProcessor } from "./OutgoingRequestProcessor.ts";
import { type UIAuthCallback } from "../interactive-auth.ts";
import { type ServerSideSecretStorage } from "../secret-storage.ts";
@@ -33,6 +33,7 @@ import { type ServerSideSecretStorage } from "../secret-storage.ts";
*/
export class CrossSigningIdentity {
public constructor(
private readonly logger: Logger,
private readonly olmMachine: OlmMachine,
private readonly outgoingRequestProcessor: OutgoingRequestProcessor,
private readonly secretStorage: ServerSideSecretStorage,
@@ -61,7 +62,7 @@ export class CrossSigningIdentity {
olmDeviceStatus.hasMaster && olmDeviceStatus.hasUserSigning && olmDeviceStatus.hasSelfSigning;
// Log all relevant state for easier parsing of debug logs.
logger.log("bootstrapCrossSigning: starting", {
this.logger.debug("bootstrapCrossSigning: starting", {
setupNewCrossSigning: opts.setupNewCrossSigning,
olmDeviceHasMaster: olmDeviceStatus.hasMaster,
olmDeviceHasUserSigning: olmDeviceStatus.hasUserSigning,
@@ -71,23 +72,23 @@ export class CrossSigningIdentity {
if (olmDeviceHasKeys) {
if (!(await this.secretStorage.hasKey())) {
logger.warn(
this.logger.warn(
"bootstrapCrossSigning: Olm device has private keys, but secret storage is not yet set up; doing nothing for now.",
);
// the keys should get uploaded to 4S once that is set up.
} else if (!privateKeysInSecretStorage) {
// the device has the keys but they are not in 4S, so update it
logger.log("bootstrapCrossSigning: Olm device has private keys: exporting to secret storage");
this.logger.debug("bootstrapCrossSigning: Olm device has private keys: exporting to secret storage");
await this.exportCrossSigningKeysToStorage();
} else {
logger.log(
this.logger.debug(
"bootstrapCrossSigning: Olm device has private keys and they are saved in secret storage; doing nothing",
);
}
} /* (!olmDeviceHasKeys) */ else {
if (privateKeysInSecretStorage) {
// they are in 4S, so import from there
logger.log(
this.logger.debug(
"bootstrapCrossSigning: Cross-signing private keys not found locally, but they are available " +
"in secret storage, reading storage and caching locally",
);
@@ -116,7 +117,7 @@ export class CrossSigningIdentity {
device.free();
}
} else {
logger.log(
this.logger.debug(
"bootstrapCrossSigning: Cross-signing private keys not found locally or in secret storage, creating new keys",
);
await this.resetCrossSigning(opts.authUploadDeviceSigningKeys);
@@ -125,7 +126,7 @@ export class CrossSigningIdentity {
// TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the
// server -- in which case we should call OlmDevice.bootstrap_cross_signing. How do we know?
logger.log("bootstrapCrossSigning: complete");
this.logger.debug("bootstrapCrossSigning: complete");
}
/** Reset our cross-signing keys
@@ -142,7 +143,7 @@ export class CrossSigningIdentity {
// If 4S is configured we need to update it.
if (!(await this.secretStorage.hasKey())) {
logger.warn(
this.logger.warn(
"resetCrossSigning: Secret storage is not yet set up; not exporting keys to secret storage yet.",
);
// the keys should get uploaded to 4S once that is set up.
@@ -150,11 +151,11 @@ export class CrossSigningIdentity {
// Update 4S before uploading cross-signing keys, to stay consistent with legacy that asks
// 4S passphrase before asking for account password.
// Ultimately should be made atomic and resistant to forgotten password/passphrase.
logger.log("resetCrossSigning: exporting private keys to secret storage");
this.logger.debug("resetCrossSigning: exporting private keys to secret storage");
await this.exportCrossSigningKeysToStorage();
}
logger.log("resetCrossSigning: publishing public keys to server");
this.logger.debug("resetCrossSigning: publishing public keys to server");
for (const req of [
outgoingRequests.uploadKeysRequest,
outgoingRequests.uploadSigningKeysRequest,
@@ -178,17 +179,17 @@ export class CrossSigningIdentity {
if (exported?.masterKey) {
await this.secretStorage.store("m.cross_signing.master", exported.masterKey);
} else {
logger.error(`Cannot export MSK to secret storage, private key unknown`);
this.logger.error(`Cannot export MSK to secret storage, private key unknown`);
}
if (exported?.self_signing_key) {
await this.secretStorage.store("m.cross_signing.self_signing", exported.self_signing_key);
} else {
logger.error(`Cannot export SSK to secret storage, private key unknown`);
this.logger.error(`Cannot export SSK to secret storage, private key unknown`);
}
if (exported?.userSigningKey) {
await this.secretStorage.store("m.cross_signing.user_signing", exported.userSigningKey);
} else {
logger.error(`Cannot export USK to secret storage, private key unknown`);
this.logger.error(`Cannot export USK to secret storage, private key unknown`);
}
}
}

View File

@@ -28,7 +28,7 @@ import {
UploadSigningKeysRequest,
} from "@matrix-org/matrix-sdk-crypto-wasm";
import { logger } from "../logger.ts";
import { type Logger } from "../logger.ts";
import { calculateRetryBackoff, type IHttpOpts, type MatrixHttpApi, Method } from "../http-api/index.ts";
import { logDuration, type QueryDict, sleep } from "../utils.ts";
import { type AuthDict, type UIAuthCallback } from "../interactive-auth.ts";
@@ -49,6 +49,7 @@ import { UnstablePrefix as DehydrationUnstablePrefix } from "./DehydratedDeviceM
*/
export class OutgoingRequestProcessor {
public constructor(
private readonly logger: Logger,
private readonly olmMachine: OlmMachine,
private readonly http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
) {}
@@ -100,13 +101,13 @@ export class OutgoingRequestProcessor {
// PutDehydratedDeviceRequest does not implement OutgoingRequest and does not need to be marked as sent.
return;
} else {
logger.warn("Unsupported outgoing message", Object.getPrototypeOf(msg));
this.logger.warn("Unsupported outgoing message", Object.getPrototypeOf(msg));
resp = "";
}
if (msg.id) {
try {
await logDuration(logger, `Mark Request as sent ${msg.type}`, async () => {
await logDuration(this.logger, `Mark Request as sent ${msg.type}`, async () => {
await this.olmMachine.markRequestAsSent(msg.id!, msg.type, resp);
});
} catch (e) {
@@ -116,13 +117,13 @@ export class OutgoingRequestProcessor {
e instanceof Error &&
(e.message === "Attempt to use a moved value" || e.message === "null pointer passed to rust")
) {
logger.log(`Ignoring error '${e.message}': client is likely shutting down`);
this.logger.debug(`Ignoring error '${e.message}': client is likely shutting down`);
} else {
throw e;
}
}
} else {
logger.trace(`Outgoing request type:${msg.type} does not have an ID`);
this.logger.trace(`Outgoing request type:${msg.type} does not have an ID`);
}
}
@@ -143,7 +144,7 @@ export class OutgoingRequestProcessor {
}
}
logger.info(
this.logger.info(
`Sending batch of to-device messages. type=${request.event_type} txnid=${request.txn_id}`,
messageList,
);

View File

@@ -29,7 +29,7 @@ import {
import { EventType } from "../@types/event.ts";
import { type IContent, type MatrixEvent } from "../models/event.ts";
import { type Room } from "../models/room.ts";
import { type Logger, logger, LogSpan } from "../logger.ts";
import { type Logger, LogSpan } from "../logger.ts";
import { type KeyClaimManager } from "./KeyClaimManager.ts";
import { type RoomMember } from "../models/room-member.ts";
import { HistoryVisibility } from "../@types/partials.ts";
@@ -44,8 +44,6 @@ import { type DeviceIsolationMode, DeviceIsolationModeKind } from "../crypto-api
* @internal
*/
export class RoomEncryptor {
private readonly prefixedLogger: Logger;
/** whether the room members have been loaded and tracked for the first time */
private lazyLoadedMembersResolved = false;
@@ -57,6 +55,7 @@ export class RoomEncryptor {
private currentEncryptionPromise: Promise<void> = Promise.resolve();
/**
* @param prefixedLogger - A logger to use for log messages.
* @param olmMachine - The rust-sdk's OlmMachine
* @param keyClaimManager - Our KeyClaimManager, which manages the queue of one-time-key claim requests
* @param outgoingRequestManager - The OutgoingRequestManager, which manages the queue of outgoing requests.
@@ -64,14 +63,13 @@ export class RoomEncryptor {
* @param encryptionSettings - body of the m.room.encryption event currently in force in this room
*/
public constructor(
private readonly prefixedLogger: Logger,
private readonly olmMachine: OlmMachine,
private readonly keyClaimManager: KeyClaimManager,
private readonly outgoingRequestManager: OutgoingRequestsManager,
private readonly room: Room,
private encryptionSettings: IContent,
) {
this.prefixedLogger = logger.getChild(`[${room.roomId} encryption]`);
// start tracking devices for any users already known to be in this room.
// Do not load members here, would defeat lazy loading.
const members = room.getJoinedMembers();
@@ -212,7 +210,7 @@ export class RoomEncryptor {
// This could end up being racy (if two calls to ensureEncryptionSession happen at the same time), but that's
// not a particular problem, since `OlmMachine.updateTrackedUsers` just adds any users that weren't already tracked.
if (!this.lazyLoadedMembersResolved) {
await logDuration(this.prefixedLogger, "loadMembersIfNeeded: updateTrackedUsers", async () => {
await logDuration(logger, "loadMembersIfNeeded: updateTrackedUsers", async () => {
await this.olmMachine.updateTrackedUsers(members.map((u) => new RustSdkCryptoJs.UserId(u.userId)));
});
logger.debug(`Updated tracked users`);
@@ -229,7 +227,7 @@ export class RoomEncryptor {
// XXX future improvement process only KeysQueryRequests for the users that have never been queried.
logger.debug(`Processing outgoing requests`);
await logDuration(this.prefixedLogger, "doProcessOutgoingRequests", async () => {
await logDuration(logger, "doProcessOutgoingRequests", async () => {
await this.outgoingRequestManager.doProcessOutgoingRequests();
});
} else {
@@ -250,7 +248,7 @@ export class RoomEncryptor {
const userList = members.map((u) => new UserId(u.userId));
await logDuration(this.prefixedLogger, "ensureSessionsForUsers", async () => {
await logDuration(logger, "ensureSessionsForUsers", async () => {
await this.keyClaimManager.ensureSessionsForUsers(logger, userList);
});
@@ -289,7 +287,7 @@ export class RoomEncryptor {
break;
}
await logDuration(this.prefixedLogger, "shareRoomKey", async () => {
await logDuration(logger, "shareRoomKey", async () => {
const shareMessages: ToDeviceRequest[] = await this.olmMachine.shareRoomKey(
new RoomId(this.room.roomId),
// safe to pass without cloning, as it's not reused here (before or after)

View File

@@ -28,7 +28,7 @@ import {
type KeyBackupRestoreResult,
type KeyBackupRoomSessions,
} from "../crypto-api/keybackup.ts";
import { logger } from "../logger.ts";
import { type Logger } from "../logger.ts";
import { ClientPrefix, type IHttpOpts, MatrixError, type MatrixHttpApi, Method } from "../http-api/index.ts";
import { TypedEventEmitter } from "../models/typed-event-emitter.ts";
import { encodeUri, logDuration } from "../utils.ts";
@@ -81,6 +81,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
private backupKeysLoopRunning = false;
public constructor(
private readonly logger: Logger,
private readonly olmMachine: OlmMachine,
private readonly http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
private readonly outgoingRequestProcessor: OutgoingRequestProcessor,
@@ -131,7 +132,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
const backupKeys: RustSdkCryptoJs.BackupKeys = await this.olmMachine.getBackupKeys();
const decryptionKey = backupKeys?.decryptionKey;
const backupMatchesSavedPrivateKey =
!!decryptionKey && backupInfoMatchesBackupDecryptionKey(info, decryptionKey);
!!decryptionKey && this.backupInfoMatchesBackupDecryptionKey(info, decryptionKey);
return {
matchesDecryptionKey: backupMatchesSavedPrivateKey,
trusted: signatureVerification.trusted(),
@@ -171,14 +172,14 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
try {
latestBackupInfo = await this.requestKeyBackupVersion();
} catch (e) {
logger.warn("handleBackupSecretReceived: Error checking for latest key backup", e);
this.logger.warn("handleBackupSecretReceived: Error checking for latest key backup", e);
return false;
}
if (!latestBackupInfo?.version) {
// There is no server-side key backup.
// This decryption key is useless to us.
logger.warn(
this.logger.warn(
"handleBackupSecretReceived: Received a backup decryption key, but there is no trusted server-side key backup",
);
return false;
@@ -186,21 +187,21 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
try {
const backupDecryptionKey = RustSdkCryptoJs.BackupDecryptionKey.fromBase64(secret);
const privateKeyMatches = backupInfoMatchesBackupDecryptionKey(latestBackupInfo, backupDecryptionKey);
const privateKeyMatches = this.backupInfoMatchesBackupDecryptionKey(latestBackupInfo, backupDecryptionKey);
if (!privateKeyMatches) {
logger.warn(
this.logger.warn(
`handleBackupSecretReceived: Private decryption key does not match the public key of the current remote backup.`,
);
// just ignore the secret
return false;
}
logger.info(
this.logger.info(
`handleBackupSecretReceived: A valid backup decryption key has been received and stored in cache.`,
);
await this.saveBackupDecryptionKey(backupDecryptionKey, latestBackupInfo.version);
return true;
} catch (e) {
logger.warn("handleBackupSecretReceived: Invalid backup decryption key", e);
this.logger.warn("handleBackupSecretReceived: Invalid backup decryption key", e);
}
return false;
@@ -282,19 +283,19 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
/** Helper for `checkKeyBackup` */
private async doCheckKeyBackup(): Promise<KeyBackupCheck | null> {
logger.log("Checking key backup status...");
this.logger.debug("Checking key backup status...");
let backupInfo: KeyBackupInfo | null | undefined;
try {
backupInfo = await this.requestKeyBackupVersion();
} catch (e) {
logger.warn("Error checking for active key backup", e);
this.logger.warn("Error checking for active key backup", e);
this.serverBackupInfo = undefined;
return null;
}
this.checkedForBackup = true;
if (backupInfo && !backupInfo.version) {
logger.warn("active backup lacks a useful 'version'; ignoring it");
this.logger.warn("active backup lacks a useful 'version'; ignoring it");
backupInfo = undefined;
}
this.serverBackupInfo = backupInfo;
@@ -303,10 +304,10 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
if (!backupInfo) {
if (activeVersion !== null) {
logger.log("No key backup present on server: disabling key backup");
this.logger.debug("No key backup present on server: disabling key backup");
await this.disableKeyBackup();
} else {
logger.log("No key backup present on server: not enabling key backup");
this.logger.debug("No key backup present on server: not enabling key backup");
}
return null;
}
@@ -317,23 +318,25 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
// (b) the public key matches the private decryption key that we have received from 4S.
if (!trustInfo.matchesDecryptionKey && !trustInfo.trusted) {
if (activeVersion !== null) {
logger.log("Key backup present on server but not trusted: disabling key backup");
this.logger.debug("Key backup present on server but not trusted: disabling key backup");
await this.disableKeyBackup();
} else {
logger.log("Key backup present on server but not trusted: not enabling key backup");
this.logger.debug("Key backup present on server but not trusted: not enabling key backup");
}
} else {
if (activeVersion === null) {
logger.log(`Found usable key backup v${backupInfo.version}: enabling key backups`);
this.logger.debug(`Found usable key backup v${backupInfo.version}: enabling key backups`);
await this.enableKeyBackup(backupInfo);
} else if (activeVersion !== backupInfo.version) {
logger.log(`On backup version ${activeVersion} but found version ${backupInfo.version}: switching.`);
this.logger.debug(
`On backup version ${activeVersion} but found version ${backupInfo.version}: switching.`,
);
// This will remove any pending backup request, remove the backup key and reset the backup state of each room key we have.
await this.disableKeyBackup();
// Enabling will now trigger re-upload of all the keys
await this.enableKeyBackup(backupInfo);
} else {
logger.log(`Backup version ${backupInfo.version} still current`);
this.logger.debug(`Backup version ${backupInfo.version} still current`);
}
}
return { backupInfo, trustInfo };
@@ -374,12 +377,12 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
private async backupKeysLoop(maxDelay = 10000): Promise<void> {
if (this.backupKeysLoopRunning) {
logger.log(`Backup loop already running`);
this.logger.debug(`Backup loop already running`);
return;
}
this.backupKeysLoopRunning = true;
logger.log(`Backup: Starting keys upload loop for backup version:${this.activeBackupVersion}.`);
this.logger.debug(`Backup: Starting keys upload loop for backup version:${this.activeBackupVersion}.`);
// wait between 0 and `maxDelay` seconds, to avoid backup
// requests from different clients hitting the server all at
@@ -401,18 +404,18 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
let request: RustSdkCryptoJs.KeysBackupRequest | undefined = undefined;
try {
request = await logDuration(
logger,
this.logger,
"BackupRoomKeys: Get keys to backup from rust crypto-sdk",
async () => {
return await this.olmMachine.backupRoomKeys();
},
);
} catch (err) {
logger.error("Backup: Failed to get keys to backup from rust crypto-sdk", err);
this.logger.error("Backup: Failed to get keys to backup from rust crypto-sdk", err);
}
if (!request || this.stopped || !this.activeBackupVersion) {
logger.log(`Backup: Ending loop for version ${this.activeBackupVersion}.`);
this.logger.debug(`Backup: Ending loop for version ${this.activeBackupVersion}.`);
if (!request) {
// nothing more to upload
this.emit(CryptoEvent.KeyBackupSessionsRemaining, 0);
@@ -439,7 +442,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
const keyCount = await this.olmMachine.roomKeyCounts();
remainingToUploadCount = keyCount.total - keyCount.backedUp;
} catch (err) {
logger.error("Backup: Failed to get key counts from rust crypto-sdk", err);
this.logger.error("Backup: Failed to get key counts from rust crypto-sdk", err);
}
}
@@ -455,15 +458,15 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
}
} catch (err) {
numFailures++;
logger.error("Backup: Error processing backup request for rust crypto-sdk", err);
this.logger.error("Backup: Error processing backup request for rust crypto-sdk", err);
if (err instanceof MatrixError) {
const errCode = err.data.errcode;
if (errCode == "M_NOT_FOUND" || errCode == "M_WRONG_ROOM_KEYS_VERSION") {
logger.log(`Backup: Failed to upload keys to current vesion: ${errCode}.`);
this.logger.debug(`Backup: Failed to upload keys to current vesion: ${errCode}.`);
try {
await this.disableKeyBackup();
} catch (error) {
logger.error("Backup: An error occurred while disabling key backup:", error);
this.logger.error("Backup: An error occurred while disabling key backup:", error);
}
this.emit(CryptoEvent.KeyBackupFailed, err.data.errcode!);
// There was an active backup and we are out of sync with the server
@@ -480,7 +483,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
continue;
}
} catch (error) {
logger.warn(
this.logger.warn(
"Backup: An error occurred while retrieving a rate-limit retry delay",
error,
);
@@ -590,7 +593,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
* @param version - The backup version to delete.
*/
public async deleteKeyBackupVersion(version: string): Promise<void> {
logger.debug(`deleteKeyBackupVersion v:${version}`);
this.logger.debug(`deleteKeyBackupVersion v:${version}`);
const path = encodeUri("/room_keys/version/$version", { $version: version });
await this.http.authedRequest<void>(Method.Delete, path, undefined, undefined, {
prefix: ClientPrefix.V3,
@@ -607,7 +610,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
* @param decryptionKey - The private key to use for decryption.
*/
public createBackupDecryptor(decryptionKey: RustSdkCryptoJs.BackupDecryptionKey): BackupDecryptor {
return new RustBackupDecryptor(decryptionKey);
return new RustBackupDecryptor(this.logger, decryptionKey);
}
/**
@@ -707,7 +710,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
totalFailures += currentChunk.length;
// We failed to import some keys, but we should still try to import the rest?
// Log the error and continue
logger.error("Error importing keys from backup", e);
this.logger.error("Error importing keys from backup", e);
}
opts?.progressCallback?.({
@@ -755,27 +758,28 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
return { total: totalKeyCount, imported: totalImported };
}
}
/**
* Checks if the provided backup info matches the given private key.
*
* @param info - The backup info to check.
* @param backupDecryptionKey - The `BackupDecryptionKey` private key to check against.
* @returns `true` if the private key can decrypt the backup, `false` otherwise.
*/
function backupInfoMatchesBackupDecryptionKey(
info: KeyBackupInfo,
backupDecryptionKey: RustSdkCryptoJs.BackupDecryptionKey,
): boolean {
if (info.algorithm !== "m.megolm_backup.v1.curve25519-aes-sha2") {
logger.warn("backupMatchesPrivateKey: Unsupported backup algorithm", info.algorithm);
return false;
/**
* Checks if the provided backup info matches the given private key.
*
* @param info - The backup info to check.
* @param backupDecryptionKey - The `BackupDecryptionKey` private key to check against.
* @returns `true` if the private key can decrypt the backup, `false` otherwise.
*/
private backupInfoMatchesBackupDecryptionKey(
info: KeyBackupInfo,
backupDecryptionKey: RustSdkCryptoJs.BackupDecryptionKey,
): boolean {
if (info.algorithm !== "m.megolm_backup.v1.curve25519-aes-sha2") {
this.logger.warn("backupMatchesPrivateKey: Unsupported backup algorithm", info.algorithm);
return false;
}
return (
(info.auth_data as Curve25519AuthData)?.public_key === backupDecryptionKey.megolmV1PublicKey.publicKeyBase64
);
}
return (info.auth_data as Curve25519AuthData)?.public_key === backupDecryptionKey.megolmV1PublicKey.publicKeyBase64;
}
/**
* Implementation of {@link BackupDecryptor} for the rust crypto backend.
*/
@@ -783,7 +787,10 @@ export class RustBackupDecryptor implements BackupDecryptor {
private decryptionKey: RustSdkCryptoJs.BackupDecryptionKey;
public sourceTrusted: boolean;
public constructor(decryptionKey: RustSdkCryptoJs.BackupDecryptionKey) {
public constructor(
private readonly logger: Logger,
decryptionKey: RustSdkCryptoJs.BackupDecryptionKey,
) {
this.decryptionKey = decryptionKey;
this.sourceTrusted = false;
}
@@ -807,7 +814,7 @@ export class RustBackupDecryptor implements BackupDecryptor {
decrypted.session_id = sessionId;
keys.push(decrypted);
} catch (e) {
logger.log("Failed to decrypt megolm session from backup", e, sessionData);
this.logger.debug("Failed to decrypt megolm session from backup", e, sessionData);
}
}
return keys;

View File

@@ -163,7 +163,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
private readonly cryptoCallbacks: CryptoCallbacks,
) {
super();
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
this.outgoingRequestProcessor = new OutgoingRequestProcessor(logger, olmMachine, http);
this.outgoingRequestsManager = new OutgoingRequestsManager(
this.logger,
olmMachine,
@@ -172,7 +172,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
this.backupManager = new RustBackupManager(olmMachine, http, this.outgoingRequestProcessor);
this.backupManager = new RustBackupManager(logger, olmMachine, http, this.outgoingRequestProcessor);
this.perSessionBackupDownloader = new PerSessionKeyBackupDownloader(
this.logger,
this.olmMachine,
@@ -206,7 +206,12 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
CryptoEvent.DehydratedDeviceRotationError,
]);
this.crossSigningIdentity = new CrossSigningIdentity(olmMachine, this.outgoingRequestProcessor, secretStorage);
this.crossSigningIdentity = new CrossSigningIdentity(
logger,
olmMachine,
this.outgoingRequestProcessor,
secretStorage,
);
// Check and start in background the key backup connection
this.checkKeyBackupAndEnable();
@@ -1625,6 +1630,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
existingEncryptor.onCryptoEvent(config);
} else {
this.roomEncryptors[room.roomId] = new RoomEncryptor(
this.logger.getChild(`[${room.roomId} encryption]`),
this.olmMachine,
this.keyClaimManager,
this.outgoingRequestsManager,