mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-23230] Implement KDF Change Service (#15748)
* Add new mp service api * Fix tests * Add test coverage * Add newline * Fix type * Rename to "unwrapUserKeyFromMasterPasswordUnlockData" * Fix build * Fix build on cli * Fix linting * Re-sort spec * Add tests * Fix test and build issues * Fix build * Clean up * Remove introduced function * Clean up comments * Fix abstract class types * Fix comments * Cleanup * Cleanup * Update libs/common/src/key-management/master-password/types/master-password.types.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/master-password/services/master-password.service.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/master-password/types/master-password.types.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Add comments * Fix build * Add arg null check * Cleanup * Fix build * Fix build on browser * Implement KDF change service * Deprecate encryptUserKeyWithMasterKey * Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Add tests for null params * Fix builds * Cleanup and deprecate more functions * Fix formatting * Prettier * Clean up * Update libs/key-management/src/abstractions/key.service.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Make emailToSalt private and expose abstract saltForUser * Add tests * Add docs * Fix build * Fix tests * Fix tests * Address feedback and fix primitive obsession * Consolidate active account checks in change kdf confirmation component * Update libs/common/src/key-management/kdf/services/change-kdf-service.spec.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Add defensive parameter checks * Add tests * Add comment for follow-up epic * Move change kdf service, remove abstraction and add api service * Fix test * Drop redundant null check * Address feedback * Add throw on empty password * Fix tests * Mark change kdf service as internal * Add abstract classes * Switch to abstraction * use sdk EncString in MasterPasswordUnlockData * fix remaining tests --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Jake Fink <jfink@bitwarden.com>
This commit is contained in:
@@ -303,6 +303,14 @@ export class InputPasswordComponent implements OnInit {
|
||||
throw new Error("KdfConfig is required to create master key.");
|
||||
}
|
||||
|
||||
const salt =
|
||||
this.userId != null
|
||||
? await firstValueFrom(this.masterPasswordService.saltForUser$(this.userId))
|
||||
: this.masterPasswordService.emailToSalt(this.email);
|
||||
if (salt == null) {
|
||||
throw new Error("Salt is required to create master key.");
|
||||
}
|
||||
|
||||
// 2. Verify current password is correct (if necessary)
|
||||
if (
|
||||
this.flow === InputPasswordFlow.ChangePassword ||
|
||||
@@ -348,6 +356,7 @@ export class InputPasswordComponent implements OnInit {
|
||||
|
||||
const passwordInputResult: PasswordInputResult = {
|
||||
newPassword,
|
||||
salt,
|
||||
newMasterKey,
|
||||
newServerMasterKeyHash,
|
||||
newLocalMasterKeyHash,
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
import { MasterPasswordSalt } from "@bitwarden/common/key-management/master-password/types/master-password.types";
|
||||
import { MasterKey } from "@bitwarden/common/types/key";
|
||||
import { KdfConfig } from "@bitwarden/key-management";
|
||||
|
||||
export interface PasswordInputResult {
|
||||
currentPassword?: string;
|
||||
newPassword: string;
|
||||
kdfConfig?: KdfConfig;
|
||||
salt?: MasterPasswordSalt;
|
||||
newPasswordHint?: string;
|
||||
rotateUserKey?: boolean;
|
||||
|
||||
/** @deprecated This low-level cryptographic state will be removed. It will be replaced by high level calls to masterpassword service, in the consumers of this interface. */
|
||||
currentMasterKey?: MasterKey;
|
||||
/** @deprecated */
|
||||
currentServerMasterKeyHash?: string;
|
||||
/** @deprecated */
|
||||
currentLocalMasterKeyHash?: string;
|
||||
|
||||
newPassword: string;
|
||||
newPasswordHint?: string;
|
||||
/** @deprecated */
|
||||
newMasterKey?: MasterKey;
|
||||
/** @deprecated */
|
||||
newServerMasterKeyHash?: string;
|
||||
/** @deprecated */
|
||||
newLocalMasterKeyHash?: string;
|
||||
|
||||
kdfConfig?: KdfConfig;
|
||||
rotateUserKey?: boolean;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { FakeAccountService, makeEncString, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import {
|
||||
PasswordStrengthServiceAbstraction,
|
||||
PasswordStrengthService,
|
||||
@@ -61,7 +61,7 @@ const masterPassword = "password";
|
||||
const deviceId = Utils.newGuid();
|
||||
const accessToken = "ACCESS_TOKEN";
|
||||
const refreshToken = "REFRESH_TOKEN";
|
||||
const encryptedUserKey = makeEncString("USER_KEY");
|
||||
const encryptedUserKey = "USER_KEY";
|
||||
const privateKey = "PRIVATE_KEY";
|
||||
const kdf = 0;
|
||||
const kdfIterations = 10000;
|
||||
@@ -76,7 +76,7 @@ const defaultUserDecryptionOptionsServerResponse: IUserDecryptionOptionsServerRe
|
||||
KdfType: kdf,
|
||||
Iterations: kdfIterations,
|
||||
},
|
||||
MasterKeyEncryptedUserKey: encryptedUserKey.encryptedString,
|
||||
MasterKeyEncryptedUserKey: encryptedUserKey,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -99,7 +99,7 @@ export function identityTokenResponseFactory(
|
||||
ForcePasswordReset: false,
|
||||
Kdf: kdf,
|
||||
KdfIterations: kdfIterations,
|
||||
Key: encryptedUserKey.encryptedString,
|
||||
Key: encryptedUserKey,
|
||||
PrivateKey: privateKey,
|
||||
ResetMasterPassword: false,
|
||||
access_token: accessToken,
|
||||
|
||||
Reference in New Issue
Block a user