1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 10:13:31 +00:00

separate the user key in memory from user keys in storage

This commit is contained in:
Jacob Fink
2023-05-30 11:11:26 -04:00
parent f2e7a8ad11
commit 4772166e83
2 changed files with 9 additions and 15 deletions

View File

@@ -17,7 +17,7 @@ export abstract class CryptoService {
getKeyForUserEncryption: (key?: SymmetricCryptoKey) => Promise<SymmetricCryptoKey>; getKeyForUserEncryption: (key?: SymmetricCryptoKey) => Promise<SymmetricCryptoKey>;
setUserKey: (key: UserSymKey) => Promise<void>; setUserKey: (key: UserSymKey) => Promise<void>;
getUserKey: (keySuffix?: KeySuffixOptions, userId?: string) => Promise<UserSymKey>; getUserKeyFromMemory: (userId?: string) => Promise<UserSymKey>;
getUserKeyFromStorage: (keySuffix: KeySuffixOptions, userId?: string) => Promise<UserSymKey>; getUserKeyFromStorage: (keySuffix: KeySuffixOptions, userId?: string) => Promise<UserSymKey>;
hasUserKey: () => Promise<boolean>; hasUserKey: () => Promise<boolean>;
hasUserKeyInMemory: (userId?: string) => Promise<boolean>; hasUserKeyInMemory: (userId?: string) => Promise<boolean>;
@@ -84,7 +84,6 @@ export abstract class CryptoService {
decryptToUtf8: (encString: EncString, key?: SymmetricCryptoKey) => Promise<string>; decryptToUtf8: (encString: EncString, key?: SymmetricCryptoKey) => Promise<string>;
decryptFromBytes: (encBuffer: EncArrayBuffer, key: SymmetricCryptoKey) => Promise<ArrayBuffer>; decryptFromBytes: (encBuffer: EncArrayBuffer, key: SymmetricCryptoKey) => Promise<ArrayBuffer>;
setEncKey: (encKey: string) => Promise<void>; setEncKey: (encKey: string) => Promise<void>;
getEncKey: (key?: SymmetricCryptoKey) => Promise<SymmetricCryptoKey>;
hasEncKey: () => Promise<boolean>; hasEncKey: () => Promise<boolean>;
clearEncKey: (memoryOnly?: boolean, userId?: string) => Promise<any>; clearEncKey: (memoryOnly?: boolean, userId?: string) => Promise<any>;
toggleKey: () => Promise<any>; toggleKey: () => Promise<any>;

View File

@@ -48,7 +48,7 @@ export class CryptoService implements CryptoServiceAbstraction {
* if not it will return the master key. * if not it will return the master key.
*/ */
async getKeyForUserEncryption(): Promise<SymmetricCryptoKey> { async getKeyForUserEncryption(): Promise<SymmetricCryptoKey> {
const userKey = await this.getUserKey(); const userKey = await this.getUserKeyFromMemory();
if (userKey != null) { if (userKey != null) {
return userKey; return userKey;
} }
@@ -66,6 +66,8 @@ export class CryptoService implements CryptoServiceAbstraction {
*/ */
async setUserKey(key: UserSymKey, userId?: string): Promise<void> { async setUserKey(key: UserSymKey, userId?: string): Promise<void> {
await this.stateService.setUserSymKey(key, { userId: userId }); await this.stateService.setUserSymKey(key, { userId: userId });
// TODO: Should we include additional keys here? When we set the memory key from storage,
// it will reset the keys in storage as well
await this.storeAdditionalKeys(key, userId); await this.storeAdditionalKeys(key, userId);
} }
@@ -76,15 +78,8 @@ export class CryptoService implements CryptoServiceAbstraction {
* @param userId The desired user * @param userId The desired user
* @returns The user's symmetric key * @returns The user's symmetric key
*/ */
async getUserKey(keySuffix?: KeySuffixOptions, userId?: string): Promise<UserSymKey> { async getUserKeyFromMemory(userId?: string): Promise<UserSymKey> {
const userKey = await this.stateService.getUserSymKey({ userId: userId }); return await this.stateService.getUserSymKey({ userId: userId });
if (userKey != null) {
return userKey;
}
keySuffix ||= KeySuffixOptions.Auto;
return (await this.getUserKeyFromStorage(keySuffix, userId)) as UserSymKey;
} }
/** /**
@@ -235,7 +230,7 @@ export class CryptoService implements CryptoServiceAbstraction {
masterKey: MasterKey, masterKey: MasterKey,
userSymKey?: UserSymKey userSymKey?: UserSymKey
): Promise<[UserSymKey, EncString]> { ): Promise<[UserSymKey, EncString]> {
userSymKey ||= await this.getUserKey(); userSymKey ||= await this.getUserKeyFromMemory();
return this.buildProtectedUserSymKey(masterKey, userSymKey.key); return this.buildProtectedUserSymKey(masterKey, userSymKey.key);
} }
@@ -629,7 +624,7 @@ export class CryptoService implements CryptoServiceAbstraction {
* @returns A new keypair: [publicKey in Base64, encrypted privateKey] * @returns A new keypair: [publicKey in Base64, encrypted privateKey]
*/ */
async makeKeyPair(key?: SymmetricCryptoKey): Promise<[string, EncString]> { async makeKeyPair(key?: SymmetricCryptoKey): Promise<[string, EncString]> {
key ||= await this.getUserKey(); key ||= await this.getUserKeyFromMemory();
const keyPair = await this.cryptoFunctionService.rsaGenerateKeyPair(2048); const keyPair = await this.cryptoFunctionService.rsaGenerateKeyPair(2048);
const publicB64 = Utils.fromBufferToB64(keyPair[0]); const publicB64 = Utils.fromBufferToB64(keyPair[0]);
@@ -845,7 +840,7 @@ export class CryptoService implements CryptoServiceAbstraction {
// ---HELPERS--- // ---HELPERS---
protected async validateUserKey(key?: UserSymKey): Promise<boolean> { protected async validateUserKey(key?: UserSymKey): Promise<boolean> {
key ||= await this.getUserKey(); key ||= await this.getUserKeyFromMemory();
if (key == null) { if (key == null) {
return false; return false;
} }