mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 11:35:04 +01:00
create cross-signing class, support deriving msk from 4s stored privkey
and check if they match the publicized one and then trust it
This commit is contained in:
parent
ce5b27f4b8
commit
fdce098245
@ -31,6 +31,7 @@ import {Encryption as OlmEncryption} from "./e2ee/olm/Encryption";
|
|||||||
import {Decryption as MegOlmDecryption} from "./e2ee/megolm/Decryption";
|
import {Decryption as MegOlmDecryption} from "./e2ee/megolm/Decryption";
|
||||||
import {KeyLoader as MegOlmKeyLoader} from "./e2ee/megolm/decryption/KeyLoader";
|
import {KeyLoader as MegOlmKeyLoader} from "./e2ee/megolm/decryption/KeyLoader";
|
||||||
import {KeyBackup} from "./e2ee/megolm/keybackup/KeyBackup";
|
import {KeyBackup} from "./e2ee/megolm/keybackup/KeyBackup";
|
||||||
|
import {CrossSigning} from "./verification/CrossSigning";
|
||||||
import {Encryption as MegOlmEncryption} from "./e2ee/megolm/Encryption.js";
|
import {Encryption as MegOlmEncryption} from "./e2ee/megolm/Encryption.js";
|
||||||
import {MEGOLM_ALGORITHM} from "./e2ee/common.js";
|
import {MEGOLM_ALGORITHM} from "./e2ee/common.js";
|
||||||
import {RoomEncryption} from "./e2ee/RoomEncryption.js";
|
import {RoomEncryption} from "./e2ee/RoomEncryption.js";
|
||||||
@ -59,6 +60,7 @@ export class Session {
|
|||||||
this._storage = storage;
|
this._storage = storage;
|
||||||
this._hsApi = hsApi;
|
this._hsApi = hsApi;
|
||||||
this._mediaRepository = mediaRepository;
|
this._mediaRepository = mediaRepository;
|
||||||
|
this._features = features;
|
||||||
this._syncInfo = null;
|
this._syncInfo = null;
|
||||||
this._sessionInfo = sessionInfo;
|
this._sessionInfo = sessionInfo;
|
||||||
this._rooms = new ObservableMap();
|
this._rooms = new ObservableMap();
|
||||||
@ -88,6 +90,7 @@ export class Session {
|
|||||||
this._getSyncToken = () => this.syncToken;
|
this._getSyncToken = () => this.syncToken;
|
||||||
this._olmWorker = olmWorker;
|
this._olmWorker = olmWorker;
|
||||||
this._keyBackup = new ObservableValue(undefined);
|
this._keyBackup = new ObservableValue(undefined);
|
||||||
|
this._crossSigning = undefined;
|
||||||
this._observedRoomStatus = new Map();
|
this._observedRoomStatus = new Map();
|
||||||
|
|
||||||
if (olm) {
|
if (olm) {
|
||||||
@ -330,6 +333,20 @@ export class Session {
|
|||||||
txn
|
txn
|
||||||
);
|
);
|
||||||
if (keyBackup) {
|
if (keyBackup) {
|
||||||
|
if (this._features.crossSigning) {
|
||||||
|
this._crossSigning = new CrossSigning({
|
||||||
|
storage: this._storage,
|
||||||
|
secretStorage,
|
||||||
|
platform: this._platform,
|
||||||
|
olm: this._olm,
|
||||||
|
deviceTracker: this._deviceTracker,
|
||||||
|
hsApi: this._hsApi,
|
||||||
|
ownUserId: this.userId
|
||||||
|
});
|
||||||
|
await log.wrap("enable cross-signing", log => {
|
||||||
|
return this._crossSigning.init(log);
|
||||||
|
});
|
||||||
|
}
|
||||||
for (const room of this._rooms.values()) {
|
for (const room of this._rooms.values()) {
|
||||||
if (room.isEncrypted) {
|
if (room.isEncrypted) {
|
||||||
room.enableKeyBackup(keyBackup);
|
room.enableKeyBackup(keyBackup);
|
||||||
@ -337,6 +354,8 @@ export class Session {
|
|||||||
}
|
}
|
||||||
this._keyBackup.set(keyBackup);
|
this._keyBackup.set(keyBackup);
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
log.set("no_backup", true);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.catch(err);
|
log.catch(err);
|
||||||
@ -354,6 +373,10 @@ export class Session {
|
|||||||
return this._keyBackup;
|
return this._keyBackup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get crossSigning() {
|
||||||
|
return this._crossSigning;
|
||||||
|
}
|
||||||
|
|
||||||
get hasIdentity() {
|
get hasIdentity() {
|
||||||
return !!this._e2eeAccount;
|
return !!this._e2eeAccount;
|
||||||
}
|
}
|
||||||
|
68
src/matrix/verification/CrossSigning.ts
Normal file
68
src/matrix/verification/CrossSigning.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 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 {SecretStorage} from "../ssss/SecretStorage";
|
||||||
|
import type {Storage} from "../storage/idb/Storage";
|
||||||
|
import type {Platform} from "../../platform/web/Platform";
|
||||||
|
import type {DeviceTracker} from "../e2ee/DeviceTracker";
|
||||||
|
import type * as OlmNamespace from "@matrix-org/olm";
|
||||||
|
import type {HomeServerApi} from "../net/HomeServerApi";
|
||||||
|
type Olm = typeof OlmNamespace;
|
||||||
|
|
||||||
|
export class CrossSigning {
|
||||||
|
private readonly storage: Storage;
|
||||||
|
private readonly secretStorage: SecretStorage;
|
||||||
|
private readonly platform: Platform;
|
||||||
|
private readonly deviceTracker: DeviceTracker;
|
||||||
|
private readonly olm: Olm;
|
||||||
|
private readonly hsApi: HomeServerApi;
|
||||||
|
private readonly ownUserId: string;
|
||||||
|
private _isMasterKeyTrusted: boolean = false;
|
||||||
|
|
||||||
|
constructor(options: {storage: Storage, secretStorage: SecretStorage, deviceTracker: DeviceTracker, platform: Platform, olm: Olm, ownUserId: string, hsApi: HomeServerApi}) {
|
||||||
|
this.storage = options.storage;
|
||||||
|
this.secretStorage = options.secretStorage;
|
||||||
|
this.platform = options.platform;
|
||||||
|
this.deviceTracker = options.deviceTracker;
|
||||||
|
this.olm = options.olm;
|
||||||
|
this.hsApi = options.hsApi;
|
||||||
|
this.ownUserId = options.ownUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(log) {
|
||||||
|
// use errorboundary here
|
||||||
|
const txn = await this.storage.readTxn([this.storage.storeNames.accountData]);
|
||||||
|
|
||||||
|
const mskSeed = await this.secretStorage.readSecret("m.cross_signing.master", txn);
|
||||||
|
const signing = new this.olm.PkSigning();
|
||||||
|
let derivedPublicKey;
|
||||||
|
try {
|
||||||
|
const seed = new Uint8Array(this.platform.encoding.base64.decode(mskSeed));
|
||||||
|
derivedPublicKey = signing.init_with_seed(seed);
|
||||||
|
} finally {
|
||||||
|
signing.free();
|
||||||
|
}
|
||||||
|
const publishedMasterKey = await this.deviceTracker.getMasterKeyForUser(this.ownUserId, this.hsApi, log);
|
||||||
|
log.set({publishedMasterKey, derivedPublicKey});
|
||||||
|
this._isMasterKeyTrusted = publishedMasterKey === derivedPublicKey;
|
||||||
|
log.set("isMasterKeyTrusted", this.isMasterKeyTrusted);
|
||||||
|
}
|
||||||
|
|
||||||
|
get isMasterKeyTrusted(): boolean {
|
||||||
|
return this._isMasterKeyTrusted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user