From 9afce480dee2c3909457478ee89f64897ef7f3f8 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Fri, 12 Dec 2025 15:55:43 +0100 Subject: [PATCH] Replace uses of encstring with unsigned shared key --- .../member-actions/member-actions.service.ts | 2 +- .../response/emergency-access.response.ts | 5 +-- .../services/emergency-access.service.ts | 25 +++++++-------- .../organization-auth-request.service.spec.ts | 14 +++----- .../services/web-provider.service.spec.ts | 6 +++- .../providers/setup/setup.component.ts | 2 +- .../setup/setup-business-unit.component.ts | 2 +- .../organization-user-confirm.request.ts | 3 +- .../default-organization-user.service.spec.ts | 5 +-- .../default-organization-user.service.ts | 2 +- ...initial-password.service.implementation.ts | 4 +-- ...fault-set-initial-password.service.spec.ts | 9 +++--- .../auth-request.service.abstraction.ts | 3 +- .../webauthn-login.strategy.ts | 3 +- .../auth-request/auth-request.service.spec.ts | 9 +++--- .../auth-request/auth-request.service.ts | 7 ++-- .../data/encrypted-organization-key.data.ts | 4 ++- .../domain/encrypted-organization-key.ts | 16 ++++++---- .../provider/provider-setup.request.ts | 5 ++- .../response/profile-organization.response.ts | 4 ++- .../response/profile-provider.response.ts | 4 ++- .../models/response/auth-request.response.ts | 4 ++- .../response/protected-device.response.ts | 6 ++-- ...-device-user-decryption-option.response.ts | 6 ++-- ...webauthn-prf-decryption-option.response.ts | 6 ++-- ...reset-enrollment.service.implementation.ts | 2 +- .../organization-billing.service.spec.ts | 17 +++++----- .../services/organization-billing.service.ts | 6 ++-- .../crypto/abstractions/encrypt.service.ts | 5 +-- .../crypto/models/enc-string.ts | 9 ------ .../encrypt.service.implementation.ts | 18 +++++------ .../crypto/services/encrypt.service.spec.ts | 15 +++++---- .../device-trust.service.abstraction.ts | 3 +- .../device-trust.service.implementation.ts | 11 ++++--- .../services/device-trust.service.spec.ts | 32 ++++++++----------- .../keys/models/rotateable-key-set.ts | 4 ++- ...default-rotateable-key-set.service.spec.ts | 7 ++-- .../default-rotateable-key-set.service.ts | 4 +-- .../services/key-state/provider-keys.state.ts | 5 +-- .../src/abstractions/key.service.ts | 5 ++- libs/key-management/src/key.service.spec.ts | 26 +++++++-------- libs/key-management/src/key.service.ts | 15 +++++---- 42 files changed, 183 insertions(+), 157 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts b/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts index 5e19e26954e..cf80f371fab 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/member-actions/member-actions.service.ts @@ -144,7 +144,7 @@ export class MemberActionsService { switchMap((orgKey) => this.encryptService.encapsulateKeyUnsigned(orgKey, publicKey)), map((encKey) => { const req = new OrganizationUserConfirmRequest(); - req.key = encKey.encryptedString; + req.key = encKey; return req; }), ), diff --git a/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts b/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts index 1c58bd7dd5d..62a27432e7a 100644 --- a/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts +++ b/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts @@ -1,6 +1,7 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; import { CipherResponse } from "@bitwarden/common/vault/models/response/cipher.response"; import { KdfType } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; @@ -56,7 +57,7 @@ export class EmergencyAccessGrantorDetailsResponse extends BaseResponse { } export class EmergencyAccessTakeoverResponse extends BaseResponse { - keyEncrypted: string; + keyEncrypted: UnsignedSharedKey; kdf: KdfType; kdfIterations: number; kdfMemory?: number; @@ -74,7 +75,7 @@ export class EmergencyAccessTakeoverResponse extends BaseResponse { } export class EmergencyAccessViewResponse extends BaseResponse { - keyEncrypted: string; + keyEncrypted: UnsignedSharedKey; ciphers: CipherResponse[] = []; constructor(response: any) { diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts index b91bc932e83..2edbdf7d82c 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts @@ -5,10 +5,6 @@ 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 { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; -import { - EncryptedString, - EncString, -} from "@bitwarden/common/key-management/crypto/models/enc-string"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { UserId } from "@bitwarden/common/types/guid"; @@ -24,6 +20,7 @@ import { KdfType, UserKeyRotationKeyRecoveryProvider, } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; @@ -258,7 +255,7 @@ export class EmergencyAccessService } const grantorUserKey = (await this.encryptService.decapsulateKeyUnsigned( - new EncString(response.keyEncrypted), + response.keyEncrypted, activeUserPrivateKey, )) as UserKey; @@ -288,7 +285,7 @@ export class EmergencyAccessService } const grantorKey = await this.encryptService.decapsulateKeyUnsigned( - new EncString(takeoverResponse.keyEncrypted), + takeoverResponse.keyEncrypted, activeUserPrivateKey, ); if (grantorKey == null) { @@ -424,16 +421,18 @@ export class EmergencyAccessService return requests; } - private async encryptKey(userKey: UserKey, publicKey: Uint8Array): Promise { - const publicKeyEncryptedUserKey = await this.encryptService.encapsulateKeyUnsigned( - userKey, - publicKey, - ); + private async encryptKey(userKey: UserKey, publicKey: Uint8Array): Promise { + // Encapsulate the user-key for the grantee's public key. There is no sender authentication provided here! + const granteePublicKeyEncapsulatedUnsignedGrantorUserKey = + await this.encryptService.encapsulateKeyUnsigned(userKey, publicKey); - if (publicKeyEncryptedUserKey == null || !publicKeyEncryptedUserKey.encryptedString) { + if ( + granteePublicKeyEncapsulatedUnsignedGrantorUserKey == null || + !granteePublicKeyEncapsulatedUnsignedGrantorUserKey + ) { throw new Error("publicKeyEncryptedUserKey not found"); } - return publicKeyEncryptedUserKey.encryptedString; + return granteePublicKeyEncapsulatedUnsignedGrantorUserKey; } } diff --git a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts index 25d12672dd3..855114d9adc 100644 --- a/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts +++ b/bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.spec.ts @@ -6,11 +6,11 @@ import { OrganizationUserResetPasswordDetailsResponse, } from "@bitwarden/admin-console/common"; 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 { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { newGuid } from "@bitwarden/guid"; import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { UserId } from "@bitwarden/user-core"; import { OrganizationAuthRequestApiService } from "./organization-auth-request-api.service"; @@ -196,7 +196,7 @@ describe("OrganizationAuthRequestService", () => { organizationUserResetPasswordDetailsResponse, ); - const encryptedUserKey = new EncString("encryptedUserKey"); + const encryptedUserKey = "unsignedSharedKey" as UnsignedSharedKey; encryptService.decapsulateKeyUnsigned.mockResolvedValue( new SymmetricCryptoKey(new Uint8Array(32)), ); @@ -213,13 +213,7 @@ describe("OrganizationAuthRequestService", () => { expect(organizationAuthRequestApiService.bulkUpdatePendingRequests).toHaveBeenCalledWith( organizationId, - [ - new OrganizationAuthRequestUpdateRequest( - "requestId1", - true, - encryptedUserKey.encryptedString, - ), - ], + [new OrganizationAuthRequestUpdateRequest("requestId1", true, encryptedUserKey)], ); }); }); @@ -241,7 +235,7 @@ describe("OrganizationAuthRequestService", () => { organizationUserResetPasswordDetailsResponse, ); - const encryptedUserKey = new EncString("encryptedUserKey"); + const encryptedUserKey = "unsignedSharedKey" as UnsignedSharedKey; encryptService.decapsulateKeyUnsigned.mockResolvedValue( new SymmetricCryptoKey(new Uint8Array(32)), ); diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.spec.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.spec.ts index 2accd760fcb..103e7bc612b 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.spec.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.spec.ts @@ -13,6 +13,7 @@ import { OrgKey, ProviderKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { newGuid } from "@bitwarden/guid"; import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { UserId } from "@bitwarden/user-core"; import { WebProviderService } from "./web-provider.service"; @@ -122,7 +123,10 @@ describe("WebProviderService", () => { const defaultCollectionTranslation = "Default Collection"; beforeEach(() => { - keyService.makeOrgKey.mockResolvedValue([new EncString("mockEncryptedKey"), mockOrgKey]); + keyService.makeOrgKey.mockResolvedValue([ + "mockEncryptedKey" as UnsignedSharedKey, + mockOrgKey, + ]); keyService.makeKeyPair.mockResolvedValue([publicKey, encryptedPrivateKey]); i18nService.t.mockReturnValue(defaultCollectionTranslation); encryptService.encryptString.mockResolvedValue(encryptedCollectionName); diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts index 87c48608b10..9e8f16ae407 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts @@ -125,7 +125,7 @@ export class SetupComponent implements OnInit, OnDestroy { } const activeUserId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); const providerKey = await this.keyService.makeOrgKey(activeUserId); - const key = providerKey[0].encryptedString; + const key = providerKey[0]; const request = new ProviderSetupRequest(); request.name = this.formGroup.value.name!; diff --git a/bitwarden_license/bit-web/src/app/billing/providers/setup/setup-business-unit.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/setup/setup-business-unit.component.ts index 4b8dfce05d5..4d9c5ee399d 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/setup/setup-business-unit.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/setup/setup-business-unit.component.ts @@ -83,7 +83,7 @@ export class SetupBusinessUnitComponent extends BaseAcceptComponent { ); const userId = await firstValueFrom(activeUserId$); - const [{ encryptedString: encryptedProviderKey }, providerKey] = + const [encryptedProviderKey, providerKey] = await this.keyService.makeOrgKey(userId); const organizationKey = await firstValueFrom(organizationKey$); diff --git a/libs/admin-console/src/common/organization-user/models/requests/organization-user-confirm.request.ts b/libs/admin-console/src/common/organization-user/models/requests/organization-user-confirm.request.ts index 50826d068c1..ade7da840c3 100644 --- a/libs/admin-console/src/common/organization-user/models/requests/organization-user-confirm.request.ts +++ b/libs/admin-console/src/common/organization-user/models/requests/organization-user-confirm.request.ts @@ -1,6 +1,7 @@ import { EncryptedString } from "@bitwarden/common/key-management/crypto/models/enc-string"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; export class OrganizationUserConfirmRequest { - key: EncryptedString | undefined; + key: UnsignedSharedKey | undefined; defaultUserCollectionName: EncryptedString | undefined; } diff --git a/libs/admin-console/src/common/organization-user/services/default-organization-user.service.spec.ts b/libs/admin-console/src/common/organization-user/services/default-organization-user.service.spec.ts index 982fb3ca5e0..c1491240bbc 100644 --- a/libs/admin-console/src/common/organization-user/services/default-organization-user.service.spec.ts +++ b/libs/admin-console/src/common/organization-user/services/default-organization-user.service.spec.ts @@ -18,6 +18,7 @@ import { CsprngArray } from "@bitwarden/common/types/csprng"; import { OrganizationId } from "@bitwarden/common/types/guid"; import { OrgKey } from "@bitwarden/common/types/key"; import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { DefaultOrganizationUserService } from "./default-organization-user.service"; @@ -36,7 +37,7 @@ describe("DefaultOrganizationUserService", () => { const mockPublicKey = new Uint8Array(64) as CsprngArray; const mockRandomBytes = new Uint8Array(64) as CsprngArray; const mockOrgKey = new SymmetricCryptoKey(mockRandomBytes) as OrgKey; - const mockEncryptedKey = { encryptedString: "encrypted-key" } as EncString; + const mockEncryptedKey = "encrypted-key" as UnsignedSharedKey; const mockEncryptedCollectionName = { encryptedString: "encrypted-collection-name" } as EncString; const mockDefaultCollectionName = "My Items"; @@ -116,7 +117,7 @@ describe("DefaultOrganizationUserService", () => { mockOrganization.id, mockUserId, { - key: mockEncryptedKey.encryptedString, + key: mockEncryptedKey, defaultUserCollectionName: mockEncryptedCollectionName.encryptedString, } as OrganizationUserConfirmRequest, ); diff --git a/libs/admin-console/src/common/organization-user/services/default-organization-user.service.ts b/libs/admin-console/src/common/organization-user/services/default-organization-user.service.ts index 4f503a92675..99597179296 100644 --- a/libs/admin-console/src/common/organization-user/services/default-organization-user.service.ts +++ b/libs/admin-console/src/common/organization-user/services/default-organization-user.service.ts @@ -46,7 +46,7 @@ export class DefaultOrganizationUserService implements OrganizationUserService { return combineLatest([encryptedKey$, encryptedCollectionName$]).pipe( map(([key, collectionName]) => ({ - key: key.encryptedString, + key: key, defaultUserCollectionName: collectionName.encryptedString, })), ); diff --git a/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.implementation.ts b/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.implementation.ts index df5220b5255..cb791b853ba 100644 --- a/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.implementation.ts +++ b/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.implementation.ts @@ -236,7 +236,7 @@ export class DefaultSetInitialPasswordService implements SetInitialPasswordServi orgPublicKey, ); - if (orgPublicKeyEncryptedUserKey == null || !orgPublicKeyEncryptedUserKey.encryptedString) { + if (orgPublicKeyEncryptedUserKey == null || !orgPublicKeyEncryptedUserKey) { throw new Error( "orgPublicKeyEncryptedUserKey not found. Could not handle reset password auto enroll.", ); @@ -244,7 +244,7 @@ export class DefaultSetInitialPasswordService implements SetInitialPasswordServi const enrollmentRequest = new OrganizationUserResetPasswordEnrollmentRequest(); enrollmentRequest.masterPasswordHash = masterKeyHash; - enrollmentRequest.resetPasswordKey = orgPublicKeyEncryptedUserKey.encryptedString; + enrollmentRequest.resetPasswordKey = orgPublicKeyEncryptedUserKey; await this.organizationUserApiService.putOrganizationUserResetPasswordEnrollment( orgId, diff --git a/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.spec.ts b/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.spec.ts index 8b95090e776..7b328b090fa 100644 --- a/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.spec.ts +++ b/libs/angular/src/auth/password-management/set-initial-password/default-set-initial-password.service.spec.ts @@ -34,6 +34,7 @@ import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey, UserPrivateKey, UserPublicKey } from "@bitwarden/common/types/key"; import { DEFAULT_KDF_CONFIG, KdfConfigService, KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { DefaultSetInitialPasswordService } from "./default-set-initial-password.service.implementation"; import { @@ -111,7 +112,7 @@ describe("DefaultSetInitialPasswordService", () => { let keysRequest: KeysRequest; let organizationKeys: OrganizationKeysResponse; - let orgPublicKeyEncryptedUserKey: EncString; + let orgPublicKeyEncryptedUserKey: UnsignedSharedKey; let userDecryptionOptions: UserDecryptionOptions; let userDecryptionOptionsSubject: BehaviorSubject; @@ -145,7 +146,7 @@ describe("DefaultSetInitialPasswordService", () => { privateKey: "orgPrivateKey", publicKey: "orgPublicKey", } as OrganizationKeysResponse; - orgPublicKeyEncryptedUserKey = new EncString("orgPublicKeyEncryptedUserKey"); + orgPublicKeyEncryptedUserKey = "orgPublicKeyEncryptedUserKey" as UnsignedSharedKey; userDecryptionOptions = new UserDecryptionOptions({ hasMasterPassword: true }); userDecryptionOptionsSubject = new BehaviorSubject(userDecryptionOptions); @@ -164,7 +165,7 @@ describe("DefaultSetInitialPasswordService", () => { enrollmentRequest = new OrganizationUserResetPasswordEnrollmentRequest(); enrollmentRequest.masterPasswordHash = credentials.newServerMasterKeyHash; - enrollmentRequest.resetPasswordKey = orgPublicKeyEncryptedUserKey.encryptedString; + enrollmentRequest.resetPasswordKey = orgPublicKeyEncryptedUserKey; }); interface MockConfig { @@ -449,7 +450,7 @@ describe("DefaultSetInitialPasswordService", () => { if (property === "orgPublicKeyEncryptedUserKey") { orgPublicKeyEncryptedUserKey = null; } else { - orgPublicKeyEncryptedUserKey.encryptedString = "" as EncryptedString; + orgPublicKeyEncryptedUserKey = "" as UnsignedSharedKey; } setupMocks({ ...defaultMockConfig, resetPasswordAutoEnroll: true }); diff --git a/libs/auth/src/common/abstractions/auth-request.service.abstraction.ts b/libs/auth/src/common/abstractions/auth-request.service.abstraction.ts index 1bfbfd8d004..9b393a14375 100644 --- a/libs/auth/src/common/abstractions/auth-request.service.abstraction.ts +++ b/libs/auth/src/common/abstractions/auth-request.service.abstraction.ts @@ -5,6 +5,7 @@ import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; export abstract class AuthRequestServiceAbstraction { /** Emits an auth request id when an auth request has been approved. */ @@ -93,7 +94,7 @@ export abstract class AuthRequestServiceAbstraction { * @returns The decrypted `UserKey`. */ abstract decryptPubKeyEncryptedUserKey( - pubKeyEncryptedUserKey: string, + pubKeyEncryptedUserKey: UnsignedSharedKey, privateKey: ArrayBuffer, ): Promise; /** diff --git a/libs/auth/src/common/login-strategies/webauthn-login.strategy.ts b/libs/auth/src/common/login-strategies/webauthn-login.strategy.ts index dbce7628335..2e864b7b2fa 100644 --- a/libs/auth/src/common/login-strategies/webauthn-login.strategy.ts +++ b/libs/auth/src/common/login-strategies/webauthn-login.strategy.ts @@ -6,7 +6,6 @@ import { Jsonify } from "type-fest"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { WebAuthnLoginTokenRequest } from "@bitwarden/common/auth/models/request/identity-token/webauthn-login-token.request"; import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response"; -import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; @@ -89,7 +88,7 @@ export class WebAuthnLoginStrategy extends LoginStrategy { // decrypt user key with private key const userKey = await this.encryptService.decapsulateKeyUnsigned( - new EncString(webAuthnPrfOption.encryptedUserKey.encryptedString), + webAuthnPrfOption.encryptedUserKey, privateKey, ); diff --git a/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts b/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts index 8cb0cc279ae..c4c7b240dc6 100644 --- a/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts +++ b/libs/auth/src/common/services/auth-request/auth-request.service.spec.ts @@ -16,6 +16,7 @@ import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { newGuid } from "@bitwarden/guid"; import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { DefaultAuthRequestApiService } from "./auth-request-api.service"; import { AuthRequestService } from "./auth-request.service"; @@ -89,9 +90,9 @@ describe("AuthRequestService", () => { describe("approveOrDenyAuthRequest", () => { beforeEach(() => { - encryptService.encapsulateKeyUnsigned.mockResolvedValue({ - encryptedString: "ENCRYPTED_STRING", - } as EncString); + encryptService.encapsulateKeyUnsigned.mockResolvedValue( + "ENCRYPTED_STRING" as UnsignedSharedKey, + ); appIdService.getAppId.mockResolvedValue("APP_ID"); }); it("should throw if auth request is missing id or key", async () => { @@ -221,7 +222,7 @@ describe("AuthRequestService", () => { // Act const result = await sut.decryptPubKeyEncryptedUserKey( - mockPubKeyEncryptedUserKey, + mockPubKeyEncryptedUserKey as UnsignedSharedKey, mockPrivateKey, ); diff --git a/libs/auth/src/common/services/auth-request/auth-request.service.ts b/libs/auth/src/common/services/auth-request/auth-request.service.ts index ba4b9eaf174..b21b545938f 100644 --- a/libs/auth/src/common/services/auth-request/auth-request.service.ts +++ b/libs/auth/src/common/services/auth-request/auth-request.service.ts @@ -25,6 +25,7 @@ import { import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { AuthRequestApiServiceAbstraction } from "../../abstractions/auth-request-api.service"; import { AuthRequestServiceAbstraction } from "../../abstractions/auth-request.service.abstraction"; @@ -143,7 +144,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction { const encryptedKey = await this.encryptService.encapsulateKeyUnsigned(keyToEncrypt, pubKey); const response = new PasswordlessAuthRequest( - encryptedKey.encryptedString, + encryptedKey, undefined, await this.appIdService.getAppId(), approve, @@ -186,11 +187,11 @@ export class AuthRequestService implements AuthRequestServiceAbstraction { // Decryption helpers async decryptPubKeyEncryptedUserKey( - pubKeyEncryptedUserKey: string, + pubKeyEncryptedUserKey: UnsignedSharedKey, privateKey: Uint8Array, ): Promise { const decryptedUserKey = await this.encryptService.decapsulateKeyUnsigned( - new EncString(pubKeyEncryptedUserKey), + pubKeyEncryptedUserKey, privateKey, ); diff --git a/libs/common/src/admin-console/models/data/encrypted-organization-key.data.ts b/libs/common/src/admin-console/models/data/encrypted-organization-key.data.ts index 8ecbeefb814..0a4b59fe504 100644 --- a/libs/common/src/admin-console/models/data/encrypted-organization-key.data.ts +++ b/libs/common/src/admin-console/models/data/encrypted-organization-key.data.ts @@ -1,10 +1,12 @@ +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + export type EncryptedOrganizationKeyData = | OrganizationEncryptedOrganizationKeyData | ProviderEncryptedOrganizationKeyData; type OrganizationEncryptedOrganizationKeyData = { type: "organization"; - key: string; + key: UnsignedSharedKey; }; type ProviderEncryptedOrganizationKeyData = { diff --git a/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts b/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts index 5546ee1770e..262004a06d9 100644 --- a/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts +++ b/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts @@ -1,3 +1,5 @@ +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { EncryptService } from "../../../key-management/crypto/abstractions/encrypt.service"; import { EncString } from "../../../key-management/crypto/models/enc-string"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -5,15 +7,15 @@ import { OrgKey, UserPrivateKey } from "../../../types/key"; import { EncryptedOrganizationKeyData } from "../data/encrypted-organization-key.data"; export abstract class BaseEncryptedOrganizationKey { - abstract get encryptedOrganizationKey(): EncString; + abstract get encryptedOrganizationKey(): UnsignedSharedKey; static fromData(data: EncryptedOrganizationKeyData) { switch (data.type) { case "organization": - return new EncryptedOrganizationKey(data.key); + return new EncryptedOrganizationKey(data.key as UnsignedSharedKey); case "provider": - return new ProviderEncryptedOrganizationKey(data.key, data.providerId); + return new ProviderEncryptedOrganizationKey(data.key as UnsignedSharedKey, data.providerId); default: return null; @@ -28,7 +30,7 @@ export abstract class BaseEncryptedOrganizationKey { } export class EncryptedOrganizationKey implements BaseEncryptedOrganizationKey { - constructor(private key: string) {} + constructor(private key: UnsignedSharedKey) {} async decrypt(encryptService: EncryptService, privateKey: UserPrivateKey) { return (await encryptService.decapsulateKeyUnsigned( @@ -38,7 +40,7 @@ export class EncryptedOrganizationKey implements BaseEncryptedOrganizationKey { } get encryptedOrganizationKey() { - return new EncString(this.key); + return this.key; } toData(): EncryptedOrganizationKeyData { @@ -51,7 +53,7 @@ export class EncryptedOrganizationKey implements BaseEncryptedOrganizationKey { export class ProviderEncryptedOrganizationKey implements BaseEncryptedOrganizationKey { constructor( - private key: string, + private key: UnsignedSharedKey, private providerId: string, ) {} @@ -67,7 +69,7 @@ export class ProviderEncryptedOrganizationKey implements BaseEncryptedOrganizati } get encryptedOrganizationKey() { - return new EncString(this.key); + return this.key; } toData(): EncryptedOrganizationKeyData { diff --git a/libs/common/src/admin-console/models/request/provider/provider-setup.request.ts b/libs/common/src/admin-console/models/request/provider/provider-setup.request.ts index 001bba11cf4..e904d789124 100644 --- a/libs/common/src/admin-console/models/request/provider/provider-setup.request.ts +++ b/libs/common/src/admin-console/models/request/provider/provider-setup.request.ts @@ -1,4 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line + +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + // @ts-strict-ignore interface TokenizedPaymentMethod { type: "bankAccount" | "card" | "payPal"; @@ -20,7 +23,7 @@ export class ProviderSetupRequest { businessName: string; billingEmail: string; token: string; - key: string; + key: UnsignedSharedKey; paymentMethod: TokenizedPaymentMethod; billingAddress: BillingAddress; } diff --git a/libs/common/src/admin-console/models/response/profile-organization.response.ts b/libs/common/src/admin-console/models/response/profile-organization.response.ts index 263e8e7d6b9..cb6cb227970 100644 --- a/libs/common/src/admin-console/models/response/profile-organization.response.ts +++ b/libs/common/src/admin-console/models/response/profile-organization.response.ts @@ -1,3 +1,5 @@ +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { MemberDecryptionType } from "../../../auth/enums/sso"; import { ProductTierType } from "../../../billing/enums"; import { BaseResponse } from "../../../models/response/base.response"; @@ -29,7 +31,7 @@ export class ProfileOrganizationResponse extends BaseResponse { seats: number; maxCollections: number; maxStorageGb?: number; - key: string; + key: UnsignedSharedKey; hasPublicAndPrivateKeys: boolean; status: OrganizationUserStatusType; type: OrganizationUserType; diff --git a/libs/common/src/admin-console/models/response/profile-provider.response.ts b/libs/common/src/admin-console/models/response/profile-provider.response.ts index ce35b064d52..7d89c785d6b 100644 --- a/libs/common/src/admin-console/models/response/profile-provider.response.ts +++ b/libs/common/src/admin-console/models/response/profile-provider.response.ts @@ -1,3 +1,5 @@ +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { BaseResponse } from "../../../models/response/base.response"; import { ProviderStatusType, @@ -10,7 +12,7 @@ import { PermissionsApi } from "../api/permissions.api"; export class ProfileProviderResponse extends BaseResponse { id: string; name: string; - key: string; + key: UnsignedSharedKey; status: ProviderUserStatusType; type: ProviderUserType; enabled: boolean; diff --git a/libs/common/src/auth/models/response/auth-request.response.ts b/libs/common/src/auth/models/response/auth-request.response.ts index 94c65000919..e16883c13d0 100644 --- a/libs/common/src/auth/models/response/auth-request.response.ts +++ b/libs/common/src/auth/models/response/auth-request.response.ts @@ -1,3 +1,5 @@ +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { DeviceType } from "../../../enums"; import { BaseResponse } from "../../../models/response/base.response"; @@ -11,7 +13,7 @@ export class AuthRequestResponse extends BaseResponse { requestDeviceIdentifier: string; requestIpAddress: string; requestCountryName: string; - key: string; // could be either an encrypted MasterKey or an encrypted UserKey + key: UnsignedSharedKey; // could be either an encrypted MasterKey or an encrypted UserKey masterPasswordHash: string; // if hash is present, the `key` above is an encrypted MasterKey (else `key` is an encrypted UserKey) creationDate: string; requestApproved?: boolean; diff --git a/libs/common/src/auth/models/response/protected-device.response.ts b/libs/common/src/auth/models/response/protected-device.response.ts index 77a077ac1af..8b99d9754bd 100644 --- a/libs/common/src/auth/models/response/protected-device.response.ts +++ b/libs/common/src/auth/models/response/protected-device.response.ts @@ -2,6 +2,8 @@ // @ts-strict-ignore import { Jsonify } from "type-fest"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { DeviceType } from "../../../enums"; import { EncString } from "../../../key-management/crypto/models/enc-string"; import { RotateableKeySet } from "../../../key-management/keys/models/rotateable-key-set"; @@ -16,7 +18,7 @@ export class ProtectedDeviceResponse extends BaseResponse { this.type = this.getResponseProperty("type"); this.creationDate = new Date(this.getResponseProperty("creationDate")); if (response.encryptedUserKey) { - this.encryptedUserKey = new EncString(this.getResponseProperty("encryptedUserKey")); + this.encryptedUserKey = this.getResponseProperty("encryptedUserKey"); } if (response.encryptedPublicKey) { this.encryptedPublicKey = new EncString(this.getResponseProperty("encryptedPublicKey")); @@ -32,7 +34,7 @@ export class ProtectedDeviceResponse extends BaseResponse { * Intended to be the users symmetric key that is encrypted in some form, the current way to encrypt this is with * the devices public key. */ - encryptedUserKey: EncString; + encryptedUserKey: UnsignedSharedKey; /** * Intended to be the public key that was generated for a device upon trust and encrypted. Currenly encrypted using * a users symmetric key so that when trusted and unlocked a user can decrypt the public key for all their devices. diff --git a/libs/common/src/auth/models/response/user-decryption-options/trusted-device-user-decryption-option.response.ts b/libs/common/src/auth/models/response/user-decryption-options/trusted-device-user-decryption-option.response.ts index 1a4e1b3d275..825c28a1203 100644 --- a/libs/common/src/auth/models/response/user-decryption-options/trusted-device-user-decryption-option.response.ts +++ b/libs/common/src/auth/models/response/user-decryption-options/trusted-device-user-decryption-option.response.ts @@ -1,5 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { EncString } from "../../../../key-management/crypto/models/enc-string"; import { BaseResponse } from "../../../../models/response/base.response"; @@ -18,7 +20,7 @@ export class TrustedDeviceUserDecryptionOptionResponse extends BaseResponse { hasManageResetPasswordPermission: boolean; isTdeOffboarding: boolean; encryptedPrivateKey: EncString; - encryptedUserKey: EncString; + encryptedUserKey: UnsignedSharedKey; constructor(response: any) { super(response); @@ -35,7 +37,7 @@ export class TrustedDeviceUserDecryptionOptionResponse extends BaseResponse { this.encryptedPrivateKey = new EncString(this.getResponseProperty("EncryptedPrivateKey")); } if (response.EncryptedUserKey) { - this.encryptedUserKey = new EncString(this.getResponseProperty("EncryptedUserKey")); + this.encryptedUserKey = this.getResponseProperty("EncryptedUserKey"); } } } diff --git a/libs/common/src/auth/models/response/user-decryption-options/webauthn-prf-decryption-option.response.ts b/libs/common/src/auth/models/response/user-decryption-options/webauthn-prf-decryption-option.response.ts index 478f6d88b5b..4294a519502 100644 --- a/libs/common/src/auth/models/response/user-decryption-options/webauthn-prf-decryption-option.response.ts +++ b/libs/common/src/auth/models/response/user-decryption-options/webauthn-prf-decryption-option.response.ts @@ -1,5 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { EncString } from "../../../../key-management/crypto/models/enc-string"; import { BaseResponse } from "../../../../models/response/base.response"; @@ -10,7 +12,7 @@ export interface IWebAuthnPrfDecryptionOptionServerResponse { export class WebAuthnPrfDecryptionOptionResponse extends BaseResponse { encryptedPrivateKey: EncString; - encryptedUserKey: EncString; + encryptedUserKey: UnsignedSharedKey; constructor(response: IWebAuthnPrfDecryptionOptionServerResponse) { super(response); @@ -18,7 +20,7 @@ export class WebAuthnPrfDecryptionOptionResponse extends BaseResponse { this.encryptedPrivateKey = new EncString(this.getResponseProperty("EncryptedPrivateKey")); } if (response.EncryptedUserKey) { - this.encryptedUserKey = new EncString(this.getResponseProperty("EncryptedUserKey")); + this.encryptedUserKey = this.getResponseProperty("EncryptedUserKey") as UnsignedSharedKey; } } } diff --git a/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts b/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts index 55644009f16..c170734da2b 100644 --- a/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts +++ b/libs/common/src/auth/services/password-reset-enrollment.service.implementation.ts @@ -63,7 +63,7 @@ export class PasswordResetEnrollmentServiceImplementation const encryptedKey = await this.encryptService.encapsulateKeyUnsigned(userKey, orgPublicKey); const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest(); - resetRequest.resetPasswordKey = encryptedKey.encryptedString; + resetRequest.resetPasswordKey = encryptedKey; await this.organizationUserApiService.putOrganizationUserResetPasswordEnrollment( organizationId, diff --git a/libs/common/src/billing/services/organization-billing.service.spec.ts b/libs/common/src/billing/services/organization-billing.service.spec.ts index a14dd0f0279..0b1399fdc8c 100644 --- a/libs/common/src/billing/services/organization-billing.service.spec.ts +++ b/libs/common/src/billing/services/organization-billing.service.spec.ts @@ -16,6 +16,7 @@ import { newGuid } from "@bitwarden/guid"; // This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. // eslint-disable-next-line no-restricted-imports import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { UserId } from "@bitwarden/user-core"; import { OrganizationKeysRequest } from "../../admin-console/models/request/organization-keys.request"; @@ -80,7 +81,7 @@ describe("OrganizationBillingService", () => { } as OrganizationResponse; organizationApiService.create.mockResolvedValue(organizationResponse); - keyService.makeOrgKey.mockResolvedValue([new EncString("encrypted-key"), {} as OrgKey]); + keyService.makeOrgKey.mockResolvedValue(["encrypted-key" as UnsignedSharedKey, {} as OrgKey]); keyService.makeKeyPair.mockResolvedValue(["key", new EncString("encrypted-key")]); encryptService.encryptString.mockResolvedValue(new EncString("collection-encrypted")); @@ -104,7 +105,7 @@ describe("OrganizationBillingService", () => { } as SubscriptionInformation; organizationApiService.create.mockRejectedValue(new Error("Failed to create organization")); - keyService.makeOrgKey.mockResolvedValue([new EncString("encrypted-key"), {} as OrgKey]); + keyService.makeOrgKey.mockResolvedValue(["encrypted-key" as UnsignedSharedKey, {} as OrgKey]); keyService.makeKeyPair.mockResolvedValue(["key", new EncString("encrypted-key")]); encryptService.encryptString.mockResolvedValue(new EncString("collection-encrypted")); @@ -164,7 +165,7 @@ describe("OrganizationBillingService", () => { } as OrganizationResponse; organizationApiService.createWithoutPayment.mockResolvedValue(organizationResponse); - keyService.makeOrgKey.mockResolvedValue([new EncString("encrypted-key"), {} as OrgKey]); + keyService.makeOrgKey.mockResolvedValue(["encrypted-key" as UnsignedSharedKey, {} as OrgKey]); keyService.makeKeyPair.mockResolvedValue(["key", new EncString("encrypted-key")]); encryptService.encryptString.mockResolvedValue(new EncString("collection-encrypted")); @@ -186,7 +187,7 @@ describe("OrganizationBillingService", () => { } as SubscriptionInformation; organizationApiService.createWithoutPayment.mockRejectedValue(new Error("Creation failed")); - keyService.makeOrgKey.mockResolvedValue([new EncString("encrypted-key"), {} as OrgKey]); + keyService.makeOrgKey.mockResolvedValue(["encrypted-key" as UnsignedSharedKey, {} as OrgKey]); keyService.makeKeyPair.mockResolvedValue(["key", new EncString("encrypted-key")]); encryptService.encryptString.mockResolvedValue(new EncString("collection-encrypted")); @@ -224,7 +225,7 @@ describe("OrganizationBillingService", () => { } as OrganizationResponse; organizationApiService.create.mockResolvedValue(organizationResponse); - keyService.makeOrgKey.mockResolvedValue([new EncString("encrypted-key"), {} as OrgKey]); + keyService.makeOrgKey.mockResolvedValue(["encrypted-key" as UnsignedSharedKey, {} as OrgKey]); keyService.makeKeyPair.mockResolvedValue(["key", new EncString("encrypted-key")]); encryptService.encryptString.mockResolvedValue(new EncString("collection-encrypted")); @@ -258,7 +259,7 @@ describe("OrganizationBillingService", () => { } as SubscriptionInformation; organizationApiService.create.mockRejectedValue(new Error("Failed to create organization")); - keyService.makeOrgKey.mockResolvedValue([new EncString("encrypted-key"), {} as OrgKey]); + keyService.makeOrgKey.mockResolvedValue(["encrypted-key" as UnsignedSharedKey, {} as OrgKey]); keyService.makeKeyPair.mockResolvedValue(["key", new EncString("encrypted-key")]); encryptService.encryptString.mockResolvedValue(new EncString("collection-encrypted")); // Act & Assert @@ -271,7 +272,7 @@ describe("OrganizationBillingService", () => { describe("organization key creation methods", () => { const organizationKeys = { orgKey: new SymmetricCryptoKey(new Uint8Array(64)) as OrgKey, - publicKeyEncapsulatedOrgKey: new EncString("encryptedOrgKey"), + publicKeyEncapsulatedOrgKey: "encryptedOrgKey" as UnsignedSharedKey, publicKey: "public-key", encryptedPrivateKey: new EncString("encryptedPrivateKey"), }; @@ -298,7 +299,7 @@ describe("OrganizationBillingService", () => { billingEmail: "test@example.com", initiationPath: "Registration form", planType: 0, - key: organizationKeys.publicKeyEncapsulatedOrgKey.encryptedString, + key: organizationKeys.publicKeyEncapsulatedOrgKey, keys: new OrganizationKeysRequest( organizationKeys.publicKey, organizationKeys.encryptedPrivateKey.encryptedString!, diff --git a/libs/common/src/billing/services/organization-billing.service.ts b/libs/common/src/billing/services/organization-billing.service.ts index fdc9c6215c9..5fe6c611939 100644 --- a/libs/common/src/billing/services/organization-billing.service.ts +++ b/libs/common/src/billing/services/organization-billing.service.ts @@ -1,8 +1,10 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore + // This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. // eslint-disable-next-line no-restricted-imports import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { UserId } from "@bitwarden/user-core"; import { ApiService } from "../../abstractions/api.service"; @@ -27,7 +29,7 @@ import { PlanType } from "../enums"; import { OrganizationNoPaymentMethodCreateRequest } from "../models/request/organization-no-payment-method-create-request"; interface OrganizationKeys { - encryptedKey: EncString; + encryptedKey: UnsignedSharedKey; publicKey: string; encryptedPrivateKey: EncString; encryptedCollectionName: EncString; @@ -158,7 +160,7 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs request: OrganizationCreateRequest | OrganizationNoPaymentMethodCreateRequest, keys: OrganizationKeys, ): void { - request.key = keys.encryptedKey.encryptedString; + request.key = keys.encryptedKey; request.keys = new OrganizationKeysRequest( keys.publicKey, keys.encryptedPrivateKey.encryptedString, diff --git a/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts b/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts index 25e5f949b40..3e9705e08bd 100644 --- a/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts +++ b/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts @@ -1,4 +1,5 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { EncArrayBuffer } from "../../../platform/models/domain/enc-array-buffer"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; @@ -143,7 +144,7 @@ export abstract class EncryptService { abstract encapsulateKeyUnsigned( sharedKey: SymmetricCryptoKey, encapsulationKey: Uint8Array, - ): Promise; + ): Promise; /** * Decapsulates a shared symmetric key with an asymmetric private key * Note: This does not establish sender authenticity @@ -154,7 +155,7 @@ export abstract class EncryptService { * @throws Error if decapsulation fails */ abstract decapsulateKeyUnsigned( - encryptedSharedKey: EncString, + encryptedSharedKey: UnsignedSharedKey, decapsulationKey: Uint8Array, ): Promise; diff --git a/libs/common/src/key-management/crypto/models/enc-string.ts b/libs/common/src/key-management/crypto/models/enc-string.ts index a737771f799..7983f03ad67 100644 --- a/libs/common/src/key-management/crypto/models/enc-string.ts +++ b/libs/common/src/key-management/crypto/models/enc-string.ts @@ -101,15 +101,6 @@ export class EncString { this.iv = encPieces[0]; this.data = encPieces[1]; break; - case EncryptionType.Rsa2048_OaepSha256_B64: - case EncryptionType.Rsa2048_OaepSha1_B64: - this.data = encPieces[0]; - break; - case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64: - case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64: - this.data = encPieces[0]; - this.mac = encPieces[1]; - break; default: return; } diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts index a5da0c82382..ef8e9862d88 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts @@ -10,7 +10,7 @@ import { EncryptionType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; -import { PureCrypto } from "@bitwarden/sdk-internal"; +import { PureCrypto, UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { EncryptService } from "../abstractions/encrypt.service"; @@ -215,7 +215,7 @@ export class EncryptServiceImplementation implements EncryptService { async encapsulateKeyUnsigned( sharedKey: SymmetricCryptoKey, encapsulationKey: Uint8Array, - ): Promise { + ): Promise { if (sharedKey == null) { throw new Error("No sharedKey provided for encapsulation"); } @@ -223,13 +223,14 @@ export class EncryptServiceImplementation implements EncryptService { throw new Error("No encapsulationKey provided for encapsulation"); } await SdkLoadService.Ready; - return new EncString( - PureCrypto.encapsulate_key_unsigned(sharedKey.toEncoded(), encapsulationKey), - ); + return PureCrypto.encapsulate_key_unsigned( + sharedKey.toEncoded(), + encapsulationKey, + ) as UnsignedSharedKey; } async decapsulateKeyUnsigned( - encryptedSharedKey: EncString, + encryptedSharedKey: UnsignedSharedKey, decapsulationKey: Uint8Array, ): Promise { if (encryptedSharedKey == null) { @@ -240,10 +241,7 @@ export class EncryptServiceImplementation implements EncryptService { } await SdkLoadService.Ready; - const keyBytes = PureCrypto.decapsulate_key_unsigned( - encryptedSharedKey.encryptedString, - decapsulationKey, - ); + const keyBytes = PureCrypto.decapsulate_key_unsigned(encryptedSharedKey, decapsulationKey); return new SymmetricCryptoKey(keyBytes); } diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts index 466f59da7c9..4c0453a4266 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts @@ -8,7 +8,7 @@ import { EncryptionType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; -import { PureCrypto } from "@bitwarden/sdk-internal"; +import { PureCrypto, UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { makeStaticByteArray } from "../../../../spec"; @@ -357,7 +357,7 @@ describe("EncryptService", () => { it("encrypts data with provided key", async () => { const actual = await encryptService.encapsulateKeyUnsigned(testKey, publicKey); - expect(actual).toEqual(new EncString("encapsulated_key_unsigned")); + expect(actual).toEqual("encapsulated_key_unsigned"); }); }); @@ -369,13 +369,16 @@ describe("EncryptService", () => { }); it("throws if no private key is provided", () => { - return expect(encryptService.decapsulateKeyUnsigned(encString, null)).rejects.toThrow( - "No decapsulationKey provided for decapsulation", - ); + const unsignedSharedKey = encString.encryptedString as unknown as UnsignedSharedKey; + return expect( + encryptService.decapsulateKeyUnsigned(unsignedSharedKey, null), + ).rejects.toThrow("No decapsulationKey provided for decapsulation"); }); it("decrypts data with provided key", async () => { - const actual = await encryptService.decapsulateKeyUnsigned(makeEncString(data), privateKey); + const unsignedSharedKey = makeEncString(data) + .encryptedString as unknown as UnsignedSharedKey; + const actual = await encryptService.decapsulateKeyUnsigned(unsignedSharedKey, privateKey); expect(actual.toEncoded()).toEqualBuffer(new Uint8Array(64)); }); }); diff --git a/libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts b/libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts index 2bc99e5e5c2..cb938f08e8d 100644 --- a/libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts +++ b/libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts @@ -1,6 +1,7 @@ import { Observable } from "rxjs"; import { OtherDeviceKeysUpdateRequest } from "@bitwarden/common/auth/models/request/update-devices-trust.request"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { DeviceResponse } from "../../../auth/abstractions/devices/responses/device.response"; import { UserId } from "../../../types/guid"; @@ -42,7 +43,7 @@ export abstract class DeviceTrustServiceAbstraction { abstract decryptUserKeyWithDeviceKey( userId: UserId, encryptedDevicePrivateKey: EncString, - encryptedUserKey: EncString, + encryptedUserKey: UnsignedSharedKey, deviceKey: DeviceKey, ): Promise; abstract rotateDevicesTrust( diff --git a/libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts b/libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts index 59bd7bc11f2..a28ac827888 100644 --- a/libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts +++ b/libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts @@ -8,6 +8,7 @@ import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common" // This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. // eslint-disable-next-line no-restricted-imports import { KeyService } from "@bitwarden/key-management"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { AccountService } from "../../../auth/abstractions/account.service"; import { DeviceResponse } from "../../../auth/abstractions/devices/responses/device.response"; @@ -188,7 +189,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction { const deviceIdentifier = await this.appIdService.getAppId(); const deviceResponse = await this.devicesApiService.updateTrustedDeviceKeys( deviceIdentifier, - devicePublicKeyEncryptedUserKey.encryptedString, + devicePublicKeyEncryptedUserKey, userKeyEncryptedDevicePublicKey.encryptedString, deviceKeyEncryptedDevicePrivateKey.encryptedString, ); @@ -250,7 +251,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction { const request = new OtherDeviceKeysUpdateRequest(); request.encryptedPublicKey = newRotateableKeySet.encryptedPublicKey.encryptedString; - request.encryptedUserKey = newRotateableKeySet.encapsulatedDownstreamKey.encryptedString; + request.encryptedUserKey = newRotateableKeySet.encapsulatedDownstreamKey; request.deviceId = device.id; return request; }) @@ -313,7 +314,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction { ); const currentDeviceUpdateRequest = new DeviceKeysUpdateRequest(); - currentDeviceUpdateRequest.encryptedUserKey = encryptedNewUserKey.encryptedString; + currentDeviceUpdateRequest.encryptedUserKey = encryptedNewUserKey; currentDeviceUpdateRequest.encryptedPublicKey = encryptedDevicePublicKey.encryptedString; // TODO: For device management, allow this method to take an array of device ids that can be looped over and individually rotated @@ -387,7 +388,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction { async decryptUserKeyWithDeviceKey( userId: UserId, encryptedDevicePrivateKey: EncString, - encryptedUserKey: EncString, + encryptedUserKey: UnsignedSharedKey, deviceKey: DeviceKey, ): Promise { if (!userId) { @@ -418,7 +419,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction { // Attempt to decrypt encryptedUserDataKey with devicePrivateKey const userKey = await this.encryptService.decapsulateKeyUnsigned( - new EncString(encryptedUserKey.encryptedString), + encryptedUserKey, devicePrivateKey, ); diff --git a/libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts b/libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts index 024a21766ee..fb0496d4573 100644 --- a/libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts +++ b/libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts @@ -40,6 +40,7 @@ import { KeyGenerationService } from "../../crypto"; import { CryptoFunctionService } from "../../crypto/abstractions/crypto-function.service"; import { EncryptService } from "../../crypto/abstractions/encrypt.service"; import { EncString } from "../../crypto/models/enc-string"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { SHOULD_TRUST_DEVICE, @@ -350,7 +351,7 @@ describe("deviceTrustService", () => { const deviceRsaKeyLength = 2048; let mockDeviceRsaKeyPair: [Uint8Array, Uint8Array]; - let mockDevicePublicKeyEncryptedUserKey: EncString; + let mockDevicePublicKeyEncryptedUserKey: UnsignedSharedKey; let mockUserKeyEncryptedDevicePublicKey: EncString; let mockDeviceKeyEncryptedDevicePrivateKey: EncString; @@ -386,10 +387,8 @@ describe("deviceTrustService", () => { new Uint8Array(deviceRsaKeyLength), ]; - mockDevicePublicKeyEncryptedUserKey = new EncString( - EncryptionType.Rsa2048_OaepSha1_B64, - "mockDevicePublicKeyEncryptedUserKey", - ); + mockDevicePublicKeyEncryptedUserKey = + "4.mockDevicePublicKeyEncryptedUserKey" as UnsignedSharedKey; mockUserKeyEncryptedDevicePublicKey = new EncString( EncryptionType.AesCbc256_HmacSha256_B64, @@ -460,7 +459,7 @@ describe("deviceTrustService", () => { expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledTimes(1); expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledWith( mockDeviceId, - mockDevicePublicKeyEncryptedUserKey.encryptedString, + mockDevicePublicKeyEncryptedUserKey, mockUserKeyEncryptedDevicePublicKey.encryptedString, mockDeviceKeyEncryptedDevicePrivateKey.encryptedString, ); @@ -542,7 +541,7 @@ describe("deviceTrustService", () => { describe("decryptUserKeyWithDeviceKey", () => { let mockDeviceKey: DeviceKey; let mockEncryptedDevicePrivateKey: EncString; - let mockEncryptedUserKey: EncString; + let mockEncryptedUserKey: UnsignedSharedKey; let mockUserKey: UserKey; beforeEach(() => { @@ -557,10 +556,7 @@ describe("deviceTrustService", () => { "mockEncryptedDevicePrivateKey", ); - mockEncryptedUserKey = new EncString( - EncryptionType.AesCbc256_HmacSha256_B64, - "mockEncryptedUserKey", - ); + mockEncryptedUserKey = "2.mockEncryptedUserKey" as UnsignedSharedKey; jest.clearAllMocks(); }); @@ -698,7 +694,7 @@ describe("deviceTrustService", () => { encryptService.decryptBytes.mockResolvedValue(null); encryptService.encryptString.mockResolvedValue(new EncString("test_encrypted_data")); encryptService.encapsulateKeyUnsigned.mockResolvedValue( - new EncString("test_encrypted_data"), + "test_encrypted_data" as UnsignedSharedKey, ); const protectedDeviceResponse = new ProtectedDeviceResponse({ @@ -708,7 +704,7 @@ describe("deviceTrustService", () => { name: "Firefox", type: DeviceType.FirefoxBrowser, encryptedPublicKey: "", - encryptedUserKey: "", + encryptedUserKey: "" as UnsignedSharedKey, }); devicesApiService.getDeviceKeys.mockResolvedValue(protectedDeviceResponse); @@ -746,7 +742,7 @@ describe("deviceTrustService", () => { encryptService.unwrapEncapsulationKey.mockResolvedValue(new Uint8Array(64)); encryptService.wrapEncapsulationKey.mockResolvedValue(new EncString("test_encrypted_data")); encryptService.encapsulateKeyUnsigned.mockResolvedValue( - new EncString("test_encrypted_data"), + "test_encrypted_data" as UnsignedSharedKey, ); const protectedDeviceResponse = new ProtectedDeviceResponse({ @@ -756,7 +752,7 @@ describe("deviceTrustService", () => { name: "Firefox", type: DeviceType.FirefoxBrowser, encryptedPublicKey: "", - encryptedUserKey: "", + encryptedUserKey: "" as UnsignedSharedKey, }); devicesApiService.getDeviceKeys.mockResolvedValue(protectedDeviceResponse); const fakeOldUserKeyData = new Uint8Array(64); @@ -823,7 +819,7 @@ describe("deviceTrustService", () => { it("rotates current device keys and calls api service when the current device is trusted", async () => { const currentEncryptedPublicKey = new EncString("2.cHVibGlj|cHVibGlj|cHVibGlj"); - const currentEncryptedUserKey = new EncString("4.dXNlcg=="); + const currentEncryptedUserKey = "4.dXNlcg==" as UnsignedSharedKey; const fakeOldUserKeyData = new Uint8Array(new Uint8Array(64)); // Fill the first byte with something identifiable @@ -849,7 +845,7 @@ describe("deviceTrustService", () => { name: "Firefox", type: DeviceType.FirefoxBrowser, encryptedPublicKey: currentEncryptedPublicKey.encryptedString, - encryptedUserKey: currentEncryptedUserKey.encryptedString, + encryptedUserKey: currentEncryptedUserKey, }), ); }); @@ -871,7 +867,7 @@ describe("deviceTrustService", () => { expect(new Uint8Array(data.toEncoded())[0]).toBe(FakeNewUserKeyMarker); // New key should have the first byte be '1'; expect(new Uint8Array(publicKey)[0]).toBe(FakeDecryptedPublicKeyMarker); - return Promise.resolve(new EncString("4.ZW5jcnlwdGVkdXNlcg==")); + return Promise.resolve("4.ZW5jcnlwdGVkdXNlcg==" as UnsignedSharedKey); }); // Mock the reencryption of the device public key with the new user key diff --git a/libs/common/src/key-management/keys/models/rotateable-key-set.ts b/libs/common/src/key-management/keys/models/rotateable-key-set.ts index 630fa2eebba..65dc5955122 100644 --- a/libs/common/src/key-management/keys/models/rotateable-key-set.ts +++ b/libs/common/src/key-management/keys/models/rotateable-key-set.ts @@ -1,3 +1,5 @@ +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; import { PrfKey } from "../../../types/key"; import { EncString } from "../../crypto/models/enc-string"; @@ -21,7 +23,7 @@ export class RotateableKeySet { it("should create a new key set", async () => { const externalKey = createSymmetricKey(); const userKey = createSymmetricKey(); - const encryptedUserKey = new EncString("encryptedUserKey"); + const encryptedUserKey = "encryptedUserKey" as UnsignedSharedKey; const encryptedPublicKey = new EncString("encryptedPublicKey"); const encryptedPrivateKey = new EncString("encryptedPrivateKey"); keyService.makeKeyPair.mockResolvedValue(["publicKey", encryptedPrivateKey]); @@ -73,7 +74,7 @@ describe("DefaultRotateableKeySetService", () => { describe("rotateKeySet", () => { const keySet = new RotateableKeySet( - new EncString("encUserKey"), + "encUserKey" as UnsignedSharedKey, new EncString("encPublicKey"), new EncString("encPrivateKey"), ); @@ -149,7 +150,7 @@ describe("DefaultRotateableKeySetService", () => { const newDownstreamKey = new SymmetricCryptoKey(new Uint8Array(64)); const publicKey = Utils.fromB64ToArray("decryptedPublicKey"); const newEncryptedPublicKey = new EncString("newEncPublicKey"); - const newEncryptedRotateableKey = new EncString("newEncUserKey"); + const newEncryptedRotateableKey = "newEncUserKey" as UnsignedSharedKey; encryptService.unwrapEncapsulationKey.mockResolvedValue(publicKey); encryptService.wrapEncapsulationKey.mockResolvedValue(newEncryptedPublicKey); diff --git a/libs/common/src/key-management/keys/services/default-rotateable-key-set.service.ts b/libs/common/src/key-management/keys/services/default-rotateable-key-set.service.ts index 3e568cb2aee..008a6c999a8 100644 --- a/libs/common/src/key-management/keys/services/default-rotateable-key-set.service.ts +++ b/libs/common/src/key-management/keys/services/default-rotateable-key-set.service.ts @@ -67,13 +67,13 @@ export class DefaultRotateableKeySetService implements RotateableKeySetService { publicKey, newDownstreamKey, ); - const newEncryptedRotateableKey = await this.encryptService.encapsulateKeyUnsigned( + const encapsulatedDownstreamKey = await this.encryptService.encapsulateKeyUnsigned( newDownstreamKey, publicKey, ); const newRotateableKeySet = new RotateableKeySet( - newEncryptedRotateableKey, + encapsulatedDownstreamKey, newEncryptedPublicKey, keySet.encryptedPrivateKey, ); diff --git a/libs/common/src/platform/services/key-state/provider-keys.state.ts b/libs/common/src/platform/services/key-state/provider-keys.state.ts index cbc8fb69beb..ecb49720c61 100644 --- a/libs/common/src/platform/services/key-state/provider-keys.state.ts +++ b/libs/common/src/platform/services/key-state/provider-keys.state.ts @@ -1,8 +1,9 @@ -import { EncryptedString } from "../../../key-management/crypto/models/enc-string"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; + import { ProviderId } from "../../../types/guid"; import { CRYPTO_DISK, UserKeyDefinition } from "../../state"; -export const USER_ENCRYPTED_PROVIDER_KEYS = UserKeyDefinition.record( +export const USER_ENCRYPTED_PROVIDER_KEYS = UserKeyDefinition.record( CRYPTO_DISK, "providerKeys", { diff --git a/libs/key-management/src/abstractions/key.service.ts b/libs/key-management/src/abstractions/key.service.ts index feb4a38ac27..2a5513f0698 100644 --- a/libs/key-management/src/abstractions/key.service.ts +++ b/libs/key-management/src/abstractions/key.service.ts @@ -20,6 +20,7 @@ import { UserPrivateKey, UserPublicKey, } from "@bitwarden/common/types/key"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { KdfConfig } from "../models/kdf-config"; @@ -262,7 +263,9 @@ export abstract class KeyService { * @throws Error when no public key is found for the target user. * @returns The new encrypted OrgKey | ProviderKey and the decrypted key itself */ - abstract makeOrgKey(userId: UserId): Promise<[EncString, T]>; + abstract makeOrgKey( + userId: UserId, + ): Promise<[UnsignedSharedKey, T]>; /** * Sets the user's encrypted private key in storage and * clears the decrypted private key from memory diff --git a/libs/key-management/src/key.service.spec.ts b/libs/key-management/src/key.service.spec.ts index a5b4eb01c7c..af4146f38e0 100644 --- a/libs/key-management/src/key.service.spec.ts +++ b/libs/key-management/src/key.service.spec.ts @@ -47,6 +47,7 @@ import { OrgKey, ProviderKey, } from "@bitwarden/common/types/key"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { KdfConfigService } from "./abstractions/kdf-config.service"; import { UserPrivateKeyDecryptionFailedError } from "./abstractions/key.service"; @@ -516,13 +517,12 @@ describe("keyService", () => { return output; } - function fakeOrgKeyDecryption(encryptedString: EncString, userPrivateKey: Uint8Array) { + function fakeOrgKeyDecryption(encryptedString: UnsignedSharedKey, userPrivateKey: Uint8Array) { const output = new Uint8Array(64); - output.set(encryptedString.dataBytes); - output.set( - userPrivateKey.subarray(0, 64 - encryptedString.dataBytes.length), - encryptedString.dataBytes.length, - ); + const dataBytes = encryptedString.split(".")[1]; + const dataBytesArray = Uint8Array.from(atob(dataBytes), (c) => c.charCodeAt(0)); + output.set(dataBytesArray); + output.set(userPrivateKey.subarray(0, 64 - dataBytes.length), dataBytes.length); return output; } @@ -532,7 +532,7 @@ describe("keyService", () => { userKey: UserKey; encryptedPrivateKey: EncString; orgKeys: Record; - providerKeys: Record; + providerKeys: Record; }; function updateKeys(keys: Partial = {}) { @@ -595,7 +595,7 @@ describe("keyService", () => { userKey: makeSymmetricCryptoKey(64), encryptedPrivateKey: makeEncString("privateKey"), orgKeys: { - [org1Id]: { type: "organization", key: makeEncString("org1Key").encryptedString! }, + [org1Id]: { type: "organization", key: "org1Key" as UnsignedSharedKey }, }, }); @@ -615,7 +615,7 @@ describe("keyService", () => { userKey: makeSymmetricCryptoKey(64), encryptedPrivateKey: makeEncString("privateKey"), orgKeys: { - [org1Id]: { type: "organization", key: makeEncString("org1Key").encryptedString! }, + [org1Id]: { type: "organization", key: "org1Key" as UnsignedSharedKey }, }, providerKeys: {}, }); @@ -637,7 +637,7 @@ describe("keyService", () => { userKey: makeSymmetricCryptoKey(64), encryptedPrivateKey: makeEncString("privateKey"), orgKeys: { - [org1Id]: { type: "organization", key: makeEncString("org1Key").encryptedString! }, + [org1Id]: { type: "organization", key: "org1Key" as UnsignedSharedKey }, [org2Id]: { type: "provider", key: makeEncString("provider1Key").encryptedString!, @@ -645,7 +645,7 @@ describe("keyService", () => { }, }, providerKeys: { - provider1: makeEncString("provider1Key").encryptedString!, + provider1: "provider1Key" as UnsignedSharedKey, }, }); @@ -700,7 +700,7 @@ describe("keyService", () => { // User has their org keys set updateKeys({ orgKeys: { - [org1Id]: { type: "organization", key: makeEncString("org1Key").encryptedString! }, + [org1Id]: { type: "organization", key: "org1Key" as UnsignedSharedKey }, }, }); @@ -1003,7 +1003,7 @@ describe("keyService", () => { describe("makeOrgKey", () => { const mockUserPublicKey = new Uint8Array(64) as UserPublicKey; const shareKey = new SymmetricCryptoKey(new Uint8Array(64)); - const mockEncapsulatedKey = new EncString("mockEncapsulatedKey"); + const mockEncapsulatedKey = "mockEncapsulatedKey" as UnsignedSharedKey; beforeEach(() => { keyService.userPublicKey$ = jest diff --git a/libs/key-management/src/key.service.ts b/libs/key-management/src/key.service.ts index f0e5f6ee08e..e90b4ff7f79 100644 --- a/libs/key-management/src/key.service.ts +++ b/libs/key-management/src/key.service.ts @@ -60,6 +60,7 @@ import { UserPrivateKey, UserPublicKey, } from "@bitwarden/common/types/key"; +import { UnsignedSharedKey } from "@bitwarden/sdk-internal"; import { KdfConfigService } from "./abstractions/kdf-config.service"; import { @@ -434,10 +435,10 @@ export class DefaultKeyService implements KeyServiceAbstraction { async setProviderKeys(providers: ProfileProviderResponse[], userId: UserId): Promise { await this.stateProvider.getUser(userId, USER_ENCRYPTED_PROVIDER_KEYS).update(() => { - const encProviderKeys: { [providerId: ProviderId]: EncryptedString } = {}; + const encProviderKeys: { [providerId: ProviderId]: UnsignedSharedKey } = {}; providers.forEach((provider) => { - encProviderKeys[provider.id as ProviderId] = provider.key as EncryptedString; + encProviderKeys[provider.id as ProviderId] = provider.key; }); return encProviderKeys; @@ -464,7 +465,9 @@ export class DefaultKeyService implements KeyServiceAbstraction { await this.stateProvider.setUserState(USER_ENCRYPTED_PROVIDER_KEYS, null, userId); } - async makeOrgKey(userId: UserId): Promise<[EncString, T]> { + async makeOrgKey( + userId: UserId, + ): Promise<[UnsignedSharedKey, T]> { if (userId == null) { throw new Error("UserId is required"); } @@ -856,7 +859,7 @@ export class DefaultKeyService implements KeyServiceAbstraction { // Convert each value in the record to it's own decryption observable convertValues(async (_, value) => { const decapsulatedKey = await this.encryptService.decapsulateKeyUnsigned( - new EncString(value), + value, userPrivateKey, ); return decapsulatedKey as ProviderKey; @@ -917,7 +920,7 @@ export class DefaultKeyService implements KeyServiceAbstraction { switchMap(async ([encryptedOrgKeys, providerKeys]) => { const userPubKey = await this.derivePublicKey(userPrivateKey); - const result: Record = {}; + const result: Record = {}; encryptedOrgKeys = encryptedOrgKeys ?? {}; for (const orgId of Object.keys(encryptedOrgKeys) as OrganizationId[]) { if (result[orgId] != null) { @@ -928,7 +931,7 @@ export class DefaultKeyService implements KeyServiceAbstraction { continue; } - let orgKey: EncString; + let orgKey: UnsignedSharedKey; // Because the SDK only supports user encrypted org keys, we need to re-encrypt // any provider encrypted org keys with the user's public key. This should be removed