mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[PM-21586] Return null in decryptUserKeyWithMasterKey if decrypt fails (#14756)
* Return null in decryptUserKeyWithMasterKey if decrypt fails * Show error on invalid master password * Add logs
This commit is contained in:
@@ -37,13 +37,13 @@ export abstract class MasterPasswordServiceAbstraction {
|
|||||||
* @param userKey The user's encrypted symmetric key
|
* @param userKey The user's encrypted symmetric key
|
||||||
* @throws If either the MasterKey or UserKey are not resolved, or if the UserKey encryption type
|
* @throws If either the MasterKey or UserKey are not resolved, or if the UserKey encryption type
|
||||||
* is neither AesCbc256_B64 nor AesCbc256_HmacSha256_B64
|
* is neither AesCbc256_B64 nor AesCbc256_HmacSha256_B64
|
||||||
* @returns The user key
|
* @returns The user key or null if the masterkey is wrong
|
||||||
*/
|
*/
|
||||||
abstract decryptUserKeyWithMasterKey: (
|
abstract decryptUserKeyWithMasterKey: (
|
||||||
masterKey: MasterKey,
|
masterKey: MasterKey,
|
||||||
userId: string,
|
userId: string,
|
||||||
userKey?: EncString,
|
userKey?: EncString,
|
||||||
) => Promise<UserKey>;
|
) => Promise<UserKey | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class InternalMasterPasswordServiceAbstraction extends MasterPasswordServiceAbstraction {
|
export abstract class InternalMasterPasswordServiceAbstraction extends MasterPasswordServiceAbstraction {
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
|
|||||||
masterKey: MasterKey,
|
masterKey: MasterKey,
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
userKey?: EncString,
|
userKey?: EncString,
|
||||||
): Promise<UserKey> {
|
): Promise<UserKey | null> {
|
||||||
userKey ??= await this.getMasterKeyEncryptedUserKey(userId);
|
userKey ??= await this.getMasterKeyEncryptedUserKey(userId);
|
||||||
masterKey ??= await firstValueFrom(this.masterKey$(userId));
|
masterKey ??= await firstValueFrom(this.masterKey$(userId));
|
||||||
|
|
||||||
@@ -177,16 +177,26 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
|
|||||||
let decUserKey: SymmetricCryptoKey;
|
let decUserKey: SymmetricCryptoKey;
|
||||||
|
|
||||||
if (userKey.encryptionType === EncryptionType.AesCbc256_B64) {
|
if (userKey.encryptionType === EncryptionType.AesCbc256_B64) {
|
||||||
decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, masterKey);
|
try {
|
||||||
|
decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, masterKey);
|
||||||
|
} catch {
|
||||||
|
this.logService.warning("Failed to decrypt user key with master key.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else if (userKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) {
|
} else if (userKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) {
|
||||||
const newKey = await this.keyGenerationService.stretchKey(masterKey);
|
try {
|
||||||
decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, newKey);
|
const newKey = await this.keyGenerationService.stretchKey(masterKey);
|
||||||
|
decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, newKey);
|
||||||
|
} catch {
|
||||||
|
this.logService.warning("Failed to decrypt user key with stretched master key.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unsupported encryption type.");
|
throw new Error("Unsupported encryption type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decUserKey == null) {
|
if (decUserKey == null) {
|
||||||
this.logService.warning("Failed to decrypt user key with master key.");
|
this.logService.warning("Failed to decrypt user key with master key, user key is null.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -556,6 +556,15 @@ export class LockComponent implements OnInit, OnDestroy {
|
|||||||
masterPasswordVerificationResponse!.masterKey,
|
masterPasswordVerificationResponse!.masterKey,
|
||||||
this.activeAccount.id,
|
this.activeAccount.id,
|
||||||
);
|
);
|
||||||
|
if (userKey == null) {
|
||||||
|
this.toastService.showToast({
|
||||||
|
variant: "error",
|
||||||
|
title: this.i18nService.t("errorOccurred"),
|
||||||
|
message: this.i18nService.t("invalidMasterPassword"),
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.setUserKeyAndContinue(userKey, true);
|
await this.setUserKeyAndContinue(userKey, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user