1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-22 11:45:59 +01:00

Use a passed in key in derivation so we can validate other keys (#8954)

* Use a passed in key in derivation so we can validate other keys

* Fix user key type tests
This commit is contained in:
Matt Gibson 2024-04-27 16:32:34 -04:00 committed by GitHub
parent 0ecde07525
commit 88eeebb084
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 17 deletions

View File

@ -100,7 +100,7 @@ export class CryptoService implements CryptoServiceAbstraction {
USER_PRIVATE_KEY,
{
encryptService: this.encryptService,
cryptoService: this,
getUserKey: (userId) => this.getUserKey(userId),
},
);
this.activeUserPrivateKey$ = this.activeUserPrivateKeyState.state$; // may be null
@ -738,13 +738,23 @@ export class CryptoService implements CryptoServiceAbstraction {
// Can decrypt private key
const privateKey = await USER_PRIVATE_KEY.derive([userId, encPrivateKey], {
encryptService: this.encryptService,
cryptoService: this,
getUserKey: () => Promise.resolve(key),
});
if (privateKey == null) {
// failed to decrypt
return false;
}
// Can successfully derive public key
await USER_PUBLIC_KEY.derive(privateKey, {
const publicKey = await USER_PUBLIC_KEY.derive(privateKey, {
cryptoFunctionService: this.cryptoFunctionService,
});
if (publicKey == null) {
// failed to decrypt
return false;
}
} catch (e) {
return false;
}

View File

@ -8,7 +8,6 @@ import { EncryptService } from "../../abstractions/encrypt.service";
import { EncryptionType } from "../../enums";
import { Utils } from "../../misc/utils";
import { EncString } from "../../models/domain/enc-string";
import { CryptoService } from "../crypto.service";
import {
USER_ENCRYPTED_PRIVATE_KEY,
@ -89,40 +88,37 @@ describe("Derived decrypted private key", () => {
});
it("should derive decrypted private key", async () => {
const cryptoService = mock<CryptoService>();
cryptoService.getUserKey.mockResolvedValue(userKey);
const getUserKey = jest.fn(async () => userKey);
const encryptService = mock<EncryptService>();
encryptService.decryptToBytes.mockResolvedValue(decryptedPrivateKey);
const result = await sut.derive([userId, encryptedPrivateKey], {
encryptService,
cryptoService,
getUserKey,
});
expect(result).toEqual(decryptedPrivateKey);
});
it("should handle null input values", async () => {
const cryptoService = mock<CryptoService>();
cryptoService.getUserKey.mockResolvedValue(userKey);
const getUserKey = jest.fn(async () => userKey);
const encryptService = mock<EncryptService>();
const result = await sut.derive([userId, null], {
encryptService,
cryptoService,
getUserKey,
});
expect(result).toEqual(null);
});
it("should handle null user key", async () => {
const cryptoService = mock<CryptoService>();
cryptoService.getUserKey.mockResolvedValue(null);
const getUserKey = jest.fn(async () => null);
const encryptService = mock<EncryptService>();
const result = await sut.derive([userId, encryptedPrivateKey], {
encryptService,
cryptoService,
getUserKey,
});
expect(result).toEqual(null);

View File

@ -1,10 +1,10 @@
import { UserId } from "../../../types/guid";
import { UserPrivateKey, UserPublicKey, UserKey } from "../../../types/key";
import { CryptoFunctionService } from "../../abstractions/crypto-function.service";
import { EncryptService } from "../../abstractions/encrypt.service";
import { EncString, EncryptedString } from "../../models/domain/enc-string";
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
import { CRYPTO_DISK, DeriveDefinition, CRYPTO_MEMORY, UserKeyDefinition } from "../../state";
import { CryptoService } from "../crypto.service";
export const USER_EVER_HAD_USER_KEY = new UserKeyDefinition<boolean>(
CRYPTO_DISK,
@ -28,15 +28,15 @@ export const USER_PRIVATE_KEY = DeriveDefinition.fromWithUserId<
EncryptedString,
UserPrivateKey,
// TODO: update cryptoService to user key directly
{ encryptService: EncryptService; cryptoService: CryptoService }
{ encryptService: EncryptService; getUserKey: (userId: UserId) => Promise<UserKey> }
>(USER_ENCRYPTED_PRIVATE_KEY, {
deserializer: (obj) => new Uint8Array(Object.values(obj)) as UserPrivateKey,
derive: async ([userId, encPrivateKeyString], { encryptService, cryptoService }) => {
derive: async ([userId, encPrivateKeyString], { encryptService, getUserKey }) => {
if (encPrivateKeyString == null) {
return null;
}
const userKey = await cryptoService.getUserKey(userId);
const userKey = await getUserKey(userId);
if (userKey == null) {
return null;
}