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:
Bruno Windels 2022-01-28 13:07:49 +01:00
parent c81dde53e7
commit a499689bd8
3 changed files with 40 additions and 25 deletions

View file

@ -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();
}
}
}
/**

View file

@ -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 {

View file

@ -25,6 +25,7 @@ export enum BackupStatus {
export enum KeySource {
DeviceMessage = 1,
Backup,
Outbound
}
export interface InboundGroupSessionEntry {