mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 15:23:33 +00:00
Feature/[PM-1378] - Trusted Device Encryption - Establish trust logic for all clients (#5339)
* PM1378 - (1) Create state service methods for securely storing a device symmetric key while following existing pattern of DuckDuckGoKey generation (2) Create makeDeviceKey method on crypto service which leverages the new state service methods for storing the device key. * PM-1378 - Document CSPRNG types w/ comments explaining what they are and when they should be used. * PM-1378 - TODO to add tests for makeDeviceKey method * PM-1378 - Create Devices API service for creating and updating device encrypted master keys + move models according to latest code standards ( I think) * PM-1378 - TODO clean up - DeviceResponse properly moved next to device api service abstraction per ADR 0013 * PM-1378 - CryptoService makeDeviceKey test written * PM-1378 - Tweak crypto service makeDeviceKey test to leverage a describe for the function to better group related code. * PM-1378 - Move known devices call out of API service and into new devices-api.service and update all references. All clients building. * PM-1378 - Comment clean up * PM-1378 - Refactor out master key naming as that is a reserved specific key generated from the MP key derivation process + use same property on request object as back end. * PM-1378 - Missed a use of master key * PM-1378 - More abstraction updates to remove master key. * PM-1378 - Convert crypto service makeDeviceKey into getDeviceKey method to consolidate service logic based on PR feedback * PM-1378- Updating makeDeviceKey --> getDeviceKey tests to match updated code * PM-1378 - Current work on updating establish trusted device logic in light of new encryption mechanisms (introduction of a device asymmetric key pair in order to allow for key rotation while maintaining trusted devices) * PM-1378 - (1) CryptoService.TrustDevice() naming refactors (2) Lots of test additions and tweaks for trustDevice() * PM-1378 - Updated TrustedDeviceKeysRequest names to be consistent across the client side board. * PM-1378 - Move trusted device crypto service methods out of crypto service into new DeviceCryptoService for better single responsibility design * PM-1378 - (1) Add getDeviceByIdentifier endpoint to devices api as will need it later (2) Update TrustedDeviceKeysRequest and DeviceResponse models to match latest server side generic encrypted key names * PM-1378 - PR feedback fix - use JSDOC comments and move from abstraction to implementation * PM-1378 - Per PR feedback, makeDeviceKey should be private - updated tests with workaround. * PM-1378- Per PR feedback, refactored deviceKey to use partialKey dict so we can associate userId with specific device keys. * PM-1378 - Replace deviceId with deviceIdentifier per PR feedback * PM-1378 - Remove unnecessary createTrustedDeviceKey methods * PM-1378 - Update device crypto service to leverage updateTrustedDeviceKeys + update tests * PM-1378 - Update trustDevice logic - (1) Use getEncKey to get user symmetric key as it's the correct method and (2) Attempt to retrieve the userSymKey earlier on and short circuit if it is not found. * PM-1378 - Replace deviceId with deviceIdentifier because they are not the same thing * PM-1378 - Per PR feedback, (1) on web/browser extension, store device key in local storage under account.keys existing structure (2) on desktop, store deviceKey in secure storage. (3) Exempt account.keys.deviceKey from being cleared on account reset * PM-1378 - Desktop testing revealed that I forgot to add userId existence and options reconciliation checks back * PM-1378 - Per discussion with Jake, create DeviceKey custom type which is really just an opaque<SymmetricCryptoKey> so we can more easily differentiate between key types. * PM-1378 - Update symmetric-crypto-key.ts opaque DeviceKey to properly setup Opaque type. * PM-1378 - Fix wrong return type for getDeviceKey on DeviceCryptoServiceAbstraction per PR feedback
This commit is contained in:
@@ -361,7 +361,6 @@ export abstract class ApiService {
|
||||
putDeviceVerificationSettings: (
|
||||
request: DeviceVerificationRequest
|
||||
) => Promise<DeviceVerificationResponse>;
|
||||
getKnownDevice: (email: string, deviceIdentifier: string) => Promise<boolean>;
|
||||
|
||||
getEmergencyAccessTrusted: () => Promise<ListResponse<EmergencyAccessGranteeDetailsResponse>>;
|
||||
getEmergencyAccessGranted: () => Promise<ListResponse<EmergencyAccessGrantorDetailsResponse>>;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { DeviceKey } from "../models/domain/symmetric-crypto-key";
|
||||
|
||||
import { DeviceResponse } from "./devices/responses/device.response";
|
||||
|
||||
export abstract class DeviceCryptoServiceAbstraction {
|
||||
trustDevice: () => Promise<DeviceResponse>;
|
||||
getDeviceKey: () => Promise<DeviceKey>;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { DeviceResponse } from "./responses/device.response";
|
||||
|
||||
export abstract class DevicesApiServiceAbstraction {
|
||||
getKnownDevice: (email: string, deviceIdentifier: string) => Promise<boolean>;
|
||||
|
||||
getDeviceByIdentifier: (deviceIdentifier: string) => Promise<DeviceResponse>;
|
||||
|
||||
updateTrustedDeviceKeys: (
|
||||
deviceIdentifier: string,
|
||||
devicePublicKeyEncryptedUserSymKey: string,
|
||||
userSymKeyEncryptedDevicePublicKey: string,
|
||||
deviceKeyEncryptedDevicePrivateKey: string
|
||||
) => Promise<DeviceResponse>;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { DeviceType } from "../../../enums";
|
||||
import { BaseResponse } from "../../../models/response/base.response";
|
||||
|
||||
export class DeviceResponse extends BaseResponse {
|
||||
id: string;
|
||||
name: number;
|
||||
identifier: string;
|
||||
type: DeviceType;
|
||||
creationDate: string;
|
||||
encryptedUserKey: string;
|
||||
encryptedPublicKey: string;
|
||||
encryptedPrivateKey: string;
|
||||
|
||||
constructor(response: any) {
|
||||
super(response);
|
||||
this.id = this.getResponseProperty("Id");
|
||||
this.name = this.getResponseProperty("Name");
|
||||
this.identifier = this.getResponseProperty("Identifier");
|
||||
this.type = this.getResponseProperty("Type");
|
||||
this.creationDate = this.getResponseProperty("CreationDate");
|
||||
this.encryptedUserKey = this.getResponseProperty("EncryptedUserKey");
|
||||
this.encryptedPublicKey = this.getResponseProperty("EncryptedPublicKey");
|
||||
this.encryptedPrivateKey = this.getResponseProperty("EncryptedPrivateKey");
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import { ServerConfigData } from "../models/data/server-config.data";
|
||||
import { Account, AccountSettingsSettings } from "../models/domain/account";
|
||||
import { EncString } from "../models/domain/enc-string";
|
||||
import { StorageOptions } from "../models/domain/storage-options";
|
||||
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
|
||||
import { DeviceKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
|
||||
import { WindowState } from "../models/domain/window-state";
|
||||
import { GeneratedPasswordHistory } from "../tools/generator/password";
|
||||
import { SendData } from "../tools/send/models/data/send.data";
|
||||
@@ -163,6 +163,8 @@ export abstract class StateService<T extends Account = Account> {
|
||||
setDontShowIdentitiesCurrentTab: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||
getDuckDuckGoSharedKey: (options?: StorageOptions) => Promise<string>;
|
||||
setDuckDuckGoSharedKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getDeviceKey: (options?: StorageOptions) => Promise<DeviceKey | null>;
|
||||
setDeviceKey: (value: DeviceKey, options?: StorageOptions) => Promise<void>;
|
||||
getEmail: (options?: StorageOptions) => Promise<string>;
|
||||
setEmail: (value: string, options?: StorageOptions) => Promise<void>;
|
||||
getEmailVerified: (options?: StorageOptions) => Promise<boolean>;
|
||||
|
||||
Reference in New Issue
Block a user