1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-06 18:57:56 +01:00

rename key hash to password hash on crypto service

This commit is contained in:
Jacob Fink 2023-07-06 12:38:36 -04:00
parent b4fd44320d
commit 84874fdd11
No known key found for this signature in database
GPG Key ID: C2F7ACF05859D008
10 changed files with 45 additions and 42 deletions

View File

@ -120,7 +120,7 @@ export class LockComponent implements OnInit, OnDestroy {
const userKey = await this.cryptoService.getUserKeyFromStorage(KeySuffixOptions.Biometric);
if (userKey) {
await this.setKeyAndContinue(userKey, false);
await this.setUserKeyAndContinue(userKey, false);
}
return !!userKey;
@ -198,7 +198,7 @@ export class LockComponent implements OnInit, OnDestroy {
failed = decryptedPin !== this.pin;
if (!failed) {
await this.setKeyAndContinue(userKey);
await this.setUserKeyAndContinue(userKey);
}
} catch {
failed = true;
@ -240,36 +240,36 @@ export class LockComponent implements OnInit, OnDestroy {
kdf,
kdfConfig
);
const storedKeyHash = await this.cryptoService.getKeyHash();
const storedPasswordHash = await this.cryptoService.getPasswordHash();
let passwordValid = false;
if (storedKeyHash != null) {
if (storedPasswordHash != null) {
// Offline unlock possible
passwordValid = await this.cryptoService.compareAndUpdateKeyHash(
passwordValid = await this.cryptoService.compareAndUpdatePasswordHash(
this.masterPassword,
masterKey
);
} else {
// Online only
const request = new SecretVerificationRequest();
const serverKeyHash = await this.cryptoService.hashPassword(
const serverPasswordHash = await this.cryptoService.hashPassword(
this.masterPassword,
masterKey,
HashPurpose.ServerAuthorization
);
request.masterPasswordHash = serverKeyHash;
request.masterPasswordHash = serverPasswordHash;
try {
this.formPromise = this.apiService.postAccountVerifyPassword(request);
const response = await this.formPromise;
this.enforcedMasterPasswordOptions = MasterPasswordPolicyOptions.fromResponse(response);
passwordValid = true;
const localKeyHash = await this.cryptoService.hashPassword(
const localPasswordHash = await this.cryptoService.hashPassword(
this.masterPassword,
masterKey,
HashPurpose.LocalAuthorization
);
await this.cryptoService.setKeyHash(localKeyHash);
await this.cryptoService.setPasswordHash(localPasswordHash);
} catch (e) {
this.logService.error(e);
} finally {
@ -288,10 +288,10 @@ export class LockComponent implements OnInit, OnDestroy {
const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
await this.cryptoService.setMasterKey(masterKey);
await this.setKeyAndContinue(userKey, true);
await this.setUserKeyAndContinue(userKey, true);
}
private async setKeyAndContinue(key: UserKey, evaluatePasswordAfterUnlock = false) {
private async setUserKeyAndContinue(key: UserKey, evaluatePasswordAfterUnlock = false) {
await this.cryptoService.setUserKey(key);
await this.doContinue(evaluatePasswordAfterUnlock);
}

View File

@ -182,11 +182,11 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
await this.cryptoService.setUserKey(userKey[0]);
await this.cryptoService.setPrivateKey(keyPair[1].encryptedString);
const localKeyHash = await this.cryptoService.hashPassword(
const localPasswordHash = await this.cryptoService.hashPassword(
this.masterPassword,
masterKey,
HashPurpose.LocalAuthorization
);
await this.cryptoService.setKeyHash(localKeyHash);
await this.cryptoService.setPasswordHash(localPasswordHash);
}
}

View File

@ -27,7 +27,7 @@ export class PasswordRepromptComponent {
}
async submit() {
if (!(await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, null))) {
if (!(await this.cryptoService.compareAndUpdatePasswordHash(this.masterPassword, null))) {
this.platformUtilsService.showToast(
"error",
this.i18nService.t("errorOccurred"),

View File

@ -142,7 +142,7 @@ describe("PasswordLogInStrategy", () => {
await passwordLogInStrategy.logIn(credentials);
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localHashedPassword);
expect(cryptoService.setPasswordHash).toHaveBeenCalledWith(localHashedPassword);
expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);

View File

@ -143,7 +143,7 @@ export class PasswordLogInStrategy extends LogInStrategy {
protected override async setMasterKey(response: IdentityTokenResponse) {
await this.cryptoService.setMasterKey(this.masterKey);
await this.cryptoService.setKeyHash(this.localHashedPassword);
await this.cryptoService.setPasswordHash(this.localHashedPassword);
}
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {

View File

@ -93,7 +93,7 @@ describe("SsoLogInStrategy", () => {
await passwordlessLoginStrategy.logIn(credentials);
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localPasswordHash);
expect(cryptoService.setPasswordHash).toHaveBeenCalledWith(localPasswordHash);
expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);

View File

@ -81,7 +81,7 @@ export class PasswordlessLogInStrategy extends LogInStrategy {
protected override async setMasterKey(response: IdentityTokenResponse) {
await this.cryptoService.setMasterKey(this.passwordlessCredentials.decKey);
await this.cryptoService.setKeyHash(this.passwordlessCredentials.localPasswordHash);
await this.cryptoService.setPasswordHash(this.passwordlessCredentials.localPasswordHash);
}
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {

View File

@ -61,7 +61,7 @@ export class UserVerificationService implements UserVerificationServiceAbstracti
throw new Error(this.i18nService.t("invalidVerificationCode"));
}
} else {
const passwordValid = await this.cryptoService.compareAndUpdateKeyHash(
const passwordValid = await this.cryptoService.compareAndUpdatePasswordHash(
verification.secret,
null
);

View File

@ -155,28 +155,28 @@ export abstract class CryptoService {
*/
hashPassword: (password: string, key: MasterKey, hashPurpose?: HashPurpose) => Promise<string>;
/**
* Sets the user's key hash
* @param keyHash The user's key hash to set
* Sets the user's master password hash
* @param keyHash The user's master password hash to set
*/
setKeyHash: (keyHash: string) => Promise<void>;
setPasswordHash: (keyHash: string) => Promise<void>;
/**
* @returns The user's key hash
* @returns The user's master password hash
*/
getKeyHash: () => Promise<string>;
getPasswordHash: () => Promise<string>;
/**
* Clears the user's stored key hash
* Clears the user's stored master password hash
* @param userId The desired user
*/
clearKeyHash: () => Promise<void>;
clearPasswordHash: () => Promise<void>;
/**
* Compares the provided master password to the stored key hash and updates
* if the stored hash is outdated
* Compares the provided master password to the stored password hash and server password hash.
* Updates the stored hash if outdated.
* @param masterPassword The user's master password
* @param key The user's master key
* @returns True if the provided master password matches either the stored
* key hash
* key hash or the server key hash
*/
compareAndUpdateKeyHash: (masterPassword: string, key: MasterKey) => Promise<boolean>;
compareAndUpdatePasswordHash: (masterPassword: string, masterKey: MasterKey) => Promise<boolean>;
/**
* Stores the encrypted organization keys and clears any decrypted
* organization keys currently in memory

View File

@ -220,38 +220,41 @@ export class CryptoService implements CryptoServiceAbstraction {
return Utils.fromBufferToB64(hash);
}
async setKeyHash(keyHash: string): Promise<void> {
async setPasswordHash(keyHash: string): Promise<void> {
await this.stateService.setKeyHash(keyHash);
}
async getKeyHash(): Promise<string> {
async getPasswordHash(): Promise<string> {
return await this.stateService.getKeyHash();
}
async clearKeyHash(userId?: string): Promise<void> {
async clearPasswordHash(userId?: string): Promise<void> {
return await this.stateService.setKeyHash(null, { userId: userId });
}
async compareAndUpdateKeyHash(masterPassword: string, key: MasterKey): Promise<boolean> {
const storedKeyHash = await this.getKeyHash();
if (masterPassword != null && storedKeyHash != null) {
async compareAndUpdatePasswordHash(
masterPassword: string,
masterKey: MasterKey
): Promise<boolean> {
const storedPasswordHash = await this.getPasswordHash();
if (masterPassword != null && storedPasswordHash != null) {
const localKeyHash = await this.hashPassword(
masterPassword,
key,
masterKey,
HashPurpose.LocalAuthorization
);
if (localKeyHash != null && storedKeyHash === localKeyHash) {
if (localKeyHash != null && storedPasswordHash === localKeyHash) {
return true;
}
// TODO: remove serverKeyHash check in 1-2 releases after everyone's keyHash has been updated
const serverKeyHash = await this.hashPassword(
masterPassword,
key,
masterKey,
HashPurpose.ServerAuthorization
);
if (serverKeyHash != null && storedKeyHash === serverKeyHash) {
await this.setKeyHash(localKeyHash);
if (serverKeyHash != null && storedPasswordHash === serverKeyHash) {
await this.setPasswordHash(localKeyHash);
return true;
}
}
@ -561,7 +564,7 @@ export class CryptoService implements CryptoServiceAbstraction {
async clearKeys(userId?: string): Promise<any> {
await this.clearUserKey(true, userId);
await this.clearKeyHash(userId);
await this.clearPasswordHash(userId);
await this.clearOrgKeys(false, userId);
await this.clearProviderKeys(false, userId);
await this.clearKeyPair(false, userId);