mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 03:25:12 +01:00
implementent SecretStorage.load
This commit is contained in:
parent
67ad975377
commit
caa65870f3
@ -536,12 +536,12 @@ export class Session {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this._olm && this._e2eeAccount) {
|
if (this._olm && this._e2eeAccount) {
|
||||||
// try set up session backup and cross-signing if we stored the ssss key
|
this._secretStorage = new SecretStorage({
|
||||||
const ssssKey = await ssssReadKey(txn);
|
platform: this._platform,
|
||||||
if (ssssKey) {
|
storage: this._storage,
|
||||||
// this will close the txn above, so we do it last
|
olm: this._olm
|
||||||
await this._tryLoadSecretStorage(ssssKey, log);
|
});
|
||||||
}
|
await this._secretStorage.load(txn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
import {BaseObservableValue, RetainedObservableValue} from "../../observable/value";
|
import {BaseObservableValue, RetainedObservableValue} from "../../observable/value";
|
||||||
import {KeyType} from "./index";
|
import {KeyType, SSSS_KEY} from "./index";
|
||||||
import {keyFromPassphrase} from "./passphrase";
|
import {keyFromPassphrase} from "./passphrase";
|
||||||
import {keyFromRecoveryKey} from "./recoveryKey";
|
import {keyFromRecoveryKey} from "./recoveryKey";
|
||||||
import {Key, KeyDescription, KeyDescriptionData} from "./common";
|
import {Key, KeyDescription, KeyDescriptionData} from "./common";
|
||||||
@ -48,11 +48,17 @@ class DecryptionError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyCredentials = {
|
type StringKeyCredential = {
|
||||||
type: KeyType,
|
type: KeyType.Passphrase | KeyType.RecoveryKey,
|
||||||
credential: string
|
credential: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BitsKeyCredential = {
|
||||||
|
type: KeyType.KeyBits,
|
||||||
|
credential: Uint8Array
|
||||||
|
}
|
||||||
|
type KeyCredentials = StringKeyCredential | BitsKeyCredential;
|
||||||
|
|
||||||
export class SecretStorage {
|
export class SecretStorage {
|
||||||
// we know the id but don't have the description yet
|
// we know the id but don't have the description yet
|
||||||
private keyId?: string;
|
private keyId?: string;
|
||||||
@ -73,11 +79,32 @@ export class SecretStorage {
|
|||||||
this.observedSecrets = new Map();
|
this.observedSecrets = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
async load(txn: Transaction) {
|
||||||
// read key
|
// first try to read the key bits from previously enabling 4S
|
||||||
|
const keyData = await txn.session.get(SSSS_KEY);
|
||||||
|
if (keyData) {
|
||||||
|
const keyAccountData = await txn.accountData.get(`m.secret_storage.key.${keyData.id}`);
|
||||||
|
if (keyAccountData) {
|
||||||
|
this.keyId = keyData.id;
|
||||||
|
this.keyDescription = new KeyDescription(keyData.id, keyAccountData.content as KeyDescriptionData);
|
||||||
|
this.keyCredentials = {type: KeyType.KeyBits, credential: keyData.binaryKey};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// then prepare to track the default key
|
||||||
|
const defaultKey = await txn.accountData.get("m.secret_storage.default_key");
|
||||||
|
const keyId = defaultKey?.content?.key;
|
||||||
|
if (keyId) {
|
||||||
|
this.keyId = keyId;
|
||||||
|
const keyData = await txn.accountData.get(`m.secret_storage.key.${keyId}`);
|
||||||
|
if (keyData) {
|
||||||
|
this.keyDescription = new KeyDescription(keyId, keyData.content as KeyDescriptionData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateKey(this.keyDescription, this.keyCredentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setKey(type: KeyType, credential: string) {
|
async setKey(type: KeyType.Passphrase | KeyType.RecoveryKey, credential: string) {
|
||||||
const credentials: KeyCredentials = {type, credential};
|
const credentials: KeyCredentials = {type, credential};
|
||||||
this.keyCredentials = credentials;
|
this.keyCredentials = credentials;
|
||||||
this.updateKey(this.keyDescription, this.keyCredentials);
|
this.updateKey(this.keyDescription, this.keyCredentials);
|
||||||
@ -104,6 +131,8 @@ export class SecretStorage {
|
|||||||
} else if (credentials.type === KeyType.RecoveryKey) {
|
} else if (credentials.type === KeyType.RecoveryKey) {
|
||||||
this.key = await keyFromRecoveryKey(keyDescription, credentials.credential, this.olm, this.platform);
|
this.key = await keyFromRecoveryKey(keyDescription, credentials.credential, this.olm, this.platform);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (credentials.type === KeyType.KeyBits) {
|
||||||
|
this.key = new Key(keyDescription, credentials.credential);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -26,12 +26,13 @@ import type * as OlmNamespace from "@matrix-org/olm"
|
|||||||
|
|
||||||
type Olm = typeof OlmNamespace;
|
type Olm = typeof OlmNamespace;
|
||||||
|
|
||||||
const SSSS_KEY = `${SESSION_E2EE_KEY_PREFIX}ssssKey`;
|
export const SSSS_KEY = `${SESSION_E2EE_KEY_PREFIX}ssssKey`;
|
||||||
const BACKUPVERSION_KEY = `${SESSION_E2EE_KEY_PREFIX}keyBackupVersion`;
|
const BACKUPVERSION_KEY = `${SESSION_E2EE_KEY_PREFIX}keyBackupVersion`;
|
||||||
|
|
||||||
export enum KeyType {
|
export enum KeyType {
|
||||||
RecoveryKey,
|
RecoveryKey,
|
||||||
Passphrase
|
Passphrase,
|
||||||
|
KeyBits // decoded bits from either recovery key or passphrase, as stored on disk
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readDefaultKeyDescription(storage: Storage): Promise<KeyDescription | undefined> {
|
async function readDefaultKeyDescription(storage: Storage): Promise<KeyDescription | undefined> {
|
||||||
|
@ -27,7 +27,7 @@ const DEFAULT_BITSIZE = 256;
|
|||||||
* @param {Platform} platform
|
* @param {Platform} platform
|
||||||
* @return {Key}
|
* @return {Key}
|
||||||
*/
|
*/
|
||||||
export async function keyFromPassphrase(passphrase: string, platform: Platform): Promise<Key> {
|
export async function keyFromPassphrase(keyDescription: KeyDescription, passphrase: string, platform: Platform): Promise<Key> {
|
||||||
const {passphraseParams} = keyDescription;
|
const {passphraseParams} = keyDescription;
|
||||||
if (!passphraseParams) {
|
if (!passphraseParams) {
|
||||||
throw new Error("not a passphrase key");
|
throw new Error("not a passphrase key");
|
||||||
|
Loading…
Reference in New Issue
Block a user