forked from mystiq/hydrogen-web
also write room key that we create ourselves with RoomKey infrastructure
so all keys are written in one place and the flags are always correct
This commit is contained in:
parent
c81dde53e7
commit
a499689bd8
3 changed files with 40 additions and 25 deletions
|
@ -15,12 +15,14 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {MEGOLM_ALGORITHM} from "../common.js";
|
||||
import {OutboundRoomKey} from "./decryption/RoomKey";
|
||||
|
||||
export class Encryption {
|
||||
constructor({pickleKey, olm, account, storage, now, ownDeviceId}) {
|
||||
constructor({pickleKey, olm, account, keyLoader, storage, now, ownDeviceId}) {
|
||||
this._pickleKey = pickleKey;
|
||||
this._olm = olm;
|
||||
this._account = account;
|
||||
this._keyLoader = keyLoader;
|
||||
this._storage = storage;
|
||||
this._now = now;
|
||||
this._ownDeviceId = ownDeviceId;
|
||||
|
@ -64,7 +66,7 @@ export class Encryption {
|
|||
let roomKeyMessage;
|
||||
try {
|
||||
let sessionEntry = await txn.outboundGroupSessions.get(roomId);
|
||||
roomKeyMessage = this._readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn);
|
||||
roomKeyMessage = await this._readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn);
|
||||
if (roomKeyMessage) {
|
||||
this._writeSession(this._now(), session, roomId, txn);
|
||||
}
|
||||
|
@ -79,7 +81,7 @@ export class Encryption {
|
|||
}
|
||||
}
|
||||
|
||||
_readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn) {
|
||||
async _readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn) {
|
||||
if (sessionEntry) {
|
||||
session.unpickle(this._pickleKey, sessionEntry.session);
|
||||
}
|
||||
|
@ -91,7 +93,8 @@ export class Encryption {
|
|||
}
|
||||
session.create();
|
||||
const roomKeyMessage = this._createRoomKeyMessage(session, roomId);
|
||||
this._storeAsInboundSession(session, roomId, txn);
|
||||
const roomKey = new OutboundRoomKey(roomId, session, this._account.identityKeys);
|
||||
await roomKey.write(this._keyLoader, txn);
|
||||
return roomKeyMessage;
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +126,7 @@ export class Encryption {
|
|||
let encryptedContent;
|
||||
try {
|
||||
let sessionEntry = await txn.outboundGroupSessions.get(roomId);
|
||||
roomKeyMessage = this._readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn);
|
||||
roomKeyMessage = await this._readOrCreateSession(session, sessionEntry, roomId, encryptionParams, txn);
|
||||
encryptedContent = this._encryptContent(roomId, session, type, content);
|
||||
// update timestamp when a new session is created
|
||||
const createdAt = roomKeyMessage ? this._now() : sessionEntry.createdAt;
|
||||
|
@ -190,26 +193,6 @@ export class Encryption {
|
|||
chain_index: session.message_index()
|
||||
}
|
||||
}
|
||||
|
||||
_storeAsInboundSession(outboundSession, roomId, txn) {
|
||||
const {identityKeys} = this._account;
|
||||
const claimedKeys = {ed25519: identityKeys.ed25519};
|
||||
const session = new this._olm.InboundGroupSession();
|
||||
try {
|
||||
session.create(outboundSession.session_key());
|
||||
const sessionEntry = {
|
||||
roomId,
|
||||
senderKey: identityKeys.curve25519,
|
||||
sessionId: session.session_id(),
|
||||
session: session.pickle(this._pickleKey),
|
||||
claimedKeys,
|
||||
};
|
||||
txn.inboundGroupSessions.set(sessionEntry);
|
||||
return sessionEntry;
|
||||
} finally {
|
||||
session.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -155,7 +155,38 @@ class DeviceMessageRoomKey extends IncomingRoomKey {
|
|||
loadInto(session) {
|
||||
session.create(this.serializationKey);
|
||||
}
|
||||
}
|
||||
|
||||
// a room key we send out ourselves,
|
||||
// here adapted to write it as an incoming key
|
||||
// as we don't send it to ourself with a to_device msg
|
||||
export class OutboundRoomKey extends IncomingRoomKey {
|
||||
private _sessionKey: string;
|
||||
|
||||
constructor(
|
||||
private readonly _roomId: string,
|
||||
private readonly outboundSession: Olm.OutboundGroupSession,
|
||||
private readonly identityKeys: {[algo: string]: string}
|
||||
) {
|
||||
super();
|
||||
// this is a new key, so always better than what might be in storage, no need to check
|
||||
this.isBetter = true;
|
||||
// cache this, as it is used by key loader to find a matching key and
|
||||
// this calls into WASM so is not just reading a prop
|
||||
this._sessionKey = this.outboundSession.session_key();
|
||||
}
|
||||
|
||||
get roomId(): string { return this._roomId; }
|
||||
get senderKey(): string { return this.identityKeys.curve25519; }
|
||||
get sessionId(): string { return this.outboundSession.session_id(); }
|
||||
get claimedEd25519Key(): string { return this.identityKeys.ed25519; }
|
||||
get serializationKey(): string { return this._sessionKey; }
|
||||
get serializationType(): string { return "create"; }
|
||||
protected get keySource(): KeySource { return KeySource.Outbound; }
|
||||
|
||||
loadInto(session: Olm.InboundGroupSession) {
|
||||
session.create(this.serializationKey);
|
||||
}
|
||||
}
|
||||
|
||||
class BackupRoomKey extends IncomingRoomKey {
|
||||
|
|
|
@ -25,6 +25,7 @@ export enum BackupStatus {
|
|||
export enum KeySource {
|
||||
DeviceMessage = 1,
|
||||
Backup,
|
||||
Outbound
|
||||
}
|
||||
|
||||
export interface InboundGroupSessionEntry {
|
||||
|
|
Loading…
Reference in a new issue