1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-19 02:51:14 +02:00

Changed method names and added documentation

This commit is contained in:
Todd Martin 2024-07-07 16:34:36 -04:00
parent 48de33fc7a
commit 5ad0e87093
No known key found for this signature in database
GPG Key ID: 663E7AF5C839BC8F
6 changed files with 86 additions and 36 deletions

View File

@ -21,7 +21,7 @@ export default class BiometricDarwinMain implements OsBiometricService {
} }
} }
async getBiometricKey(service: string, key: string): Promise<string | null> { async getBiometricEncryptedData(service: string, key: string): Promise<string | null> {
const success = await this.authenticateBiometric(); const success = await this.authenticateBiometric();
if (!success) { if (!success) {
@ -31,7 +31,7 @@ export default class BiometricDarwinMain implements OsBiometricService {
return await passwords.getPassword(service, key); return await passwords.getPassword(service, key);
} }
async setBiometricKey(service: string, key: string, value: string): Promise<void> { async setBiometricEncryptedData(service: string, key: string, value: string): Promise<void> {
if (await this.valueUpToDate(service, key, value)) { if (await this.valueUpToDate(service, key, value)) {
return; return;
} }
@ -39,7 +39,7 @@ export default class BiometricDarwinMain implements OsBiometricService {
return await passwords.setPassword(service, key, value); return await passwords.setPassword(service, key, value);
} }
async deleteBiometricKey(service: string, key: string): Promise<void> { async deleteBiometricEncryptedData(service: string, key: string): Promise<void> {
return await passwords.deletePassword(service, key); return await passwords.deletePassword(service, key);
} }

View File

@ -9,7 +9,7 @@ export default class NoopBiometricsService implements OsBiometricService {
return false; return false;
} }
async getBiometricKey( async getBiometricEncryptedData(
service: string, service: string,
storageKey: string, storageKey: string,
clientKeyHalfB64: string, clientKeyHalfB64: string,
@ -17,7 +17,7 @@ export default class NoopBiometricsService implements OsBiometricService {
return null; return null;
} }
async setBiometricKey( async setBiometricEncryptedData(
service: string, service: string,
storageKey: string, storageKey: string,
value: string, value: string,
@ -26,7 +26,7 @@ export default class NoopBiometricsService implements OsBiometricService {
return; return;
} }
async deleteBiometricKey(service: string, key: string): Promise<void> {} async deleteBiometricEncryptedData(service: string, key: string): Promise<void> {}
async authenticateBiometric(): Promise<boolean> { async authenticateBiometric(): Promise<boolean> {
throw new Error("Not supported on this platform"); throw new Error("Not supported on this platform");

View File

@ -27,7 +27,7 @@ export default class BiometricWindowsMain implements OsBiometricService {
return await biometrics.available(); return await biometrics.available();
} }
async getBiometricKey( async getBiometricEncryptedData(
service: string, service: string,
storageKey: string, storageKey: string,
clientKeyHalfB64: string, clientKeyHalfB64: string,
@ -60,7 +60,7 @@ export default class BiometricWindowsMain implements OsBiometricService {
} }
} }
async setBiometricKey( async setBiometricEncryptedData(
service: string, service: string,
storageKey: string, storageKey: string,
value: string, value: string,
@ -89,7 +89,7 @@ export default class BiometricWindowsMain implements OsBiometricService {
); );
} }
async deleteBiometricKey(service: string, key: string): Promise<void> { async deleteBiometricEncryptedData(service: string, key: string): Promise<void> {
await passwords.deletePassword(service, key); await passwords.deletePassword(service, key);
await passwords.deletePassword(service, key + KEY_WITNESS_SUFFIX); await passwords.deletePassword(service, key + KEY_WITNESS_SUFFIX);
} }

View File

@ -1,42 +1,85 @@
export abstract class BiometricsServiceAbstraction { export abstract class BiometricsServiceAbstraction {
/**
* Checks if the OS supports biometric authentication.
* @returns True if the OS supports biometric authentication, false otherwise.
*/
abstract osSupportsBiometric(): Promise<boolean>; abstract osSupportsBiometric(): Promise<boolean>;
/**
* Checks to see if the user can authenticate using biometric authentication by ensuring that
* the OS supports biometric authentication and that the user has registered a client key half if configured.
* @param service The name of the service under which the client key half shoul be registered.
* @param storageKey The name with which the client key half shoul be registered.
* @param userId The `userID` for which the client key half should be registered.
* @returns True if the user can authenticate using biometric authentication, false otherwise.
*/
abstract canAuthBiometric({ abstract canAuthBiometric({
service, service,
key, storageKey,
userId, userId,
}: { }: {
service: string; service: string;
key: string; storageKey: string;
userId: string; userId: string;
}): Promise<boolean>; }): Promise<boolean>;
/**
* Authenticates the user using biometric authentication.
* @returns True if the user was successfully authenticated, false otherwise.
*/
abstract authenticateBiometric(): Promise<boolean>; abstract authenticateBiometric(): Promise<boolean>;
abstract getBiometricKey(service: string, key: string): Promise<string | null>; /**
abstract setBiometricKey(service: string, key: string, value: string): Promise<void>; * Retrieves data from the platform's secure storage after decrypting with a biometrically-derived key.
* @param service The name of the service under which the key is registered.
* @param storageKey The name with which the key is stored in secure storage.
* @returns The decrypted data, or null if the data could not be retrieved.
*/
abstract getBiometricEncryptedData(service: string, storageKey: string): Promise<string | null>;
/**
* Sets data in the platform's secure storage after encrypting with a biometrically-derived key.
* @param service The name of the service under which the data should be registered.
* @param storageKey The name with which the data is stored in secure storage.
* @param value The data to store.
*/
abstract setBiometricEncryptedData(
service: string,
storageKey: string,
value: string,
): Promise<void>;
/**
* Registers the client key half for encrypting and decrypting the data stored in `storageKey`. The other half is protected by the OS.
* @param service The name of the service under which the key should be registered.
* @param storageKey The name with which the data is stored in secure storage.
* @param value The client-side encryption key half to store.
*/
abstract setEncryptionKeyHalf({ abstract setEncryptionKeyHalf({
service, service,
key, storageKey,
value, value,
}: { }: {
service: string; service: string;
key: string; storageKey: string;
value: string; value: string;
}): void; }): void;
abstract deleteBiometricKey(service: string, key: string): Promise<void>; /**
* Deletes the biometrically-protected data stored under `storageKey`.
* @param service The name of the service under which the key was registered.
* @param storageKey The name with which the key was stored in secure storage.
*/
abstract deleteBiometricEncryptedData(service: string, storageKey: string): Promise<void>;
} }
export interface OsBiometricService { export interface OsBiometricService {
osSupportsBiometric(): Promise<boolean>; osSupportsBiometric(): Promise<boolean>;
authenticateBiometric(): Promise<boolean>; authenticateBiometric(): Promise<boolean>;
getBiometricKey( getBiometricEncryptedData(
service: string, service: string,
key: string, storageKey: string,
clientKeyHalfB64: string | undefined, clientKeyHalfB64: string | undefined,
): Promise<string | null>; ): Promise<string | null>;
setBiometricKey( setBiometricEncryptedData(
service: string, service: string,
key: string, storageKey: string,
value: string, value: string,
clientKeyHalfB64: string | undefined, clientKeyHalfB64: string | undefined,
): Promise<void>; ): Promise<void>;
deleteBiometricKey(service: string, key: string): Promise<void>; deleteBiometricEncryptedData(service: string, storageKey: string): Promise<void>;
} }

View File

@ -90,11 +90,11 @@ export class BiometricsService implements BiometricsServiceAbstraction {
return result; return result;
} }
async getBiometricKey(service: string, storageKey: string): Promise<string | null> { async getBiometricEncryptedData(service: string, storageKey: string): Promise<string | null> {
return await this.interruptProcessReload(async () => { return await this.interruptProcessReload(async () => {
await this.enforceClientKeyHalf(service, storageKey); await this.enforceClientKeyHalf(service, storageKey);
return await this.platformSpecificService.getBiometricKey( return await this.platformSpecificService.getBiometricEncryptedData(
service, service,
storageKey, storageKey,
this.getClientKeyHalf(service, storageKey), this.getClientKeyHalf(service, storageKey),
@ -102,10 +102,14 @@ export class BiometricsService implements BiometricsServiceAbstraction {
}); });
} }
async setBiometricKey(service: string, storageKey: string, value: string): Promise<void> { async setBiometricEncryptedData(
service: string,
storageKey: string,
value: string,
): Promise<void> {
await this.enforceClientKeyHalf(service, storageKey); await this.enforceClientKeyHalf(service, storageKey);
return await this.platformSpecificService.setBiometricKey( return await this.platformSpecificService.setBiometricEncryptedData(
service, service,
storageKey, storageKey,
value, value,
@ -113,26 +117,25 @@ export class BiometricsService implements BiometricsServiceAbstraction {
); );
} }
/** Registers the client-side encryption key half for the OS stored Biometric key. The other half is protected by the OS.*/
async setEncryptionKeyHalf({ async setEncryptionKeyHalf({
service, service,
key, storageKey,
value, value,
}: { }: {
service: string; service: string;
key: string; storageKey: string;
value: string; value: string;
}): Promise<void> { }): Promise<void> {
if (value == null) { if (value == null) {
this.clientKeyHalves.delete(this.clientKeyHalfKey(service, key)); this.clientKeyHalves.delete(this.clientKeyHalfKey(service, storageKey));
} else { } else {
this.clientKeyHalves.set(this.clientKeyHalfKey(service, key), value); this.clientKeyHalves.set(this.clientKeyHalfKey(service, storageKey), value);
} }
} }
async deleteBiometricKey(service: string, storageKey: string): Promise<void> { async deleteBiometricEncryptedData(service: string, storageKey: string): Promise<void> {
this.clientKeyHalves.delete(this.clientKeyHalfKey(service, storageKey)); this.clientKeyHalves.delete(this.clientKeyHalfKey(service, storageKey));
return await this.platformSpecificService.deleteBiometricKey(service, storageKey); return await this.platformSpecificService.deleteBiometricEncryptedData(service, storageKey);
} }
private async interruptProcessReload<T>( private async interruptProcessReload<T>(

View File

@ -93,7 +93,7 @@ export class DesktopCredentialStorageListener {
private async getPassword(serviceName: string, key: string, keySuffix: string) { private async getPassword(serviceName: string, key: string, keySuffix: string) {
let val: string; let val: string;
if (keySuffix === AuthRequiredSuffix) { if (keySuffix === AuthRequiredSuffix) {
val = (await this.biometricService.getBiometricKey(serviceName, key)) ?? null; val = (await this.biometricService.getBiometricEncryptedData(serviceName, key)) ?? null;
} else { } else {
val = await passwords.getPassword(serviceName, key); val = await passwords.getPassword(serviceName, key);
} }
@ -112,11 +112,15 @@ export class DesktopCredentialStorageListener {
const valueObj = JSON.parse(value) as BiometricKey; const valueObj = JSON.parse(value) as BiometricKey;
await this.biometricService.setEncryptionKeyHalf({ await this.biometricService.setEncryptionKeyHalf({
service: serviceName, service: serviceName,
key, storageKey: key,
value: valueObj?.clientEncKeyHalf, value: valueObj?.clientEncKeyHalf,
}); });
// Value is usually a JSON string, but we need to pass the key half as well, so we re-stringify key here. // Value is usually a JSON string, but we need to pass the key half as well, so we re-stringify key here.
await this.biometricService.setBiometricKey(serviceName, key, JSON.stringify(valueObj?.key)); await this.biometricService.setBiometricEncryptedData(
serviceName,
key,
JSON.stringify(valueObj?.key),
);
} else { } else {
await passwords.setPassword(serviceName, key, value); await passwords.setPassword(serviceName, key, value);
} }
@ -124,7 +128,7 @@ export class DesktopCredentialStorageListener {
private async deletePassword(serviceName: string, key: string, keySuffix: string) { private async deletePassword(serviceName: string, key: string, keySuffix: string) {
if (keySuffix === AuthRequiredSuffix) { if (keySuffix === AuthRequiredSuffix) {
await this.biometricService.deleteBiometricKey(serviceName, key); await this.biometricService.deleteBiometricEncryptedData(serviceName, key);
} else { } else {
await passwords.deletePassword(serviceName, key); await passwords.deletePassword(serviceName, key);
} }