diff --git a/src/crypto/CrossSigning.js b/src/crypto/CrossSigning.js index 6d86d1bd9..ff5bc7080 100644 --- a/src/crypto/CrossSigning.js +++ b/src/crypto/CrossSigning.js @@ -24,6 +24,7 @@ import {decodeBase64, encodeBase64, pkSign, pkVerify} from './olmlib'; import {EventEmitter} from 'events'; import {logger} from '../logger'; import {IndexedDBCryptoStore} from '../crypto/store/indexeddb-crypto-store'; +import {decryptAES, encryptAES} from './aes'; function publicKeyFromKeyInfo(keyInfo) { // `keys` is an object with { [`ed25519:${pubKey}`]: pubKey } @@ -637,10 +638,10 @@ export class DeviceTrustLevel { } } -export function createCryptoStoreCacheCallbacks(store) { +export function createCryptoStoreCacheCallbacks(store, olmdevice) { return { - getCrossSigningKeyCache: function(type, _expectedPublicKey) { - return new Promise((resolve) => { + getCrossSigningKeyCache: async function(type, _expectedPublicKey) { + const key = await new Promise((resolve) => { return store.doTxn( 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], @@ -649,13 +650,23 @@ export function createCryptoStoreCacheCallbacks(store) { }, ); }); + + if (key && key.ciphertext) { + const pickleKey = Buffer.from(olmdevice._pickleKey); + const decrypted = await decryptAES(key, pickleKey, type); + return decodeBase64(decrypted); + } else { + return key; + } }, - storeCrossSigningKeyCache: function(type, key) { + storeCrossSigningKeyCache: async function(type, key) { if (!(key instanceof Uint8Array)) { throw new Error( `storeCrossSigningKeyCache expects Uint8Array, got ${key}`, ); } + const pickleKey = Buffer.from(olmdevice._pickleKey); + key = await encryptAES(encodeBase64(key), pickleKey, type); return store.doTxn( 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT], diff --git a/src/crypto/index.js b/src/crypto/index.js index aa74cae97..06cc2add2 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -56,6 +56,7 @@ import {ToDeviceChannel, ToDeviceRequests} from "./verification/request/ToDevice import * as httpApi from "../http-api"; import {IllegalMethod} from "./verification/IllegalMethod"; import {KeySignatureUploadError} from "../errors"; +import {decryptAES, encryptAES} from './aes'; const DeviceVerification = DeviceInfo.DeviceVerification; @@ -231,7 +232,7 @@ export function Crypto(baseApis, sessionStore, userId, deviceId, this._sendKeyRequestsImmediately = false; const cryptoCallbacks = this._baseApis._cryptoCallbacks || {}; - const cacheCallbacks = createCryptoStoreCacheCallbacks(cryptoStore); + const cacheCallbacks = createCryptoStoreCacheCallbacks(cryptoStore, this._olmDevice); this._crossSigningInfo = new CrossSigningInfo( userId, @@ -798,8 +799,8 @@ Crypto.prototype.checkSecretStoragePrivateKey = function(privateKey, expectedPub * Fetches the backup private key, if cached * @returns {Promise} the key, if any, or null */ -Crypto.prototype.getSessionBackupPrivateKey = function() { - return new Promise((resolve) => { +Crypto.prototype.getSessionBackupPrivateKey = async function() { + const key = await new Promise((resolve) => { this._cryptoStore.doTxn( 'readonly', [IndexedDBCryptoStore.STORE_ACCOUNT], @@ -812,6 +813,14 @@ Crypto.prototype.getSessionBackupPrivateKey = function() { }, ); }); + + if (key && key.ciphertext) { + const pickleKey = Buffer.from(this._olmDevice._pickleKey); + const decrypted = await decryptAES(key, pickleKey, "m.megolm_backup.v1"); + return olmlib.decodeBase64(decrypted); + } else { + return key; + } }; /** @@ -823,6 +832,8 @@ Crypto.prototype.storeSessionBackupPrivateKey = async function(key) { if (!(key instanceof Uint8Array)) { throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${key}`); } + const pickleKey = Buffer.from(this._olmDevice._pickleKey); + key = await encryptAES(olmlib.encodeBase64(key), pickleKey, "m.megolm_backup.v1"); return this._cryptoStore.doTxn( 'readwrite', [IndexedDBCryptoStore.STORE_ACCOUNT],