mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +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 {KeyLoader as MegOlmKeyLoader} from "./e2ee/megolm/decryption/KeyLoader";
|
||||
import {KeyBackup} from "./e2ee/megolm/keybackup/KeyBackup";
|
||||
import {CrossSigning} from "./verification/CrossSigning";
|
||||
import {Encryption as MegOlmEncryption} from "./e2ee/megolm/Encryption.js";
|
||||
import {MEGOLM_ALGORITHM} from "./e2ee/common.js";
|
||||
import {RoomEncryption} from "./e2ee/RoomEncryption.js";
|
||||
@ -59,6 +60,7 @@ export class Session {
|
||||
this._storage = storage;
|
||||
this._hsApi = hsApi;
|
||||
this._mediaRepository = mediaRepository;
|
||||
this._features = features;
|
||||
this._syncInfo = null;
|
||||
this._sessionInfo = sessionInfo;
|
||||
this._rooms = new ObservableMap();
|
||||
@ -88,6 +90,7 @@ export class Session {
|
||||
this._getSyncToken = () => this.syncToken;
|
||||
this._olmWorker = olmWorker;
|
||||
this._keyBackup = new ObservableValue(undefined);
|
||||
this._crossSigning = undefined;
|
||||
this._observedRoomStatus = new Map();
|
||||
|
||||
if (olm) {
|
||||
@ -330,6 +333,20 @@ export class Session {
|
||||
txn
|
||||
);
|
||||
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()) {
|
||||
if (room.isEncrypted) {
|
||||
room.enableKeyBackup(keyBackup);
|
||||
@ -337,6 +354,8 @@ export class Session {
|
||||
}
|
||||
this._keyBackup.set(keyBackup);
|
||||
return true;
|
||||
} else {
|
||||
log.set("no_backup", true);
|
||||
}
|
||||
} catch (err) {
|
||||
log.catch(err);
|
||||
@ -354,6 +373,10 @@ export class Session {
|
||||
return this._keyBackup;
|
||||
}
|
||||
|
||||
get crossSigning() {
|
||||
return this._crossSigning;
|
||||
}
|
||||
|
||||
get hasIdentity() {
|
||||
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