1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-02-20 02:01:47 +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, newMasterKey: MasterKey,
newUserKey: [UserKey, EncString] newUserKey: [UserKey, EncString]
) { ) {
const masterKey = await this.cryptoService.getOrDeriveMasterKey(this.currentMasterPassword);
const request = new PasswordRequest(); const request = new PasswordRequest();
request.masterPasswordHash = await this.cryptoService.hashMasterKey( request.masterPasswordHash = await this.cryptoService.hashMasterKey(
this.currentMasterPassword, this.currentMasterPassword,
null masterKey
); );
request.masterPasswordHint = this.masterPasswordHint; request.masterPasswordHint = this.masterPasswordHint;
request.newMasterPasswordHash = newMasterPasswordHash; request.newMasterPasswordHash = newMasterPasswordHash;

View File

@ -75,7 +75,8 @@ export class ChangeKdfConfirmationComponent {
request.kdfIterations = this.kdfConfig.iterations; request.kdfIterations = this.kdfConfig.iterations;
request.kdfMemory = this.kdfConfig.memory; request.kdfMemory = this.kdfConfig.memory;
request.kdfParallelism = this.kdfConfig.parallelism; 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 email = await this.stateService.getEmail();
const newMasterKey = await this.cryptoService.makeMasterKey( const newMasterKey = await this.cryptoService.makeMasterKey(
masterPassword, masterPassword,

View File

@ -78,7 +78,10 @@ export class UpdateKeyComponent {
const request = new UpdateKeyRequest(); const request = new UpdateKeyRequest();
request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null; request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null;
request.key = newUserKey[1].encryptedString; 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); await this.syncService.fullSync(true);

View File

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

View File

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

View File

@ -102,6 +102,12 @@ export abstract class CryptoService {
* @returns The user's master key * @returns The user's master key
*/ */
getMasterKey: (userId?: string) => Promise<MasterKey>; 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 * Generates a master key from the provided password
* @param password The user's master password * @param password The user's master password

View File

@ -151,6 +151,16 @@ export class CryptoService implements CryptoServiceAbstraction {
return masterKey; 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( async makeMasterKey(
password: string, password: string,
email: string, email: string,