mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-22 21:21:35 +01:00
rename key hash to password hash on crypto service
This commit is contained in:
parent
b4fd44320d
commit
84874fdd11
@ -120,7 +120,7 @@ export class LockComponent implements OnInit, OnDestroy {
|
|||||||
const userKey = await this.cryptoService.getUserKeyFromStorage(KeySuffixOptions.Biometric);
|
const userKey = await this.cryptoService.getUserKeyFromStorage(KeySuffixOptions.Biometric);
|
||||||
|
|
||||||
if (userKey) {
|
if (userKey) {
|
||||||
await this.setKeyAndContinue(userKey, false);
|
await this.setUserKeyAndContinue(userKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!userKey;
|
return !!userKey;
|
||||||
@ -198,7 +198,7 @@ export class LockComponent implements OnInit, OnDestroy {
|
|||||||
failed = decryptedPin !== this.pin;
|
failed = decryptedPin !== this.pin;
|
||||||
|
|
||||||
if (!failed) {
|
if (!failed) {
|
||||||
await this.setKeyAndContinue(userKey);
|
await this.setUserKeyAndContinue(userKey);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
failed = true;
|
failed = true;
|
||||||
@ -240,36 +240,36 @@ export class LockComponent implements OnInit, OnDestroy {
|
|||||||
kdf,
|
kdf,
|
||||||
kdfConfig
|
kdfConfig
|
||||||
);
|
);
|
||||||
const storedKeyHash = await this.cryptoService.getKeyHash();
|
const storedPasswordHash = await this.cryptoService.getPasswordHash();
|
||||||
|
|
||||||
let passwordValid = false;
|
let passwordValid = false;
|
||||||
|
|
||||||
if (storedKeyHash != null) {
|
if (storedPasswordHash != null) {
|
||||||
// Offline unlock possible
|
// Offline unlock possible
|
||||||
passwordValid = await this.cryptoService.compareAndUpdateKeyHash(
|
passwordValid = await this.cryptoService.compareAndUpdatePasswordHash(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
masterKey
|
masterKey
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Online only
|
// Online only
|
||||||
const request = new SecretVerificationRequest();
|
const request = new SecretVerificationRequest();
|
||||||
const serverKeyHash = await this.cryptoService.hashPassword(
|
const serverPasswordHash = await this.cryptoService.hashPassword(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
masterKey,
|
masterKey,
|
||||||
HashPurpose.ServerAuthorization
|
HashPurpose.ServerAuthorization
|
||||||
);
|
);
|
||||||
request.masterPasswordHash = serverKeyHash;
|
request.masterPasswordHash = serverPasswordHash;
|
||||||
try {
|
try {
|
||||||
this.formPromise = this.apiService.postAccountVerifyPassword(request);
|
this.formPromise = this.apiService.postAccountVerifyPassword(request);
|
||||||
const response = await this.formPromise;
|
const response = await this.formPromise;
|
||||||
this.enforcedMasterPasswordOptions = MasterPasswordPolicyOptions.fromResponse(response);
|
this.enforcedMasterPasswordOptions = MasterPasswordPolicyOptions.fromResponse(response);
|
||||||
passwordValid = true;
|
passwordValid = true;
|
||||||
const localKeyHash = await this.cryptoService.hashPassword(
|
const localPasswordHash = await this.cryptoService.hashPassword(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
masterKey,
|
masterKey,
|
||||||
HashPurpose.LocalAuthorization
|
HashPurpose.LocalAuthorization
|
||||||
);
|
);
|
||||||
await this.cryptoService.setKeyHash(localKeyHash);
|
await this.cryptoService.setPasswordHash(localPasswordHash);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logService.error(e);
|
this.logService.error(e);
|
||||||
} finally {
|
} finally {
|
||||||
@ -288,10 +288,10 @@ export class LockComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
|
const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
|
||||||
await this.cryptoService.setMasterKey(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.cryptoService.setUserKey(key);
|
||||||
await this.doContinue(evaluatePasswordAfterUnlock);
|
await this.doContinue(evaluatePasswordAfterUnlock);
|
||||||
}
|
}
|
||||||
|
@ -182,11 +182,11 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
await this.cryptoService.setUserKey(userKey[0]);
|
await this.cryptoService.setUserKey(userKey[0]);
|
||||||
await this.cryptoService.setPrivateKey(keyPair[1].encryptedString);
|
await this.cryptoService.setPrivateKey(keyPair[1].encryptedString);
|
||||||
|
|
||||||
const localKeyHash = await this.cryptoService.hashPassword(
|
const localPasswordHash = await this.cryptoService.hashPassword(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
masterKey,
|
masterKey,
|
||||||
HashPurpose.LocalAuthorization
|
HashPurpose.LocalAuthorization
|
||||||
);
|
);
|
||||||
await this.cryptoService.setKeyHash(localKeyHash);
|
await this.cryptoService.setPasswordHash(localPasswordHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ export class PasswordRepromptComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
if (!(await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, null))) {
|
if (!(await this.cryptoService.compareAndUpdatePasswordHash(this.masterPassword, null))) {
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
"error",
|
"error",
|
||||||
this.i18nService.t("errorOccurred"),
|
this.i18nService.t("errorOccurred"),
|
||||||
|
@ -142,7 +142,7 @@ describe("PasswordLogInStrategy", () => {
|
|||||||
await passwordLogInStrategy.logIn(credentials);
|
await passwordLogInStrategy.logIn(credentials);
|
||||||
|
|
||||||
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
|
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
|
||||||
expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localHashedPassword);
|
expect(cryptoService.setPasswordHash).toHaveBeenCalledWith(localHashedPassword);
|
||||||
expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
|
expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
|
||||||
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
|
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
|
||||||
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
|
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
|
||||||
|
@ -143,7 +143,7 @@ export class PasswordLogInStrategy extends LogInStrategy {
|
|||||||
|
|
||||||
protected override async setMasterKey(response: IdentityTokenResponse) {
|
protected override async setMasterKey(response: IdentityTokenResponse) {
|
||||||
await this.cryptoService.setMasterKey(this.masterKey);
|
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> {
|
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {
|
||||||
|
@ -93,7 +93,7 @@ describe("SsoLogInStrategy", () => {
|
|||||||
await passwordlessLoginStrategy.logIn(credentials);
|
await passwordlessLoginStrategy.logIn(credentials);
|
||||||
|
|
||||||
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
|
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
|
||||||
expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localPasswordHash);
|
expect(cryptoService.setPasswordHash).toHaveBeenCalledWith(localPasswordHash);
|
||||||
expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
|
expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
|
||||||
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
|
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
|
||||||
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
|
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
|
||||||
|
@ -81,7 +81,7 @@ export class PasswordlessLogInStrategy extends LogInStrategy {
|
|||||||
|
|
||||||
protected override async setMasterKey(response: IdentityTokenResponse) {
|
protected override async setMasterKey(response: IdentityTokenResponse) {
|
||||||
await this.cryptoService.setMasterKey(this.passwordlessCredentials.decKey);
|
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> {
|
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {
|
||||||
|
@ -61,7 +61,7 @@ export class UserVerificationService implements UserVerificationServiceAbstracti
|
|||||||
throw new Error(this.i18nService.t("invalidVerificationCode"));
|
throw new Error(this.i18nService.t("invalidVerificationCode"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const passwordValid = await this.cryptoService.compareAndUpdateKeyHash(
|
const passwordValid = await this.cryptoService.compareAndUpdatePasswordHash(
|
||||||
verification.secret,
|
verification.secret,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
@ -155,28 +155,28 @@ export abstract class CryptoService {
|
|||||||
*/
|
*/
|
||||||
hashPassword: (password: string, key: MasterKey, hashPurpose?: HashPurpose) => Promise<string>;
|
hashPassword: (password: string, key: MasterKey, hashPurpose?: HashPurpose) => Promise<string>;
|
||||||
/**
|
/**
|
||||||
* Sets the user's key hash
|
* Sets the user's master password hash
|
||||||
* @param keyHash The user's key hash to set
|
* @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
|
* @param userId The desired user
|
||||||
*/
|
*/
|
||||||
clearKeyHash: () => Promise<void>;
|
clearPasswordHash: () => Promise<void>;
|
||||||
/**
|
/**
|
||||||
* Compares the provided master password to the stored key hash and updates
|
* Compares the provided master password to the stored password hash and server password hash.
|
||||||
* if the stored hash is outdated
|
* Updates the stored hash if outdated.
|
||||||
* @param masterPassword The user's master password
|
* @param masterPassword The user's master password
|
||||||
* @param key The user's master key
|
* @param key The user's master key
|
||||||
* @returns True if the provided master password matches either the stored
|
* @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
|
* Stores the encrypted organization keys and clears any decrypted
|
||||||
* organization keys currently in memory
|
* organization keys currently in memory
|
||||||
|
@ -220,38 +220,41 @@ export class CryptoService implements CryptoServiceAbstraction {
|
|||||||
return Utils.fromBufferToB64(hash);
|
return Utils.fromBufferToB64(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setKeyHash(keyHash: string): Promise<void> {
|
async setPasswordHash(keyHash: string): Promise<void> {
|
||||||
await this.stateService.setKeyHash(keyHash);
|
await this.stateService.setKeyHash(keyHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getKeyHash(): Promise<string> {
|
async getPasswordHash(): Promise<string> {
|
||||||
return await this.stateService.getKeyHash();
|
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 });
|
return await this.stateService.setKeyHash(null, { userId: userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async compareAndUpdateKeyHash(masterPassword: string, key: MasterKey): Promise<boolean> {
|
async compareAndUpdatePasswordHash(
|
||||||
const storedKeyHash = await this.getKeyHash();
|
masterPassword: string,
|
||||||
if (masterPassword != null && storedKeyHash != null) {
|
masterKey: MasterKey
|
||||||
|
): Promise<boolean> {
|
||||||
|
const storedPasswordHash = await this.getPasswordHash();
|
||||||
|
if (masterPassword != null && storedPasswordHash != null) {
|
||||||
const localKeyHash = await this.hashPassword(
|
const localKeyHash = await this.hashPassword(
|
||||||
masterPassword,
|
masterPassword,
|
||||||
key,
|
masterKey,
|
||||||
HashPurpose.LocalAuthorization
|
HashPurpose.LocalAuthorization
|
||||||
);
|
);
|
||||||
if (localKeyHash != null && storedKeyHash === localKeyHash) {
|
if (localKeyHash != null && storedPasswordHash === localKeyHash) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove serverKeyHash check in 1-2 releases after everyone's keyHash has been updated
|
// TODO: remove serverKeyHash check in 1-2 releases after everyone's keyHash has been updated
|
||||||
const serverKeyHash = await this.hashPassword(
|
const serverKeyHash = await this.hashPassword(
|
||||||
masterPassword,
|
masterPassword,
|
||||||
key,
|
masterKey,
|
||||||
HashPurpose.ServerAuthorization
|
HashPurpose.ServerAuthorization
|
||||||
);
|
);
|
||||||
if (serverKeyHash != null && storedKeyHash === serverKeyHash) {
|
if (serverKeyHash != null && storedPasswordHash === serverKeyHash) {
|
||||||
await this.setKeyHash(localKeyHash);
|
await this.setPasswordHash(localKeyHash);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -561,7 +564,7 @@ export class CryptoService implements CryptoServiceAbstraction {
|
|||||||
|
|
||||||
async clearKeys(userId?: string): Promise<any> {
|
async clearKeys(userId?: string): Promise<any> {
|
||||||
await this.clearUserKey(true, userId);
|
await this.clearUserKey(true, userId);
|
||||||
await this.clearKeyHash(userId);
|
await this.clearPasswordHash(userId);
|
||||||
await this.clearOrgKeys(false, userId);
|
await this.clearOrgKeys(false, userId);
|
||||||
await this.clearProviderKeys(false, userId);
|
await this.clearProviderKeys(false, userId);
|
||||||
await this.clearKeyPair(false, userId);
|
await this.clearKeyPair(false, userId);
|
||||||
|
Loading…
Reference in New Issue
Block a user