From 8a936c953183b604b801437187312365926a86f2 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 13 Jan 2025 12:06:14 +0100 Subject: [PATCH 1/2] Make argon2 default for registration --- apps/desktop/src/auth/register.component.ts | 3 +++ .../register-form/register-form.component.ts | 3 +++ .../src/auth/components/register.component.ts | 18 ++++++++++++++++-- .../input-password/input-password.component.ts | 15 +++++++++++++-- .../input-password/password-input-result.ts | 4 ++-- .../default-set-password-jit.service.ts | 4 ++-- .../set-password-jit.service.abstraction.ts | 4 ++-- libs/common/src/enums/feature-flag.enum.ts | 2 ++ libs/key-management/src/index.ts | 1 + libs/key-management/src/models/kdf-config.ts | 13 +++++++++++++ 10 files changed, 57 insertions(+), 10 deletions(-) diff --git a/apps/desktop/src/auth/register.component.ts b/apps/desktop/src/auth/register.component.ts index f3df5b88476..b6cc9be3581 100644 --- a/apps/desktop/src/auth/register.component.ts +++ b/apps/desktop/src/auth/register.component.ts @@ -8,6 +8,7 @@ import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -42,6 +43,7 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit, auditService: AuditService, dialogService: DialogService, toastService: ToastService, + configService: ConfigService, ) { super( formValidationErrorService, @@ -59,6 +61,7 @@ export class RegisterComponent extends BaseRegisterComponent implements OnInit, auditService, dialogService, toastService, + configService, ); } diff --git a/apps/web/src/app/auth/register-form/register-form.component.ts b/apps/web/src/app/auth/register-form/register-form.component.ts index 7d3e6dbd00e..f497dffa7ac 100644 --- a/apps/web/src/app/auth/register-form/register-form.component.ts +++ b/apps/web/src/app/auth/register-form/register-form.component.ts @@ -13,6 +13,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request"; import { RegisterRequest } from "@bitwarden/common/models/request/register.request"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -55,6 +56,7 @@ export class RegisterFormComponent extends BaseRegisterComponent implements OnIn dialogService: DialogService, acceptOrgInviteService: AcceptOrganizationInviteService, toastService: ToastService, + configService: ConfigService, ) { super( formValidationErrorService, @@ -72,6 +74,7 @@ export class RegisterFormComponent extends BaseRegisterComponent implements OnIn auditService, dialogService, toastService, + configService, ); this.modifyRegisterRequest = async (request: RegisterRequest) => { // Org invites are deep linked. Non-existent accounts are redirected to the register page. diff --git a/libs/angular/src/auth/components/register.component.ts b/libs/angular/src/auth/components/register.component.ts index 279294f4c06..19f6dee2e4b 100644 --- a/libs/angular/src/auth/components/register.component.ts +++ b/libs/angular/src/auth/components/register.component.ts @@ -8,9 +8,11 @@ import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitw import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { RegisterResponse } from "@bitwarden/common/auth/models/response/register.response"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request"; import { RegisterRequest } from "@bitwarden/common/models/request/register.request"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -19,7 +21,12 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { Utils } from "@bitwarden/common/platform/misc/utils"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; +import { + DEFAULT_KDF_CONFIG, + KdfConfig, + KeyService, + NEW_ARGON2_DEFAULT_KDF_CONFIG, +} from "@bitwarden/key-management"; import { AllValidationErrors, @@ -99,6 +106,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn protected auditService: AuditService, protected dialogService: DialogService, protected toastService: ToastService, + private configService: ConfigService, ) { super(environmentService, i18nService, platformUtilsService, toastService); this.showTerms = !platformUtilsService.isSelfHost(); @@ -283,7 +291,11 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn name: string, ): Promise { const hint = this.formGroup.value.hint; - const kdfConfig = DEFAULT_KDF_CONFIG; + // Create and hash new master key + let kdfConfig: KdfConfig = DEFAULT_KDF_CONFIG; + if (await this.configService.getFeatureFlag(FeatureFlag.Argon2Default)) { + kdfConfig = NEW_ARGON2_DEFAULT_KDF_CONFIG; + } const key = await this.keyService.makeMasterKey(masterPassword, email, kdfConfig); const newUserKey = await this.keyService.makeUserKey(key); const masterKeyHash = await this.keyService.hashMasterKey(masterPassword, key); @@ -298,6 +310,8 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn this.captchaToken, kdfConfig.kdfType, kdfConfig.iterations, + kdfConfig.memory, + kdfConfig.parallelism, ); request.keys = new KeysRequest(keys[0], keys[1].encryptedString); if (this.modifyRegisterRequest) { diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index 94baecb9ef2..d6b7fad5c35 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -11,6 +11,8 @@ import { import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { HashPurpose } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -24,7 +26,12 @@ import { InputModule, ToastService, } from "@bitwarden/components"; -import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; +import { + DEFAULT_KDF_CONFIG, + KdfConfig, + KeyService, + NEW_ARGON2_DEFAULT_KDF_CONFIG, +} from "@bitwarden/key-management"; import { InputsFieldMatch } from "../../../../angular/src/auth/validators/inputs-field-match.validator"; import { SharedModule } from "../../../../components/src/shared"; @@ -103,6 +110,7 @@ export class InputPasswordComponent { private i18nService: I18nService, private policyService: PolicyService, private toastService: ToastService, + private configService: ConfigService, ) {} get minPasswordLengthMsg() { @@ -141,7 +149,10 @@ export class InputPasswordComponent { } // Create and hash new master key - const kdfConfig = DEFAULT_KDF_CONFIG; + let kdfConfig: KdfConfig = DEFAULT_KDF_CONFIG; + if (await this.configService.getFeatureFlag(FeatureFlag.Argon2Default)) { + kdfConfig = NEW_ARGON2_DEFAULT_KDF_CONFIG; + } if (this.email == null) { throw new Error("Email is required to create master key."); diff --git a/libs/auth/src/angular/input-password/password-input-result.ts b/libs/auth/src/angular/input-password/password-input-result.ts index 07157aaf4ca..ff14a8e1055 100644 --- a/libs/auth/src/angular/input-password/password-input-result.ts +++ b/libs/auth/src/angular/input-password/password-input-result.ts @@ -1,11 +1,11 @@ import { MasterKey } from "@bitwarden/common/types/key"; -import { PBKDF2KdfConfig } from "@bitwarden/key-management"; +import { KdfConfig } from "@bitwarden/key-management"; export interface PasswordInputResult { masterKey: MasterKey; masterKeyHash: string; localMasterKeyHash: string; - kdfConfig: PBKDF2KdfConfig; + kdfConfig: KdfConfig; hint: string; password: string; } diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts index 84c580662be..8b5c69806db 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts @@ -19,7 +19,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { PBKDF2KdfConfig, KdfConfigService, KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService, KdfConfig } from "@bitwarden/key-management"; import { SetPasswordCredentials, @@ -125,7 +125,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService { private async updateAccountDecryptionProperties( masterKey: MasterKey, - kdfConfig: PBKDF2KdfConfig, + kdfConfig: KdfConfig, protectedUserKey: [UserKey, EncString], userId: UserId, ) { diff --git a/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts b/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts index 18c4df9c18b..03952e4c3db 100644 --- a/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts +++ b/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts @@ -2,13 +2,13 @@ // @ts-strict-ignore import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey } from "@bitwarden/common/types/key"; -import { PBKDF2KdfConfig } from "@bitwarden/key-management"; +import { KdfConfig } from "@bitwarden/key-management"; export interface SetPasswordCredentials { masterKey: MasterKey; masterKeyHash: string; localMasterKeyHash: string; - kdfConfig: PBKDF2KdfConfig; + kdfConfig: KdfConfig; hint: string; orgSsoIdentifier: string; orgId: string; diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 0ab7d47acfc..42482c0e901 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -45,6 +45,7 @@ export enum FeatureFlag { PM12443RemovePagingLogic = "pm-12443-remove-paging-logic", PrivateKeyRegeneration = "pm-12241-private-key-regeneration", ResellerManagedOrgAlert = "PM-15814-alert-owners-of-reseller-managed-orgs", + Argon2Default = "argon2-default", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -100,6 +101,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.PM12443RemovePagingLogic]: FALSE, [FeatureFlag.PrivateKeyRegeneration]: FALSE, [FeatureFlag.ResellerManagedOrgAlert]: FALSE, + [FeatureFlag.Argon2Default]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; diff --git a/libs/key-management/src/index.ts b/libs/key-management/src/index.ts index cd90e78bbfb..d80cea4f2c9 100644 --- a/libs/key-management/src/index.ts +++ b/libs/key-management/src/index.ts @@ -15,6 +15,7 @@ export { Argon2KdfConfig, KdfConfig, DEFAULT_KDF_CONFIG, + NEW_ARGON2_DEFAULT_KDF_CONFIG, } from "./models/kdf-config"; export { KdfConfigService } from "./abstractions/kdf-config.service"; export { DefaultKdfConfigService } from "./kdf-config.service"; diff --git a/libs/key-management/src/models/kdf-config.ts b/libs/key-management/src/models/kdf-config.ts index 11431337a39..1ca06ff020e 100644 --- a/libs/key-management/src/models/kdf-config.ts +++ b/libs/key-management/src/models/kdf-config.ts @@ -45,6 +45,14 @@ export class PBKDF2KdfConfig { } } + get memory(): number | undefined { + return undefined; + } + + get parallelism(): number | undefined { + return undefined; + } + static fromJSON(json: Jsonify): PBKDF2KdfConfig { return new PBKDF2KdfConfig(json.iterations); } @@ -126,3 +134,8 @@ export class Argon2KdfConfig { } export const DEFAULT_KDF_CONFIG = new PBKDF2KdfConfig(PBKDF2KdfConfig.ITERATIONS.defaultValue); +export const NEW_ARGON2_DEFAULT_KDF_CONFIG = new Argon2KdfConfig( + Argon2KdfConfig.ITERATIONS.defaultValue, + Argon2KdfConfig.MEMORY.defaultValue, + Argon2KdfConfig.PARALLELISM.defaultValue, +); From 1e1a2baa17e2c3118b405e08c7f1286d85bd9cf0 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 13 Jan 2025 12:14:14 +0100 Subject: [PATCH 2/2] Fix build on browser --- apps/browser/src/auth/popup/register.component.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/browser/src/auth/popup/register.component.ts b/apps/browser/src/auth/popup/register.component.ts index f8a332f0fd1..5171425c712 100644 --- a/apps/browser/src/auth/popup/register.component.ts +++ b/apps/browser/src/auth/popup/register.component.ts @@ -9,6 +9,7 @@ import { FormValidationErrorsService } from "@bitwarden/angular/platform/abstrac import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -42,6 +43,7 @@ export class RegisterComponent extends BaseRegisterComponent { auditService: AuditService, dialogService: DialogService, toastService: ToastService, + configService: ConfigService, ) { super( formValidationErrorService, @@ -59,6 +61,7 @@ export class RegisterComponent extends BaseRegisterComponent { auditService, dialogService, toastService, + configService, ); } }