1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 07:43:35 +00:00

[PM-22623] Remove most TS encryption code, remove service workers (#15153)

* Add new encrypt service functions

* Undo changes

* Cleanup

* Fix build

* Fix comments

* Switch encrypt service to use SDK functions

* Move remaining functions to PureCrypto

* Tests

* Increase test coverage

* Enforce sdk.ready and drop unused codepaths

* Delete unused code

* Delete unused code

* Delete more code

* Add forgotten sdk init logic

* Fix build

* Fix cli

* Fix tests

* Fix build

* Fix browser build

* Remove compare and add more comments / warnings

* Run prettier

* Remove unused feature flags

* Add hazmat warning to aesDecrypt

* Fix build

* Fix comment

* Fix test
This commit is contained in:
Bernd Schoolmann
2025-07-30 15:50:00 +02:00
committed by GitHub
parent 2e6977e98c
commit 5dae5267d9
39 changed files with 77 additions and 706 deletions

View File

@@ -73,10 +73,7 @@ import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service";
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { BulkEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/bulk-encrypt.service.implementation";
import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation";
import { FallbackBulkEncryptService } from "@bitwarden/common/key-management/crypto/services/fallback-bulk-encrypt.service";
import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/multithread-encrypt.service.implementation";
import { WebCryptoFunctionService } from "@bitwarden/common/key-management/crypto/services/web-crypto-function.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation";
@@ -363,7 +360,6 @@ export default class MainBackground {
vaultFilterService: VaultFilterService;
usernameGenerationService: UsernameGenerationServiceAbstraction;
encryptService: EncryptService;
bulkEncryptService: FallbackBulkEncryptService;
folderApiService: FolderApiServiceAbstraction;
policyApiService: PolicyApiServiceAbstraction;
sendApiService: SendApiServiceAbstraction;
@@ -577,13 +573,11 @@ export default class MainBackground {
storageServiceProvider,
);
this.encryptService = BrowserApi.isManifestVersion(2)
? new MultithreadEncryptServiceImplementation(
this.cryptoFunctionService,
this.logService,
true,
)
: new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, true);
this.encryptService = new EncryptServiceImplementation(
this.cryptoFunctionService,
this.logService,
true,
);
this.singleUserStateProvider = new DefaultSingleUserStateProvider(
storageServiceProvider,
@@ -883,8 +877,6 @@ export default class MainBackground {
this.themeStateService = new DefaultThemeStateService(this.globalStateProvider);
this.bulkEncryptService = new FallbackBulkEncryptService(this.encryptService);
this.cipherEncryptionService = new DefaultCipherEncryptionService(
this.sdkService,
this.logService,
@@ -899,7 +891,6 @@ export default class MainBackground {
this.stateService,
this.autofillSettingsService,
this.encryptService,
this.bulkEncryptService,
this.cipherFileUploadService,
this.configService,
this.stateProvider,
@@ -1400,13 +1391,6 @@ export default class MainBackground {
// Only the "true" background should run migrations
await this.stateService.init({ runMigrations: true });
this.configService.serverConfig$.subscribe((newConfig) => {
if (newConfig != null) {
this.encryptService.onServerConfigChange(newConfig);
this.bulkEncryptService.onServerConfigChange(newConfig);
}
});
// This is here instead of in in the InitService b/c we don't plan for
// side effects to run in the Browser InitService.
const accounts = await firstValueFrom(this.accountService.accounts$);
@@ -1439,15 +1423,6 @@ 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 the user is logged out, switch to the next account
const active = await firstValueFrom(this.accountService.activeAccount$);
if (active != null) {

View File

@@ -3,9 +3,6 @@ import { inject, Inject, Injectable } from "@angular/core";
import { AbstractThemingService } from "@bitwarden/angular/platform/services/theming/theming.service.abstraction";
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -30,9 +27,6 @@ export class InitService {
private themingService: AbstractThemingService,
private sdkLoadService: SdkLoadService,
private viewCacheService: PopupViewCacheService,
private configService: ConfigService,
private encryptService: EncryptService,
private bulkEncryptService: BulkEncryptService,
@Inject(DOCUMENT) private document: Document,
) {}
@@ -40,12 +34,6 @@ export class InitService {
return async () => {
await this.sdkLoadService.loadAndInit();
await this.stateService.init({ runMigrations: false }); // Browser background is responsible for migrations
this.configService.serverConfig$.subscribe((newConfig) => {
if (newConfig != null) {
this.encryptService.onServerConfigChange(newConfig);
this.bulkEncryptService.onServerConfigChange(newConfig);
}
});
await this.i18nService.init();
this.twoFactorService.init();
await this.viewCacheService.init();

View File

@@ -3,7 +3,6 @@
"include": [
"src",
"../../libs/common/src/autofill/constants",
"../../libs/common/custom-matchers.d.ts",
"../../libs/common/src/key-management/crypto/services/encrypt.worker.ts"
"../../libs/common/custom-matchers.d.ts"
]
}

View File

@@ -199,7 +199,6 @@ const mainConfig = {
"./src/autofill/overlay/inline-menu/pages/list/bootstrap-autofill-inline-menu-list.ts",
"overlay/menu":
"./src/autofill/overlay/inline-menu/pages/menu-container/bootstrap-autofill-inline-menu-container.ts",
"encrypt-worker": "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts",
"content/send-on-installed-message": "./src/vault/content/send-on-installed-message.ts",
"content/send-popup-open-message": "./src/vault/content/send-popup-open-message.ts",
},

View File

@@ -62,7 +62,6 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
import { ClientType } from "@bitwarden/common/enums";
import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation";
import { FallbackBulkEncryptService } from "@bitwarden/common/key-management/crypto/services/fallback-bulk-encrypt.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation";
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/services/key-connector.service";
@@ -290,7 +289,6 @@ export class ServiceContainer {
cipherAuthorizationService: CipherAuthorizationService;
ssoUrlService: SsoUrlService;
masterPasswordApiService: MasterPasswordApiServiceAbstraction;
bulkEncryptService: FallbackBulkEncryptService;
cipherEncryptionService: CipherEncryptionService;
restrictedItemTypesService: RestrictedItemTypesService;
cliRestrictedItemTypesService: CliRestrictedItemTypesService;
@@ -325,7 +323,6 @@ export class ServiceContainer {
this.logService,
true,
);
this.bulkEncryptService = new FallbackBulkEncryptService(this.encryptService);
this.storageService = new LowdbStorageService(this.logService, null, p, false, true);
this.secureStorageService = new NodeEnvSecureStorageService(
this.storageService,
@@ -719,7 +716,6 @@ export class ServiceContainer {
this.stateService,
this.autofillSettingsService,
this.encryptService,
this.bulkEncryptService,
this.cipherFileUploadService,
this.configService,
this.stateProvider,
@@ -921,12 +917,6 @@ export class ServiceContainer {
await this.sdkLoadService.loadAndInit();
await this.storageService.init();
await this.stateService.init();
this.configService.serverConfig$.subscribe((newConfig) => {
if (newConfig != null) {
this.encryptService.onServerConfigChange(newConfig);
this.bulkEncryptService.onServerConfigChange(newConfig);
}
});
this.containerService.attachToGlobal(global);
await this.i18nService.init();
this.twoFactorService.init();

View File

@@ -7,10 +7,8 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
@@ -53,8 +51,6 @@ export class InitService {
private autofillService: DesktopAutofillService,
private autotypeService: DesktopAutotypeService,
private sdkLoadService: SdkLoadService,
private configService: ConfigService,
private bulkEncryptService: BulkEncryptService,
@Inject(DOCUMENT) private document: Document,
) {}
@@ -65,13 +61,6 @@ export class InitService {
this.nativeMessagingService.init();
await this.stateService.init({ runMigrations: false }); // Desktop will run them in main process
this.configService.serverConfig$.subscribe((newConfig) => {
if (newConfig != null) {
this.encryptService.onServerConfigChange(newConfig);
this.bulkEncryptService.onServerConfigChange(newConfig);
}
});
const accounts = await firstValueFrom(this.accountService.accounts$);
const setUserKeyInMemoryPromises = [];
for (const userId of Object.keys(accounts) as UserId[]) {

View File

@@ -90,8 +90,10 @@ describe("BiometricMessageHandlerService", () => {
reloadProcess: jest.fn(),
},
};
cryptoFunctionService.rsaEncrypt.mockResolvedValue(Utils.fromUtf8ToArray("encrypted"));
cryptoFunctionService.randomBytes.mockResolvedValue(new Uint8Array(64) as CsprngArray);
cryptoFunctionService.rsaEncrypt.mockResolvedValue(
Utils.fromUtf8ToArray("encrypted") as CsprngArray,
);
service = new BiometricMessageHandlerService(
cryptoFunctionService,

View File

@@ -3,6 +3,6 @@
"angularCompilerOptions": {
"strictTemplates": true
},
"include": ["src", "../../libs/common/src/key-management/crypto/services/encrypt.worker.ts"],
"include": ["src"],
"exclude": ["src/**/*.spec.ts"]
}

View File

@@ -4,12 +4,10 @@ import { MockProxy } from "jest-mock-extended";
import mock from "jest-mock-extended/lib/Mock";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { UserKeyResponse } from "@bitwarden/common/models/response/user-key.response";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { EncryptionType } from "@bitwarden/common/platform/enums";
import { Utils } from "@bitwarden/common/platform/misc/utils";
@@ -38,11 +36,9 @@ describe("EmergencyAccessService", () => {
let apiService: MockProxy<ApiService>;
let keyService: MockProxy<KeyService>;
let encryptService: MockProxy<EncryptService>;
let bulkEncryptService: MockProxy<BulkEncryptService>;
let cipherService: MockProxy<CipherService>;
let logService: MockProxy<LogService>;
let emergencyAccessService: EmergencyAccessService;
let configService: ConfigService;
const mockNewUserKey = new SymmetricCryptoKey(new Uint8Array(64)) as UserKey;
const mockTrustedPublicKeys = [Utils.fromUtf8ToArray("trustedPublicKey")];
@@ -52,7 +48,6 @@ describe("EmergencyAccessService", () => {
apiService = mock<ApiService>();
keyService = mock<KeyService>();
encryptService = mock<EncryptService>();
bulkEncryptService = mock<BulkEncryptService>();
cipherService = mock<CipherService>();
logService = mock<LogService>();
@@ -61,10 +56,8 @@ describe("EmergencyAccessService", () => {
apiService,
keyService,
encryptService,
bulkEncryptService,
cipherService,
logService,
configService,
);
});

View File

@@ -3,14 +3,11 @@ import { Injectable } from "@angular/core";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyData } from "@bitwarden/common/admin-console/models/data/policy.data";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import {
EncryptedString,
EncString,
} from "@bitwarden/common/key-management/crypto/models/enc-string";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { UserId } from "@bitwarden/common/types/guid";
@@ -59,10 +56,8 @@ export class EmergencyAccessService
private apiService: ApiService,
private keyService: KeyService,
private encryptService: EncryptService,
private bulkEncryptService: BulkEncryptService,
private cipherService: CipherService,
private logService: LogService,
private configService: ConfigService,
) {}
/**
@@ -258,17 +253,8 @@ export class EmergencyAccessService
)) as UserKey;
let ciphers: CipherView[] = [];
if (await this.configService.getFeatureFlag(FeatureFlag.PM4154_BulkEncryptionService)) {
ciphers = await this.bulkEncryptService.decryptItems(
response.ciphers.map((c) => new Cipher(c)),
grantorUserKey,
);
} else {
ciphers = await this.encryptService.decryptItems(
response.ciphers.map((c) => new Cipher(c)),
grantorUserKey,
);
}
const ciphersEncrypted = response.ciphers.map((c) => new Cipher(c));
ciphers = await Promise.all(ciphersEncrypted.map(async (c) => c.decrypt(grantorUserKey)));
return ciphers.sort(this.cipherService.getLocaleSortingFunction());
}

View File

@@ -7,10 +7,8 @@ import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abstractions/bulk-encrypt.service";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
@@ -42,8 +40,6 @@ export class InitService {
private versionService: VersionService,
private ipcService: IpcService,
private sdkLoadService: SdkLoadService,
private configService: ConfigService,
private bulkEncryptService: BulkEncryptService,
private taskService: TaskService,
@Inject(DOCUMENT) private document: Document,
) {}
@@ -53,13 +49,6 @@ export class InitService {
await this.sdkLoadService.loadAndInit();
await this.stateService.init();
this.configService.serverConfig$.subscribe((newConfig) => {
if (newConfig != null) {
this.encryptService.onServerConfigChange(newConfig);
this.bulkEncryptService.onServerConfigChange(newConfig);
}
});
const activeAccount = await firstValueFrom(this.accountService.activeAccount$);
if (activeAccount) {
// If there is an active account, we must await the process of setting the user key in memory

View File

@@ -63,7 +63,7 @@ export class SendAccessFileComponent {
try {
const encBuf = await EncArrayBuffer.fromResponse(response);
const decBuf = await this.encryptService.decryptToBytes(encBuf, this.decKey);
const decBuf = await this.encryptService.decryptFileData(encBuf, this.decKey);
this.fileDownloadService.download({
fileName: this.send.file.fileName,
blobData: decBuf,

View File

@@ -1,8 +1,5 @@
{
"extends": "./tsconfig.json",
"files": ["src/polyfills.ts", "src/main.ts", "src/theme.ts"],
"include": [
"src/connectors/*.ts",
"../../libs/common/src/key-management/crypto/services/encrypt.worker.ts"
]
"include": ["src/connectors/*.ts"]
}

View File

@@ -4,10 +4,5 @@
"strictTemplates": true
},
"files": ["src/polyfills.ts", "src/main.ts", "src/theme.ts"],
"include": [
"src/connectors/*.ts",
"src/**/*.stories.ts",
"src/**/*.spec.ts",
"../../libs/common/src/key-management/crypto/services/encrypt.worker.ts"
]
"include": ["src/connectors/*.ts", "src/**/*.stories.ts", "src/**/*.spec.ts"]
}