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:
parent
f2339b0586
commit
dafe795854
@ -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,
|
||||||
);
|
);
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
@ -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);
|
||||||
|
@ -287,6 +287,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
deps: [
|
deps: [
|
||||||
ApiService,
|
ApiService,
|
||||||
CryptoService,
|
CryptoService,
|
||||||
|
EncryptService,
|
||||||
I18nServiceAbstraction,
|
I18nServiceAbstraction,
|
||||||
KdfConfigService,
|
KdfConfigService,
|
||||||
InternalMasterPasswordServiceAbstraction,
|
InternalMasterPasswordServiceAbstraction,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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(
|
||||||
|
@ -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"),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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";
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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';
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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> {
|
||||||
|
Loading…
Reference in New Issue
Block a user