1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-02-17 01:31:25 +01:00

[PM-3215][PM-3289] Create MasterKey from Password If Needed (#5931)

* Create MasterKey from Password

- Check if the MasterKey is stored or not
- Create it if it's not

* Add getOrDeriveKey Helper

* Use Helper In More Places
This commit is contained in:
Justin Baur 2023-08-04 11:33:18 -04:00 committed by GitHub
parent c56e85687c
commit 7af6aa93e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 12 deletions

View File

@ -190,10 +190,11 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
newMasterKey: MasterKey,
newUserKey: [UserKey, EncString]
) {
const masterKey = await this.cryptoService.getOrDeriveMasterKey(this.currentMasterPassword);
const request = new PasswordRequest();
request.masterPasswordHash = await this.cryptoService.hashMasterKey(
this.currentMasterPassword,
null
masterKey
);
request.masterPasswordHint = this.masterPasswordHint;
request.newMasterPasswordHash = newMasterPasswordHash;

View File

@ -75,7 +75,8 @@ export class ChangeKdfConfirmationComponent {
request.kdfIterations = this.kdfConfig.iterations;
request.kdfMemory = this.kdfConfig.memory;
request.kdfParallelism = this.kdfConfig.parallelism;
request.masterPasswordHash = await this.cryptoService.hashMasterKey(masterPassword, null);
const masterKey = await this.cryptoService.getOrDeriveMasterKey(masterPassword);
request.masterPasswordHash = await this.cryptoService.hashMasterKey(masterPassword, masterKey);
const email = await this.stateService.getEmail();
const newMasterKey = await this.cryptoService.makeMasterKey(
masterPassword,

View File

@ -78,7 +78,10 @@ export class UpdateKeyComponent {
const request = new UpdateKeyRequest();
request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null;
request.key = newUserKey[1].encryptedString;
request.masterPasswordHash = await this.cryptoService.hashMasterKey(this.masterPassword, null);
request.masterPasswordHash = await this.cryptoService.hashMasterKey(
this.masterPassword,
await this.cryptoService.getOrDeriveMasterKey(this.masterPassword)
);
await this.syncService.fullSync(true);

View File

@ -110,9 +110,9 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
}
async performSubmitActions(
masterPasswordHash: string,
masterKey: MasterKey,
userKey: [UserKey, EncString]
newMasterKeyHash: string,
newMasterKey: MasterKey,
newUserKey: [UserKey, EncString]
) {
// Override in sub-class
}

View File

@ -95,19 +95,19 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent {
}
async performSubmitActions(
masterPasswordHash: string,
masterKey: MasterKey,
userKey: [UserKey, EncString]
newMasterKeyHash: string,
newMasterKey: MasterKey,
newUserKey: [UserKey, EncString]
) {
try {
// Create Request
const request = new PasswordRequest();
request.masterPasswordHash = await this.cryptoService.hashMasterKey(
this.currentMasterPassword,
null
await this.cryptoService.getOrDeriveMasterKey(this.currentMasterPassword)
);
request.newMasterPasswordHash = masterPasswordHash;
request.key = userKey[1].encryptedString;
request.newMasterPasswordHash = newMasterKeyHash;
request.key = newUserKey[1].encryptedString;
// Update user's password
this.apiService.postPassword(request);

View File

@ -102,6 +102,12 @@ export abstract class CryptoService {
* @returns The user's master key
*/
getMasterKey: (userId?: string) => Promise<MasterKey>;
/**
* @param password The user's master password that will be used to derive a master key if one isn't found
* @param userId The desired user
*/
getOrDeriveMasterKey: (password: string, userId?: string) => Promise<MasterKey>;
/**
* Generates a master key from the provided password
* @param password The user's master password

View File

@ -151,6 +151,16 @@ export class CryptoService implements CryptoServiceAbstraction {
return masterKey;
}
async getOrDeriveMasterKey(password: string, userId?: string) {
let masterKey = await this.getMasterKey(userId);
return (masterKey ||= await this.makeMasterKey(
password,
await this.stateService.getEmail({ userId: userId }),
await this.stateService.getKdfType({ userId: userId }),
await this.stateService.getKdfConfig({ userId: userId })
));
}
async makeMasterKey(
password: string,
email: string,