1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-06 19:53:59 +00:00

Rename to "unwrapUserKeyFromMasterPasswordUnlockData"

This commit is contained in:
Bernd Schoolmann
2025-07-16 16:56:47 +02:00
parent 7312206a16
commit 59f6e7d5ee
4 changed files with 66 additions and 32 deletions

View File

@@ -1,11 +1,17 @@
import { Observable } from "rxjs";
// eslint-disable-next-line no-restricted-imports
import { KdfConfig } from "@bitwarden/key-management";
import { ForceSetPasswordReason } from "../../../auth/models/domain/force-set-password-reason";
import { EncString } from "../../../platform/models/domain/enc-string";
import { UserId } from "../../../types/guid";
import { MasterKey, UserKey } from "../../../types/key";
import { KdfConfig } from "@bitwarden/key-management";
import { MasterKeyWrappedUserKey, MasterPasswordAuthenticationData, MasterPasswordUnlockData } from "../types/master-password.types";
import {
MasterKeyWrappedUserKey,
MasterPasswordAuthenticationData,
MasterPasswordUnlockData,
} from "../types/master-password.types";
export abstract class MasterPasswordServiceAbstraction {
/**
@@ -47,7 +53,6 @@ export abstract class MasterPasswordServiceAbstraction {
userKey?: EncString,
) => Promise<UserKey | null>;
abstract makeMasterPasswordAuthenticationData: (
password: string,
kdf: KdfConfig,
@@ -69,7 +74,7 @@ export abstract class MasterPasswordServiceAbstraction {
userKey: UserKey,
) => Promise<MasterKeyWrappedUserKey>;
abstract unwrapMasterKeyWrappedUserKey: (
abstract unwrapUserKeyFromMasterPasswordUnlockData: (
password: string,
masterPasswordUnlockData: MasterPasswordUnlockData,
) => Promise<UserKey>;

View File

@@ -108,10 +108,10 @@ export class FakeMasterPasswordService implements InternalMasterPasswordServiceA
return this.mock.makeMasterKeyWrappedUserKey(password, kdf, salt, userKey);
}
unwrapMasterKeyWrappedUserKey(
unwrapUserKeyFromMasterPasswordUnlockData(
password: string,
masterPasswordUnlockData: MasterPasswordUnlockData,
): Promise<UserKey> {
return this.mock.unwrapMasterKeyWrappedUserKey(password, masterPasswordUnlockData);
return this.mock.unwrapUserKeyFromMasterPasswordUnlockData(password, masterPasswordUnlockData);
}
}

View File

@@ -277,7 +277,7 @@ describe("MasterPasswordService", () => {
it("wraps and unwraps user key with password", async () => {
const wrappedKey = await sut.makeMasterKeyWrappedUserKey(password, kdf, salt, userKey);
const unwrappedUserkey = await sut.unwrapMasterKeyWrappedUserKey(password, {
const unwrappedUserkey = await sut.unwrapUserKeyFromMasterPasswordUnlockData(password, {
kdf,
salt,
masterKeyWrappedUserKey: wrappedKey,

View File

@@ -20,7 +20,13 @@ import { MasterKey, UserKey } from "../../../types/key";
import { EncryptService } from "../../crypto/abstractions/encrypt.service";
import { InternalMasterPasswordServiceAbstraction } from "../abstractions/master-password.service.abstraction";
import { KdfConfig, KeyService } from "@bitwarden/key-management";
import { MasterKeyWrappedUserKey, MasterPasswordAuthenticationData, MasterPasswordAuthenticationHash, MasterPasswordSalt, MasterPasswordUnlockData } from "../types/master-password.types";
import {
MasterKeyWrappedUserKey,
MasterPasswordAuthenticationData,
MasterPasswordAuthenticationHash,
MasterPasswordSalt,
MasterPasswordUnlockData,
} from "../types/master-password.types";
import { PureCrypto } from "@bitwarden/sdk-internal";
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
import { CryptoFunctionService } from "../../crypto/abstractions/crypto-function.service";
@@ -66,7 +72,7 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
private encryptService: EncryptService,
private logService: LogService,
private cryptoFunctionService: CryptoFunctionService,
) { }
) {}
/**
* @deprecated This will be made private
@@ -119,7 +125,6 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
throw new Error("User ID is required.");
}
const masterKey = await firstValueFrom(this.masterKey$(userId));
const userKey = await this.getMasterKeyEncryptedUserKey(userId);
@@ -250,7 +255,7 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
}
/**
* Makes the authentication hash for authenticating to the server with the master password.
* Makes the authentication hash for authenticating to the server with the master password.
*/
async makeMasterPasswordAuthenticationData(
password: string,
@@ -259,18 +264,20 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
): Promise<MasterPasswordAuthenticationData> {
const SERVER_AUTHENTICATION_HASH_ITERATIONS = 1;
const masterKey = await this.keyGenerationService.deriveKeyFromPassword(
const masterKey = (await this.keyGenerationService.deriveKeyFromPassword(
password,
salt,
kdf,
) as MasterKey;
)) as MasterKey;
const masterPasswordAuthenticationHash = Utils.fromBufferToB64(await this.cryptoFunctionService.pbkdf2(
masterKey.toEncoded(),
password,
"sha256",
SERVER_AUTHENTICATION_HASH_ITERATIONS,
)) as MasterPasswordAuthenticationHash;
const masterPasswordAuthenticationHash = Utils.fromBufferToB64(
await this.cryptoFunctionService.pbkdf2(
masterKey.toEncoded(),
password,
"sha256",
SERVER_AUTHENTICATION_HASH_ITERATIONS,
),
) as MasterPasswordAuthenticationHash;
return {
kdf,
@@ -283,20 +290,37 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
* Creates a MasterPasswordUnlockData bundle that encrypts the user-key with a key derived from the password. The
* bundle also contains the KDF settings and salt used to derive the key, which are required to decrypt the user-key later.
*/
async makeMasterPasswordUnlockData(password: string, kdf: KdfConfig, salt: MasterPasswordSalt, userKey: UserKey): Promise<MasterPasswordUnlockData> {
async makeMasterPasswordUnlockData(
password: string,
kdf: KdfConfig,
salt: MasterPasswordSalt,
userKey: UserKey,
): Promise<MasterPasswordUnlockData> {
return {
salt,
kdf,
masterKeyWrappedUserKey: await this.makeMasterKeyWrappedUserKey(password, kdf, salt, userKey)
masterKeyWrappedUserKey: await this.makeMasterKeyWrappedUserKey(password, kdf, salt, userKey),
};
}
/**
* Wraps a user-key with a password provided KDF settings. The same KDF settings and salt must be provided to unwrap the user-key, otherwise it will fail to decrypt.
*/
async makeMasterKeyWrappedUserKey(password: string, kdf: KdfConfig, salt: MasterPasswordSalt, userKey: UserKey): Promise<MasterKeyWrappedUserKey> {
* Wraps a user-key with a password provided KDF settings. The same KDF settings and salt must be provided to unwrap the user-key, otherwise it will fail to decrypt.
*/
async makeMasterKeyWrappedUserKey(
password: string,
kdf: KdfConfig,
salt: MasterPasswordSalt,
userKey: UserKey,
): Promise<MasterKeyWrappedUserKey> {
await SdkLoadService.Ready;
return new EncString(PureCrypto.encrypt_user_key_with_master_password(userKey.toEncoded(), password, salt, kdf.toSdkConfig())) as MasterKeyWrappedUserKey;
return new EncString(
PureCrypto.encrypt_user_key_with_master_password(
userKey.toEncoded(),
password,
salt,
kdf.toSdkConfig(),
),
) as MasterKeyWrappedUserKey;
}
/**
@@ -304,14 +328,19 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
* @throws If the encryption type is not supported.
* @throws If the password, KDF, or salt don't match the original wrapping parameters.
*/
async unwrapMasterKeyWrappedUserKey(password: string, masterPasswordUnlockData: MasterPasswordUnlockData): Promise<UserKey> {
async unwrapUserKeyFromMasterPasswordUnlockData(
password: string,
masterPasswordUnlockData: MasterPasswordUnlockData,
): Promise<UserKey> {
await SdkLoadService.Ready;
const userKey = new SymmetricCryptoKey(PureCrypto.decrypt_user_key_with_master_password(
masterPasswordUnlockData.masterKeyWrappedUserKey!.encryptedString,
password,
masterPasswordUnlockData.salt,
masterPasswordUnlockData.kdf.toSdkConfig(),
));
const userKey = new SymmetricCryptoKey(
PureCrypto.decrypt_user_key_with_master_password(
masterPasswordUnlockData.masterKeyWrappedUserKey!.encryptedString,
password,
masterPasswordUnlockData.salt,
masterPasswordUnlockData.kdf.toSdkConfig(),
),
);
return userKey as UserKey;
}
}