mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
[PM-21001] Move KM usage of encrypt service (#14541)
* Add new encrypt service functions * Undo changes * Cleanup * Fix build * Fix comments * Move KM usage of encrypt service * Fix build
This commit is contained in:
@@ -49,6 +49,7 @@ export abstract class EncryptService {
|
||||
key: SymmetricCryptoKey,
|
||||
decryptTrace?: string,
|
||||
): Promise<Uint8Array | null>;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by BulkEncryptService, remove once the feature is tested and the featureflag PM-4154-multi-worker-encryption-service is removed
|
||||
* @param items The items to decrypt
|
||||
|
||||
@@ -209,7 +209,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
|
||||
devices.data
|
||||
.filter((device) => device.isTrusted)
|
||||
.map(async (device) => {
|
||||
const publicKey = await this.encryptService.decryptToBytes(
|
||||
const publicKey = await this.encryptService.unwrapEncapsulationKey(
|
||||
new EncString(device.encryptedPublicKey),
|
||||
oldUserKey,
|
||||
);
|
||||
@@ -220,7 +220,10 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
|
||||
return null;
|
||||
}
|
||||
|
||||
const newEncryptedPublicKey = await this.encryptService.encrypt(publicKey, newUserKey);
|
||||
const newEncryptedPublicKey = await this.encryptService.wrapEncapsulationKey(
|
||||
publicKey,
|
||||
newUserKey,
|
||||
);
|
||||
const newEncryptedUserKey = await this.encryptService.encapsulateKeyUnsigned(
|
||||
newUserKey,
|
||||
publicKey,
|
||||
@@ -278,7 +281,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
|
||||
const currentDeviceKeys = await this.devicesApiService.getDeviceKeys(deviceIdentifier);
|
||||
|
||||
// Decrypt the existing device public key with the old user key
|
||||
const decryptedDevicePublicKey = await this.encryptService.decryptToBytes(
|
||||
const decryptedDevicePublicKey = await this.encryptService.unwrapEncapsulationKey(
|
||||
currentDeviceKeys.encryptedPublicKey,
|
||||
oldUserKey,
|
||||
);
|
||||
@@ -394,7 +397,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
|
||||
|
||||
try {
|
||||
// attempt to decrypt encryptedDevicePrivateKey with device key
|
||||
const devicePrivateKey = await this.encryptService.decryptToBytes(
|
||||
const devicePrivateKey = await this.encryptService.unwrapDecapsulationKey(
|
||||
encryptedDevicePrivateKey,
|
||||
deviceKey,
|
||||
);
|
||||
|
||||
@@ -623,9 +623,9 @@ describe("deviceTrustService", () => {
|
||||
});
|
||||
|
||||
it("successfully returns the user key when provided keys (including device key) can decrypt it", async () => {
|
||||
const decryptToBytesSpy = jest
|
||||
.spyOn(encryptService, "decryptToBytes")
|
||||
.mockResolvedValue(new Uint8Array(userKeyBytesLength));
|
||||
const unwrapDecapsulationKeySpy = jest
|
||||
.spyOn(encryptService, "unwrapDecapsulationKey")
|
||||
.mockResolvedValue(new Uint8Array(2048));
|
||||
const rsaDecryptSpy = jest
|
||||
.spyOn(encryptService, "decapsulateKeyUnsigned")
|
||||
.mockResolvedValue(new SymmetricCryptoKey(new Uint8Array(userKeyBytesLength)));
|
||||
@@ -638,13 +638,13 @@ describe("deviceTrustService", () => {
|
||||
);
|
||||
|
||||
expect(result).toEqual(mockUserKey);
|
||||
expect(decryptToBytesSpy).toHaveBeenCalledTimes(1);
|
||||
expect(unwrapDecapsulationKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(rsaDecryptSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("returns null and removes device key when the decryption fails", async () => {
|
||||
const decryptToBytesSpy = jest
|
||||
.spyOn(encryptService, "decryptToBytes")
|
||||
const unwrapDecapsulationKeySpy = jest
|
||||
.spyOn(encryptService, "unwrapDecapsulationKey")
|
||||
.mockRejectedValue(new Error("Decryption error"));
|
||||
const setDeviceKeySpy = jest.spyOn(deviceTrustService as any, "setDeviceKey");
|
||||
|
||||
@@ -656,7 +656,7 @@ describe("deviceTrustService", () => {
|
||||
);
|
||||
|
||||
expect(result).toBeNull();
|
||||
expect(decryptToBytesSpy).toHaveBeenCalledTimes(1);
|
||||
expect(unwrapDecapsulationKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(setDeviceKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(setDeviceKeySpy).toHaveBeenCalledWith(mockUserId, null);
|
||||
});
|
||||
@@ -704,8 +704,8 @@ describe("deviceTrustService", () => {
|
||||
DeviceResponse,
|
||||
),
|
||||
);
|
||||
encryptService.decryptToBytes.mockResolvedValue(null);
|
||||
encryptService.encrypt.mockResolvedValue(new EncString("test_encrypted_data"));
|
||||
encryptService.decryptBytes.mockResolvedValue(null);
|
||||
encryptService.encryptString.mockResolvedValue(new EncString("test_encrypted_data"));
|
||||
encryptService.encapsulateKeyUnsigned.mockResolvedValue(
|
||||
new EncString("test_encrypted_data"),
|
||||
);
|
||||
@@ -752,9 +752,11 @@ describe("deviceTrustService", () => {
|
||||
DeviceResponse,
|
||||
),
|
||||
);
|
||||
encryptService.decryptToBytes.mockResolvedValue(new Uint8Array(64));
|
||||
encryptService.encrypt.mockResolvedValue(new EncString("test_encrypted_data"));
|
||||
encryptService.rsaEncrypt.mockResolvedValue(new EncString("test_encrypted_data"));
|
||||
encryptService.unwrapEncapsulationKey.mockResolvedValue(new Uint8Array(64));
|
||||
encryptService.wrapEncapsulationKey.mockResolvedValue(new EncString("test_encrypted_data"));
|
||||
encryptService.encapsulateKeyUnsigned.mockResolvedValue(
|
||||
new EncString("test_encrypted_data"),
|
||||
);
|
||||
|
||||
const protectedDeviceResponse = new ProtectedDeviceResponse({
|
||||
id: "",
|
||||
@@ -862,13 +864,15 @@ describe("deviceTrustService", () => {
|
||||
});
|
||||
|
||||
// Mock the decryption of the public key with the old user key
|
||||
encryptService.decryptToBytes.mockImplementationOnce((_encValue, privateKeyValue) => {
|
||||
expect(privateKeyValue.inner().type).toBe(EncryptionType.AesCbc256_HmacSha256_B64);
|
||||
expect(new Uint8Array(privateKeyValue.toEncoded())[0]).toBe(FakeOldUserKeyMarker);
|
||||
const data = new Uint8Array(250);
|
||||
data.fill(FakeDecryptedPublicKeyMarker, 0, 1);
|
||||
return Promise.resolve(data);
|
||||
});
|
||||
encryptService.unwrapEncapsulationKey.mockImplementationOnce(
|
||||
(_encValue, privateKeyValue) => {
|
||||
expect(privateKeyValue.inner().type).toBe(EncryptionType.AesCbc256_HmacSha256_B64);
|
||||
expect(new Uint8Array(privateKeyValue.toEncoded())[0]).toBe(FakeOldUserKeyMarker);
|
||||
const data = new Uint8Array(250);
|
||||
data.fill(FakeDecryptedPublicKeyMarker, 0, 1);
|
||||
return Promise.resolve(data);
|
||||
},
|
||||
);
|
||||
|
||||
// Mock the encryption of the new user key with the decrypted public key
|
||||
encryptService.encapsulateKeyUnsigned.mockImplementationOnce((data, publicKey) => {
|
||||
|
||||
@@ -174,21 +174,13 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
|
||||
throw new Error("No master key found.");
|
||||
}
|
||||
|
||||
let decUserKey: Uint8Array;
|
||||
let decUserKey: SymmetricCryptoKey;
|
||||
|
||||
if (userKey.encryptionType === EncryptionType.AesCbc256_B64) {
|
||||
decUserKey = await this.encryptService.decryptToBytes(
|
||||
userKey,
|
||||
masterKey,
|
||||
"Content: User Key; Encrypting Key: Master Key",
|
||||
);
|
||||
decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, masterKey);
|
||||
} else if (userKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) {
|
||||
const newKey = await this.keyGenerationService.stretchKey(masterKey);
|
||||
decUserKey = await this.encryptService.decryptToBytes(
|
||||
userKey,
|
||||
newKey,
|
||||
"Content: User Key; Encrypting Key: Stretched Master Key",
|
||||
);
|
||||
decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, newKey);
|
||||
} else {
|
||||
throw new Error("Unsupported encryption type.");
|
||||
}
|
||||
@@ -198,6 +190,6 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SymmetricCryptoKey(decUserKey) as UserKey;
|
||||
return decUserKey as UserKey;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user