1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-22 11:45:59 +01:00

Move asymmetric crypto functions out of crypto service (#10903)

This commit is contained in:
Bernd Schoolmann 2024-10-01 08:47:41 -07:00 committed by GitHub
parent f2339b0586
commit dafe795854
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 126 additions and 152 deletions

View File

@ -753,6 +753,7 @@ export default class MainBackground {
this.accountService, this.accountService,
this.masterPasswordService, this.masterPasswordService,
this.cryptoService, this.cryptoService,
this.encryptService,
this.apiService, this.apiService,
this.stateProvider, this.stateProvider,
); );

View File

@ -4,6 +4,7 @@ import {
} from "@bitwarden/admin-console/common"; } from "@bitwarden/admin-console/common";
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { Response } from "../../models/response"; import { Response } from "../../models/response";
@ -12,6 +13,7 @@ export class ConfirmCommand {
constructor( constructor(
private apiService: ApiService, private apiService: ApiService,
private cryptoService: CryptoService, private cryptoService: CryptoService,
private encryptService: EncryptService,
private organizationUserApiService: OrganizationUserApiService, private organizationUserApiService: OrganizationUserApiService,
) {} ) {}
@ -53,7 +55,7 @@ export class ConfirmCommand {
} }
const publicKeyResponse = await this.apiService.getUserPublicKey(orgUser.userId); const publicKeyResponse = await this.apiService.getUserPublicKey(orgUser.userId);
const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey); const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);
const key = await this.cryptoService.rsaEncrypt(orgKey.key, publicKey); const key = await this.encryptService.rsaEncrypt(orgKey.key, publicKey);
const req = new OrganizationUserConfirmRequest(); const req = new OrganizationUserConfirmRequest();
req.key = key.encryptedString; req.key = key.encryptedString;
await this.organizationUserApiService.postOrganizationUserConfirm( await this.organizationUserApiService.postOrganizationUserConfirm(

View File

@ -117,6 +117,7 @@ export class OssServeConfigurator {
this.confirmCommand = new ConfirmCommand( this.confirmCommand = new ConfirmCommand(
this.serviceContainer.apiService, this.serviceContainer.apiService,
this.serviceContainer.cryptoService, this.serviceContainer.cryptoService,
this.serviceContainer.encryptService,
this.serviceContainer.organizationUserApiService, this.serviceContainer.organizationUserApiService,
); );
this.restoreCommand = new RestoreCommand(this.serviceContainer.cipherService); this.restoreCommand = new RestoreCommand(this.serviceContainer.cipherService);

View File

@ -534,6 +534,7 @@ export class ServiceContainer {
this.accountService, this.accountService,
this.masterPasswordService, this.masterPasswordService,
this.cryptoService, this.cryptoService,
this.encryptService,
this.apiService, this.apiService,
this.stateProvider, this.stateProvider,
); );

View File

@ -415,6 +415,7 @@ export class VaultProgram extends BaseProgram {
const command = new ConfirmCommand( const command = new ConfirmCommand(
this.serviceContainer.apiService, this.serviceContainer.apiService,
this.serviceContainer.cryptoService, this.serviceContainer.cryptoService,
this.serviceContainer.encryptService,
this.serviceContainer.organizationUserApiService, this.serviceContainer.organizationUserApiService,
); );
const response = await command.run(object, id, cmd); const response = await command.run(object, id, cmd);

View File

@ -287,6 +287,7 @@ const safeProviders: SafeProvider[] = [
deps: [ deps: [
ApiService, ApiService,
CryptoService, CryptoService,
EncryptService,
I18nServiceAbstraction, I18nServiceAbstraction,
KdfConfigService, KdfConfigService,
InternalMasterPasswordServiceAbstraction, InternalMasterPasswordServiceAbstraction,

View File

@ -8,6 +8,7 @@ import { ProviderUserBulkPublicKeyResponse } from "@bitwarden/common/admin-conso
import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response"; import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response";
import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
@ -31,6 +32,7 @@ export abstract class BaseBulkConfirmComponent implements OnInit {
protected constructor( protected constructor(
protected cryptoService: CryptoService, protected cryptoService: CryptoService,
protected encryptService: EncryptService,
protected i18nService: I18nService, protected i18nService: I18nService,
) {} ) {}
@ -67,7 +69,7 @@ export abstract class BaseBulkConfirmComponent implements OnInit {
if (publicKey == null) { if (publicKey == null) {
continue; continue;
} }
const encryptedKey = await this.cryptoService.rsaEncrypt(key.key, publicKey); const encryptedKey = await this.encryptService.rsaEncrypt(key.key, publicKey);
userIdsWithKeys.push({ userIdsWithKeys.push({
id: user.id, id: user.id,
key: encryptedKey.encryptedString, key: encryptedKey.encryptedString,

View File

@ -8,6 +8,7 @@ import {
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums"; import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
@ -41,6 +42,7 @@ export class BulkConfirmComponent implements OnInit {
constructor( constructor(
@Inject(DIALOG_DATA) protected data: BulkConfirmDialogData, @Inject(DIALOG_DATA) protected data: BulkConfirmDialogData,
protected cryptoService: CryptoService, protected cryptoService: CryptoService,
protected encryptService: EncryptService,
protected apiService: ApiService, protected apiService: ApiService,
private organizationUserApiService: OrganizationUserApiService, private organizationUserApiService: OrganizationUserApiService,
private i18nService: I18nService, private i18nService: I18nService,
@ -81,7 +83,7 @@ export class BulkConfirmComponent implements OnInit {
if (publicKey == null) { if (publicKey == null) {
continue; continue;
} }
const encryptedKey = await this.cryptoService.rsaEncrypt(key.key, publicKey); const encryptedKey = await this.encryptService.rsaEncrypt(key.key, publicKey);
userIdsWithKeys.push({ userIdsWithKeys.push({
id: user.id, id: user.id,
key: encryptedKey.encryptedString, key: encryptedKey.encryptedString,

View File

@ -39,6 +39,7 @@ import { isNotSelfUpgradable, ProductTierType } from "@bitwarden/common/billing/
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
@ -107,6 +108,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
i18nService: I18nService, i18nService: I18nService,
organizationManagementPreferencesService: OrganizationManagementPreferencesService, organizationManagementPreferencesService: OrganizationManagementPreferencesService,
cryptoService: CryptoService, cryptoService: CryptoService,
private encryptService: EncryptService,
validationService: ValidationService, validationService: ValidationService,
logService: LogService, logService: LogService,
userNamePipe: UserNamePipe, userNamePipe: UserNamePipe,
@ -289,7 +291,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
async confirmUser(user: OrganizationUserView, publicKey: Uint8Array): Promise<void> { async confirmUser(user: OrganizationUserView, publicKey: Uint8Array): Promise<void> {
const orgKey = await this.cryptoService.getOrgKey(this.organization.id); const orgKey = await this.cryptoService.getOrgKey(this.organization.id);
const key = await this.cryptoService.rsaEncrypt(orgKey.key, publicKey); const key = await this.encryptService.rsaEncrypt(orgKey.key, publicKey);
const request = new OrganizationUserConfirmRequest(); const request = new OrganizationUserConfirmRequest();
request.key = key.encryptedString; request.key = key.encryptedString;
await this.organizationUserApiService.postOrganizationUserConfirm( await this.organizationUserApiService.postOrganizationUserConfirm(

View File

@ -71,7 +71,7 @@ describe("OrganizationUserResetPasswordService", () => {
const mockUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey; const mockUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey;
cryptoService.getUserKey.mockResolvedValue(mockUserKey); cryptoService.getUserKey.mockResolvedValue(mockUserKey);
cryptoService.rsaEncrypt.mockResolvedValue( encryptService.rsaEncrypt.mockResolvedValue(
new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "mockEncryptedUserKey"), new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "mockEncryptedUserKey"),
); );
}); });
@ -103,7 +103,7 @@ describe("OrganizationUserResetPasswordService", () => {
it("should rsa encrypt the user key", async () => { it("should rsa encrypt the user key", async () => {
await sut.buildRecoveryKey(mockOrgId); await sut.buildRecoveryKey(mockOrgId);
expect(cryptoService.rsaEncrypt).toHaveBeenCalledWith(expect.anything(), expect.anything()); expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(expect.anything(), expect.anything());
}); });
}); });
@ -128,7 +128,7 @@ describe("OrganizationUserResetPasswordService", () => {
cryptoService.getOrgKey.mockResolvedValue(mockOrgKey); cryptoService.getOrgKey.mockResolvedValue(mockOrgKey);
encryptService.decryptToBytes.mockResolvedValue(mockRandomBytes); encryptService.decryptToBytes.mockResolvedValue(mockRandomBytes);
cryptoService.rsaDecrypt.mockResolvedValue(mockRandomBytes); encryptService.rsaDecrypt.mockResolvedValue(mockRandomBytes);
const mockMasterKey = new SymmetricCryptoKey(mockRandomBytes) as MasterKey; const mockMasterKey = new SymmetricCryptoKey(mockRandomBytes) as MasterKey;
cryptoService.makeMasterKey.mockResolvedValue(mockMasterKey); cryptoService.makeMasterKey.mockResolvedValue(mockMasterKey);
cryptoService.hashMasterKey.mockResolvedValue("test-master-key-hash"); cryptoService.hashMasterKey.mockResolvedValue("test-master-key-hash");
@ -172,7 +172,7 @@ describe("OrganizationUserResetPasswordService", () => {
publicKey: "test-public-key", publicKey: "test-public-key",
}), }),
); );
cryptoService.rsaEncrypt.mockResolvedValue( encryptService.rsaEncrypt.mockResolvedValue(
new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "mockEncryptedUserKey"), new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "mockEncryptedUserKey"),
); );
}); });

View File

@ -57,7 +57,7 @@ export class OrganizationUserResetPasswordService
if (userKey == null) { if (userKey == null) {
throw new Error("No user key found"); throw new Error("No user key found");
} }
const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey); const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey);
return encryptedKey.encryptedString; return encryptedKey.encryptedString;
} }
@ -96,7 +96,10 @@ export class OrganizationUserResetPasswordService
); );
// Decrypt User's Reset Password Key to get UserKey // Decrypt User's Reset Password Key to get UserKey
const decValue = await this.cryptoService.rsaDecrypt(response.resetPasswordKey, decPrivateKey); const decValue = await this.encryptService.rsaDecrypt(
new EncString(response.resetPasswordKey),
decPrivateKey,
);
const existingUserKey = new SymmetricCryptoKey(decValue) as UserKey; const existingUserKey = new SymmetricCryptoKey(decValue) as UserKey;
// determine Kdf Algorithm // determine Kdf Algorithm

View File

@ -35,7 +35,7 @@ describe("RotateableKeySetService", () => {
const encryptedPrivateKey = Symbol(); const encryptedPrivateKey = Symbol();
cryptoService.makeKeyPair.mockResolvedValue(["publicKey", encryptedPrivateKey as any]); cryptoService.makeKeyPair.mockResolvedValue(["publicKey", encryptedPrivateKey as any]);
cryptoService.getUserKey.mockResolvedValue({ key: userKey.key } as any); cryptoService.getUserKey.mockResolvedValue({ key: userKey.key } as any);
cryptoService.rsaEncrypt.mockResolvedValue(encryptedUserKey as any); encryptService.rsaEncrypt.mockResolvedValue(encryptedUserKey as any);
encryptService.encrypt.mockResolvedValue(encryptedPublicKey as any); encryptService.encrypt.mockResolvedValue(encryptedPublicKey as any);
const result = await service.createKeySet(externalKey as any); const result = await service.createKeySet(externalKey as any);

View File

@ -25,7 +25,7 @@ export class RotateableKeySetService {
const userKey = await this.cryptoService.getUserKey(); const userKey = await this.cryptoService.getUserKey();
const rawPublicKey = Utils.fromB64ToArray(publicKey); const rawPublicKey = Utils.fromB64ToArray(publicKey);
const encryptedUserKey = await this.cryptoService.rsaEncrypt(userKey.key, rawPublicKey); const encryptedUserKey = await this.encryptService.rsaEncrypt(userKey.key, rawPublicKey);
const encryptedPublicKey = await this.encryptService.encrypt(rawPublicKey, userKey); const encryptedPublicKey = await this.encryptService.encrypt(rawPublicKey, userKey);
return new RotateableKeySet(encryptedUserKey, encryptedPublicKey, encryptedPrivateKey); return new RotateableKeySet(encryptedUserKey, encryptedPublicKey, encryptedPrivateKey);
} }

View File

@ -132,7 +132,7 @@ describe("EmergencyAccessService", () => {
cryptoService.getUserKey.mockResolvedValueOnce(mockUserKey); cryptoService.getUserKey.mockResolvedValueOnce(mockUserKey);
apiService.getUserPublicKey.mockResolvedValueOnce(mockUserPublicKeyResponse); apiService.getUserPublicKey.mockResolvedValueOnce(mockUserPublicKeyResponse);
cryptoService.rsaEncrypt.mockResolvedValueOnce(mockUserPublicKeyEncryptedUserKey); encryptService.rsaEncrypt.mockResolvedValueOnce(mockUserPublicKeyEncryptedUserKey);
emergencyAccessApiService.postEmergencyAccessConfirm.mockResolvedValueOnce(); emergencyAccessApiService.postEmergencyAccessConfirm.mockResolvedValueOnce();
@ -162,7 +162,7 @@ describe("EmergencyAccessService", () => {
const mockDecryptedGrantorUserKey = new Uint8Array(64); const mockDecryptedGrantorUserKey = new Uint8Array(64);
cryptoService.getPrivateKey.mockResolvedValue(new Uint8Array(64)); cryptoService.getPrivateKey.mockResolvedValue(new Uint8Array(64));
cryptoService.rsaDecrypt.mockResolvedValueOnce(mockDecryptedGrantorUserKey); encryptService.rsaDecrypt.mockResolvedValueOnce(mockDecryptedGrantorUserKey);
const mockMasterKey = new SymmetricCryptoKey(new Uint8Array(64) as CsprngArray) as MasterKey; const mockMasterKey = new SymmetricCryptoKey(new Uint8Array(64) as CsprngArray) as MasterKey;
@ -200,7 +200,7 @@ describe("EmergencyAccessService", () => {
}); });
it("should not post a new password if decryption fails", async () => { it("should not post a new password if decryption fails", async () => {
cryptoService.rsaDecrypt.mockResolvedValueOnce(null); encryptService.rsaDecrypt.mockResolvedValueOnce(null);
emergencyAccessApiService.postEmergencyAccessTakeover.mockResolvedValueOnce({ emergencyAccessApiService.postEmergencyAccessTakeover.mockResolvedValueOnce({
keyEncrypted: "EncryptedKey", keyEncrypted: "EncryptedKey",
kdf: KdfType.PBKDF2_SHA256, kdf: KdfType.PBKDF2_SHA256,
@ -259,7 +259,7 @@ describe("EmergencyAccessService", () => {
publicKey: "mockPublicKey", publicKey: "mockPublicKey",
} as UserKeyResponse); } as UserKeyResponse);
cryptoService.rsaEncrypt.mockImplementation((plainValue, publicKey) => { encryptService.rsaEncrypt.mockImplementation((plainValue, publicKey) => {
return Promise.resolve( return Promise.resolve(
new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "Encrypted: " + plainValue), new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "Encrypted: " + plainValue),
); );

View File

@ -17,7 +17,7 @@ import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { KdfType } from "@bitwarden/common/platform/enums"; import { KdfType } from "@bitwarden/common/platform/enums";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { UserId } from "@bitwarden/common/types/guid"; import { UserId } from "@bitwarden/common/types/guid";
import { UserKey } from "@bitwarden/common/types/key"; import { UserKey } from "@bitwarden/common/types/key";
@ -224,8 +224,8 @@ export class EmergencyAccessService
throw new Error("Active user does not have a private key, cannot get view only ciphers."); throw new Error("Active user does not have a private key, cannot get view only ciphers.");
} }
const grantorKeyBuffer = await this.cryptoService.rsaDecrypt( const grantorKeyBuffer = await this.encryptService.rsaDecrypt(
response.keyEncrypted, new EncString(response.keyEncrypted),
activeUserPrivateKey, activeUserPrivateKey,
); );
const grantorUserKey = new SymmetricCryptoKey(grantorKeyBuffer) as UserKey; const grantorUserKey = new SymmetricCryptoKey(grantorKeyBuffer) as UserKey;
@ -261,8 +261,8 @@ export class EmergencyAccessService
throw new Error("Active user does not have a private key, cannot complete a takeover."); throw new Error("Active user does not have a private key, cannot complete a takeover.");
} }
const grantorKeyBuffer = await this.cryptoService.rsaDecrypt( const grantorKeyBuffer = await this.encryptService.rsaDecrypt(
takeoverResponse.keyEncrypted, new EncString(takeoverResponse.keyEncrypted),
activeUserPrivateKey, activeUserPrivateKey,
); );
if (grantorKeyBuffer == null) { if (grantorKeyBuffer == null) {
@ -355,6 +355,6 @@ export class EmergencyAccessService
} }
private async encryptKey(userKey: UserKey, publicKey: Uint8Array): Promise<EncryptedString> { private async encryptKey(userKey: UserKey, publicKey: Uint8Array): Promise<EncryptedString> {
return (await this.cryptoService.rsaEncrypt(userKey.key, publicKey)).encryptedString; return (await this.encryptService.rsaEncrypt(userKey.key, publicKey)).encryptedString;
} }
} }

View File

@ -184,7 +184,7 @@ export class AcceptOrganizationInviteService {
// RSA Encrypt user's encKey.key with organization public key // RSA Encrypt user's encKey.key with organization public key
const userKey = await this.cryptoService.getUserKey(); const userKey = await this.cryptoService.getUserKey();
const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey); const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey);
// Add reset password key to accept request // Add reset password key to accept request
request.resetPasswordKey = encryptedKey.encryptedString; request.resetPasswordKey = encryptedKey.encryptedString;

View File

@ -35,6 +35,7 @@ import { ClientType } from "@bitwarden/common/enums";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service";
@ -202,6 +203,7 @@ const safeProviders: SafeProvider[] = [
deps: [ deps: [
ApiService, ApiService,
CryptoServiceAbstraction, CryptoServiceAbstraction,
EncryptService,
I18nServiceAbstraction, I18nServiceAbstraction,
KdfConfigService, KdfConfigService,
InternalMasterPasswordServiceAbstraction, InternalMasterPasswordServiceAbstraction,

View File

@ -124,8 +124,8 @@ describe("OrganizationAuthRequestService", () => {
); );
const encryptedUserKey = new EncString("encryptedUserKey"); const encryptedUserKey = new EncString("encryptedUserKey");
cryptoService.rsaDecrypt.mockResolvedValue(new Uint8Array(32)); encryptService.rsaDecrypt.mockResolvedValue(new Uint8Array(32));
cryptoService.rsaEncrypt.mockResolvedValue(encryptedUserKey); encryptService.rsaEncrypt.mockResolvedValue(encryptedUserKey);
const mockPendingAuthRequest = new PendingAuthRequestView(); const mockPendingAuthRequest = new PendingAuthRequestView();
mockPendingAuthRequest.id = "requestId1"; mockPendingAuthRequest.id = "requestId1";
@ -166,8 +166,8 @@ describe("OrganizationAuthRequestService", () => {
); );
const encryptedUserKey = new EncString("encryptedUserKey"); const encryptedUserKey = new EncString("encryptedUserKey");
cryptoService.rsaDecrypt.mockResolvedValue(new Uint8Array(32)); encryptService.rsaDecrypt.mockResolvedValue(new Uint8Array(32));
cryptoService.rsaEncrypt.mockResolvedValue(encryptedUserKey); encryptService.rsaEncrypt.mockResolvedValue(encryptedUserKey);
const mockPendingAuthRequest = new PendingAuthRequestView(); const mockPendingAuthRequest = new PendingAuthRequestView();
mockPendingAuthRequest.id = "requestId1"; mockPendingAuthRequest.id = "requestId1";

View File

@ -117,10 +117,13 @@ export class OrganizationAuthRequestService {
); );
// Decrypt user key with decrypted org private key // Decrypt user key with decrypted org private key
const decValue = await this.cryptoService.rsaDecrypt(encryptedUserKey, decOrgPrivateKey); const decValue = await this.encryptService.rsaDecrypt(
new EncString(encryptedUserKey),
decOrgPrivateKey,
);
const userKey = new SymmetricCryptoKey(decValue); const userKey = new SymmetricCryptoKey(decValue);
// Re-encrypt user Key with the Device Public Key // Re-encrypt user Key with the Device Public Key
return await this.cryptoService.rsaEncrypt(userKey.key, devicePubKey); return await this.encryptService.rsaEncrypt(userKey.key, devicePubKey);
} }
} }

View File

@ -13,6 +13,7 @@ import { ProviderUserBulkPublicKeyResponse } from "@bitwarden/common/admin-conso
import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response"; import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response";
import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { DialogService } from "@bitwarden/components"; import { DialogService } from "@bitwarden/components";
@ -34,10 +35,11 @@ export class BulkConfirmDialogComponent extends BaseBulkConfirmComponent {
constructor( constructor(
private apiService: ApiService, private apiService: ApiService,
protected cryptoService: CryptoService, protected cryptoService: CryptoService,
protected encryptService: EncryptService,
@Inject(DIALOG_DATA) protected dialogParams: BulkConfirmDialogParams, @Inject(DIALOG_DATA) protected dialogParams: BulkConfirmDialogParams,
protected i18nService: I18nService, protected i18nService: I18nService,
) { ) {
super(cryptoService, i18nService); super(cryptoService, encryptService, i18nService);
this.providerId = dialogParams.providerId; this.providerId = dialogParams.providerId;
this.users = dialogParams.users; this.users = dialogParams.users;

View File

@ -15,6 +15,7 @@ import { ProviderUserConfirmRequest } from "@bitwarden/common/admin-console/mode
import { ProviderUserUserDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user.response"; import { ProviderUserUserDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user.response";
import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
@ -66,6 +67,7 @@ export class MembersComponent extends BaseMembersComponent<ProviderUser> {
toastService: ToastService, toastService: ToastService,
userNamePipe: UserNamePipe, userNamePipe: UserNamePipe,
validationService: ValidationService, validationService: ValidationService,
private encryptService: EncryptService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private providerService: ProviderService, private providerService: ProviderService,
private router: Router, private router: Router,
@ -184,7 +186,7 @@ export class MembersComponent extends BaseMembersComponent<ProviderUser> {
async confirmUser(user: ProviderUser, publicKey: Uint8Array): Promise<void> { async confirmUser(user: ProviderUser, publicKey: Uint8Array): Promise<void> {
const providerKey = await this.cryptoService.getProviderKey(this.providerId); const providerKey = await this.cryptoService.getProviderKey(this.providerId);
const key = await this.cryptoService.rsaEncrypt(providerKey.key, publicKey); const key = await this.encryptService.rsaEncrypt(providerKey.key, publicKey);
const request = new ProviderUserConfirmRequest(); const request = new ProviderUserConfirmRequest();
request.key = key.encryptedString; request.key = key.encryptedString;
await this.apiService.postProviderUserConfirm(this.providerId, user.id, request); await this.apiService.postProviderUserConfirm(this.providerId, user.id, request);

View File

@ -17,6 +17,7 @@ import { ProviderUserUserDetailsResponse } from "@bitwarden/common/admin-console
import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -65,6 +66,7 @@ export class PeopleComponent
modalService: ModalService, modalService: ModalService,
platformUtilsService: PlatformUtilsService, platformUtilsService: PlatformUtilsService,
cryptoService: CryptoService, cryptoService: CryptoService,
private encryptService: EncryptService,
private router: Router, private router: Router,
searchService: SearchService, searchService: SearchService,
validationService: ValidationService, validationService: ValidationService,
@ -150,7 +152,7 @@ export class PeopleComponent
async confirmUser(user: ProviderUserUserDetailsResponse, publicKey: Uint8Array): Promise<any> { async confirmUser(user: ProviderUserUserDetailsResponse, publicKey: Uint8Array): Promise<any> {
const providerKey = await this.cryptoService.getProviderKey(this.providerId); const providerKey = await this.cryptoService.getProviderKey(this.providerId);
const key = await this.cryptoService.rsaEncrypt(providerKey.key, publicKey); const key = await this.encryptService.rsaEncrypt(providerKey.key, publicKey);
const request = new ProviderUserConfirmRequest(); const request = new ProviderUserConfirmRequest();
request.key = key.encryptedString; request.key = key.encryptedString;
await this.apiService.postProviderUserConfirm(this.providerId, user.id, request); await this.apiService.postProviderUserConfirm(this.providerId, user.id, request);

View File

@ -215,7 +215,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent implements
// RSA Encrypt user key with organization public key // RSA Encrypt user key with organization public key
const userKey = await this.cryptoService.getUserKey(); const userKey = await this.cryptoService.getUserKey();
const encryptedUserKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey); const encryptedUserKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey);
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest(); const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
resetRequest.masterPasswordHash = masterPasswordHash; resetRequest.masterPasswordHash = masterPasswordHash;

View File

@ -961,6 +961,7 @@ const safeProviders: SafeProvider[] = [
OrganizationApiServiceAbstraction, OrganizationApiServiceAbstraction,
AccountServiceAbstraction, AccountServiceAbstraction,
CryptoServiceAbstraction, CryptoServiceAbstraction,
EncryptService,
OrganizationUserApiService, OrganizationUserApiService,
I18nServiceAbstraction, I18nServiceAbstraction,
], ],
@ -1090,6 +1091,7 @@ const safeProviders: SafeProvider[] = [
AccountServiceAbstraction, AccountServiceAbstraction,
InternalMasterPasswordServiceAbstraction, InternalMasterPasswordServiceAbstraction,
CryptoServiceAbstraction, CryptoServiceAbstraction,
EncryptService,
ApiServiceAbstraction, ApiServiceAbstraction,
StateProvider, StateProvider,
], ],
@ -1285,6 +1287,7 @@ const safeProviders: SafeProvider[] = [
deps: [ deps: [
ApiServiceAbstraction, ApiServiceAbstraction,
CryptoServiceAbstraction, CryptoServiceAbstraction,
EncryptService,
I18nServiceAbstraction, I18nServiceAbstraction,
KdfConfigServiceAbstraction, KdfConfigServiceAbstraction,
InternalMasterPasswordServiceAbstraction, InternalMasterPasswordServiceAbstraction,

View File

@ -15,6 +15,7 @@ import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-con
import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request";
import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
@ -33,6 +34,7 @@ describe("DefaultSetPasswordJitService", () => {
let apiService: MockProxy<ApiService>; let apiService: MockProxy<ApiService>;
let cryptoService: MockProxy<CryptoService>; let cryptoService: MockProxy<CryptoService>;
let encryptService: MockProxy<EncryptService>;
let i18nService: MockProxy<I18nService>; let i18nService: MockProxy<I18nService>;
let kdfConfigService: MockProxy<KdfConfigService>; let kdfConfigService: MockProxy<KdfConfigService>;
let masterPasswordService: MockProxy<InternalMasterPasswordServiceAbstraction>; let masterPasswordService: MockProxy<InternalMasterPasswordServiceAbstraction>;
@ -43,6 +45,7 @@ describe("DefaultSetPasswordJitService", () => {
beforeEach(() => { beforeEach(() => {
apiService = mock<ApiService>(); apiService = mock<ApiService>();
cryptoService = mock<CryptoService>(); cryptoService = mock<CryptoService>();
encryptService = mock<EncryptService>();
i18nService = mock<I18nService>(); i18nService = mock<I18nService>();
kdfConfigService = mock<KdfConfigService>(); kdfConfigService = mock<KdfConfigService>();
masterPasswordService = mock<InternalMasterPasswordServiceAbstraction>(); masterPasswordService = mock<InternalMasterPasswordServiceAbstraction>();
@ -53,6 +56,7 @@ describe("DefaultSetPasswordJitService", () => {
sut = new DefaultSetPasswordJitService( sut = new DefaultSetPasswordJitService(
apiService, apiService,
cryptoService, cryptoService,
encryptService,
i18nService, i18nService,
kdfConfigService, kdfConfigService,
masterPasswordService, masterPasswordService,
@ -168,7 +172,7 @@ describe("DefaultSetPasswordJitService", () => {
} }
cryptoService.userKey$.mockReturnValue(of(userKey)); cryptoService.userKey$.mockReturnValue(of(userKey));
cryptoService.rsaEncrypt.mockResolvedValue(userKeyEncString); encryptService.rsaEncrypt.mockResolvedValue(userKeyEncString);
organizationUserApiService.putOrganizationUserResetPasswordEnrollment.mockResolvedValue( organizationUserApiService.putOrganizationUserResetPasswordEnrollment.mockResolvedValue(
undefined, undefined,
@ -210,7 +214,7 @@ describe("DefaultSetPasswordJitService", () => {
// Assert // Assert
expect(apiService.setPassword).toHaveBeenCalledWith(setPasswordRequest); expect(apiService.setPassword).toHaveBeenCalledWith(setPasswordRequest);
expect(organizationApiService.getKeys).toHaveBeenCalledWith(orgId); expect(organizationApiService.getKeys).toHaveBeenCalledWith(orgId);
expect(cryptoService.rsaEncrypt).toHaveBeenCalledWith(userKey.key, orgPublicKey); expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(userKey.key, orgPublicKey);
expect( expect(
organizationUserApiService.putOrganizationUserResetPasswordEnrollment, organizationUserApiService.putOrganizationUserResetPasswordEnrollment,
).toHaveBeenCalled(); ).toHaveBeenCalled();

View File

@ -14,6 +14,7 @@ import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config
import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request";
import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
@ -29,6 +30,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
constructor( constructor(
protected apiService: ApiService, protected apiService: ApiService,
protected cryptoService: CryptoService, protected cryptoService: CryptoService,
protected encryptService: EncryptService,
protected i18nService: I18nService, protected i18nService: I18nService,
protected kdfConfigService: KdfConfigService, protected kdfConfigService: KdfConfigService,
protected masterPasswordService: InternalMasterPasswordServiceAbstraction, protected masterPasswordService: InternalMasterPasswordServiceAbstraction,
@ -157,7 +159,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
throw new Error("userKey not found. Could not handle reset password auto enroll."); throw new Error("userKey not found. Could not handle reset password auto enroll.");
} }
const encryptedUserKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey); const encryptedUserKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey);
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest(); const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
resetRequest.masterPasswordHash = masterKeyHash; resetRequest.masterPasswordHash = masterKeyHash;

View File

@ -226,7 +226,7 @@ describe("WebAuthnLoginStrategy", () => {
const mockUserKey = new SymmetricCryptoKey(mockUserKeyArray) as UserKey; const mockUserKey = new SymmetricCryptoKey(mockUserKeyArray) as UserKey;
encryptService.decryptToBytes.mockResolvedValue(mockPrfPrivateKey); encryptService.decryptToBytes.mockResolvedValue(mockPrfPrivateKey);
cryptoService.rsaDecrypt.mockResolvedValue(mockUserKeyArray); encryptService.rsaDecrypt.mockResolvedValue(mockUserKeyArray);
// Act // Act
await webAuthnLoginStrategy.logIn(webAuthnCredentials); await webAuthnLoginStrategy.logIn(webAuthnCredentials);
@ -244,9 +244,9 @@ describe("WebAuthnLoginStrategy", () => {
idTokenResponse.userDecryptionOptions.webAuthnPrfOption.encryptedPrivateKey, idTokenResponse.userDecryptionOptions.webAuthnPrfOption.encryptedPrivateKey,
webAuthnCredentials.prfKey, webAuthnCredentials.prfKey,
); );
expect(cryptoService.rsaDecrypt).toHaveBeenCalledTimes(1); expect(encryptService.rsaDecrypt).toHaveBeenCalledTimes(1);
expect(cryptoService.rsaDecrypt).toHaveBeenCalledWith( expect(encryptService.rsaDecrypt).toHaveBeenCalledWith(
idTokenResponse.userDecryptionOptions.webAuthnPrfOption.encryptedUserKey.encryptedString, idTokenResponse.userDecryptionOptions.webAuthnPrfOption.encryptedUserKey,
mockPrfPrivateKey, mockPrfPrivateKey,
); );
expect(cryptoService.setUserKey).toHaveBeenCalledWith(mockUserKey, userId); expect(cryptoService.setUserKey).toHaveBeenCalledWith(mockUserKey, userId);
@ -273,7 +273,7 @@ describe("WebAuthnLoginStrategy", () => {
// Assert // Assert
expect(encryptService.decryptToBytes).not.toHaveBeenCalled(); expect(encryptService.decryptToBytes).not.toHaveBeenCalled();
expect(cryptoService.rsaDecrypt).not.toHaveBeenCalled(); expect(encryptService.rsaDecrypt).not.toHaveBeenCalled();
expect(cryptoService.setUserKey).not.toHaveBeenCalled(); expect(cryptoService.setUserKey).not.toHaveBeenCalled();
}); });
@ -325,7 +325,7 @@ describe("WebAuthnLoginStrategy", () => {
apiService.postIdentityToken.mockResolvedValue(idTokenResponse); apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
cryptoService.rsaDecrypt.mockResolvedValue(null); encryptService.rsaDecrypt.mockResolvedValue(null);
// Act // Act
await webAuthnLoginStrategy.logIn(webAuthnCredentials); await webAuthnLoginStrategy.logIn(webAuthnCredentials);

View File

@ -4,6 +4,7 @@ import { Jsonify } from "type-fest";
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; 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 { 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 { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { UserId } from "@bitwarden/common/types/guid"; import { UserId } from "@bitwarden/common/types/guid";
import { UserKey } from "@bitwarden/common/types/key"; import { UserKey } from "@bitwarden/common/types/key";
@ -86,8 +87,8 @@ export class WebAuthnLoginStrategy extends LoginStrategy {
); );
// decrypt user key with private key // decrypt user key with private key
const userKey = await this.cryptoService.rsaDecrypt( const userKey = await this.encryptService.rsaDecrypt(
webAuthnPrfOption.encryptedUserKey.encryptedString, new EncString(webAuthnPrfOption.encryptedUserKey.encryptedString),
privateKey, privateKey,
); );

View File

@ -6,6 +6,7 @@ import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/maste
import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response"; import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
@ -24,6 +25,7 @@ describe("AuthRequestService", () => {
let masterPasswordService: FakeMasterPasswordService; let masterPasswordService: FakeMasterPasswordService;
const appIdService = mock<AppIdService>(); const appIdService = mock<AppIdService>();
const cryptoService = mock<CryptoService>(); const cryptoService = mock<CryptoService>();
const encryptService = mock<EncryptService>();
const apiService = mock<ApiService>(); const apiService = mock<ApiService>();
let mockPrivateKey: Uint8Array; let mockPrivateKey: Uint8Array;
@ -40,6 +42,7 @@ describe("AuthRequestService", () => {
accountService, accountService,
masterPasswordService, masterPasswordService,
cryptoService, cryptoService,
encryptService,
apiService, apiService,
stateProvider, stateProvider,
); );
@ -82,7 +85,7 @@ describe("AuthRequestService", () => {
describe("approveOrDenyAuthRequest", () => { describe("approveOrDenyAuthRequest", () => {
beforeEach(() => { beforeEach(() => {
cryptoService.rsaEncrypt.mockResolvedValue({ encryptService.rsaEncrypt.mockResolvedValue({
encryptedString: "ENCRYPTED_STRING", encryptedString: "ENCRYPTED_STRING",
} as EncString); } as EncString);
appIdService.getAppId.mockResolvedValue("APP_ID"); appIdService.getAppId.mockResolvedValue("APP_ID");
@ -108,7 +111,7 @@ describe("AuthRequestService", () => {
new AuthRequestResponse({ id: "123", publicKey: "KEY" }), new AuthRequestResponse({ id: "123", publicKey: "KEY" }),
); );
expect(cryptoService.rsaEncrypt).toHaveBeenCalledWith(new Uint8Array(64), expect.anything()); expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(new Uint8Array(64), expect.anything());
}); });
it("should use the user key if the master key and hash do not exist", async () => { it("should use the user key if the master key and hash do not exist", async () => {
@ -119,7 +122,7 @@ describe("AuthRequestService", () => {
new AuthRequestResponse({ id: "123", publicKey: "KEY" }), new AuthRequestResponse({ id: "123", publicKey: "KEY" }),
); );
expect(cryptoService.rsaEncrypt).toHaveBeenCalledWith(new Uint8Array(64), expect.anything()); expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(new Uint8Array(64), expect.anything());
}); });
}); });
describe("setUserKeyAfterDecryptingSharedUserKey", () => { describe("setUserKeyAfterDecryptingSharedUserKey", () => {
@ -211,7 +214,7 @@ describe("AuthRequestService", () => {
const mockDecryptedUserKeyBytes = new Uint8Array(64); const mockDecryptedUserKeyBytes = new Uint8Array(64);
const mockDecryptedUserKey = new SymmetricCryptoKey(mockDecryptedUserKeyBytes) as UserKey; const mockDecryptedUserKey = new SymmetricCryptoKey(mockDecryptedUserKeyBytes) as UserKey;
cryptoService.rsaDecrypt.mockResolvedValueOnce(mockDecryptedUserKeyBytes); encryptService.rsaDecrypt.mockResolvedValueOnce(mockDecryptedUserKeyBytes);
// Act // Act
const result = await sut.decryptPubKeyEncryptedUserKey( const result = await sut.decryptPubKeyEncryptedUserKey(
@ -220,7 +223,10 @@ describe("AuthRequestService", () => {
); );
// Assert // Assert
expect(cryptoService.rsaDecrypt).toBeCalledWith(mockPubKeyEncryptedUserKey, mockPrivateKey); expect(encryptService.rsaDecrypt).toBeCalledWith(
new EncString(mockPubKeyEncryptedUserKey),
mockPrivateKey,
);
expect(result).toEqual(mockDecryptedUserKey); expect(result).toEqual(mockDecryptedUserKey);
}); });
}); });
@ -238,7 +244,7 @@ describe("AuthRequestService", () => {
const mockDecryptedMasterKeyHashBytes = new Uint8Array(64); const mockDecryptedMasterKeyHashBytes = new Uint8Array(64);
const mockDecryptedMasterKeyHash = Utils.fromBufferToUtf8(mockDecryptedMasterKeyHashBytes); const mockDecryptedMasterKeyHash = Utils.fromBufferToUtf8(mockDecryptedMasterKeyHashBytes);
cryptoService.rsaDecrypt encryptService.rsaDecrypt
.mockResolvedValueOnce(mockDecryptedMasterKeyBytes) .mockResolvedValueOnce(mockDecryptedMasterKeyBytes)
.mockResolvedValueOnce(mockDecryptedMasterKeyHashBytes); .mockResolvedValueOnce(mockDecryptedMasterKeyHashBytes);
@ -250,14 +256,14 @@ describe("AuthRequestService", () => {
); );
// Assert // Assert
expect(cryptoService.rsaDecrypt).toHaveBeenNthCalledWith( expect(encryptService.rsaDecrypt).toHaveBeenNthCalledWith(
1, 1,
mockPubKeyEncryptedMasterKey, new EncString(mockPubKeyEncryptedMasterKey),
mockPrivateKey, mockPrivateKey,
); );
expect(cryptoService.rsaDecrypt).toHaveBeenNthCalledWith( expect(encryptService.rsaDecrypt).toHaveBeenNthCalledWith(
2, 2,
mockPubKeyEncryptedMasterKeyHash, new EncString(mockPubKeyEncryptedMasterKeyHash),
mockPrivateKey, mockPrivateKey,
); );
expect(result.masterKey).toEqual(mockDecryptedMasterKey); expect(result.masterKey).toEqual(mockDecryptedMasterKey);

View File

@ -10,7 +10,9 @@ import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth
import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response"; import { AuthRequestPushNotification } from "@bitwarden/common/models/response/notification.response";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { import {
AUTH_REQUEST_DISK_LOCAL, AUTH_REQUEST_DISK_LOCAL,
@ -44,6 +46,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
private accountService: AccountService, private accountService: AccountService,
private masterPasswordService: InternalMasterPasswordServiceAbstraction, private masterPasswordService: InternalMasterPasswordServiceAbstraction,
private cryptoService: CryptoService, private cryptoService: CryptoService,
private encryptService: EncryptService,
private apiService: ApiService, private apiService: ApiService,
private stateProvider: StateProvider, private stateProvider: StateProvider,
) { ) {
@ -102,7 +105,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
if (masterKey && masterKeyHash) { if (masterKey && masterKeyHash) {
// Only encrypt the master password hash if masterKey exists as // Only encrypt the master password hash if masterKey exists as
// we won't have a masterKeyHash without a masterKey // we won't have a masterKeyHash without a masterKey
encryptedMasterKeyHash = await this.cryptoService.rsaEncrypt( encryptedMasterKeyHash = await this.encryptService.rsaEncrypt(
Utils.fromUtf8ToArray(masterKeyHash), Utils.fromUtf8ToArray(masterKeyHash),
pubKey, pubKey,
); );
@ -112,7 +115,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
keyToEncrypt = userKey.key; keyToEncrypt = userKey.key;
} }
const encryptedKey = await this.cryptoService.rsaEncrypt(keyToEncrypt, pubKey); const encryptedKey = await this.encryptService.rsaEncrypt(keyToEncrypt, pubKey);
const response = new PasswordlessAuthRequest( const response = new PasswordlessAuthRequest(
encryptedKey.encryptedString, encryptedKey.encryptedString,
@ -161,8 +164,8 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
pubKeyEncryptedUserKey: string, pubKeyEncryptedUserKey: string,
privateKey: Uint8Array, privateKey: Uint8Array,
): Promise<UserKey> { ): Promise<UserKey> {
const decryptedUserKeyBytes = await this.cryptoService.rsaDecrypt( const decryptedUserKeyBytes = await this.encryptService.rsaDecrypt(
pubKeyEncryptedUserKey, new EncString(pubKeyEncryptedUserKey),
privateKey, privateKey,
); );
@ -174,13 +177,13 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
pubKeyEncryptedMasterKeyHash: string, pubKeyEncryptedMasterKeyHash: string,
privateKey: Uint8Array, privateKey: Uint8Array,
): Promise<{ masterKey: MasterKey; masterKeyHash: string }> { ): Promise<{ masterKey: MasterKey; masterKeyHash: string }> {
const decryptedMasterKeyArrayBuffer = await this.cryptoService.rsaDecrypt( const decryptedMasterKeyArrayBuffer = await this.encryptService.rsaDecrypt(
pubKeyEncryptedMasterKey, new EncString(pubKeyEncryptedMasterKey),
privateKey, privateKey,
); );
const decryptedMasterKeyHashArrayBuffer = await this.cryptoService.rsaDecrypt( const decryptedMasterKeyHashArrayBuffer = await this.encryptService.rsaDecrypt(
pubKeyEncryptedMasterKeyHash, new EncString(pubKeyEncryptedMasterKeyHash),
privateKey, privateKey,
); );

View File

@ -144,7 +144,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
deviceKeyEncryptedDevicePrivateKey, deviceKeyEncryptedDevicePrivateKey,
] = await Promise.all([ ] = await Promise.all([
// Encrypt user key with the DevicePublicKey // Encrypt user key with the DevicePublicKey
this.cryptoService.rsaEncrypt(userKey.key, devicePublicKey), this.encryptService.rsaEncrypt(userKey.key, devicePublicKey),
// Encrypt devicePublicKey with user key // Encrypt devicePublicKey with user key
this.encryptService.encrypt(devicePublicKey, userKey), this.encryptService.encrypt(devicePublicKey, userKey),
@ -206,7 +206,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
); );
// Encrypt the brand new user key with the now-decrypted public key for the device // Encrypt the brand new user key with the now-decrypted public key for the device
const encryptedNewUserKey = await this.cryptoService.rsaEncrypt( const encryptedNewUserKey = await this.encryptService.rsaEncrypt(
newUserKey.key, newUserKey.key,
decryptedDevicePublicKey, decryptedDevicePublicKey,
); );
@ -317,8 +317,8 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
); );
// Attempt to decrypt encryptedUserDataKey with devicePrivateKey // Attempt to decrypt encryptedUserDataKey with devicePrivateKey
const userKey = await this.cryptoService.rsaDecrypt( const userKey = await this.encryptService.rsaDecrypt(
encryptedUserKey.encryptedString, new EncString(encryptedUserKey.encryptedString),
devicePrivateKey, devicePrivateKey,
); );

View File

@ -372,7 +372,7 @@ describe("deviceTrustService", () => {
.mockResolvedValue(mockUserKey); .mockResolvedValue(mockUserKey);
cryptoSvcRsaEncryptSpy = jest cryptoSvcRsaEncryptSpy = jest
.spyOn(cryptoService, "rsaEncrypt") .spyOn(encryptService, "rsaEncrypt")
.mockResolvedValue(mockDevicePublicKeyEncryptedUserKey); .mockResolvedValue(mockDevicePublicKeyEncryptedUserKey);
encryptServiceEncryptSpy = jest encryptServiceEncryptSpy = jest
@ -577,7 +577,7 @@ describe("deviceTrustService", () => {
.spyOn(encryptService, "decryptToBytes") .spyOn(encryptService, "decryptToBytes")
.mockResolvedValue(new Uint8Array(userKeyBytesLength)); .mockResolvedValue(new Uint8Array(userKeyBytesLength));
const rsaDecryptSpy = jest const rsaDecryptSpy = jest
.spyOn(cryptoService, "rsaDecrypt") .spyOn(encryptService, "rsaDecrypt")
.mockResolvedValue(new Uint8Array(userKeyBytesLength)); .mockResolvedValue(new Uint8Array(userKeyBytesLength));
const result = await deviceTrustService.decryptUserKeyWithDeviceKey( const result = await deviceTrustService.decryptUserKeyWithDeviceKey(
@ -696,7 +696,7 @@ describe("deviceTrustService", () => {
}); });
// Mock the encryption of the new user key with the decrypted public key // Mock the encryption of the new user key with the decrypted public key
cryptoService.rsaEncrypt.mockImplementationOnce((data, publicKey) => { encryptService.rsaEncrypt.mockImplementationOnce((data, publicKey) => {
expect(data.byteLength).toBe(64); // New key should also be 64 bytes expect(data.byteLength).toBe(64); // New key should also be 64 bytes
expect(new Uint8Array(data)[0]).toBe(FakeNewUserKeyMarker); // New key should have the first byte be '1'; expect(new Uint8Array(data)[0]).toBe(FakeNewUserKeyMarker); // New key should have the first byte be '1';

View File

@ -2,6 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended";
import { BehaviorSubject } from "rxjs"; import { BehaviorSubject } from "rxjs";
import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { UserId } from "../../../../common/src/types/guid"; import { UserId } from "../../../../common/src/types/guid";
import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction";
@ -18,6 +19,7 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
let organizationApiService: MockProxy<OrganizationApiServiceAbstraction>; let organizationApiService: MockProxy<OrganizationApiServiceAbstraction>;
let accountService: MockProxy<AccountService>; let accountService: MockProxy<AccountService>;
let cryptoService: MockProxy<CryptoService>; let cryptoService: MockProxy<CryptoService>;
let encryptService: MockProxy<EncryptService>;
let organizationUserApiService: MockProxy<OrganizationUserApiService>; let organizationUserApiService: MockProxy<OrganizationUserApiService>;
let i18nService: MockProxy<I18nService>; let i18nService: MockProxy<I18nService>;
let service: PasswordResetEnrollmentServiceImplementation; let service: PasswordResetEnrollmentServiceImplementation;
@ -27,12 +29,14 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
accountService = mock<AccountService>(); accountService = mock<AccountService>();
accountService.activeAccount$ = activeAccountSubject; accountService.activeAccount$ = activeAccountSubject;
cryptoService = mock<CryptoService>(); cryptoService = mock<CryptoService>();
encryptService = mock<EncryptService>();
organizationUserApiService = mock<OrganizationUserApiService>(); organizationUserApiService = mock<OrganizationUserApiService>();
i18nService = mock<I18nService>(); i18nService = mock<I18nService>();
service = new PasswordResetEnrollmentServiceImplementation( service = new PasswordResetEnrollmentServiceImplementation(
organizationApiService, organizationApiService,
accountService, accountService,
cryptoService, cryptoService,
encryptService,
organizationUserApiService, organizationUserApiService,
i18nService, i18nService,
); );
@ -96,7 +100,7 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
activeAccountSubject.next(Object.assign(user1AccountInfo, { id: "userId" as UserId })); activeAccountSubject.next(Object.assign(user1AccountInfo, { id: "userId" as UserId }));
cryptoService.getUserKey.mockResolvedValue({ key: "key" } as any); cryptoService.getUserKey.mockResolvedValue({ key: "key" } as any);
cryptoService.rsaEncrypt.mockResolvedValue(encryptedKey as any); encryptService.rsaEncrypt.mockResolvedValue(encryptedKey as any);
await service.enroll("orgId"); await service.enroll("orgId");
@ -118,7 +122,7 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
}; };
const encryptedKey = { encryptedString: "encryptedString" }; const encryptedKey = { encryptedString: "encryptedString" };
organizationApiService.getKeys.mockResolvedValue(orgKeyResponse as any); organizationApiService.getKeys.mockResolvedValue(orgKeyResponse as any);
cryptoService.rsaEncrypt.mockResolvedValue(encryptedKey as any); encryptService.rsaEncrypt.mockResolvedValue(encryptedKey as any);
await service.enroll("orgId", "userId", { key: "key" } as any); await service.enroll("orgId", "userId", { key: "key" } as any);

View File

@ -4,6 +4,7 @@ import {
OrganizationUserApiService, OrganizationUserApiService,
OrganizationUserResetPasswordEnrollmentRequest, OrganizationUserResetPasswordEnrollmentRequest,
} from "@bitwarden/admin-console/common"; } from "@bitwarden/admin-console/common";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction";
import { CryptoService } from "../../platform/abstractions/crypto.service"; import { CryptoService } from "../../platform/abstractions/crypto.service";
@ -20,6 +21,7 @@ export class PasswordResetEnrollmentServiceImplementation
protected organizationApiService: OrganizationApiServiceAbstraction, protected organizationApiService: OrganizationApiServiceAbstraction,
protected accountService: AccountService, protected accountService: AccountService,
protected cryptoService: CryptoService, protected cryptoService: CryptoService,
protected encryptService: EncryptService,
protected organizationUserApiService: OrganizationUserApiService, protected organizationUserApiService: OrganizationUserApiService,
protected i18nService: I18nService, protected i18nService: I18nService,
) {} ) {}
@ -47,7 +49,7 @@ export class PasswordResetEnrollmentServiceImplementation
userId ?? (await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id)))); userId ?? (await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))));
userKey = userKey ?? (await this.cryptoService.getUserKey(userId)); userKey = userKey ?? (await this.cryptoService.getUserKey(userId));
// RSA Encrypt user's userKey.key with organization public key // RSA Encrypt user's userKey.key with organization public key
const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, orgPublicKey); const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, orgPublicKey);
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest(); const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
resetRequest.resetPasswordKey = encryptedKey.encryptedString; resetRequest.resetPasswordKey = encryptedKey.encryptedString;

View File

@ -329,22 +329,6 @@ export abstract class CryptoService {
* @param userId The user's Id * @param userId The user's Id
*/ */
abstract clearKeys(userId?: string): Promise<any>; abstract clearKeys(userId?: string): Promise<any>;
/**
* RSA encrypts a value.
* @param data The data to encrypt
* @param publicKey The public key to use for encryption, if not provided, the user's public key will be used
* @returns The encrypted data
* @throws If the given publicKey is a null-ish value.
*/
abstract rsaEncrypt(data: Uint8Array, publicKey: Uint8Array): Promise<EncString>;
/**
* Decrypts a value using RSA.
* @param encValue The encrypted value to decrypt
* @param privateKey The private key to use for decryption
* @returns The decrypted value
* @throws If the given privateKey is a null-ish value.
*/
abstract rsaDecrypt(encValue: string, privateKey: Uint8Array): Promise<Uint8Array>;
abstract randomNumber(min: number, max: number): Promise<number>; abstract randomNumber(min: number, max: number): Promise<number>;
/** /**
* Generates a new cipher key * Generates a new cipher key

View File

@ -45,7 +45,7 @@ import { KeyGenerationService } from "../abstractions/key-generation.service";
import { LogService } from "../abstractions/log.service"; import { LogService } from "../abstractions/log.service";
import { PlatformUtilsService } from "../abstractions/platform-utils.service"; import { PlatformUtilsService } from "../abstractions/platform-utils.service";
import { StateService } from "../abstractions/state.service"; import { StateService } from "../abstractions/state.service";
import { KeySuffixOptions, HashPurpose, EncryptionType } from "../enums"; import { KeySuffixOptions, HashPurpose } from "../enums";
import { convertValues } from "../misc/convert-values"; import { convertValues } from "../misc/convert-values";
import { EFFLongWordList } from "../misc/wordlist"; import { EFFLongWordList } from "../misc/wordlist";
import { EncString, EncryptedString } from "../models/domain/enc-string"; import { EncString, EncryptedString } from "../models/domain/enc-string";
@ -441,7 +441,7 @@ export class CryptoService implements CryptoServiceAbstraction {
const shareKey = await this.keyGenerationService.createKey(512); const shareKey = await this.keyGenerationService.createKey(512);
userId ??= await firstValueFrom(this.stateProvider.activeUserId$); userId ??= await firstValueFrom(this.stateProvider.activeUserId$);
const publicKey = await firstValueFrom(this.userPublicKey$(userId)); const publicKey = await firstValueFrom(this.userPublicKey$(userId));
const encShareKey = await this.rsaEncrypt(shareKey.key, publicKey); const encShareKey = await this.encryptService.rsaEncrypt(shareKey.key, publicKey);
return [encShareKey, shareKey as T]; return [encShareKey, shareKey as T];
} }
@ -550,68 +550,6 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.stateProvider.setUserState(USER_EVER_HAD_USER_KEY, null, userId); await this.stateProvider.setUserState(USER_EVER_HAD_USER_KEY, null, userId);
} }
async rsaEncrypt(data: Uint8Array, publicKey: Uint8Array): Promise<EncString> {
if (publicKey == null) {
throw new Error("'publicKey' is a required parameter and must be non-null");
}
const encBytes = await this.cryptoFunctionService.rsaEncrypt(data, publicKey, "sha1");
return new EncString(EncryptionType.Rsa2048_OaepSha1_B64, Utils.fromBufferToB64(encBytes));
}
async rsaDecrypt(encValue: string, privateKey: Uint8Array): Promise<Uint8Array> {
if (privateKey == null) {
throw new Error("'privateKey' is a required parameter and must be non-null");
}
const headerPieces = encValue.split(".");
let encType: EncryptionType = null;
let encPieces: string[];
if (headerPieces.length === 1) {
encType = EncryptionType.Rsa2048_OaepSha256_B64;
encPieces = [headerPieces[0]];
} else if (headerPieces.length === 2) {
try {
encType = parseInt(headerPieces[0], null);
encPieces = headerPieces[1].split("|");
} catch (e) {
this.logService.error(e);
}
}
switch (encType) {
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha1_B64:
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64: // HmacSha256 types are deprecated
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
break;
default:
throw new Error("encType unavailable.");
}
if (encPieces == null || encPieces.length <= 0) {
throw new Error("encPieces unavailable.");
}
const data = Utils.fromB64ToArray(encPieces[0]);
let alg: "sha1" | "sha256" = "sha1";
switch (encType) {
case EncryptionType.Rsa2048_OaepSha256_B64:
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
alg = "sha256";
break;
case EncryptionType.Rsa2048_OaepSha1_B64:
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
break;
default:
throw new Error("encType unavailable.");
}
return this.cryptoFunctionService.rsaDecrypt(data, privateKey, alg);
}
// EFForg/OpenWireless // EFForg/OpenWireless
// ref https://github.com/EFForg/OpenWireless/blob/master/app/js/diceware.js // ref https://github.com/EFForg/OpenWireless/blob/master/app/js/diceware.js
async randomNumber(min: number, max: number): Promise<number> { async randomNumber(min: number, max: number): Promise<number> {