diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index a4bf6b0c0b..684c6c1ff8 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -222,18 +222,28 @@ export class LockComponent implements OnInit, OnDestroy { const kdf = await this.stateService.getKdfType(); const kdfConfig = await this.stateService.getKdfConfig(); - const key = await this.cryptoService.makeKey(this.masterPassword, this.email, kdf, kdfConfig); + const masterKey = await this.cryptoService.makeMasterKey( + this.masterPassword, + this.email, + kdf, + kdfConfig + ); const storedKeyHash = await this.cryptoService.getKeyHash(); let passwordValid = false; if (storedKeyHash != null) { - passwordValid = await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, key); + // Offline unlock possible + passwordValid = await this.cryptoService.compareAndUpdateKeyHash( + this.masterPassword, + masterKey + ); } else { + // Online only const request = new SecretVerificationRequest(); const serverKeyHash = await this.cryptoService.hashPassword( this.masterPassword, - key, + masterKey, HashPurpose.ServerAuthorization ); request.masterPasswordHash = serverKeyHash; @@ -244,12 +254,14 @@ export class LockComponent implements OnInit, OnDestroy { passwordValid = true; const localKeyHash = await this.cryptoService.hashPassword( this.masterPassword, - key, + masterKey, HashPurpose.LocalAuthorization ); await this.cryptoService.setKeyHash(localKeyHash); } catch (e) { this.logService.error(e); + } finally { + this.formPromise = null; } } @@ -262,16 +274,19 @@ export class LockComponent implements OnInit, OnDestroy { return; } + const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); + + // if MP on restart is enabled, use it to get the PIN and store the ephemeral + // pin protected user symmetric key if (this.pinSet[0]) { const protectedPin = await this.stateService.getProtectedPin(); - const encKey = await this.cryptoService.getEncKey(key); - const decPin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), encKey); - const pinKey = await this.cryptoService.makePinKey(decPin, this.email, kdf, kdfConfig); - await this.stateService.setDecryptedPinProtected( - await this.cryptoService.encrypt(key.key, pinKey) + const pin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), userKey); + const pinKey = await this.cryptoService.makePinKey(pin, this.email, kdf, kdfConfig); + await this.stateService.setUserSymKeyPinEphemeral( + await this.cryptoService.encrypt(userKey.key, pinKey) ); } - await this.setKeyAndContinue(key, true); + await this.setKeyAndContinue(userKey, true); } private async setKeyAndContinue(key: UserSymKey, evaluatePasswordAfterUnlock = false) { diff --git a/libs/common/src/platform/abstractions/crypto.service.ts b/libs/common/src/platform/abstractions/crypto.service.ts index 93a204d170..9798defb0a 100644 --- a/libs/common/src/platform/abstractions/crypto.service.ts +++ b/libs/common/src/platform/abstractions/crypto.service.ts @@ -18,10 +18,16 @@ export abstract class CryptoService { setUserKey: (key: UserSymKey) => Promise; getUserKeyFromMemory: (userId?: string) => Promise; - getUserKeyFromStorage: (keySuffix: KeySuffixOptions, userId?: string) => Promise; + getUserKeyFromStorage: ( + keySuffix: KeySuffixOptions.Auto | KeySuffixOptions.Biometric, + userId?: string + ) => Promise; hasUserKey: () => Promise; hasUserKeyInMemory: (userId?: string) => Promise; - hasUserKeyStored: (keySuffix?: KeySuffixOptions, userId?: string) => Promise; + hasUserKeyStored: ( + keySuffix?: KeySuffixOptions.Auto | KeySuffixOptions.Biometric, + userId?: string + ) => Promise; makeUserSymKey: (key: SymmetricCryptoKey) => Promise<[UserSymKey, EncString]>; clearUserKey: (clearSecretStorage?: boolean, userId?: string) => Promise; setUserSymKeyMasterKey: (UserSymKeyMasterKey: string, userId?: string) => Promise; diff --git a/libs/common/src/platform/services/crypto.service.ts b/libs/common/src/platform/services/crypto.service.ts index 0e2b7b011e..f61aee305a 100644 --- a/libs/common/src/platform/services/crypto.service.ts +++ b/libs/common/src/platform/services/crypto.service.ts @@ -127,7 +127,10 @@ export class CryptoService implements CryptoServiceAbstraction { * @param userId The desired user * @returns True if the provided version of the user symmetric key is stored */ - async hasUserKeyStored(keySuffix: KeySuffixOptions, userId?: string): Promise { + async hasUserKeyStored( + keySuffix: KeySuffixOptions.Auto | KeySuffixOptions.Biometric, + userId?: string + ): Promise { switch (keySuffix) { case KeySuffixOptions.Auto: return (await this.stateService.getUserSymKeyAuto({ userId: userId })) != null;