update to systemService and decryptAndMigrate... method

This commit is contained in:
rr-bw 2024-04-23 14:59:49 -07:00
parent b214061159
commit 1b9714bc1c
No known key found for this signature in database
GPG Key ID: 3FA13C3ADEE51D5D
4 changed files with 22 additions and 19 deletions

View File

@ -38,7 +38,7 @@ const PIN_KEY_ENCRYPTED_USER_KEY = new UserKeyDefinition<EncryptedString>(
"pinKeyEncryptedUserKey", "pinKeyEncryptedUserKey",
{ {
deserializer: (jsonValue) => jsonValue, deserializer: (jsonValue) => jsonValue,
clearOn: [], // TODO-rr-bw: verify clearOn: ["logout"], // TODO-rr-bw: verify
}, },
); );
@ -198,7 +198,7 @@ export class PinService implements PinServiceAbstraction {
const pinKey = await this.makePinKey( const pinKey = await this.makePinKey(
pin, pin,
(await firstValueFrom(this.accountService.activeAccount$))?.email, // TODO-rr-bw: verify (could this possibly be different from the UserId passed in?) (await firstValueFrom(this.accountService.activeAccount$))?.email, // TODO-rr-bw: verify (could this user possibly be different from the UserId passed in?)
await this.stateService.getKdfType({ userId }), await this.stateService.getKdfType({ userId }),
await this.stateService.getKdfConfig({ userId }), await this.stateService.getKdfConfig({ userId }),
); );
@ -351,7 +351,6 @@ export class PinService implements PinServiceAbstraction {
): Promise<UserKey> { ): Promise<UserKey> {
this.validateUserId(userId, "Cannot decrypt and migrate oldPinKeyEncryptedMasterKey."); this.validateUserId(userId, "Cannot decrypt and migrate oldPinKeyEncryptedMasterKey.");
// Decrypt
const masterKey = await this.decryptMasterKeyWithPin( const masterKey = await this.decryptMasterKeyWithPin(
userId, userId,
pin, pin,
@ -368,21 +367,17 @@ export class PinService implements PinServiceAbstraction {
); );
const pinKeyEncryptedUserKey = await this.createPinKeyEncryptedUserKey(pin, userKey, userId); const pinKeyEncryptedUserKey = await this.createPinKeyEncryptedUserKey(pin, userKey, userId);
await this.storePinKeyEncryptedUserKey(
pinKeyEncryptedUserKey,
requireMasterPasswordOnClientRestart,
userId,
);
const protectedPin = await this.createProtectedPin(pin, userKey);
await this.setProtectedPin(protectedPin.encryptedString, userId);
await this.clearOldPinKeyEncryptedMasterKey(userId); await this.clearOldPinKeyEncryptedMasterKey(userId);
if (requireMasterPasswordOnClientRestart) {
await this.setPinKeyEncryptedUserKeyEphemeral(pinKeyEncryptedUserKey, userId);
} else {
await this.setPinKeyEncryptedUserKey(pinKeyEncryptedUserKey, userId);
// We previously only set the protected pin if MP on Restart was enabled
// now we set it regardless
// TODO-rr-bw: based on this comment, shouldn't this code be placed outside the if/else block?
const protectedPin = await this.encryptService.encrypt(pin, userKey);
await this.setProtectedPin(protectedPin.encryptedString, userId);
}
// This also clears the old Biometrics key since the new Biometrics key will // This also clears the old Biometrics key since the new Biometrics key will
// be created when the user key is set. // be created when the user key is set.
await this.stateService.setCryptoMasterKeyBiometric(null); await this.stateService.setCryptoMasterKeyBiometric(null);

View File

@ -16,6 +16,7 @@ export class WebAuthnLoginPrfCryptoService implements WebAuthnLoginPrfCryptoServ
return (await this.stretchKey(new Uint8Array(prf))) as PrfKey; return (await this.stretchKey(new Uint8Array(prf))) as PrfKey;
} }
// TODO: use keyGenerationService.stretchKey
private async stretchKey(key: Uint8Array): Promise<SymmetricCryptoKey> { private async stretchKey(key: Uint8Array): Promise<SymmetricCryptoKey> {
const newKey = new Uint8Array(64); const newKey = new Uint8Array(64);
const encKey = await this.cryptoFunctionService.hkdfExpand(key, "enc", 32, "sha256"); const encKey = await this.cryptoFunctionService.hkdfExpand(key, "enc", 32, "sha256");

View File

@ -57,5 +57,10 @@ export abstract class KeyGenerationService {
kdfConfig: KdfConfig, kdfConfig: KdfConfig,
): Promise<SymmetricCryptoKey>; ): Promise<SymmetricCryptoKey>;
/**
* Derives a 64 byte key from a 32 byte key using a key derivation function.
* @param key 32 byte key.
* @returns 64 byte derived key.
*/
abstract stretchKey(key: SymmetricCryptoKey): Promise<SymmetricCryptoKey>; abstract stretchKey(key: SymmetricCryptoKey): Promise<SymmetricCryptoKey>;
} }

View File

@ -49,11 +49,13 @@ export class SystemService implements SystemServiceAbstraction {
return; return;
} }
// If there is an active user, check if they have a pinKeyEncryptedUserKeyEphemeral. If so, prevent process reload upon lock.
const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id;
// User has set a PIN, with ask for master password on restart, to protect their vault if (userId != null) {
const ephemeralPin = await this.pinService.getPinKeyEncryptedUserKeyEphemeral(userId); const ephemeralPin = await this.pinService.getPinKeyEncryptedUserKeyEphemeral(userId);
if (ephemeralPin != null) { if (ephemeralPin != null) {
return; return;
}
} }
this.cancelProcessReload(); this.cancelProcessReload();