1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-12 06:23:38 +00:00
This removes all bulk encryption/decryption.
This commit is contained in:
Matt Gibson
2024-12-18 13:21:15 -08:00
parent 12b698b11d
commit eb628f2d2d
15 changed files with 193 additions and 151 deletions

View File

@@ -92,6 +92,7 @@ import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platfor
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkPureClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
import {
@@ -114,10 +115,10 @@ import { ConfigApiService } from "@bitwarden/common/platform/services/config/con
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
import { BulkEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/bulk-encrypt.service.implementation";
// import { BulkEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/bulk-encrypt.service.implementation";
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
import { FallbackBulkEncryptService } from "@bitwarden/common/platform/services/cryptography/fallback-bulk-encrypt.service";
import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation";
// import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation";
import { Fido2ActiveRequestManager } from "@bitwarden/common/platform/services/fido2/fido2-active-request-manager";
import { Fido2AuthenticatorService } from "@bitwarden/common/platform/services/fido2/fido2-authenticator.service";
import { Fido2ClientService } from "@bitwarden/common/platform/services/fido2/fido2-client.service";
@@ -257,7 +258,10 @@ import { LocalBackedSessionStorageService } from "../platform/services/local-bac
import { BackgroundPlatformUtilsService } from "../platform/services/platform-utils/background-platform-utils.service";
import { BrowserPlatformUtilsService } from "../platform/services/platform-utils/browser-platform-utils.service";
import { PopupViewCacheBackgroundService } from "../platform/services/popup-view-cache-background.service";
import { BrowserSdkClientFactory } from "../platform/services/sdk/browser-sdk-client-factory";
import {
BrowserSdkClientFactory,
BrowserSdkPureClientFactory,
} from "../platform/services/sdk/browser-sdk-client-factory";
import { BackgroundTaskSchedulerService } from "../platform/services/task-scheduler/background-task-scheduler.service";
import { BackgroundMemoryStorageService } from "../platform/storage/background-memory-storage.service";
import { BrowserStorageServiceProvider } from "../platform/storage/browser-storage-service.provider";
@@ -377,6 +381,7 @@ export default class MainBackground {
themeStateService: DefaultThemeStateService;
autoSubmitLoginBackground: AutoSubmitLoginBackground;
sdkService: SdkService;
pureSdkClientFactory: SdkPureClientFactory;
cipherAuthorizationService: CipherAuthorizationService;
inlineMenuFieldQualificationService: InlineMenuFieldQualificationService;
@@ -494,13 +499,19 @@ export default class MainBackground {
return derivedKey;
});
this.pureSdkClientFactory = new BrowserSdkPureClientFactory(this.logService);
this.largeObjectMemoryStorageForStateProviders = new LocalBackedSessionStorageService(
sessionKey,
this.storageService,
// For local backed session storage, we expect that the encrypted data on disk will persist longer than the encryption key in memory
// and failures to decrypt because of that are completely expected. For this reason, we pass in `false` to the `EncryptServiceImplementation`
// so that MAC failures are not logged.
new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false),
new EncryptServiceImplementation(
this.pureSdkClientFactory,
this.cryptoFunctionService,
this.logService,
false,
),
this.platformUtilsService,
this.logService,
);
@@ -536,12 +547,18 @@ export default class MainBackground {
);
this.encryptService = BrowserApi.isManifestVersion(2)
? new MultithreadEncryptServiceImplementation(
? new EncryptServiceImplementation(
this.pureSdkClientFactory,
this.cryptoFunctionService,
this.logService,
true,
)
: new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, true);
: new EncryptServiceImplementation(
this.pureSdkClientFactory,
this.cryptoFunctionService,
this.logService,
true,
);
this.singleUserStateProvider = new DefaultSingleUserStateProvider(
storageServiceProvider,
@@ -1287,14 +1304,14 @@ export default class MainBackground {
this.syncServiceListener?.listener$().subscribe();
await this.autoSubmitLoginBackground.init();
if (
BrowserApi.isManifestVersion(2) &&
(await this.configService.getFeatureFlag(FeatureFlag.PM4154_BulkEncryptionService))
) {
await this.bulkEncryptService.setFeatureFlagEncryptService(
new BulkEncryptServiceImplementation(this.cryptoFunctionService, this.logService),
);
}
// if (
// BrowserApi.isManifestVersion(2) &&
// (await this.configService.getFeatureFlag(FeatureFlag.PM4154_BulkEncryptionService))
// ) {
// await this.bulkEncryptService.setFeatureFlagEncryptService(
// new BulkEncryptServiceImplementation(this.cryptoFunctionService, this.logService),
// );
// }
// If the user is logged out, switch to the next account
const active = await firstValueFrom(this.accountService.activeAccount$);

View File

@@ -1,9 +1,12 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import {
SdkClientFactory,
SdkPureClientFactory,
} from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { RecoverableSDKError } from "@bitwarden/common/platform/services/sdk/default-sdk.service";
import type { BitwardenClient } from "@bitwarden/sdk-internal";
import type { BitwardenClient, BitwardenPure } from "@bitwarden/sdk-internal";
import { BrowserApi } from "../../browser/browser-api";
@@ -60,6 +63,32 @@ async function load() {
}
}
export class BrowserSdkPureClientFactory implements SdkPureClientFactory {
constructor(private readonly logService: LogService) {}
async createPureSdkClient(): Promise<BitwardenPure> {
const startTime = performance.now();
try {
await loadWithTimeout();
} catch (error) {
throw new Error(`Failed to load: ${error.message}`);
}
const endTime = performance.now();
const elapsed = Math.round((endTime - startTime) / 1000);
const instance = (globalThis as any).init_pure();
this.logService.info("WASM pure SDK loaded in", Math.round(endTime - startTime), "ms");
// If it takes 3 seconds or more to load, we want to capture it.
if (elapsed >= 3) {
throw new RecoverableSDKError(instance, elapsed);
}
return instance;
}
}
/**
* SDK client factory with a js fallback for when WASM is not supported.
*

View File

@@ -1,6 +1,11 @@
import * as sdk from "@bitwarden/sdk-internal";
import * as wasm from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm.js";
(globalThis as any).init_pure = () => {
(sdk as any).init(wasm);
return new sdk.BitwardenPure();
};
(globalThis as any).init_sdk = (...args: ConstructorParameters<typeof sdk.BitwardenClient>) => {
(sdk as any).init(wasm);

View File

@@ -1,6 +1,11 @@
import * as sdk from "@bitwarden/sdk-internal";
import * as wasm from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm";
(globalThis as any).init_pure = () => {
(sdk as any).init(wasm);
return new sdk.BitwardenPure();
};
(globalThis as any).init_sdk = (...args: ConstructorParameters<typeof sdk.BitwardenClient>) => {
(sdk as any).init(wasm);

View File

@@ -70,7 +70,10 @@ import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/ke
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import {
SdkClientFactory,
SdkPureClientFactory,
} from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import {
AbstractStorageService,
@@ -83,7 +86,10 @@ import { flagEnabled } from "@bitwarden/common/platform/misc/flags";
import { TaskSchedulerService } from "@bitwarden/common/platform/scheduling";
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
import {
NoopSdkClientFactory,
NoopSdkPureClientFactory,
} from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
import { WebCryptoFunctionService } from "@bitwarden/common/platform/services/web-crypto-function.service";
import {
@@ -144,7 +150,10 @@ import BrowserMemoryStorageService from "../../platform/services/browser-memory-
import { BrowserScriptInjectorService } from "../../platform/services/browser-script-injector.service";
import I18nService from "../../platform/services/i18n.service";
import { ForegroundPlatformUtilsService } from "../../platform/services/platform-utils/foreground-platform-utils.service";
import { BrowserSdkClientFactory } from "../../platform/services/sdk/browser-sdk-client-factory";
import {
BrowserSdkClientFactory,
BrowserSdkPureClientFactory,
} from "../../platform/services/sdk/browser-sdk-client-factory";
import { ForegroundTaskSchedulerService } from "../../platform/services/task-scheduler/foreground-task-scheduler.service";
import { BrowserStorageServiceProvider } from "../../platform/storage/browser-storage-service.provider";
import { ForegroundMemoryStorageService } from "../../platform/storage/foreground-memory-storage.service";
@@ -584,6 +593,14 @@ const safeProviders: SafeProvider[] = [
flagEnabled("sdk") ? new BrowserSdkClientFactory(logService) : new NoopSdkClientFactory(),
deps: [LogService],
}),
safeProvider({
provide: SdkPureClientFactory,
useFactory: (logService) =>
flagEnabled("sdk")
? new BrowserSdkPureClientFactory(logService)
: new NoopSdkPureClientFactory(),
deps: [LogService],
}),
safeProvider({
provide: LoginEmailService,
useClass: LoginEmailService,

View File

@@ -66,7 +66,10 @@ import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platfor
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import {
SdkClientFactory,
SdkPureClientFactory,
} from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
import { ThemeType } from "@bitwarden/common/platform/enums";
import { AppIdService as DefaultAppIdService } from "@bitwarden/common/platform/services/app-id.service";
@@ -74,7 +77,10 @@ import { MemoryStorageService } from "@bitwarden/common/platform/services/memory
// eslint-disable-next-line import/no-restricted-paths -- Implementation for memory storage
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
import {
NoopSdkClientFactory,
NoopSdkPureClientFactory,
} from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider";
/* eslint-disable import/no-restricted-paths -- Implementation for memory storage */
import { GlobalStateProvider, StateProvider } from "@bitwarden/common/platform/state";
@@ -110,7 +116,7 @@ import { WebProcessReloadService } from "../key-management/services/web-process-
import { WebBiometricsService } from "../key-management/web-biometric.service";
import { WebEnvironmentService } from "../platform/web-environment.service";
import { WebMigrationRunner } from "../platform/web-migration-runner";
import { WebSdkClientFactory } from "../platform/web-sdk-client-factory";
import { WebSdkClientFactory, WebSdkPureClientFactory } from "../platform/web-sdk-client-factory";
import { WebStorageServiceProvider } from "../platform/web-storage-service.provider";
import { EventService } from "./event.service";
@@ -293,6 +299,11 @@ const safeProviders: SafeProvider[] = [
useClass: flagEnabled("sdk") ? WebSdkClientFactory : NoopSdkClientFactory,
deps: [],
}),
safeProvider({
provide: SdkPureClientFactory,
useClass: flagEnabled("sdk") ? WebSdkPureClientFactory : NoopSdkPureClientFactory,
deps: [],
}),
safeProvider({
provide: ProcessReloadServiceAbstraction,
useClass: WebProcessReloadService,

View File

@@ -1,6 +1,19 @@
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import {
SdkClientFactory,
SdkPureClientFactory,
} from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import * as sdk from "@bitwarden/sdk-internal";
export class WebSdkPureClientFactory implements SdkPureClientFactory {
async createPureSdkClient(): Promise<sdk.BitwardenPure> {
const module = await load();
(sdk as any).init(module);
return Promise.resolve(new sdk.BitwardenPure());
}
}
/**
* SDK client factory with a js fallback for when WASM is not supported.
*/

View File

@@ -160,7 +160,10 @@ import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwar
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import {
SdkClientFactory,
SdkPureClientFactory,
} from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
@@ -181,6 +184,8 @@ import { ConfigApiService } from "@bitwarden/common/platform/services/config/con
import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service";
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
import { BulkEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/bulk-encrypt.service.implementation";
import { FallbackBulkEncryptService } from "@bitwarden/common/platform/services/cryptography/fallback-bulk-encrypt.service";
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation";
import { DefaultBroadcasterService } from "@bitwarden/common/platform/services/default-broadcaster.service";
import { DefaultEnvironmentService } from "@bitwarden/common/platform/services/default-environment.service";
@@ -886,13 +891,13 @@ const safeProviders: SafeProvider[] = [
}),
safeProvider({
provide: EncryptService,
useClass: MultithreadEncryptServiceImplementation,
deps: [CryptoFunctionServiceAbstraction, LogService, LOG_MAC_FAILURES],
useClass: EncryptServiceImplementation,
deps: [SdkPureClientFactory, CryptoFunctionServiceAbstraction, LogService, LOG_MAC_FAILURES],
}),
safeProvider({
provide: BulkEncryptService,
useClass: BulkEncryptServiceImplementation,
deps: [CryptoFunctionServiceAbstraction, LogService],
useClass: FallbackBulkEncryptService,
deps: [EncryptService],
}),
safeProvider({
provide: EventUploadServiceAbstraction,

View File

@@ -1,4 +1,4 @@
import type { BitwardenClient } from "@bitwarden/sdk-internal";
import type { BitwardenClient, BitwardenPure } from "@bitwarden/sdk-internal";
/**
* Factory for creating SDK clients.
@@ -8,3 +8,7 @@ export abstract class SdkClientFactory {
...args: ConstructorParameters<typeof BitwardenClient>
): Promise<BitwardenClient>;
}
export abstract class SdkPureClientFactory {
abstract createPureSdkClient(): Promise<BitwardenPure>;
}

View File

@@ -12,7 +12,7 @@ import { SymmetricCryptoKey } from "./symmetric-crypto-key";
export const DECRYPT_ERROR = "[error: cannot decrypt]";
export class EncString implements Encrypted {
encryptedString?: EncryptedString;
encryptedString: EncryptedString;
encryptionType?: EncryptionType;
decryptedValue?: string;
data?: string;

View File

@@ -1,10 +1,14 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
// eslint-disable-next-line no-restricted-imports -- TODO MDG: fix this
import { SdkPureClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory";
import { Utils } from "../../../platform/misc/utils";
import { CryptoFunctionService } from "../../abstractions/crypto-function.service";
import { EncryptService } from "../../abstractions/encrypt.service";
import { LogService } from "../../abstractions/log.service";
import { EncryptionType, encryptionTypeToString as encryptionTypeName } from "../../enums";
import { EncryptionType } from "../../enums";
import { Decryptable } from "../../interfaces/decryptable.interface";
import { Encrypted } from "../../interfaces/encrypted";
import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface";
@@ -15,6 +19,7 @@ import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
export class EncryptServiceImplementation implements EncryptService {
constructor(
protected readonly sdkPureClientFactory: SdkPureClientFactory,
protected cryptoFunctionService: CryptoFunctionService,
protected logService: LogService,
protected logMacFailures: boolean,
@@ -76,56 +81,10 @@ export class EncryptServiceImplementation implements EncryptService {
key = this.resolveLegacyKey(key, encString);
// DO NOT REMOVE OR MOVE. This prevents downgrade to mac-less CBC, which would compromise integrity and confidentiality.
if (key.macKey != null && encString?.mac == null) {
this.logService.error(
"[Encrypt service] Key has mac key but payload is missing mac bytes. Key type " +
encryptionTypeName(key.encType) +
"Payload type " +
encryptionTypeName(encString.encryptionType),
"Decrypt context: " + decryptContext,
);
return null;
}
const pure = await this.sdkPureClientFactory.createPureSdkClient();
const decrypted = pure.crypto().symmetric_decrypt(encString.encryptedString, key.keyB64);
if (key.encType !== encString.encryptionType) {
this.logService.error(
"[Encrypt service] Key encryption type does not match payload encryption type. Key type " +
encryptionTypeName(key.encType) +
"Payload type " +
encryptionTypeName(encString.encryptionType),
"Decrypt context: " + decryptContext,
);
return null;
}
const fastParams = this.cryptoFunctionService.aesDecryptFastParameters(
encString.data,
encString.iv,
encString.mac,
key,
);
if (fastParams.macKey != null && fastParams.mac != null) {
const computedMac = await this.cryptoFunctionService.hmacFast(
fastParams.macData,
fastParams.macKey,
"sha256",
);
const macsEqual = await this.cryptoFunctionService.compareFast(fastParams.mac, computedMac);
if (!macsEqual) {
this.logMacFailed(
"[Encrypt service] MAC comparison failed. Key or payload has changed. Key type " +
encryptionTypeName(key.encType) +
"Payload type " +
encryptionTypeName(encString.encryptionType) +
" Decrypt context: " +
decryptContext,
);
return null;
}
}
return await this.cryptoFunctionService.aesDecryptFast(fastParams, "cbc");
return decrypted;
}
async decryptToBytes(encThing: Encrypted, key: SymmetricCryptoKey): Promise<Uint8Array> {
@@ -139,64 +98,18 @@ export class EncryptServiceImplementation implements EncryptService {
key = this.resolveLegacyKey(key, encThing);
// DO NOT REMOVE OR MOVE. This prevents downgrade to mac-less CBC, which would compromise integrity and confidentiality.
if (key.macKey != null && encThing.macBytes == null) {
this.logService.error(
"[Encrypt service] Key has mac key but payload is missing mac bytes. Key type " +
encryptionTypeName(key.encType) +
" Payload type " +
encryptionTypeName(encThing.encryptionType),
);
return null;
}
if (key.encType !== encThing.encryptionType) {
this.logService.error(
"[Encrypt service] Key encryption type does not match payload encryption type. Key type " +
encryptionTypeName(key.encType) +
" Payload type " +
encryptionTypeName(encThing.encryptionType),
);
return null;
}
if (key.macKey != null && encThing.macBytes != null) {
const macData = new Uint8Array(encThing.ivBytes.byteLength + encThing.dataBytes.byteLength);
macData.set(new Uint8Array(encThing.ivBytes), 0);
macData.set(new Uint8Array(encThing.dataBytes), encThing.ivBytes.byteLength);
const computedMac = await this.cryptoFunctionService.hmac(macData, key.macKey, "sha256");
if (computedMac === null) {
this.logMacFailed(
"[Encrypt service] Failed to compute MAC." +
" Key type " +
encryptionTypeName(key.encType) +
" Payload type " +
encryptionTypeName(encThing.encryptionType),
);
return null;
}
const macsMatch = await this.cryptoFunctionService.compare(encThing.macBytes, computedMac);
if (!macsMatch) {
this.logMacFailed(
"[Encrypt service] MAC comparison failed. Key or payload has changed." +
" Key type " +
encryptionTypeName(key.encType) +
" Payload type " +
encryptionTypeName(encThing.encryptionType),
);
return null;
}
}
const result = await this.cryptoFunctionService.aesDecrypt(
encThing.dataBytes,
encThing.ivBytes,
key.encKey,
"cbc",
const pure = await this.sdkPureClientFactory.createPureSdkClient();
const encString = new EncString(
encThing.encryptionType,
Utils.fromBufferToB64(encThing.dataBytes),
Utils.fromBufferToB64(encThing.ivBytes),
Utils.fromBufferToB64(encThing.macBytes),
);
const decrypted = pure
.crypto()
.symmetric_decrypt_to_bytes(encString.encryptedString, key.keyB64);
return result ?? null;
return decrypted ?? null;
}
async rsaEncrypt(data: Uint8Array, publicKey: Uint8Array): Promise<EncString> {
@@ -262,18 +175,18 @@ export class EncryptServiceImplementation implements EncryptService {
}
private async aesEncrypt(data: Uint8Array, key: SymmetricCryptoKey): Promise<EncryptedObject> {
const pure = await this.sdkPureClientFactory.createPureSdkClient();
const encString = new EncString(
pure.crypto().symmetric_encrypt(Utils.fromBufferToUtf8(data), key.keyB64),
);
const obj = new EncryptedObject();
obj.key = key;
obj.iv = await this.cryptoFunctionService.randomBytes(16);
obj.data = await this.cryptoFunctionService.aesEncrypt(data, obj.iv, obj.key.encKey);
obj.iv = encString.ivBytes;
obj.data = encString.dataBytes;
if (obj.key.macKey != null) {
const macData = new Uint8Array(obj.iv.byteLength + obj.data.byteLength);
macData.set(new Uint8Array(obj.iv), 0);
macData.set(new Uint8Array(obj.data), obj.iv.byteLength);
obj.mac = await this.cryptoFunctionService.hmac(macData, obj.key.macKey, "sha256");
obj.mac = encString.macBytes;
}
return obj;
}

View File

@@ -2,6 +2,9 @@
// @ts-strict-ignore
import { Jsonify } from "type-fest";
// eslint-disable-next-line no-restricted-imports -- TODO MDG: this is a bug in the restricted import rule
import { DefaultSdkPureClientFactory } from "@bitwarden/common/platform/services/sdk/default-sdk-client-factory";
import { Decryptable } from "../../interfaces/decryptable.interface";
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
import { ConsoleLogService } from "../console-log.service";
@@ -22,7 +25,13 @@ let encryptService: EncryptServiceImplementation;
export function init() {
const cryptoFunctionService = new WebCryptoFunctionService(self);
const logService = new ConsoleLogService(false);
encryptService = new EncryptServiceImplementation(cryptoFunctionService, logService, true);
const pureSdkFactory = new DefaultSdkPureClientFactory();
encryptService = new EncryptServiceImplementation(
pureSdkFactory,
cryptoFunctionService,
logService,
true,
);
const bitwardenContainerService = new ContainerService(null, encryptService);
bitwardenContainerService.attachToGlobal(self);

View File

@@ -22,11 +22,11 @@ export class FallbackBulkEncryptService implements BulkEncryptService {
items: Decryptable<T>[],
key: SymmetricCryptoKey,
): Promise<T[]> {
if (this.featureFlagEncryptService != null) {
return await this.featureFlagEncryptService.decryptItems(items, key);
} else {
return await this.encryptService.decryptItems(items, key);
}
return await this.encryptService.decryptItems(items, key);
// if (this.featureFlagEncryptService != null) {
// return await this.featureFlagEncryptService.decryptItems(items, key);
// } else {
// }
}
async setFeatureFlagEncryptService(featureFlagEncryptService: BulkEncryptService) {

View File

@@ -1,7 +1,15 @@
import * as sdk from "@bitwarden/sdk-internal";
import * as module from "@bitwarden/sdk-internal/bitwarden_wasm_internal_bg.wasm";
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
import { SdkClientFactory, SdkPureClientFactory } from "../../abstractions/sdk/sdk-client-factory";
export class DefaultSdkPureClientFactory implements SdkPureClientFactory {
async createPureSdkClient(): Promise<sdk.BitwardenPure> {
(sdk as any).init(module);
return Promise.resolve(new sdk.BitwardenPure());
}
}
/**
* Directly imports the Bitwarden SDK and initializes it.

View File

@@ -1,6 +1,12 @@
import type { BitwardenClient } from "@bitwarden/sdk-internal";
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
import { SdkClientFactory, SdkPureClientFactory } from "../../abstractions/sdk/sdk-client-factory";
export class NoopSdkPureClientFactory implements SdkPureClientFactory {
createPureSdkClient(): Promise<never> {
return Promise.reject(new Error("SDK not available"));
}
}
/**
* Noop SDK client factory.