1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-02 13:23:29 +01:00

rename 'user symmetric key' with 'user key'

This commit is contained in:
Jacob Fink 2023-06-23 10:59:54 -04:00
parent e4bfa62e70
commit 6349410ec2
No known key found for this signature in database
GPG Key ID: C2F7ACF05859D008
47 changed files with 423 additions and 457 deletions

View File

@ -13,7 +13,7 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { BrowserApi } from "../platform/browser/browser-api"; import { BrowserApi } from "../platform/browser/browser-api";
@ -329,19 +329,19 @@ export class NativeMessagingBackground {
if (message.userKeyB64) { if (message.userKeyB64) {
const userKey = new SymmetricCryptoKey( const userKey = new SymmetricCryptoKey(
Utils.fromB64ToArray(message.userKeyB64).buffer Utils.fromB64ToArray(message.userKeyB64).buffer
) as UserSymKey; ) as UserKey;
await this.cryptoService.setUserKey(userKey); await this.cryptoService.setUserKey(userKey);
} else if (message.keyB64) { } else if (message.keyB64) {
// backwards compatibility // backwards compatibility
let encUserKey = await this.stateService.getEncryptedCryptoSymmetricKey(); let encUserKey = await this.stateService.getEncryptedCryptoSymmetricKey();
encUserKey ||= await this.stateService.getUserSymKeyMasterKey(); encUserKey ||= await this.stateService.getUserKeyMasterKey();
if (!encUserKey) { if (!encUserKey) {
throw new Error("No encrypted user key found"); throw new Error("No encrypted user key found");
} }
const masterKey = new SymmetricCryptoKey( const masterKey = new SymmetricCryptoKey(
Utils.fromB64ToArray(message.keyB64).buffer Utils.fromB64ToArray(message.keyB64).buffer
) as MasterKey; ) as MasterKey;
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey( const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(
masterKey, masterKey,
new EncString(encUserKey) new EncString(encUserKey)
); );

View File

@ -2,7 +2,7 @@ import { KeySuffixOptions } from "@bitwarden/common/enums";
import { Utils } from "@bitwarden/common/platform/misc/utils"; import { Utils } from "@bitwarden/common/platform/misc/utils";
import { import {
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
@ -10,12 +10,12 @@ export class BrowserCryptoService extends CryptoService {
protected override async retrieveUserKeyFromStorage( protected override async retrieveUserKeyFromStorage(
keySuffix: KeySuffixOptions, keySuffix: KeySuffixOptions,
userId?: string userId?: string
): Promise<UserSymKey> { ): Promise<UserKey> {
if (keySuffix === KeySuffixOptions.Biometric) { if (keySuffix === KeySuffixOptions.Biometric) {
await this.platformUtilService.authenticateBiometric(); await this.platformUtilService.authenticateBiometric();
const userKey = await this.getUserKeyFromMemory(); const userKey = await this.getUserKeyFromMemory();
if (userKey) { if (userKey) {
return new SymmetricCryptoKey(Utils.fromB64ToArray(userKey.keyB64).buffer) as UserSymKey; return new SymmetricCryptoKey(Utils.fromB64ToArray(userKey.keyB64).buffer) as UserKey;
} }
} }

View File

@ -408,7 +408,7 @@ export class LoginCommand {
try { try {
const { const {
newPasswordHash, newPasswordHash,
newUserSymKey: newEncKey, newUserKey: newEncKey,
hint, hint,
} = await this.collectNewMasterPasswordDetails( } = await this.collectNewMasterPasswordDetails(
"Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now." "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now."
@ -450,7 +450,7 @@ export class LoginCommand {
try { try {
const { const {
newPasswordHash, newPasswordHash,
newUserSymKey: newEncKey, newUserKey: newEncKey,
hint, hint,
} = await this.collectNewMasterPasswordDetails( } = await this.collectNewMasterPasswordDetails(
"An organization administrator recently changed your master password. In order to access the vault, you must update your master password now." "An organization administrator recently changed your master password. In order to access the vault, you must update your master password now."
@ -476,7 +476,7 @@ export class LoginCommand {
/** /**
* Collect new master password and hint from the CLI. The collected password * Collect new master password and hint from the CLI. The collected password
* is validated against any applicable master password policies, a new master * is validated against any applicable master password policies, a new master
* key is generated, and we use it to re-encrypt the user symmetric key * key is generated, and we use it to re-encrypt the user key
* @param prompt - Message that is displayed during the initial prompt * @param prompt - Message that is displayed during the initial prompt
* @param error * @param error
*/ */
@ -485,7 +485,7 @@ export class LoginCommand {
error?: string error?: string
): Promise<{ ): Promise<{
newPasswordHash: string; newPasswordHash: string;
newUserSymKey: [SymmetricCryptoKey, EncString]; newUserKey: [SymmetricCryptoKey, EncString];
hint?: string; hint?: string;
}> { }> {
if (this.email == null || this.email === "undefined") { if (this.email == null || this.email === "undefined") {
@ -575,19 +575,16 @@ export class LoginCommand {
); );
const newPasswordHash = await this.cryptoService.hashPassword(masterPassword, newMasterKey); const newPasswordHash = await this.cryptoService.hashPassword(masterPassword, newMasterKey);
// Grab user's symmetric key // Grab user key
const userSymKey = await this.cryptoService.getUserKeyFromMemory(); const userKey = await this.cryptoService.getUserKeyFromMemory();
if (!userSymKey) { if (!userKey) {
throw new Error("User key not found."); throw new Error("User key not found.");
} }
// Re-encrypt user's symmetric key with new master key // Re-encrypt user key with new master key
const newUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey( const newUserKey = await this.cryptoService.encryptUserKeyWithMasterKey(newMasterKey, userKey);
newMasterKey,
userSymKey
);
return { newPasswordHash, newUserSymKey, hint: masterPasswordHint }; return { newPasswordHash, newUserKey: newUserKey, hint: masterPasswordHint };
} }
private async handleCaptchaRequired( private async handleCaptchaRequired(

View File

@ -76,7 +76,7 @@ export class UnlockCommand {
if (passwordValid) { if (passwordValid) {
await this.cryptoService.setMasterKey(masterKey); await this.cryptoService.setMasterKey(masterKey);
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
await this.cryptoService.setUserKey(userKey); await this.cryptoService.setUserKey(userKey);
if (await this.keyConnectorService.getConvertAccountRequired()) { if (await this.keyConnectorService.getConvertAccountRequired()) {

View File

@ -126,8 +126,8 @@ export class CreateCommand {
return Response.error("Premium status is required to use this feature."); return Response.error("Premium status is required to use this feature.");
} }
const userSymKey = await this.cryptoService.getUserKeyFromMemory(); const userKey = await this.cryptoService.getUserKeyFromMemory();
if (userSymKey == null) { if (userKey == null) {
return Response.error( return Response.error(
"You must update your encryption key before you can use this feature. " + "You must update your encryption key before you can use this feature. " +
"See https://help.bitwarden.com/article/update-encryption-key/" "See https://help.bitwarden.com/article/update-encryption-key/"

View File

@ -8,7 +8,7 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { CryptoService } from "@bitwarden/common/platform/services/crypto.service"; import { CryptoService } from "@bitwarden/common/platform/services/crypto.service";
import { CsprngString } from "@bitwarden/common/types/csprng"; import { CsprngString } from "@bitwarden/common/types/csprng";
@ -26,7 +26,7 @@ export class ElectronCryptoService extends CryptoService {
super(cryptoFunctionService, encryptService, platformUtilsService, logService, stateService); super(cryptoFunctionService, encryptService, platformUtilsService, logService, stateService);
} }
protected override async storeAdditionalKeys(key: UserSymKey, userId?: string) { protected override async storeAdditionalKeys(key: UserKey, userId?: string) {
await super.storeAdditionalKeys(key, userId); await super.storeAdditionalKeys(key, userId);
const storeBiometricKey = await this.shouldStoreKey(KeySuffixOptions.Biometric, userId); const storeBiometricKey = await this.shouldStoreKey(KeySuffixOptions.Biometric, userId);
@ -34,28 +34,28 @@ export class ElectronCryptoService extends CryptoService {
if (storeBiometricKey) { if (storeBiometricKey) {
await this.storeBiometricKey(key, userId); await this.storeBiometricKey(key, userId);
} else { } else {
await this.stateService.setUserSymKeyBiometric(null, { userId: userId }); await this.stateService.setUserKeyBiometric(null, { userId: userId });
} }
} }
protected override async retrieveUserKeyFromStorage( protected override async retrieveUserKeyFromStorage(
keySuffix: KeySuffixOptions, keySuffix: KeySuffixOptions,
userId?: string userId?: string
): Promise<UserSymKey> { ): Promise<UserKey> {
if (keySuffix === KeySuffixOptions.Biometric) { if (keySuffix === KeySuffixOptions.Biometric) {
await this.migrateBiometricKeyIfNeeded(userId); await this.migrateBiometricKeyIfNeeded(userId);
const userKey = await this.stateService.getUserSymKeyBiometric({ userId: userId }); const userKey = await this.stateService.getUserKeyBiometric({ userId: userId });
return new SymmetricCryptoKey(Utils.fromB64ToArray(userKey).buffer) as UserSymKey; return new SymmetricCryptoKey(Utils.fromB64ToArray(userKey).buffer) as UserKey;
} }
return await super.retrieveUserKeyFromStorage(keySuffix, userId); return await super.retrieveUserKeyFromStorage(keySuffix, userId);
} }
protected async storeBiometricKey(key: UserSymKey, userId?: string): Promise<void> { protected async storeBiometricKey(key: UserKey, userId?: string): Promise<void> {
let clientEncKeyHalf: CsprngString = null; let clientEncKeyHalf: CsprngString = null;
if (await this.stateService.getBiometricRequirePasswordOnStart({ userId })) { if (await this.stateService.getBiometricRequirePasswordOnStart({ userId })) {
clientEncKeyHalf = await this.getBiometricEncryptionClientKeyHalf(userId); clientEncKeyHalf = await this.getBiometricEncryptionClientKeyHalf(userId);
} }
await this.stateService.setUserSymKeyBiometric( await this.stateService.setUserKeyBiometric(
{ key: key.keyB64, clientEncKeyHalf }, { key: key.keyB64, clientEncKeyHalf },
{ userId: userId } { userId: userId }
); );
@ -87,16 +87,13 @@ export class ElectronCryptoService extends CryptoService {
// decrypt // decrypt
const masterKey = new SymmetricCryptoKey(Utils.fromB64ToArray(oldBiometricKey)) as MasterKey; const masterKey = new SymmetricCryptoKey(Utils.fromB64ToArray(oldBiometricKey)) as MasterKey;
let encUserKey = await this.stateService.getEncryptedCryptoSymmetricKey(); let encUserKey = await this.stateService.getEncryptedCryptoSymmetricKey();
encUserKey = encUserKey ?? (await this.stateService.getUserSymKeyMasterKey()); encUserKey = encUserKey ?? (await this.stateService.getUserKeyMasterKey());
if (!encUserKey) { if (!encUserKey) {
throw new Error("No user key found during biometric migration"); throw new Error("No user key found during biometric migration");
} }
const userSymKey = await this.decryptUserSymKeyWithMasterKey( const userKey = await this.decryptUserKeyWithMasterKey(masterKey, new EncString(encUserKey));
masterKey,
new EncString(encUserKey)
);
// migrate // migrate
await this.storeBiometricKey(userSymKey, userId); await this.storeBiometricKey(userKey, userId);
await this.stateService.setCryptoMasterKeyBiometric(null, { userId }); await this.stateService.setCryptoMasterKeyBiometric(null, { userId });
} }
} }

View File

@ -25,7 +25,7 @@ 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 { import {
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
@ -176,7 +176,7 @@ export class ResetPasswordComponent implements OnInit, OnDestroy {
// Decrypt User's Reset Password Key to get EncKey // Decrypt User's Reset Password Key to get EncKey
const decValue = await this.cryptoService.rsaDecrypt(resetPasswordKey, decPrivateKey); const decValue = await this.cryptoService.rsaDecrypt(resetPasswordKey, decPrivateKey);
const existingUserSymKey = new SymmetricCryptoKey(decValue) as UserSymKey; const existingUserKey = new SymmetricCryptoKey(decValue) as UserKey;
// Create new master key and hash new password // Create new master key and hash new password
const newMasterKey = await this.cryptoService.makeMasterKey( const newMasterKey = await this.cryptoService.makeMasterKey(
@ -190,15 +190,15 @@ export class ResetPasswordComponent implements OnInit, OnDestroy {
newMasterKey newMasterKey
); );
// Create new encrypted user symmetric key for the User // Create new encrypted user key for the User
const newUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey( const newUserKey = await this.cryptoService.encryptUserKeyWithMasterKey(
newMasterKey, newMasterKey,
existingUserSymKey existingUserKey
); );
// Create request // Create request
const request = new OrganizationUserResetPasswordRequest(); const request = new OrganizationUserResetPasswordRequest();
request.key = newUserSymKey[1].encryptedString; request.key = newUserKey[1].encryptedString;
request.newMasterPasswordHash = newPasswordHash; request.newMasterPasswordHash = newPasswordHash;
// Change user's password // Change user's password

View File

@ -19,7 +19,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { import {
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
@ -94,9 +94,9 @@ export class EmergencyAccessTakeoverComponent
); );
const oldKeyBuffer = await this.cryptoService.rsaDecrypt(takeoverResponse.keyEncrypted); const oldKeyBuffer = await this.cryptoService.rsaDecrypt(takeoverResponse.keyEncrypted);
const oldUserSymKey = new SymmetricCryptoKey(oldKeyBuffer) as UserSymKey; const oldUserKey = new SymmetricCryptoKey(oldKeyBuffer) as UserKey;
if (oldUserSymKey == null) { if (oldUserKey == null) {
this.platformUtilsService.showToast( this.platformUtilsService.showToast(
"error", "error",
this.i18nService.t("errorOccurred"), this.i18nService.t("errorOccurred"),
@ -120,10 +120,7 @@ export class EmergencyAccessTakeoverComponent
masterKey masterKey
); );
const encKey = await this.cryptoService.encryptUserSymKeyWithMasterKey( const encKey = await this.cryptoService.encryptUserKeyWithMasterKey(masterKey, oldUserKey);
masterKey,
oldUserSymKey
);
const request = new EmergencyAccessPasswordRequest(); const request = new EmergencyAccessPasswordRequest();
request.newMasterPasswordHash = masterPasswordHash; request.newMasterPasswordHash = masterPasswordHash;

View File

@ -77,8 +77,8 @@ export class ChangeEmailComponent implements OnInit {
this.masterPassword, this.masterPassword,
newMasterKey newMasterKey
); );
const newUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey(newMasterKey); const newUserKey = await this.cryptoService.encryptUserKeyWithMasterKey(newMasterKey);
request.key = newUserSymKey[1].encryptedString; request.key = newUserKey[1].encryptedString;
try { try {
this.formPromise = this.apiService.postEmail(request); this.formPromise = this.apiService.postEmail(request);
await this.formPromise; await this.formPromise;

View File

@ -87,8 +87,8 @@ export class ChangeKdfConfirmationComponent {
masterPassword, masterPassword,
newMasterKey newMasterKey
); );
const newUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey(newMasterKey); const newUserKey = await this.cryptoService.encryptUserKeyWithMasterKey(newMasterKey);
request.key = newUserSymKey[1].encryptedString; request.key = newUserKey[1].encryptedString;
await this.apiService.postAccountKdf(request); await this.apiService.postAccountKdf(request);
} }

View File

@ -26,7 +26,7 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { SendWithIdRequest } from "@bitwarden/common/tools/send/models/request/send-with-id.request"; import { SendWithIdRequest } from "@bitwarden/common/tools/send/models/request/send-with-id.request";
@ -184,7 +184,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
async performSubmitActions( async performSubmitActions(
newMasterPasswordHash: string, newMasterPasswordHash: string,
newMasterKey: MasterKey, newMasterKey: MasterKey,
newUserKey: [UserSymKey, EncString] newUserKey: [UserKey, EncString]
) { ) {
const request = new PasswordRequest(); const request = new PasswordRequest();
request.masterPasswordHash = await this.cryptoService.hashPassword( request.masterPasswordHash = await this.cryptoService.hashPassword(
@ -218,15 +218,15 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
} }
private async updateKey(masterKey: MasterKey, masterPasswordHash: string) { private async updateKey(masterKey: MasterKey, masterPasswordHash: string) {
const userSymKey = await this.cryptoService.makeUserSymKey(masterKey); const userKey = await this.cryptoService.makeUserKey(masterKey);
const privateKey = await this.cryptoService.getPrivateKey(); const privateKey = await this.cryptoService.getPrivateKey();
let encPrivateKey: EncString = null; let encPrivateKey: EncString = null;
if (privateKey != null) { if (privateKey != null) {
encPrivateKey = await this.cryptoService.encrypt(privateKey, userSymKey[0]); encPrivateKey = await this.cryptoService.encrypt(privateKey, userKey[0]);
} }
const request = new UpdateKeyRequest(); const request = new UpdateKeyRequest();
request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null; request.privateKey = encPrivateKey != null ? encPrivateKey.encryptedString : null;
request.key = userSymKey[1].encryptedString; request.key = userKey[1].encryptedString;
request.masterPasswordHash = masterPasswordHash; request.masterPasswordHash = masterPasswordHash;
const folders = await firstValueFrom(this.folderService.folderViews$); const folders = await firstValueFrom(this.folderService.folderViews$);
@ -234,7 +234,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
if (folders[i].id == null) { if (folders[i].id == null) {
continue; continue;
} }
const folder = await this.folderService.encrypt(folders[i], userSymKey[0]); const folder = await this.folderService.encrypt(folders[i], userKey[0]);
request.folders.push(new FolderWithIdRequest(folder)); request.folders.push(new FolderWithIdRequest(folder));
} }
@ -244,7 +244,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
continue; continue;
} }
const cipher = await this.cipherService.encrypt(ciphers[i], userSymKey[0]); const cipher = await this.cipherService.encrypt(ciphers[i], userKey[0]);
request.ciphers.push(new CipherWithIdRequest(cipher)); request.ciphers.push(new CipherWithIdRequest(cipher));
} }
@ -252,16 +252,16 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
await Promise.all( await Promise.all(
sends.map(async (send) => { sends.map(async (send) => {
const sendKey = await this.cryptoService.decryptToBytes(send.key, null); const sendKey = await this.cryptoService.decryptToBytes(send.key, null);
send.key = (await this.cryptoService.encrypt(sendKey, userSymKey[0])) ?? send.key; send.key = (await this.cryptoService.encrypt(sendKey, userKey[0])) ?? send.key;
request.sends.push(new SendWithIdRequest(send)); request.sends.push(new SendWithIdRequest(send));
}) })
); );
await this.apiService.postAccountKey(request); await this.apiService.postAccountKey(request);
await this.updateEmergencyAccesses(userSymKey[0]); await this.updateEmergencyAccesses(userKey[0]);
await this.updateAllResetPasswordKeys(userSymKey[0], masterPasswordHash); await this.updateAllResetPasswordKeys(userKey[0], masterPasswordHash);
} }
private async updateEmergencyAccesses(encKey: SymmetricCryptoKey) { private async updateEmergencyAccesses(encKey: SymmetricCryptoKey) {
@ -289,7 +289,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
} }
} }
private async updateAllResetPasswordKeys(userSymKey: UserSymKey, masterPasswordHash: string) { private async updateAllResetPasswordKeys(userKey: UserKey, masterPasswordHash: string) {
const orgs = await this.organizationService.getAll(); const orgs = await this.organizationService.getAll();
for (const org of orgs) { for (const org of orgs) {
@ -303,7 +303,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
const publicKey = Utils.fromB64ToArray(response?.publicKey); const publicKey = Utils.fromB64ToArray(response?.publicKey);
// Re-enroll - encrypt user's encKey.key with organization public key // Re-enroll - encrypt user's encKey.key with organization public key
const encryptedKey = await this.cryptoService.rsaEncrypt(userSymKey.key, publicKey.buffer); const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey.buffer);
// Create/Execute request // Create/Execute request
const request = new OrganizationUserResetPasswordEnrollmentRequest(); const request = new OrganizationUserResetPasswordEnrollmentRequest();

View File

@ -69,7 +69,7 @@ export class UpdateKeyComponent {
private async makeRequest(): Promise<UpdateKeyRequest> { private async makeRequest(): Promise<UpdateKeyRequest> {
const masterKey = await this.cryptoService.getMasterKey(); const masterKey = await this.cryptoService.getMasterKey();
const newUserKey = await this.cryptoService.makeUserSymKey(masterKey); const newUserKey = await this.cryptoService.makeUserKey(masterKey);
const privateKey = await this.cryptoService.getPrivateKey(); const privateKey = await this.cryptoService.getPrivateKey();
let encPrivateKey: EncString = null; let encPrivateKey: EncString = null;
if (privateKey != null) { if (privateKey != null) {

View File

@ -2,7 +2,7 @@ export class AdminAuthRequestUpdateRequest {
/** /**
* *
* @param requestApproved - Whether the request was approved/denied. If true, the key must be provided. * @param requestApproved - Whether the request was approved/denied. If true, the key must be provided.
* @param encryptedUserKey The user's symmetric key that has been encrypted with a device public key if the request was approved. * @param encryptedUserKey The user key that has been encrypted with a device public key if the request was approved.
*/ */
constructor(public requestApproved: boolean, public encryptedUserKey?: string) {} constructor(public requestApproved: boolean, public encryptedUserKey?: string) {}
} }

View File

@ -65,16 +65,16 @@ export class DeviceApprovalsComponent implements OnInit, OnDestroy {
} }
/** /**
* Creates a copy of the user's symmetric key that has been encrypted with the provided device's public key. * Creates a copy of the user key that has been encrypted with the provided device's public key.
* @param devicePublicKey * @param devicePublicKey
* @param resetPasswordDetails * @param resetPasswordDetails
* @private * @private
*/ */
private async getEncryptedUserSymKey( private async getEncryptedUserKey(
devicePublicKey: string, devicePublicKey: string,
resetPasswordDetails: OrganizationUserResetPasswordDetailsResponse resetPasswordDetails: OrganizationUserResetPasswordDetailsResponse
): Promise<EncString> { ): Promise<EncString> {
const encryptedUserSymKey = resetPasswordDetails.resetPasswordKey; const encryptedUserKey = resetPasswordDetails.resetPasswordKey;
const encryptedOrgPrivateKey = resetPasswordDetails.encryptedPrivateKey; const encryptedOrgPrivateKey = resetPasswordDetails.encryptedPrivateKey;
const devicePubKey = Utils.fromB64ToArray(devicePublicKey); const devicePubKey = Utils.fromB64ToArray(devicePublicKey);
@ -85,12 +85,12 @@ export class DeviceApprovalsComponent implements OnInit, OnDestroy {
orgSymKey orgSymKey
); );
// Decrypt User's symmetric key with decrypted org private key // Decrypt user key with decrypted org private key
const decValue = await this.cryptoService.rsaDecrypt(encryptedUserSymKey, decOrgPrivateKey); const decValue = await this.cryptoService.rsaDecrypt(encryptedUserKey, decOrgPrivateKey);
const userSymKey = new SymmetricCryptoKey(decValue); const userKey = new SymmetricCryptoKey(decValue);
// Re-encrypt User's Symmetric Key with the Device Public Key // Re-encrypt user Key with the Device Public Key
return await this.cryptoService.rsaEncrypt(userSymKey.key, devicePubKey.buffer); return await this.cryptoService.rsaEncrypt(userKey.key, devicePubKey.buffer);
} }
async approveRequest(authRequest: PendingAuthRequestView) { async approveRequest(authRequest: PendingAuthRequestView) {
@ -110,7 +110,7 @@ export class DeviceApprovalsComponent implements OnInit, OnDestroy {
return; return;
} }
const encryptedKey = await this.getEncryptedUserSymKey(authRequest.publicKey, details); const encryptedKey = await this.getEncryptedUserKey(authRequest.publicKey, details);
await this.organizationAuthRequestService.approvePendingRequest( await this.organizationAuthRequestService.approvePendingRequest(
this.organizationId, this.organizationId,

View File

@ -12,10 +12,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.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 { import { MasterKey, UserKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
MasterKey,
UserSymKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { DialogServiceAbstraction, SimpleDialogType } from "../../services/dialog"; import { DialogServiceAbstraction, SimpleDialogType } from "../../services/dialog";
@ -95,17 +92,15 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
newMasterKey newMasterKey
); );
let newProtectedUserSymKey: [UserSymKey, EncString] = null; let newProtectedUserKey: [UserKey, EncString] = null;
const userSymKey = await this.cryptoService.getUserKeyFromMemory(); const userKey = await this.cryptoService.getUserKeyFromMemory();
if (userSymKey == null) { if (userKey == null) {
newProtectedUserSymKey = await this.cryptoService.makeUserSymKey(newMasterKey); newProtectedUserKey = await this.cryptoService.makeUserKey(newMasterKey);
} else { } else {
newProtectedUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey( newProtectedUserKey = await this.cryptoService.encryptUserKeyWithMasterKey(newMasterKey);
newMasterKey
);
} }
await this.performSubmitActions(newMasterPasswordHash, newMasterKey, newProtectedUserSymKey); await this.performSubmitActions(newMasterPasswordHash, newMasterKey, newProtectedUserKey);
} }
async setupSubmitActions(): Promise<boolean> { async setupSubmitActions(): Promise<boolean> {
@ -117,7 +112,7 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
async performSubmitActions( async performSubmitActions(
masterPasswordHash: string, masterPasswordHash: string,
masterKey: MasterKey, masterKey: MasterKey,
userSymKey: [UserSymKey, EncString] userKey: [UserKey, EncString]
) { ) {
// Override in sub-class // Override in sub-class
} }

View File

@ -24,7 +24,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.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 { UserSymKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { UserKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
import { DialogServiceAbstraction, SimpleDialogType } from "../../services/dialog"; import { DialogServiceAbstraction, SimpleDialogType } from "../../services/dialog";
@ -153,41 +153,41 @@ export class LockComponent implements OnInit, OnDestroy {
try { try {
const kdf = await this.stateService.getKdfType(); const kdf = await this.stateService.getKdfType();
const kdfConfig = await this.stateService.getKdfConfig(); const kdfConfig = await this.stateService.getKdfConfig();
let userSymKeyPin: EncString; let userKeyPin: EncString;
let oldPinProtected: EncString; let oldPinProtected: EncString;
if (this.pinSet[0]) { if (this.pinSet[0]) {
// MP on restart enabled // MP on restart enabled
userSymKeyPin = await this.stateService.getUserSymKeyPinEphemeral(); userKeyPin = await this.stateService.getUserKeyPinEphemeral();
oldPinProtected = await this.stateService.getDecryptedPinProtected(); oldPinProtected = await this.stateService.getDecryptedPinProtected();
} else { } else {
// MP on restart disabled // MP on restart disabled
userSymKeyPin = await this.stateService.getUserSymKeyPin(); userKeyPin = await this.stateService.getUserKeyPin();
const oldEncryptedKey = await this.stateService.getEncryptedPinProtected(); const oldEncryptedKey = await this.stateService.getEncryptedPinProtected();
oldPinProtected = oldEncryptedKey ? new EncString(oldEncryptedKey) : undefined; oldPinProtected = oldEncryptedKey ? new EncString(oldEncryptedKey) : undefined;
} }
let userSymKey: UserSymKey; let userKey: UserKey;
if (oldPinProtected) { if (oldPinProtected) {
userSymKey = await this.decryptAndMigrateOldPinKey(true, kdf, kdfConfig, oldPinProtected); userKey = await this.decryptAndMigrateOldPinKey(true, kdf, kdfConfig, oldPinProtected);
} else { } else {
userSymKey = await this.cryptoService.decryptUserSymKeyWithPin( userKey = await this.cryptoService.decryptUserKeyWithPin(
this.pin, this.pin,
this.email, this.email,
kdf, kdf,
kdfConfig, kdfConfig,
userSymKeyPin userKeyPin
); );
} }
const protectedPin = await this.stateService.getProtectedPin(); const protectedPin = await this.stateService.getProtectedPin();
const decryptedPin = await this.cryptoService.decryptToUtf8( const decryptedPin = await this.cryptoService.decryptToUtf8(
new EncString(protectedPin), new EncString(protectedPin),
userSymKey userKey
); );
failed = decryptedPin !== this.pin; failed = decryptedPin !== this.pin;
if (!failed) { if (!failed) {
await this.setKeyAndContinue(userSymKey); await this.setKeyAndContinue(userKey);
} }
} catch { } catch {
failed = true; failed = true;
@ -275,22 +275,22 @@ export class LockComponent implements OnInit, OnDestroy {
return; return;
} }
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
// if MP on restart is enabled, use it to get the PIN and store the ephemeral // if MP on restart is enabled, use it to get the PIN and store the ephemeral
// pin protected user symmetric key // pin protected user key
if (this.pinSet[0]) { if (this.pinSet[0]) {
const protectedPin = await this.stateService.getProtectedPin(); const protectedPin = await this.stateService.getProtectedPin();
const pin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), userKey); const pin = await this.cryptoService.decryptToUtf8(new EncString(protectedPin), userKey);
const pinKey = await this.cryptoService.makePinKey(pin, this.email, kdf, kdfConfig); const pinKey = await this.cryptoService.makePinKey(pin, this.email, kdf, kdfConfig);
await this.stateService.setUserSymKeyPinEphemeral( await this.stateService.setUserKeyPinEphemeral(
await this.cryptoService.encrypt(userKey.key, pinKey) await this.cryptoService.encrypt(userKey.key, pinKey)
); );
} }
await this.setKeyAndContinue(userKey, true); await this.setKeyAndContinue(userKey, true);
} }
private async setKeyAndContinue(key: UserSymKey, evaluatePasswordAfterUnlock = false) { private async setKeyAndContinue(key: UserKey, evaluatePasswordAfterUnlock = false) {
await this.cryptoService.setUserKey(key); await this.cryptoService.setUserKey(key);
await this.doContinue(evaluatePasswordAfterUnlock); await this.doContinue(evaluatePasswordAfterUnlock);
} }
@ -331,7 +331,7 @@ export class LockComponent implements OnInit, OnDestroy {
private async load() { private async load() {
this.pinSet = await this.vaultTimeoutSettingsService.isPinLockSet(); this.pinSet = await this.vaultTimeoutSettingsService.isPinLockSet();
let ephemeralPinSet = await this.stateService.getUserSymKeyPinEphemeral(); let ephemeralPinSet = await this.stateService.getUserKeyPinEphemeral();
ephemeralPinSet ||= await this.stateService.getDecryptedPinProtected(); ephemeralPinSet ||= await this.stateService.getDecryptedPinProtected();
this.pinLock = (this.pinSet[0] && !!ephemeralPinSet) || this.pinSet[1]; this.pinLock = (this.pinSet[0] && !!ephemeralPinSet) || this.pinSet[1];
@ -381,21 +381,21 @@ export class LockComponent implements OnInit, OnDestroy {
} }
/** /**
* Creates a new Pin key that encrypts the user's symmetric key instead of the * Creates a new Pin key that encrypts the user key instead of the
* master key. Clears the old Pin key from state. * master key. Clears the old Pin key from state.
* @param masterPasswordOnRestart True if Master Password on Restart is enabled * @param masterPasswordOnRestart True if Master Password on Restart is enabled
* @param kdf User's KdfType * @param kdf User's KdfType
* @param kdfConfig User's KdfConfig * @param kdfConfig User's KdfConfig
* @param oldPinProtected The old Pin key from state (retrieved from different * @param oldPinProtected The old Pin key from state (retrieved from different
* places depending on if Master Password on Restart was enabled) * places depending on if Master Password on Restart was enabled)
* @returns The user's symmetric key * @returns The user key
*/ */
private async decryptAndMigrateOldPinKey( private async decryptAndMigrateOldPinKey(
masterPasswordOnRestart: boolean, masterPasswordOnRestart: boolean,
kdf: KdfType, kdf: KdfType,
kdfConfig: KdfConfig, kdfConfig: KdfConfig,
oldPinProtected?: EncString oldPinProtected?: EncString
): Promise<UserSymKey> { ): Promise<UserKey> {
// Decrypt // Decrypt
const masterKey = await this.cryptoService.decryptMasterKeyWithPin( const masterKey = await this.cryptoService.decryptMasterKeyWithPin(
this.pin, this.pin,
@ -404,28 +404,28 @@ export class LockComponent implements OnInit, OnDestroy {
kdfConfig, kdfConfig,
oldPinProtected oldPinProtected
); );
const encUserSymKey = await this.stateService.getEncryptedCryptoSymmetricKey(); const encUserKey = await this.stateService.getEncryptedCryptoSymmetricKey();
const userSymKey = await this.cryptoService.decryptUserSymKeyWithMasterKey( const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(
masterKey, masterKey,
new EncString(encUserSymKey) new EncString(encUserKey)
); );
// Migrate // Migrate
const pinKey = await this.cryptoService.makePinKey(this.pin, this.email, kdf, kdfConfig); const pinKey = await this.cryptoService.makePinKey(this.pin, this.email, kdf, kdfConfig);
const pinProtectedKey = await this.cryptoService.encrypt(userSymKey.key, pinKey); const pinProtectedKey = await this.cryptoService.encrypt(userKey.key, pinKey);
if (masterPasswordOnRestart) { if (masterPasswordOnRestart) {
await this.stateService.setDecryptedPinProtected(null); await this.stateService.setDecryptedPinProtected(null);
await this.stateService.setUserSymKeyPinEphemeral(pinProtectedKey); await this.stateService.setUserKeyPinEphemeral(pinProtectedKey);
} else { } else {
await this.stateService.setEncryptedPinProtected(null); await this.stateService.setEncryptedPinProtected(null);
await this.stateService.setUserSymKeyPin(pinProtectedKey); await this.stateService.setUserKeyPin(pinProtectedKey);
// We previously only set the protected pin if MP on Restart was enabled // We previously only set the protected pin if MP on Restart was enabled
// now we set it regardless // now we set it regardless
const encPin = await this.cryptoService.encrypt(this.pin, userSymKey); const encPin = await this.cryptoService.encrypt(this.pin, userKey);
await this.stateService.setProtectedPin(encPin.encryptedString); await this.stateService.setProtectedPin(encPin.encryptedString);
} }
// This also clears the old Biometrics key since the new Biometrics key will // This also clears the old Biometrics key since the new Biometrics key will
// be created when the user's symmetric key is set. // be created when the user key is set.
await this.stateService.setCryptoMasterKeyBiometric(null); await this.stateService.setCryptoMasterKeyBiometric(null);
return userSymKey; return userKey;
} }
} }

View File

@ -14,10 +14,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { import { MasterKey, UserKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
MasterKey,
UserSymKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { Verification } from "@bitwarden/common/types/verification"; import { Verification } from "@bitwarden/common/types/verification";
@ -100,7 +97,7 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent {
async performSubmitActions( async performSubmitActions(
masterPasswordHash: string, masterPasswordHash: string,
masterKey: MasterKey, masterKey: MasterKey,
userSymKey: [UserSymKey, EncString] userKey: [UserKey, EncString]
) { ) {
try { try {
// Create Request // Create Request
@ -110,7 +107,7 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent {
null null
); );
request.newMasterPasswordHash = masterPasswordHash; request.newMasterPasswordHash = masterPasswordHash;
request.key = userSymKey[1].encryptedString; request.key = userKey[1].encryptedString;
// Update user's password // Update user's password
this.apiService.postPassword(request); this.apiService.postPassword(request);

View File

@ -16,10 +16,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
import { import { MasterKey, UserKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
MasterKey,
UserSymKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { Verification } from "@bitwarden/common/types/verification"; import { Verification } from "@bitwarden/common/types/verification";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
@ -128,16 +125,16 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
newMasterKey newMasterKey
); );
// Grab user's symmetric key // Grab user key
const userKey = await this.cryptoService.getUserKeyFromMemory(); const userKey = await this.cryptoService.getUserKeyFromMemory();
// Encrypt user's symmetric key with new master key // Encrypt user key with new master key
const newProtectedUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey( const newProtectedUserKey = await this.cryptoService.encryptUserKeyWithMasterKey(
newMasterKey, newMasterKey,
userKey userKey
); );
await this.performSubmitActions(newPasswordHash, newMasterKey, newProtectedUserSymKey); await this.performSubmitActions(newPasswordHash, newMasterKey, newProtectedUserKey);
} catch (e) { } catch (e) {
this.logService.error(e); this.logService.error(e);
} }
@ -146,15 +143,15 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
async performSubmitActions( async performSubmitActions(
masterPasswordHash: string, masterPasswordHash: string,
masterKey: MasterKey, masterKey: MasterKey,
userSymKey: [UserSymKey, EncString] userKey: [UserKey, EncString]
) { ) {
try { try {
switch (this.reason) { switch (this.reason) {
case ForceResetPasswordReason.AdminForcePasswordReset: case ForceResetPasswordReason.AdminForcePasswordReset:
this.formPromise = this.updateTempPassword(masterPasswordHash, userSymKey); this.formPromise = this.updateTempPassword(masterPasswordHash, userKey);
break; break;
case ForceResetPasswordReason.WeakMasterPassword: case ForceResetPasswordReason.WeakMasterPassword:
this.formPromise = this.updatePassword(masterPasswordHash, userSymKey); this.formPromise = this.updatePassword(masterPasswordHash, userKey);
break; break;
} }
@ -176,26 +173,23 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
this.logService.error(e); this.logService.error(e);
} }
} }
private async updateTempPassword( private async updateTempPassword(masterPasswordHash: string, userKey: [UserKey, EncString]) {
masterPasswordHash: string,
userSymKey: [UserSymKey, EncString]
) {
const request = new UpdateTempPasswordRequest(); const request = new UpdateTempPasswordRequest();
request.key = userSymKey[1].encryptedString; request.key = userKey[1].encryptedString;
request.newMasterPasswordHash = masterPasswordHash; request.newMasterPasswordHash = masterPasswordHash;
request.masterPasswordHint = this.hint; request.masterPasswordHint = this.hint;
return this.apiService.putUpdateTempPassword(request); return this.apiService.putUpdateTempPassword(request);
} }
private async updatePassword(newMasterPasswordHash: string, userSymKey: [UserSymKey, EncString]) { private async updatePassword(newMasterPasswordHash: string, userKey: [UserKey, EncString]) {
const request = await this.userVerificationService.buildRequest( const request = await this.userVerificationService.buildRequest(
this.verification, this.verification,
PasswordRequest PasswordRequest
); );
request.masterPasswordHint = this.hint; request.masterPasswordHint = this.hint;
request.newMasterPasswordHash = newMasterPasswordHash; request.newMasterPasswordHash = newMasterPasswordHash;
request.key = userSymKey[1].encryptedString; request.key = userKey[1].encryptedString;
return this.apiService.postPassword(request); return this.apiService.postPassword(request);
} }

View File

@ -272,15 +272,15 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
const kdf = DEFAULT_KDF_TYPE; const kdf = DEFAULT_KDF_TYPE;
const kdfConfig = DEFAULT_KDF_CONFIG; const kdfConfig = DEFAULT_KDF_CONFIG;
const key = await this.cryptoService.makeMasterKey(masterPassword, email, kdf, kdfConfig); const key = await this.cryptoService.makeMasterKey(masterPassword, email, kdf, kdfConfig);
const newUserSymKey = await this.cryptoService.makeUserSymKey(key); const newUserKey = await this.cryptoService.makeUserKey(key);
const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key); const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key);
const keys = await this.cryptoService.makeKeyPair(newUserSymKey[0]); const keys = await this.cryptoService.makeKeyPair(newUserKey[0]);
const request = new RegisterRequest( const request = new RegisterRequest(
email, email,
name, name,
hashedPassword, hashedPassword,
hint, hint,
newUserSymKey[1].encryptedString, newUserKey[1].encryptedString,
this.referenceData, this.referenceData,
this.captchaToken, this.captchaToken,
kdf, kdf,

View File

@ -18,10 +18,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.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 { import { MasterKey, UserKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
MasterKey,
UserSymKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
@ -105,7 +102,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
async performSubmitActions( async performSubmitActions(
masterPasswordHash: string, masterPasswordHash: string,
masterKey: MasterKey, masterKey: MasterKey,
userKey: [UserSymKey, EncString] userKey: [UserKey, EncString]
) { ) {
const newKeyPair = await this.cryptoService.makeKeyPair(userKey[0]); const newKeyPair = await this.cryptoService.makeKeyPair(userKey[0]);
const request = new SetPasswordRequest( const request = new SetPasswordRequest(
@ -134,7 +131,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
const userId = await this.stateService.getUserId(); const userId = await this.stateService.getUserId();
const publicKey = Utils.fromB64ToArray(response.publicKey); const publicKey = Utils.fromB64ToArray(response.publicKey);
// RSA Encrypt user's symmetric key with organization public key // RSA Encrypt user key with organization public key
const userKey = await this.cryptoService.getUserKeyFromMemory(); const userKey = await this.cryptoService.getUserKeyFromMemory();
const encryptedUserKey = await this.cryptoService.rsaEncrypt( const encryptedUserKey = await this.cryptoService.rsaEncrypt(
userKey.key, userKey.key,
@ -176,7 +173,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
private async onSetPasswordSuccess( private async onSetPasswordSuccess(
masterKey: MasterKey, masterKey: MasterKey,
userKey: [UserSymKey, EncString], userKey: [UserKey, EncString],
keyPair: [string, EncString] keyPair: [string, EncString]
) { ) {
await this.stateService.setKdfType(this.kdf); await this.stateService.setKdfType(this.kdf);

View File

@ -46,9 +46,9 @@ export class SetPinComponent implements OnInit {
const encPin = await this.cryptoService.encrypt(this.pin, userKey); const encPin = await this.cryptoService.encrypt(this.pin, userKey);
await this.stateService.setProtectedPin(encPin.encryptedString); await this.stateService.setProtectedPin(encPin.encryptedString);
if (this.masterPassOnRestart) { if (this.masterPassOnRestart) {
await this.stateService.setUserSymKeyPinEphemeral(pinProtectedKey); await this.stateService.setUserKeyPinEphemeral(pinProtectedKey);
} else { } else {
await this.stateService.setUserSymKeyPin(pinProtectedKey); await this.stateService.setUserKeyPin(pinProtectedKey);
} }
await this.cryptoService.clearOldPinKeys(); await this.cryptoService.clearOldPinKeys();

View File

@ -7,8 +7,8 @@ export abstract class DevicesApiServiceAbstraction {
updateTrustedDeviceKeys: ( updateTrustedDeviceKeys: (
deviceIdentifier: string, deviceIdentifier: string,
devicePublicKeyEncryptedUserSymKey: string, devicePublicKeyEncryptedUserKey: string,
userSymKeyEncryptedDevicePublicKey: string, userKeyEncryptedDevicePublicKey: string,
deviceKeyEncryptedDevicePrivateKey: string deviceKeyEncryptedDevicePrivateKey: string
) => Promise<DeviceResponse>; ) => Promise<DeviceResponse>;
} }

View File

@ -14,7 +14,7 @@ import { EncString } from "../../platform/models/domain/enc-string";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../../platform/models/domain/symmetric-crypto-key"; } from "../../platform/models/domain/symmetric-crypto-key";
import { import {
PasswordStrengthService, PasswordStrengthService,
@ -43,7 +43,7 @@ const masterPassword = "password";
const deviceId = Utils.newGuid(); const deviceId = Utils.newGuid();
const accessToken = "ACCESS_TOKEN"; const accessToken = "ACCESS_TOKEN";
const refreshToken = "REFRESH_TOKEN"; const refreshToken = "REFRESH_TOKEN";
const userSymKey = "USER_SYM_KEY"; const userKey = "USER_KEY";
const privateKey = "PRIVATE_KEY"; const privateKey = "PRIVATE_KEY";
const captchaSiteKey = "CAPTCHA_SITE_KEY"; const captchaSiteKey = "CAPTCHA_SITE_KEY";
const kdf = 0; const kdf = 0;
@ -70,7 +70,7 @@ export function identityTokenResponseFactory(
ForcePasswordReset: false, ForcePasswordReset: false,
Kdf: kdf, Kdf: kdf,
KdfIterations: kdfIterations, KdfIterations: kdfIterations,
Key: userSymKey, Key: userKey,
PrivateKey: privateKey, PrivateKey: privateKey,
ResetMasterPassword: false, ResetMasterPassword: false,
access_token: accessToken, access_token: accessToken,
@ -135,15 +135,15 @@ describe("LogInStrategy", () => {
}); });
describe("base class", () => { describe("base class", () => {
const userSymKeyBytesLength = 64; const userKeyBytesLength = 64;
const masterKeyBytesLength = 64; const masterKeyBytesLength = 64;
let userSymKey: UserSymKey; let userKey: UserKey;
let masterKey: MasterKey; let masterKey: MasterKey;
beforeEach(() => { beforeEach(() => {
userSymKey = new SymmetricCryptoKey( userKey = new SymmetricCryptoKey(
new Uint8Array(userSymKeyBytesLength).buffer as CsprngArray new Uint8Array(userKeyBytesLength).buffer as CsprngArray
) as UserSymKey; ) as UserKey;
masterKey = new SymmetricCryptoKey( masterKey = new SymmetricCryptoKey(
new Uint8Array(masterKeyBytesLength).buffer as CsprngArray new Uint8Array(masterKeyBytesLength).buffer as CsprngArray
) as MasterKey; ) as MasterKey;
@ -206,7 +206,7 @@ describe("LogInStrategy", () => {
apiService.postIdentityToken.mockResolvedValue(tokenResponse); apiService.postIdentityToken.mockResolvedValue(tokenResponse);
cryptoService.getMasterKey.mockResolvedValue(masterKey); cryptoService.getMasterKey.mockResolvedValue(masterKey);
cryptoService.decryptUserSymKeyWithMasterKey.mockResolvedValue(userSymKey); cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
const result = await passwordLogInStrategy.logIn(credentials); const result = await passwordLogInStrategy.logIn(credentials);
@ -225,7 +225,7 @@ describe("LogInStrategy", () => {
apiService.postIdentityToken.mockResolvedValue(tokenResponse); apiService.postIdentityToken.mockResolvedValue(tokenResponse);
cryptoService.getMasterKey.mockResolvedValue(masterKey); cryptoService.getMasterKey.mockResolvedValue(masterKey);
cryptoService.decryptUserSymKeyWithMasterKey.mockResolvedValue(userSymKey); cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
await passwordLogInStrategy.logIn(credentials); await passwordLogInStrategy.logIn(credentials);

View File

@ -13,7 +13,7 @@ import { Utils } from "../../platform/misc/utils";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../../platform/models/domain/symmetric-crypto-key"; } from "../../platform/models/domain/symmetric-crypto-key";
import { import {
PasswordStrengthService, PasswordStrengthService,
@ -134,19 +134,17 @@ describe("PasswordLogInStrategy", () => {
}); });
it("sets keys after a successful authentication", async () => { it("sets keys after a successful authentication", async () => {
const userSymKey = new SymmetricCryptoKey( const userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey;
new Uint8Array(64).buffer as CsprngArray
) as UserSymKey;
cryptoService.getMasterKey.mockResolvedValue(masterKey); cryptoService.getMasterKey.mockResolvedValue(masterKey);
cryptoService.decryptUserSymKeyWithMasterKey.mockResolvedValue(userSymKey); cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
await passwordLogInStrategy.logIn(credentials); await passwordLogInStrategy.logIn(credentials);
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey); expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localHashedPassword); expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localHashedPassword);
expect(cryptoService.setUserSymKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key); expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userSymKey); expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey); expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
}); });

View File

@ -147,11 +147,11 @@ export class PasswordLogInStrategy extends LogInStrategy {
} }
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> { protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {
await this.cryptoService.setUserSymKeyMasterKey(response.key); await this.cryptoService.setUserKeyMasterKey(response.key);
const masterKey = await this.cryptoService.getMasterKey(); const masterKey = await this.cryptoService.getMasterKey();
if (masterKey) { if (masterKey) {
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
await this.cryptoService.setUserKey(userKey); await this.cryptoService.setUserKey(userKey);
} }
} }

View File

@ -11,7 +11,7 @@ import { Utils } from "../../platform/misc/utils";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../../platform/models/domain/symmetric-crypto-key"; } from "../../platform/models/domain/symmetric-crypto-key";
import { CsprngArray } from "../../types/csprng"; import { CsprngArray } from "../../types/csprng";
import { TokenService } from "../abstractions/token.service"; import { TokenService } from "../abstractions/token.service";
@ -85,19 +85,17 @@ describe("SsoLogInStrategy", () => {
it("sets keys after a successful authentication", async () => { it("sets keys after a successful authentication", async () => {
const masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; const masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey;
const userSymKey = new SymmetricCryptoKey( const userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey;
new Uint8Array(64).buffer as CsprngArray
) as UserSymKey;
cryptoService.getMasterKey.mockResolvedValue(masterKey); cryptoService.getMasterKey.mockResolvedValue(masterKey);
cryptoService.decryptUserSymKeyWithMasterKey.mockResolvedValue(userSymKey); cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
await passwordlessLoginStrategy.logIn(credentials); await passwordlessLoginStrategy.logIn(credentials);
expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey); expect(cryptoService.setMasterKey).toHaveBeenCalledWith(masterKey);
expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localPasswordHash); expect(cryptoService.setKeyHash).toHaveBeenCalledWith(localPasswordHash);
expect(cryptoService.setUserSymKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key); expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userSymKey); expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey); expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
}); });
}); });

View File

@ -85,11 +85,11 @@ export class PasswordlessLogInStrategy extends LogInStrategy {
} }
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> { protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {
await this.cryptoService.setUserSymKeyMasterKey(response.key); await this.cryptoService.setUserKeyMasterKey(response.key);
const masterKey = await this.cryptoService.getMasterKey(); const masterKey = await this.cryptoService.getMasterKey();
if (masterKey) { if (masterKey) {
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
await this.cryptoService.setUserKey(userKey); await this.cryptoService.setUserKey(userKey);
} }
} }

View File

@ -11,7 +11,7 @@ import { Utils } from "../../platform/misc/utils";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../../platform/models/domain/symmetric-crypto-key"; } from "../../platform/models/domain/symmetric-crypto-key";
import { CsprngArray } from "../../types/csprng"; import { CsprngArray } from "../../types/csprng";
import { KeyConnectorService } from "../abstractions/key-connector.service"; import { KeyConnectorService } from "../abstractions/key-connector.service";
@ -143,22 +143,20 @@ describe("SsoLogInStrategy", () => {
); );
}); });
it("decrypts and sets the user symmetric key if Key Connector is enabled", async () => { it("decrypts and sets the user key if Key Connector is enabled", async () => {
const userSymKey = new SymmetricCryptoKey( const userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey;
new Uint8Array(64).buffer as CsprngArray
) as UserSymKey;
const masterKey = new SymmetricCryptoKey( const masterKey = new SymmetricCryptoKey(
new Uint8Array(64).buffer as CsprngArray new Uint8Array(64).buffer as CsprngArray
) as MasterKey; ) as MasterKey;
apiService.postIdentityToken.mockResolvedValue(tokenResponse); apiService.postIdentityToken.mockResolvedValue(tokenResponse);
cryptoService.getMasterKey.mockResolvedValue(masterKey); cryptoService.getMasterKey.mockResolvedValue(masterKey);
cryptoService.decryptUserSymKeyWithMasterKey.mockResolvedValue(userSymKey); cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
await ssoLogInStrategy.logIn(credentials); await ssoLogInStrategy.logIn(credentials);
expect(cryptoService.decryptUserSymKeyWithMasterKey).toHaveBeenCalledWith(masterKey); expect(cryptoService.decryptUserKeyWithMasterKey).toHaveBeenCalledWith(masterKey);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userSymKey); expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
}); });
}); });
}); });

View File

@ -83,14 +83,14 @@ export class SsoLogInStrategy extends LogInStrategy {
const newSsoUser = tokenResponse.key == null; const newSsoUser = tokenResponse.key == null;
if (!newSsoUser) { if (!newSsoUser) {
await this.cryptoService.setUserSymKeyMasterKey(tokenResponse.key); await this.cryptoService.setUserKeyMasterKey(tokenResponse.key);
if (tokenResponse.keyConnectorUrl != null) { if (tokenResponse.keyConnectorUrl != null) {
const masterKey = await this.cryptoService.getMasterKey(); const masterKey = await this.cryptoService.getMasterKey();
if (!masterKey) { if (!masterKey) {
throw new Error("Master key not found"); throw new Error("Master key not found");
} }
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
await this.cryptoService.setUserKey(userKey); await this.cryptoService.setUserKey(userKey);
} }
} }

View File

@ -12,7 +12,7 @@ import { Utils } from "../../platform/misc/utils";
import { import {
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../../platform/models/domain/symmetric-crypto-key"; } from "../../platform/models/domain/symmetric-crypto-key";
import { CsprngArray } from "../../types/csprng"; import { CsprngArray } from "../../types/csprng";
import { KeyConnectorService } from "../abstractions/key-connector.service"; import { KeyConnectorService } from "../abstractions/key-connector.service";
@ -107,14 +107,14 @@ describe("UserApiLogInStrategy", () => {
expect(stateService.addAccount).toHaveBeenCalled(); expect(stateService.addAccount).toHaveBeenCalled();
}); });
it("sets the encrypted user symmetric key and private key from the identity token response", async () => { it("sets the encrypted user key and private key from the identity token response", async () => {
const tokenResponse = identityTokenResponseFactory(); const tokenResponse = identityTokenResponseFactory();
apiService.postIdentityToken.mockResolvedValue(tokenResponse); apiService.postIdentityToken.mockResolvedValue(tokenResponse);
await apiLogInStrategy.logIn(credentials); await apiLogInStrategy.logIn(credentials);
expect(cryptoService.setUserSymKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key); expect(cryptoService.setUserKeyMasterKey).toHaveBeenCalledWith(tokenResponse.key);
expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey); expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey);
}); });
@ -130,10 +130,8 @@ describe("UserApiLogInStrategy", () => {
expect(keyConnectorService.getAndSetMasterKey).toHaveBeenCalledWith(keyConnectorUrl); expect(keyConnectorService.getAndSetMasterKey).toHaveBeenCalledWith(keyConnectorUrl);
}); });
it("decrypts and sets the user symmetric key if Key Connector is enabled", async () => { it("decrypts and sets the user key if Key Connector is enabled", async () => {
const userSymKey = new SymmetricCryptoKey( const userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey;
new Uint8Array(64).buffer as CsprngArray
) as UserSymKey;
const masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; const masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey;
const tokenResponse = identityTokenResponseFactory(); const tokenResponse = identityTokenResponseFactory();
@ -142,11 +140,11 @@ describe("UserApiLogInStrategy", () => {
apiService.postIdentityToken.mockResolvedValue(tokenResponse); apiService.postIdentityToken.mockResolvedValue(tokenResponse);
environmentService.getKeyConnectorUrl.mockReturnValue(keyConnectorUrl); environmentService.getKeyConnectorUrl.mockReturnValue(keyConnectorUrl);
cryptoService.getMasterKey.mockResolvedValue(masterKey); cryptoService.getMasterKey.mockResolvedValue(masterKey);
cryptoService.decryptUserSymKeyWithMasterKey.mockResolvedValue(userSymKey); cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
await apiLogInStrategy.logIn(credentials); await apiLogInStrategy.logIn(credentials);
expect(cryptoService.decryptUserSymKeyWithMasterKey).toHaveBeenCalledWith(masterKey); expect(cryptoService.decryptUserKeyWithMasterKey).toHaveBeenCalledWith(masterKey);
expect(cryptoService.setUserKey).toHaveBeenCalledWith(userSymKey); expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey);
}); });
}); });

View File

@ -64,12 +64,12 @@ export class UserApiLogInStrategy extends LogInStrategy {
} }
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> { protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {
await this.cryptoService.setUserSymKeyMasterKey(response.key); await this.cryptoService.setUserKeyMasterKey(response.key);
if (response.apiUseKeyConnector) { if (response.apiUseKeyConnector) {
const masterKey = await this.cryptoService.getMasterKey(); const masterKey = await this.cryptoService.getMasterKey();
if (masterKey) { if (masterKey) {
const userKey = await this.cryptoService.decryptUserSymKeyWithMasterKey(masterKey); const userKey = await this.cryptoService.decryptUserKeyWithMasterKey(masterKey);
await this.cryptoService.setUserKey(userKey); await this.cryptoService.setUserKey(userKey);
} }
} }

View File

@ -297,7 +297,7 @@ export class AuthService implements AuthServiceAbstraction {
requestApproved: boolean requestApproved: boolean
): Promise<AuthRequestResponse> { ): Promise<AuthRequestResponse> {
// TODO: This currently depends on always having the Master Key and MP Hash // TODO: This currently depends on always having the Master Key and MP Hash
// We need to change this to using a different method (possibly server auth code + user sym key) // We need to change this to using a different method (possibly server auth code + user key)
const pubKey = Utils.fromB64ToArray(key); const pubKey = Utils.fromB64ToArray(key);
const masterKey = await this.cryptoService.getMasterKey(); const masterKey = await this.cryptoService.getMasterKey();
if (!masterKey) { if (!masterKey) {

View File

@ -97,9 +97,9 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
const keyConnectorRequest = new KeyConnectorUserKeyRequest(masterKey.encKeyB64); const keyConnectorRequest = new KeyConnectorUserKeyRequest(masterKey.encKeyB64);
await this.cryptoService.setMasterKey(masterKey); await this.cryptoService.setMasterKey(masterKey);
const userKey = await this.cryptoService.makeUserSymKey(masterKey); const userKey = await this.cryptoService.makeUserKey(masterKey);
await this.cryptoService.setUserKey(userKey[0]); await this.cryptoService.setUserKey(userKey[0]);
await this.cryptoService.setUserSymKeyMasterKey(userKey[1].encryptedString); await this.cryptoService.setUserKeyMasterKey(userKey[1].encryptedString);
const [pubKey, privKey] = await this.cryptoService.makeKeyPair(); const [pubKey, privKey] = await this.cryptoService.makeKeyPair();

View File

@ -10,90 +10,90 @@ import {
OrgKey, OrgKey,
PinKey, PinKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../models/domain/symmetric-crypto-key"; } from "../models/domain/symmetric-crypto-key";
export abstract class CryptoService { export abstract class CryptoService {
/** /**
* Use for encryption/decryption of data in order to support legacy * Use for encryption/decryption of data in order to support legacy
* encryption models. It will return the user symmetric key if available, * encryption models. It will return the user key if available,
* if not it will return the master key. * if not it will return the master key.
*/ */
getKeyForUserEncryption: (key?: SymmetricCryptoKey) => Promise<SymmetricCryptoKey>; getKeyForUserEncryption: (key?: SymmetricCryptoKey) => Promise<SymmetricCryptoKey>;
/** /**
* Sets the provided user symmetric key and stores * Sets the provided user key and stores
* any other necessary versions, such as biometrics * any other necessary versions, such as biometrics
* @param key The user symmetric key to set * @param key The user key to set
* @param userId The desired user * @param userId The desired user
*/ */
setUserKey: (key: UserSymKey) => Promise<void>; setUserKey: (key: UserKey) => Promise<void>;
/** /**
* Gets the user key from memory and sets it again, * Gets the user key from memory and sets it again,
* kicking off a refresh of any additional keys that are needed. * kicking off a refresh of any additional keys that are needed.
*/ */
toggleKey: () => Promise<void>; toggleKey: () => Promise<void>;
/** /**
* Retrieves the user's symmetric key * Retrieves the user key
* @param keySuffix The desired version of the user's key to retrieve * @param keySuffix The desired version of the user's key to retrieve
* from storage if it is not available in memory * from storage if it is not available in memory
* @param userId The desired user * @param userId The desired user
* @returns The user's symmetric key * @returns The user key
*/ */
getUserKeyFromMemory: (userId?: string) => Promise<UserSymKey>; getUserKeyFromMemory: (userId?: string) => Promise<UserKey>;
/** /**
* Retrieves the user's symmetric key from storage * Retrieves the user key from storage
* @param keySuffix The desired version of the user's key to retrieve * @param keySuffix The desired version of the user's key to retrieve
* @param userId The desired user * @param userId The desired user
* @returns The user's symmetric key * @returns The user key
*/ */
getUserKeyFromStorage: ( getUserKeyFromStorage: (
keySuffix: KeySuffixOptions.Auto | KeySuffixOptions.Biometric, keySuffix: KeySuffixOptions.Auto | KeySuffixOptions.Biometric,
userId?: string userId?: string
) => Promise<UserSymKey>; ) => Promise<UserKey>;
/** /**
* @returns True if any version of the user symmetric key is available * @returns True if any version of the user key is available
*/ */
hasUserKey: () => Promise<boolean>; hasUserKey: () => Promise<boolean>;
/** /**
* @param userId The desired user * @param userId The desired user
* @returns True if the user symmetric key is set in memory * @returns True if the user key is set in memory
*/ */
hasUserKeyInMemory: (userId?: string) => Promise<boolean>; hasUserKeyInMemory: (userId?: string) => Promise<boolean>;
/** /**
* @param keySuffix The desired version of the user's key to check * @param keySuffix The desired version of the user's key to check
* @param userId The desired user * @param userId The desired user
* @returns True if the provided version of the user symmetric key is stored * @returns True if the provided version of the user key is stored
*/ */
hasUserKeyStored: ( hasUserKeyStored: (
keySuffix?: KeySuffixOptions.Auto | KeySuffixOptions.Biometric, keySuffix?: KeySuffixOptions.Auto | KeySuffixOptions.Biometric,
userId?: string userId?: string
) => Promise<boolean>; ) => Promise<boolean>;
/** /**
* Generates a new user symmetric key * Generates a new user key
* @param masterKey The user's master key * @param masterKey The user's master key
* @returns A new user symmetric key and the master key protected version of it * @returns A new user key and the master key protected version of it
*/ */
makeUserSymKey: (key: MasterKey) => Promise<[UserSymKey, EncString]>; makeUserKey: (key: MasterKey) => Promise<[UserKey, EncString]>;
/** /**
* Clears the user's symmetric key * Clears the user key
* @param clearStoredKeys Clears all stored versions of the user keys as well, * @param clearStoredKeys Clears all stored versions of the user keys as well,
* such as the biometrics key * such as the biometrics key
* @param userId The desired user * @param userId The desired user
*/ */
clearUserKey: (clearSecretStorage?: boolean, userId?: string) => Promise<void>; clearUserKey: (clearSecretStorage?: boolean, userId?: string) => Promise<void>;
/** /**
* Clears the user's stored version of the user symmetric key * Clears the user's stored version of the user key
* @param keySuffix The desired version of the key to clear * @param keySuffix The desired version of the key to clear
* @param userId The desired user * @param userId The desired user
*/ */
clearStoredUserKey: (keySuffix: KeySuffixOptions, userId?: string) => Promise<void>; clearStoredUserKey: (keySuffix: KeySuffixOptions, userId?: string) => Promise<void>;
/** /**
* Stores the master key encrypted user symmetric key * Stores the master key encrypted user key
* @param userSymKeyMasterKey The master key encrypted user symmetric key to set * @param userKeyMasterKey The master key encrypted user key to set
* @param userId The desired user * @param userId The desired user
*/ */
setUserSymKeyMasterKey: (UserSymKeyMasterKey: string, userId?: string) => Promise<void>; setUserKeyMasterKey: (UserKeyMasterKey: string, userId?: string) => Promise<void>;
/** /**
* Sets the user's master key * Sets the user's master key
* @param key The user's master key to set * @param key The user's master key to set
@ -125,28 +125,28 @@ export abstract class CryptoService {
*/ */
clearMasterKey: (userId?: string) => Promise<void>; clearMasterKey: (userId?: string) => Promise<void>;
/** /**
* Encrypts the existing (or provided) user symmetric key with the * Encrypts the existing (or provided) user key with the
* provided master key * provided master key
* @param masterKey The user's master key * @param masterKey The user's master key
* @param userSymKey The user's symmetric key * @param userKey The user key
* @returns The user's symmetric key and the master key protected version of it * @returns The user key and the master key protected version of it
*/ */
encryptUserSymKeyWithMasterKey: ( encryptUserKeyWithMasterKey: (
masterKey: MasterKey, masterKey: MasterKey,
userSymKey?: UserSymKey userKey?: UserKey
) => Promise<[UserSymKey, EncString]>; ) => Promise<[UserKey, EncString]>;
/** /**
* Decrypts the user symmetric key with the provided master key * Decrypts the user key with the provided master key
* @param masterKey The user's master key * @param masterKey The user's master key
* @param userSymKey The user's encrypted symmetric key * @param userKey The user's encrypted symmetric key
* @param userId The desired user * @param userId The desired user
* @returns The user's symmetric key * @returns The user key
*/ */
decryptUserSymKeyWithMasterKey: ( decryptUserKeyWithMasterKey: (
masterKey: MasterKey, masterKey: MasterKey,
userSymKey?: EncString, userKey?: EncString,
userId?: string userId?: string
) => Promise<UserSymKey>; ) => Promise<UserKey>;
/** /**
* Creates a master password hash from the user's master password. Can * Creates a master password hash from the user's master password. Can
* be used for local authentication or for server authentication depending * be used for local authentication or for server authentication depending
@ -265,7 +265,7 @@ export abstract class CryptoService {
/** /**
* Generates a new keypair * Generates a new keypair
* @param key A key to encrypt the private key with. If not provided, * @param key A key to encrypt the private key with. If not provided,
* defaults to the user's symmetric key * defaults to the user key
* @returns A new keypair: [publicKey in Base64, encrypted privateKey] * @returns A new keypair: [publicKey in Base64, encrypted privateKey]
*/ */
makeKeyPair: (key?: SymmetricCryptoKey) => Promise<[string, EncString]>; makeKeyPair: (key?: SymmetricCryptoKey) => Promise<[string, EncString]>;
@ -284,7 +284,7 @@ export abstract class CryptoService {
*/ */
makePinKey: (pin: string, salt: string, kdf: KdfType, kdfConfig: KdfConfig) => Promise<PinKey>; makePinKey: (pin: string, salt: string, kdf: KdfType, kdfConfig: KdfConfig) => Promise<PinKey>;
/** /**
* Clears the user's pin protected user symmetric key * Clears the user's pin protected user key
* @param userId The desired user * @param userId The desired user
*/ */
clearPinProtectedKey: (userId?: string) => Promise<void>; clearPinProtectedKey: (userId?: string) => Promise<void>;
@ -294,22 +294,22 @@ export abstract class CryptoService {
*/ */
clearOldPinKeys: (userId?: string) => Promise<void>; clearOldPinKeys: (userId?: string) => Promise<void>;
/** /**
* Decrypts the user's symmetric key with their pin * Decrypts the user key with their pin
* @param pin The user's PIN * @param pin The user's PIN
* @param salt The user's salt * @param salt The user's salt
* @param kdf The user's KDF * @param kdf The user's KDF
* @param kdfConfig The user's KDF config * @param kdfConfig The user's KDF config
* @param pinProtectedUserSymKey The user's PIN protected symmetric key, if not provided * @param pinProtectedUserKey The user's PIN protected symmetric key, if not provided
* it will be retrieved from storage * it will be retrieved from storage
* @returns The decrypted user's symmetric key * @returns The decrypted user key
*/ */
decryptUserSymKeyWithPin: ( decryptUserKeyWithPin: (
pin: string, pin: string,
salt: string, salt: string,
kdf: KdfType, kdf: KdfType,
kdfConfig: KdfConfig, kdfConfig: KdfConfig,
protectedKeyCs?: EncString protectedKeyCs?: EncString
) => Promise<UserSymKey>; ) => Promise<UserKey>;
/** /**
* @param keyMaterial The key material to derive the send key from * @param keyMaterial The key material to derive the send key from
* @returns A new send key * @returns A new send key
@ -337,7 +337,7 @@ export abstract class CryptoService {
randomNumber: (min: number, max: number) => Promise<number>; randomNumber: (min: number, max: number) => Promise<number>;
/** /**
* @deprecated Left for migration purposes. Use decryptUserSymKeyWithPin instead. * @deprecated Left for migration purposes. Use decryptUserKeyWithPin instead.
*/ */
decryptMasterKeyWithPin: ( decryptMasterKeyWithPin: (
pin: string, pin: string,

View File

@ -30,7 +30,7 @@ import {
DeviceKey, DeviceKey,
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../models/domain/symmetric-crypto-key"; } from "../models/domain/symmetric-crypto-key";
export abstract class StateService<T extends Account = Account> { export abstract class StateService<T extends Account = Account> {
@ -78,13 +78,13 @@ export abstract class StateService<T extends Account = Account> {
getConvertAccountToKeyConnector: (options?: StorageOptions) => Promise<boolean>; getConvertAccountToKeyConnector: (options?: StorageOptions) => Promise<boolean>;
setConvertAccountToKeyConnector: (value: boolean, options?: StorageOptions) => Promise<void>; setConvertAccountToKeyConnector: (value: boolean, options?: StorageOptions) => Promise<void>;
/** /**
* gets the user's symmetric key * gets the user key
*/ */
getUserSymKey: (options?: StorageOptions) => Promise<UserSymKey>; getUserKey: (options?: StorageOptions) => Promise<UserKey>;
/** /**
* Sets the user's symmetric key * Sets the user key
*/ */
setUserSymKey: (value: UserSymKey, options?: StorageOptions) => Promise<void>; setUserKey: (value: UserKey, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the user's master key * Gets the user's master key
*/ */
@ -94,59 +94,59 @@ export abstract class StateService<T extends Account = Account> {
*/ */
setMasterKey: (value: MasterKey, options?: StorageOptions) => Promise<void>; setMasterKey: (value: MasterKey, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the user's symmetric key encrypted by the master key * Gets the user key encrypted by the master key
*/ */
getUserSymKeyMasterKey: (options?: StorageOptions) => Promise<string>; getUserKeyMasterKey: (options?: StorageOptions) => Promise<string>;
/** /**
* Sets the user's symmetric key encrypted by the master key * Sets the user key encrypted by the master key
*/ */
setUserSymKeyMasterKey: (value: string, options?: StorageOptions) => Promise<void>; setUserKeyMasterKey: (value: string, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the user's auto key * Gets the user's auto key
*/ */
getUserSymKeyAuto: (options?: StorageOptions) => Promise<string>; getUserKeyAuto: (options?: StorageOptions) => Promise<string>;
/** /**
* Sets the user's auto key * Sets the user's auto key
*/ */
setUserSymKeyAuto: (value: string, options?: StorageOptions) => Promise<void>; setUserKeyAuto: (value: string, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the user's biometric key * Gets the user's biometric key
*/ */
getUserSymKeyBiometric: (options?: StorageOptions) => Promise<string>; getUserKeyBiometric: (options?: StorageOptions) => Promise<string>;
/** /**
* Checks if the user has a biometric key available * Checks if the user has a biometric key available
*/ */
hasUserSymKeyBiometric: (options?: StorageOptions) => Promise<boolean>; hasUserKeyBiometric: (options?: StorageOptions) => Promise<boolean>;
/** /**
* Sets the user's biometric key * Sets the user's biometric key
*/ */
setUserSymKeyBiometric: (value: BiometricKey, options?: StorageOptions) => Promise<void>; setUserKeyBiometric: (value: BiometricKey, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the user's symmetric key encrypted by the Pin key. * Gets the user key encrypted by the Pin key.
* Used when Master Password on Reset is disabled * Used when Master Password on Reset is disabled
*/ */
getUserSymKeyPin: (options?: StorageOptions) => Promise<EncString>; getUserKeyPin: (options?: StorageOptions) => Promise<EncString>;
/** /**
* Sets the user's symmetric key encrypted by the Pin key. * Sets the user key encrypted by the Pin key.
* Used when Master Password on Reset is disabled * Used when Master Password on Reset is disabled
*/ */
setUserSymKeyPin: (value: EncString, options?: StorageOptions) => Promise<void>; setUserKeyPin: (value: EncString, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the ephemeral version of the user's symmetric key encrypted by the Pin key. * Gets the ephemeral version of the user key encrypted by the Pin key.
* Used when Master Password on Reset is enabled * Used when Master Password on Reset is enabled
*/ */
getUserSymKeyPinEphemeral: (options?: StorageOptions) => Promise<EncString>; getUserKeyPinEphemeral: (options?: StorageOptions) => Promise<EncString>;
/** /**
* Sets the ephemeral version of the user's symmetric key encrypted by the Pin key. * Sets the ephemeral version of the user key encrypted by the Pin key.
* Used when Master Password on Reset is enabled * Used when Master Password on Reset is enabled
*/ */
setUserSymKeyPinEphemeral: (value: EncString, options?: StorageOptions) => Promise<void>; setUserKeyPinEphemeral: (value: EncString, options?: StorageOptions) => Promise<void>;
/** /**
* @deprecated For migration purposes only, use getUserSymKeyMasterKey instead * @deprecated For migration purposes only, use getUserKeyMasterKey instead
*/ */
getEncryptedCryptoSymmetricKey: (options?: StorageOptions) => Promise<string>; getEncryptedCryptoSymmetricKey: (options?: StorageOptions) => Promise<string>;
/** /**
* @deprecated For migration purposes only, use setUserSymKeyMasterKey instead * @deprecated For migration purposes only, use setUserKeyMasterKey instead
*/ */
setEncryptedCryptoSymmetricKey: (value: string, options?: StorageOptions) => Promise<void>; setEncryptedCryptoSymmetricKey: (value: string, options?: StorageOptions) => Promise<void>;
/** /**
@ -154,23 +154,23 @@ export abstract class StateService<T extends Account = Account> {
*/ */
getCryptoMasterKey: (options?: StorageOptions) => Promise<SymmetricCryptoKey>; getCryptoMasterKey: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
/** /**
* @deprecated For migration purposes only, use getUserSymKeyAuto instead * @deprecated For migration purposes only, use getUserKeyAuto instead
*/ */
getCryptoMasterKeyAuto: (options?: StorageOptions) => Promise<string>; getCryptoMasterKeyAuto: (options?: StorageOptions) => Promise<string>;
/** /**
* @deprecated For migration purposes only, use setUserSymKeyAuto instead * @deprecated For migration purposes only, use setUserKeyAuto instead
*/ */
setCryptoMasterKeyAuto: (value: string, options?: StorageOptions) => Promise<void>; setCryptoMasterKeyAuto: (value: string, options?: StorageOptions) => Promise<void>;
/** /**
* @deprecated For migration purposes only, use getUserSymKeyBiometric instead * @deprecated For migration purposes only, use getUserKeyBiometric instead
*/ */
getCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<string>; getCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<string>;
/** /**
* @deprecated For migration purposes only, use hasUserSymKeyBiometric instead * @deprecated For migration purposes only, use hasUserKeyBiometric instead
*/ */
hasCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<boolean>; hasCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<boolean>;
/** /**
* @deprecated For migration purposes only, use setUserSymKeyBiometric instead * @deprecated For migration purposes only, use setUserKeyBiometric instead
*/ */
setCryptoMasterKeyBiometric: (value: BiometricKey, options?: StorageOptions) => Promise<void>; setCryptoMasterKeyBiometric: (value: BiometricKey, options?: StorageOptions) => Promise<void>;
getDecryptedCiphers: (options?: StorageOptions) => Promise<CipherView[]>; getDecryptedCiphers: (options?: StorageOptions) => Promise<CipherView[]>;
@ -192,11 +192,11 @@ export abstract class StateService<T extends Account = Account> {
options?: StorageOptions options?: StorageOptions
) => Promise<void>; ) => Promise<void>;
/** /**
* @deprecated For migration purposes only, use getDecryptedUserSymKeyPin instead * @deprecated For migration purposes only, use getDecryptedUserKeyPin instead
*/ */
getDecryptedPinProtected: (options?: StorageOptions) => Promise<EncString>; getDecryptedPinProtected: (options?: StorageOptions) => Promise<EncString>;
/** /**
* @deprecated For migration purposes only, use setDecryptedUserSymKeyPin instead * @deprecated For migration purposes only, use setDecryptedUserKeyPin instead
*/ */
setDecryptedPinProtected: (value: EncString, options?: StorageOptions) => Promise<void>; setDecryptedPinProtected: (value: EncString, options?: StorageOptions) => Promise<void>;
/** /**
@ -325,11 +325,11 @@ export abstract class StateService<T extends Account = Account> {
options?: StorageOptions options?: StorageOptions
) => Promise<void>; ) => Promise<void>;
/** /**
* @deprecated For migration purposes only, use getEncryptedUserSymKeyPin instead * @deprecated For migration purposes only, use getEncryptedUserKeyPin instead
*/ */
getEncryptedPinProtected: (options?: StorageOptions) => Promise<string>; getEncryptedPinProtected: (options?: StorageOptions) => Promise<string>;
/** /**
* @deprecated For migration purposes only, use setEncryptedUserSymKeyPin instead * @deprecated For migration purposes only, use setEncryptedUserKeyPin instead
*/ */
setEncryptedPinProtected: (value: string, options?: StorageOptions) => Promise<void>; setEncryptedPinProtected: (value: string, options?: StorageOptions) => Promise<void>;
/** /**
@ -426,11 +426,11 @@ export abstract class StateService<T extends Account = Account> {
getGeneratorOptions: (options?: StorageOptions) => Promise<any>; getGeneratorOptions: (options?: StorageOptions) => Promise<any>;
setGeneratorOptions: (value: any, options?: StorageOptions) => Promise<void>; setGeneratorOptions: (value: any, options?: StorageOptions) => Promise<void>;
/** /**
* Gets the user's Pin, encrypted by the user symmetric key * Gets the user's Pin, encrypted by the user key
*/ */
getProtectedPin: (options?: StorageOptions) => Promise<string>; getProtectedPin: (options?: StorageOptions) => Promise<string>;
/** /**
* Sets the user's Pin, encrypted by the user symmetric key * Sets the user's Pin, encrypted by the user key
*/ */
setProtectedPin: (value: string, options?: StorageOptions) => Promise<void>; setProtectedPin: (value: string, options?: StorageOptions) => Promise<void>;
getProviders: (options?: StorageOptions) => Promise<{ [id: string]: ProviderData }>; getProviders: (options?: StorageOptions) => Promise<{ [id: string]: ProviderData }>;

View File

@ -23,7 +23,7 @@ import { Utils } from "../../misc/utils";
import { ServerConfigData } from "../../models/data/server-config.data"; import { ServerConfigData } from "../../models/data/server-config.data";
import { EncryptedString, EncString } from "./enc-string"; import { EncryptedString, EncString } from "./enc-string";
import { DeviceKey, MasterKey, SymmetricCryptoKey, UserSymKey } from "./symmetric-crypto-key"; import { DeviceKey, MasterKey, SymmetricCryptoKey, UserKey } from "./symmetric-crypto-key";
export class EncryptionPair<TEncrypted, TDecrypted> { export class EncryptionPair<TEncrypted, TDecrypted> {
encrypted?: TEncrypted; encrypted?: TEncrypted;
@ -99,11 +99,11 @@ export class AccountData {
} }
export class AccountKeys { export class AccountKeys {
userSymKey?: UserSymKey; userKey?: UserKey;
masterKey?: MasterKey; masterKey?: MasterKey;
userSymKeyMasterKey?: string; userKeyMasterKey?: string;
userSymKeyAuto?: string; userKeyAuto?: string;
userSymKeyBiometric?: string; userKeyBiometric?: string;
// deprecated keys // deprecated keys
cryptoMasterKey?: SymmetricCryptoKey; cryptoMasterKey?: SymmetricCryptoKey;
cryptoMasterKeyAuto?: string; cryptoMasterKeyAuto?: string;
@ -141,7 +141,7 @@ export class AccountKeys {
} }
return Object.assign(new AccountKeys(), { return Object.assign(new AccountKeys(), {
userSymKey: SymmetricCryptoKey.fromJSON(obj?.userSymKey), userKey: SymmetricCryptoKey.fromJSON(obj?.userKey),
masterKey: SymmetricCryptoKey.fromJSON(obj?.masterKey), masterKey: SymmetricCryptoKey.fromJSON(obj?.masterKey),
cryptoMasterKey: SymmetricCryptoKey.fromJSON(obj?.cryptoMasterKey), cryptoMasterKey: SymmetricCryptoKey.fromJSON(obj?.cryptoMasterKey),
cryptoSymmetricKey: EncryptionPair.fromJSON( cryptoSymmetricKey: EncryptionPair.fromJSON(
@ -232,8 +232,8 @@ export class AccountSettings {
passwordGenerationOptions?: any; passwordGenerationOptions?: any;
usernameGenerationOptions?: any; usernameGenerationOptions?: any;
generatorOptions?: any; generatorOptions?: any;
userSymKeyPin?: EncryptedString; userKeyPin?: EncryptedString;
userSymKeyPinEphemeral?: EncryptedString; userKeyPinEphemeral?: EncryptedString;
protectedPin?: string; protectedPin?: string;
pinProtected?: EncryptionPair<string, EncString> = new EncryptionPair<string, EncString>(); // Deprecated pinProtected?: EncryptionPair<string, EncString> = new EncryptionPair<string, EncString>(); // Deprecated
settings?: AccountSettingsSettings; // TODO: Merge whatever is going on here into the AccountSettings model properly settings?: AccountSettingsSettings; // TODO: Merge whatever is going on here into the AccountSettings model properly

View File

@ -78,7 +78,7 @@ export class SymmetricCryptoKey {
// Setup all separate key types as opaque types // Setup all separate key types as opaque types
export type DeviceKey = Opaque<SymmetricCryptoKey, "DeviceKey">; export type DeviceKey = Opaque<SymmetricCryptoKey, "DeviceKey">;
export type UserSymKey = Opaque<SymmetricCryptoKey, "UserSymKey">; export type UserKey = Opaque<SymmetricCryptoKey, "UserKey">;
export type MasterKey = Opaque<SymmetricCryptoKey, "MasterKey">; export type MasterKey = Opaque<SymmetricCryptoKey, "MasterKey">;
export type PinKey = Opaque<SymmetricCryptoKey, "PinKey">; export type PinKey = Opaque<SymmetricCryptoKey, "PinKey">;
export type OrgKey = Opaque<SymmetricCryptoKey, "OrgKey">; export type OrgKey = Opaque<SymmetricCryptoKey, "OrgKey">;

View File

@ -10,7 +10,7 @@ import {
MasterKey, MasterKey,
PinKey, PinKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../models/domain/symmetric-crypto-key"; } from "../models/domain/symmetric-crypto-key";
import { CryptoService } from "../services/crypto.service"; import { CryptoService } from "../services/crypto.service";
@ -44,33 +44,33 @@ describe("cryptoService", () => {
}); });
describe("getKeyForUserDecryption", () => { describe("getKeyForUserDecryption", () => {
let mockUserSymKey: UserSymKey; let mockUserKey: UserKey;
let mockMasterKey: MasterKey; let mockMasterKey: MasterKey;
let stateSvcGetUserSymKey: jest.SpyInstance; let stateSvcGetUserKey: jest.SpyInstance;
let stateSvcGetMasterKey: jest.SpyInstance; let stateSvcGetMasterKey: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
const mockRandomBytes = new Uint8Array(64).buffer as CsprngArray; const mockRandomBytes = new Uint8Array(64).buffer as CsprngArray;
mockUserSymKey = new SymmetricCryptoKey(mockRandomBytes) as UserSymKey; mockUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey;
mockMasterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; mockMasterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey;
stateSvcGetUserSymKey = jest.spyOn(stateService, "getUserSymKey"); stateSvcGetUserKey = jest.spyOn(stateService, "getUserKey");
stateSvcGetMasterKey = jest.spyOn(stateService, "getMasterKey"); stateSvcGetMasterKey = jest.spyOn(stateService, "getMasterKey");
}); });
it("returns the user's symmetric key if available", async () => { it("returns the user key if available", async () => {
stateSvcGetUserSymKey.mockResolvedValue(mockUserSymKey); stateSvcGetUserKey.mockResolvedValue(mockUserKey);
const encryptionKey = await cryptoService.getKeyForUserEncryption(); const encryptionKey = await cryptoService.getKeyForUserEncryption();
expect(stateSvcGetUserSymKey).toHaveBeenCalled(); expect(stateSvcGetUserKey).toHaveBeenCalled();
expect(stateSvcGetMasterKey).not.toHaveBeenCalled(); expect(stateSvcGetMasterKey).not.toHaveBeenCalled();
expect(encryptionKey).toEqual(mockUserSymKey); expect(encryptionKey).toEqual(mockUserKey);
}); });
it("returns the user's master key when symmetric key is not available", async () => { it("returns the user's master key when symmetric key is not available", async () => {
stateSvcGetUserSymKey.mockResolvedValue(null); stateSvcGetUserKey.mockResolvedValue(null);
stateSvcGetMasterKey.mockResolvedValue(mockMasterKey); stateSvcGetMasterKey.mockResolvedValue(mockMasterKey);
const encryptionKey = await cryptoService.getKeyForUserEncryption(); const encryptionKey = await cryptoService.getKeyForUserEncryption();
@ -82,32 +82,32 @@ describe("cryptoService", () => {
describe("setUserKey", () => { describe("setUserKey", () => {
const mockUserId = "example user id"; const mockUserId = "example user id";
let mockUserSymKey: UserSymKey; let mockUserKey: UserKey;
beforeEach(() => { beforeEach(() => {
const mockRandomBytes = new Uint8Array(64).buffer as CsprngArray; const mockRandomBytes = new Uint8Array(64).buffer as CsprngArray;
mockUserSymKey = new SymmetricCryptoKey(mockRandomBytes) as UserSymKey; mockUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey;
}); });
it("saves an Auto key if needed", async () => { it("saves an Auto key if needed", async () => {
stateService.getVaultTimeout.mockResolvedValue(null); stateService.getVaultTimeout.mockResolvedValue(null);
await cryptoService.setUserKey(mockUserSymKey, mockUserId); await cryptoService.setUserKey(mockUserKey, mockUserId);
expect(stateService.setUserSymKeyAuto).toHaveBeenCalled(); expect(stateService.setUserKeyAuto).toHaveBeenCalled();
expect(stateService.setUserSymKeyAuto).not.toHaveBeenCalledWith(null, { userId: mockUserId }); expect(stateService.setUserKeyAuto).not.toHaveBeenCalledWith(null, { userId: mockUserId });
}); });
it("saves a Pin key if needed", async () => { it("saves a Pin key if needed", async () => {
stateService.getUserSymKeyPinEphemeral.mockResolvedValue(null); stateService.getUserKeyPinEphemeral.mockResolvedValue(null);
const cryptoSvcMakePinKey = jest.spyOn(cryptoService, "makePinKey"); const cryptoSvcMakePinKey = jest.spyOn(cryptoService, "makePinKey");
cryptoSvcMakePinKey.mockResolvedValue( cryptoSvcMakePinKey.mockResolvedValue(
new SymmetricCryptoKey(new Uint8Array(64).buffer) as PinKey new SymmetricCryptoKey(new Uint8Array(64).buffer) as PinKey
); );
await cryptoService.setUserKey(mockUserSymKey, mockUserId); await cryptoService.setUserKey(mockUserKey, mockUserId);
expect(stateService.setUserSymKeyPin).toHaveBeenCalled(); expect(stateService.setUserKeyPin).toHaveBeenCalled();
}); });
}); });
}); });

View File

@ -31,7 +31,7 @@ import {
OrgKey, OrgKey,
PinKey, PinKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../models/domain/symmetric-crypto-key"; } from "../models/domain/symmetric-crypto-key";
export class CryptoService implements CryptoServiceAbstraction { export class CryptoService implements CryptoServiceAbstraction {
@ -54,8 +54,8 @@ export class CryptoService implements CryptoServiceAbstraction {
return await this.getMasterKey(); return await this.getMasterKey();
} }
async setUserKey(key: UserSymKey, userId?: string): Promise<void> { async setUserKey(key: UserKey, userId?: string): Promise<void> {
await this.stateService.setUserSymKey(key, { userId: userId }); await this.stateService.setUserKey(key, { userId: userId });
await this.storeAdditionalKeys(key, userId); await this.storeAdditionalKeys(key, userId);
} }
@ -64,14 +64,14 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.setUserKey(key); await this.setUserKey(key);
} }
async getUserKeyFromMemory(userId?: string): Promise<UserSymKey> { async getUserKeyFromMemory(userId?: string): Promise<UserKey> {
return await this.stateService.getUserSymKey({ userId: userId }); return await this.stateService.getUserKey({ userId: userId });
} }
async getUserKeyFromStorage( async getUserKeyFromStorage(
keySuffix: KeySuffixOptions.Auto | KeySuffixOptions.Biometric, keySuffix: KeySuffixOptions.Auto | KeySuffixOptions.Biometric,
userId?: string userId?: string
): Promise<UserSymKey> { ): Promise<UserKey> {
const userKey = await this.retrieveUserKeyFromStorage(keySuffix, userId); const userKey = await this.retrieveUserKeyFromStorage(keySuffix, userId);
if (userKey != null) { if (userKey != null) {
if (!(await this.validateUserKey(userKey))) { if (!(await this.validateUserKey(userKey))) {
@ -94,7 +94,7 @@ export class CryptoService implements CryptoServiceAbstraction {
} }
async hasUserKeyInMemory(userId?: string): Promise<boolean> { async hasUserKeyInMemory(userId?: string): Promise<boolean> {
return (await this.stateService.getUserSymKey({ userId: userId })) != null; return (await this.stateService.getUserKey({ userId: userId })) != null;
} }
async hasUserKeyStored( async hasUserKeyStored(
@ -103,23 +103,23 @@ export class CryptoService implements CryptoServiceAbstraction {
): Promise<boolean> { ): Promise<boolean> {
if (keySuffix === KeySuffixOptions.Biometric) { if (keySuffix === KeySuffixOptions.Biometric) {
const oldKey = await this.stateService.hasCryptoMasterKeyBiometric({ userId: userId }); const oldKey = await this.stateService.hasCryptoMasterKeyBiometric({ userId: userId });
return oldKey || (await this.stateService.hasUserSymKeyBiometric({ userId: userId })); return oldKey || (await this.stateService.hasUserKeyBiometric({ userId: userId }));
} }
return (await this.retrieveUserKeyFromStorage(keySuffix, userId)) != null; return (await this.retrieveUserKeyFromStorage(keySuffix, userId)) != null;
} }
async makeUserSymKey(masterKey: MasterKey): Promise<[UserSymKey, EncString]> { async makeUserKey(masterKey: MasterKey): Promise<[UserKey, EncString]> {
masterKey ||= await this.getMasterKey(); masterKey ||= await this.getMasterKey();
if (masterKey == null) { if (masterKey == null) {
throw new Error("No Master Key found."); throw new Error("No Master Key found.");
} }
const newUserSymKey = await this.cryptoFunctionService.randomBytes(64); const newUserKey = await this.cryptoFunctionService.randomBytes(64);
return this.buildProtectedSymmetricKey(masterKey, newUserSymKey); return this.buildProtectedSymmetricKey(masterKey, newUserKey);
} }
async clearUserKey(clearStoredKeys = true, userId?: string): Promise<void> { async clearUserKey(clearStoredKeys = true, userId?: string): Promise<void> {
await this.stateService.setUserSymKey(null, { userId: userId }); await this.stateService.setUserKey(null, { userId: userId });
if (clearStoredKeys) { if (clearStoredKeys) {
await this.clearAllStoredUserKeys(userId); await this.clearAllStoredUserKeys(userId);
} }
@ -128,19 +128,19 @@ export class CryptoService implements CryptoServiceAbstraction {
async clearStoredUserKey(keySuffix: KeySuffixOptions, userId?: string): Promise<void> { async clearStoredUserKey(keySuffix: KeySuffixOptions, userId?: string): Promise<void> {
switch (keySuffix) { switch (keySuffix) {
case KeySuffixOptions.Auto: case KeySuffixOptions.Auto:
this.stateService.setUserSymKeyAuto(null, { userId: userId }); this.stateService.setUserKeyAuto(null, { userId: userId });
break; break;
case KeySuffixOptions.Biometric: case KeySuffixOptions.Biometric:
this.stateService.setUserSymKeyBiometric(null, { userId: userId }); this.stateService.setUserKeyBiometric(null, { userId: userId });
break; break;
case KeySuffixOptions.Pin: case KeySuffixOptions.Pin:
this.stateService.setUserSymKeyPinEphemeral(null, { userId: userId }); this.stateService.setUserKeyPinEphemeral(null, { userId: userId });
break; break;
} }
} }
async setUserSymKeyMasterKey(userSymKeyMasterKey: string, userId?: string): Promise<void> { async setUserKeyMasterKey(userKeyMasterKey: string, userId?: string): Promise<void> {
await this.stateService.setUserSymKeyMasterKey(userSymKeyMasterKey, { userId: userId }); await this.stateService.setUserKeyMasterKey(userKeyMasterKey, { userId: userId });
} }
async setMasterKey(key: MasterKey, userId?: string): Promise<void> { async setMasterKey(key: MasterKey, userId?: string): Promise<void> {
@ -166,40 +166,40 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.stateService.setMasterKey(null, { userId: userId }); await this.stateService.setMasterKey(null, { userId: userId });
} }
async encryptUserSymKeyWithMasterKey( async encryptUserKeyWithMasterKey(
masterKey: MasterKey, masterKey: MasterKey,
userSymKey?: UserSymKey userKey?: UserKey
): Promise<[UserSymKey, EncString]> { ): Promise<[UserKey, EncString]> {
userSymKey ||= await this.getUserKeyFromMemory(); userKey ||= await this.getUserKeyFromMemory();
return this.buildProtectedSymmetricKey(masterKey, userSymKey.key); return this.buildProtectedSymmetricKey(masterKey, userKey.key);
} }
async decryptUserSymKeyWithMasterKey( async decryptUserKeyWithMasterKey(
masterKey: MasterKey, masterKey: MasterKey,
userSymKey?: EncString, userKey?: EncString,
userId?: string userId?: string
): Promise<UserSymKey> { ): Promise<UserKey> {
masterKey ||= await this.getMasterKey(); masterKey ||= await this.getMasterKey();
if (masterKey == null) { if (masterKey == null) {
throw new Error("No master key found."); throw new Error("No master key found.");
} }
if (!userSymKey) { if (!userKey) {
const userSymKeyMasterKey = await this.stateService.getUserSymKeyMasterKey({ const userKeyMasterKey = await this.stateService.getUserKeyMasterKey({
userId: userId, userId: userId,
}); });
if (userSymKeyMasterKey == null) { if (userKeyMasterKey == null) {
throw new Error("No encrypted user key found."); throw new Error("No encrypted user key found.");
} }
userSymKey = new EncString(userSymKeyMasterKey); userKey = new EncString(userKeyMasterKey);
} }
let decUserKey: ArrayBuffer; let decUserKey: ArrayBuffer;
if (userSymKey.encryptionType === EncryptionType.AesCbc256_B64) { if (userKey.encryptionType === EncryptionType.AesCbc256_B64) {
decUserKey = await this.decryptToBytes(userSymKey, masterKey); decUserKey = await this.decryptToBytes(userKey, masterKey);
} else if (userSymKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) { } else if (userKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) {
const newKey = await this.stretchKey(masterKey); const newKey = await this.stretchKey(masterKey);
decUserKey = await this.decryptToBytes(userSymKey, newKey); decUserKey = await this.decryptToBytes(userKey, newKey);
} else { } else {
throw new Error("Unsupported encryption type."); throw new Error("Unsupported encryption type.");
} }
@ -207,7 +207,7 @@ export class CryptoService implements CryptoServiceAbstraction {
return null; return null;
} }
return new SymmetricCryptoKey(decUserKey) as UserSymKey; return new SymmetricCryptoKey(decUserKey) as UserKey;
} }
async hashPassword(password: string, key: MasterKey, hashPurpose?: HashPurpose): Promise<string> { async hashPassword(password: string, key: MasterKey, hashPurpose?: HashPurpose): Promise<string> {
@ -503,7 +503,7 @@ export class CryptoService implements CryptoServiceAbstraction {
} }
async clearPinProtectedKey(userId?: string): Promise<void> { async clearPinProtectedKey(userId?: string): Promise<void> {
await this.stateService.setUserSymKeyPin(null, { userId: userId }); await this.stateService.setUserKeyPin(null, { userId: userId });
await this.clearOldPinKeys(userId); await this.clearOldPinKeys(userId);
} }
@ -512,20 +512,20 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.stateService.setDecryptedPinProtected(null, { userId: userId }); await this.stateService.setDecryptedPinProtected(null, { userId: userId });
} }
async decryptUserSymKeyWithPin( async decryptUserKeyWithPin(
pin: string, pin: string,
salt: string, salt: string,
kdf: KdfType, kdf: KdfType,
kdfConfig: KdfConfig, kdfConfig: KdfConfig,
pinProtectedUserSymKey?: EncString pinProtectedUserKey?: EncString
): Promise<UserSymKey> { ): Promise<UserKey> {
pinProtectedUserSymKey ||= await this.stateService.getUserSymKeyPin(); pinProtectedUserKey ||= await this.stateService.getUserKeyPin();
if (!pinProtectedUserSymKey) { if (!pinProtectedUserKey) {
throw new Error("No PIN protected key found."); throw new Error("No PIN protected key found.");
} }
const pinKey = await this.makePinKey(pin, salt, kdf, kdfConfig); const pinKey = await this.makePinKey(pin, salt, kdf, kdfConfig);
const userSymKey = await this.decryptToBytes(pinProtectedUserSymKey, pinKey); const userKey = await this.decryptToBytes(pinProtectedUserKey, pinKey);
return new SymmetricCryptoKey(userSymKey) as UserSymKey; return new SymmetricCryptoKey(userKey) as UserKey;
} }
async decryptMasterKeyWithPin( async decryptMasterKeyWithPin(
@ -669,7 +669,7 @@ export class CryptoService implements CryptoServiceAbstraction {
// ---HELPERS--- // ---HELPERS---
protected async validateUserKey(key?: UserSymKey): Promise<boolean> { protected async validateUserKey(key?: UserKey): Promise<boolean> {
key ||= await this.getUserKeyFromMemory(); key ||= await this.getUserKeyFromMemory();
if (key == null) { if (key == null) {
return false; return false;
@ -692,27 +692,27 @@ export class CryptoService implements CryptoServiceAbstraction {
/** /**
* Regenerates any additional keys if needed. Useful to make sure * Regenerates any additional keys if needed. Useful to make sure
* other keys stay in sync when the user's symmetric key has been rotated. * other keys stay in sync when the user key has been rotated.
* @param key The user's symmetric key * @param key The user key
* @param userId The desired user * @param userId The desired user
*/ */
protected async storeAdditionalKeys(key: UserSymKey, userId?: string) { protected async storeAdditionalKeys(key: UserKey, userId?: string) {
const storeAuto = await this.shouldStoreKey(KeySuffixOptions.Auto, userId); const storeAuto = await this.shouldStoreKey(KeySuffixOptions.Auto, userId);
if (storeAuto) { if (storeAuto) {
await this.stateService.setUserSymKeyAuto(key.keyB64, { userId: userId }); await this.stateService.setUserKeyAuto(key.keyB64, { userId: userId });
} else { } else {
await this.stateService.setUserSymKeyAuto(null, { userId: userId }); await this.stateService.setUserKeyAuto(null, { userId: userId });
} }
const storePin = await this.shouldStoreKey(KeySuffixOptions.Pin, userId); const storePin = await this.shouldStoreKey(KeySuffixOptions.Pin, userId);
if (storePin) { if (storePin) {
await this.storePinKey(key); await this.storePinKey(key);
} else { } else {
await this.stateService.setUserSymKeyPin(null, { userId: userId }); await this.stateService.setUserKeyPin(null, { userId: userId });
} }
} }
protected async storePinKey(key: UserSymKey) { protected async storePinKey(key: UserKey) {
const email = await this.stateService.getEmail(); const email = await this.stateService.getEmail();
const kdf = await this.stateService.getKdfType(); const kdf = await this.stateService.getKdfType();
const kdfConfig = await this.stateService.getKdfConfig(); const kdfConfig = await this.stateService.getKdfConfig();
@ -721,7 +721,7 @@ export class CryptoService implements CryptoServiceAbstraction {
key key
); );
const pinKey = await this.makePinKey(pin, email, kdf, kdfConfig); const pinKey = await this.makePinKey(pin, email, kdf, kdfConfig);
await this.stateService.setUserSymKeyPin(await this.encrypt(key.key, pinKey)); await this.stateService.setUserKeyPin(await this.encrypt(key.key, pinKey));
} }
protected async shouldStoreKey(keySuffix: KeySuffixOptions, userId?: string) { protected async shouldStoreKey(keySuffix: KeySuffixOptions, userId?: string) {
@ -741,10 +741,10 @@ export class CryptoService implements CryptoServiceAbstraction {
const protectedPin = await this.stateService.getProtectedPin({ userId: userId }); const protectedPin = await this.stateService.getProtectedPin({ userId: userId });
// This could cause a possible timing issue. Need to make sure the ephemeral key is set before // This could cause a possible timing issue. Need to make sure the ephemeral key is set before
// we set our user key // we set our user key
const userSymKeyPinEphemeral = await this.stateService.getUserSymKeyPinEphemeral({ const userKeyPinEphemeral = await this.stateService.getUserKeyPinEphemeral({
userId: userId, userId: userId,
}); });
shouldStoreKey = !!protectedPin && !userSymKeyPinEphemeral; shouldStoreKey = !!protectedPin && !userKeyPinEphemeral;
break; break;
} }
} }
@ -754,12 +754,12 @@ export class CryptoService implements CryptoServiceAbstraction {
protected async retrieveUserKeyFromStorage( protected async retrieveUserKeyFromStorage(
keySuffix: KeySuffixOptions, keySuffix: KeySuffixOptions,
userId?: string userId?: string
): Promise<UserSymKey> { ): Promise<UserKey> {
if (keySuffix === KeySuffixOptions.Auto) { if (keySuffix === KeySuffixOptions.Auto) {
await this.migrateAutoKeyIfNeeded(userId); await this.migrateAutoKeyIfNeeded(userId);
const userKey = await this.stateService.getUserSymKeyAuto({ userId: userId }); const userKey = await this.stateService.getUserKeyAuto({ userId: userId });
if (userKey) { if (userKey) {
return new SymmetricCryptoKey(Utils.fromB64ToArray(userKey).buffer) as UserSymKey; return new SymmetricCryptoKey(Utils.fromB64ToArray(userKey).buffer) as UserKey;
} }
} }
return null; return null;
@ -772,12 +772,12 @@ export class CryptoService implements CryptoServiceAbstraction {
const masterKey = new SymmetricCryptoKey( const masterKey = new SymmetricCryptoKey(
Utils.fromB64ToArray(oldAutoKey).buffer Utils.fromB64ToArray(oldAutoKey).buffer
) as MasterKey; ) as MasterKey;
const userSymKey = await this.decryptUserSymKeyWithMasterKey( const userKey = await this.decryptUserKeyWithMasterKey(
masterKey, masterKey,
new EncString(await this.stateService.getEncryptedCryptoSymmetricKey()) new EncString(await this.stateService.getEncryptedCryptoSymmetricKey())
); );
// migrate // migrate
await this.stateService.setUserSymKeyAuto(userSymKey.keyB64, { userId: userId }); await this.stateService.setUserKeyAuto(userKey.keyB64, { userId: userId });
await this.stateService.setCryptoMasterKeyAuto(null, { userId: userId }); await this.stateService.setCryptoMasterKeyAuto(null, { userId: userId });
} }
} }
@ -828,9 +828,9 @@ export class CryptoService implements CryptoServiceAbstraction {
} }
private async clearAllStoredUserKeys(userId?: string): Promise<void> { private async clearAllStoredUserKeys(userId?: string): Promise<void> {
await this.stateService.setUserSymKeyAuto(null, { userId: userId }); await this.stateService.setUserKeyAuto(null, { userId: userId });
await this.stateService.setUserSymKeyBiometric(null, { userId: userId }); await this.stateService.setUserKeyBiometric(null, { userId: userId });
await this.stateService.setUserSymKeyPinEphemeral(null, { userId: userId }); await this.stateService.setUserKeyPinEphemeral(null, { userId: userId });
} }
async makeKey( async makeKey(

View File

@ -54,7 +54,7 @@ import {
DeviceKey, DeviceKey,
MasterKey, MasterKey,
SymmetricCryptoKey, SymmetricCryptoKey,
UserSymKey, UserKey,
} from "../models/domain/symmetric-crypto-key"; } from "../models/domain/symmetric-crypto-key";
const keys = { const keys = {
@ -69,7 +69,7 @@ const keys = {
const partialKeys = { const partialKeys = {
userAutoKey: "_user_auto", userAutoKey: "_user_auto",
userBiometricKey: "_user_biometric", userBiometricKey: "_user_biometric",
userSymKey: "_user_sym", userKey: "_user_key",
autoKey: "_masterkey_auto", autoKey: "_masterkey_auto",
biometricKey: "_masterkey_biometric", biometricKey: "_masterkey_biometric",
@ -122,7 +122,7 @@ export class StateService<
// FIXME: This should be refactored into AuthService or a similar service, // FIXME: This should be refactored into AuthService or a similar service,
// as checking for the existence of the crypto key is a low level // as checking for the existence of the crypto key is a low level
// implementation detail. // implementation detail.
this.activeAccountUnlockedSubject.next((await this.getUserSymKey()) != null); this.activeAccountUnlockedSubject.next((await this.getUserKey()) != null);
}) })
) )
.subscribe(); .subscribe();
@ -559,23 +559,23 @@ export class StateService<
} }
/** /**
* User's symmetric key used to encrypt/decrypt data * user key used to encrypt/decrypt data
*/ */
async getUserSymKey(options?: StorageOptions): Promise<UserSymKey> { async getUserKey(options?: StorageOptions): Promise<UserKey> {
const account = await this.getAccount( const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultInMemoryOptions()) this.reconcileOptions(options, await this.defaultInMemoryOptions())
); );
return account?.keys?.userSymKey as UserSymKey; return account?.keys?.userKey as UserKey;
} }
/** /**
* User's symmetric key used to encrypt/decrypt data * user key used to encrypt/decrypt data
*/ */
async setUserSymKey(value: UserSymKey, options?: StorageOptions): Promise<void> { async setUserKey(value: UserKey, options?: StorageOptions): Promise<void> {
const account = await this.getAccount( const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultInMemoryOptions()) this.reconcileOptions(options, await this.defaultInMemoryOptions())
); );
account.keys.userSymKey = value; account.keys.userKey = value;
await this.saveAccount( await this.saveAccount(
account, account,
this.reconcileOptions(options, await this.defaultInMemoryOptions()) this.reconcileOptions(options, await this.defaultInMemoryOptions())
@ -619,21 +619,21 @@ export class StateService<
* The master key encrypted User symmetric key, saved on every auth * The master key encrypted User symmetric key, saved on every auth
* so we can unlock with MP offline * so we can unlock with MP offline
*/ */
async getUserSymKeyMasterKey(options?: StorageOptions): Promise<string> { async getUserKeyMasterKey(options?: StorageOptions): Promise<string> {
return ( return (
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())) await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
)?.keys.userSymKeyMasterKey; )?.keys.userKeyMasterKey;
} }
/** /**
* The master key encrypted User symmetric key, saved on every auth * The master key encrypted User symmetric key, saved on every auth
* so we can unlock with MP offline * so we can unlock with MP offline
*/ */
async setUserSymKeyMasterKey(value: string, options?: StorageOptions): Promise<void> { async setUserKeyMasterKey(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount( const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultOnDiskOptions()) this.reconcileOptions(options, await this.defaultOnDiskOptions())
); );
account.keys.userSymKeyMasterKey = value; account.keys.userKeyMasterKey = value;
await this.saveAccount( await this.saveAccount(
account, account,
this.reconcileOptions(options, await this.defaultOnDiskOptions()) this.reconcileOptions(options, await this.defaultOnDiskOptions())
@ -641,9 +641,9 @@ export class StateService<
} }
/** /**
* User's symmetric key when using the "never" option of vault timeout * user key when using the "never" option of vault timeout
*/ */
async getUserSymKeyAuto(options?: StorageOptions): Promise<string> { async getUserKeyAuto(options?: StorageOptions): Promise<string> {
options = this.reconcileOptions( options = this.reconcileOptions(
this.reconcileOptions(options, { keySuffix: "auto" }), this.reconcileOptions(options, { keySuffix: "auto" }),
await this.defaultSecureStorageOptions() await this.defaultSecureStorageOptions()
@ -658,9 +658,9 @@ export class StateService<
} }
/** /**
* User's symmetric key when using the "never" option of vault timeout * user key when using the "never" option of vault timeout
*/ */
async setUserSymKeyAuto(value: string, options?: StorageOptions): Promise<void> { async setUserKeyAuto(value: string, options?: StorageOptions): Promise<void> {
options = this.reconcileOptions( options = this.reconcileOptions(
this.reconcileOptions(options, { keySuffix: "auto" }), this.reconcileOptions(options, { keySuffix: "auto" }),
await this.defaultSecureStorageOptions() await this.defaultSecureStorageOptions()
@ -674,7 +674,7 @@ export class StateService<
/** /**
* User's encrypted symmetric key when using biometrics * User's encrypted symmetric key when using biometrics
*/ */
async getUserSymKeyBiometric(options?: StorageOptions): Promise<string> { async getUserKeyBiometric(options?: StorageOptions): Promise<string> {
options = this.reconcileOptions( options = this.reconcileOptions(
this.reconcileOptions(options, { keySuffix: "biometric" }), this.reconcileOptions(options, { keySuffix: "biometric" }),
await this.defaultSecureStorageOptions() await this.defaultSecureStorageOptions()
@ -688,7 +688,7 @@ export class StateService<
); );
} }
async hasUserSymKeyBiometric(options?: StorageOptions): Promise<boolean> { async hasUserKeyBiometric(options?: StorageOptions): Promise<boolean> {
options = this.reconcileOptions( options = this.reconcileOptions(
this.reconcileOptions(options, { keySuffix: "biometric" }), this.reconcileOptions(options, { keySuffix: "biometric" }),
await this.defaultSecureStorageOptions() await this.defaultSecureStorageOptions()
@ -702,7 +702,7 @@ export class StateService<
); );
} }
async setUserSymKeyBiometric(value: BiometricKey, options?: StorageOptions): Promise<void> { async setUserKeyBiometric(value: BiometricKey, options?: StorageOptions): Promise<void> {
options = this.reconcileOptions( options = this.reconcileOptions(
this.reconcileOptions(options, { keySuffix: "biometric" }), this.reconcileOptions(options, { keySuffix: "biometric" }),
await this.defaultSecureStorageOptions() await this.defaultSecureStorageOptions()
@ -713,36 +713,36 @@ export class StateService<
await this.saveSecureStorageKey(partialKeys.userBiometricKey, value, options); await this.saveSecureStorageKey(partialKeys.userBiometricKey, value, options);
} }
async getUserSymKeyPin(options?: StorageOptions): Promise<EncString> { async getUserKeyPin(options?: StorageOptions): Promise<EncString> {
return EncString.fromJSON( return EncString.fromJSON(
(await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))) (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())))
?.settings?.userSymKeyPin ?.settings?.userKeyPin
); );
} }
async setUserSymKeyPin(value: EncString, options?: StorageOptions): Promise<void> { async setUserKeyPin(value: EncString, options?: StorageOptions): Promise<void> {
const account = await this.getAccount( const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultOnDiskOptions()) this.reconcileOptions(options, await this.defaultOnDiskOptions())
); );
account.settings.userSymKeyPin = value?.encryptedString; account.settings.userKeyPin = value?.encryptedString;
await this.saveAccount( await this.saveAccount(
account, account,
this.reconcileOptions(options, await this.defaultOnDiskOptions()) this.reconcileOptions(options, await this.defaultOnDiskOptions())
); );
} }
async getUserSymKeyPinEphemeral(options?: StorageOptions): Promise<EncString> { async getUserKeyPinEphemeral(options?: StorageOptions): Promise<EncString> {
return EncString.fromJSON( return EncString.fromJSON(
(await this.getAccount(this.reconcileOptions(options, await this.defaultInMemoryOptions()))) (await this.getAccount(this.reconcileOptions(options, await this.defaultInMemoryOptions())))
?.settings?.userSymKeyPinEphemeral ?.settings?.userKeyPinEphemeral
); );
} }
async setUserSymKeyPinEphemeral(value: EncString, options?: StorageOptions): Promise<void> { async setUserKeyPinEphemeral(value: EncString, options?: StorageOptions): Promise<void> {
const account = await this.getAccount( const account = await this.getAccount(
this.reconcileOptions(options, await this.defaultInMemoryOptions()) this.reconcileOptions(options, await this.defaultInMemoryOptions())
); );
account.settings.userSymKeyPinEphemeral = value?.encryptedString; account.settings.userKeyPinEphemeral = value?.encryptedString;
await this.saveAccount( await this.saveAccount(
account, account,
this.reconcileOptions(options, await this.defaultInMemoryOptions()) this.reconcileOptions(options, await this.defaultInMemoryOptions())
@ -750,7 +750,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKeyAuto instead * @deprecated Use UserKeyAuto instead
*/ */
async getCryptoMasterKeyAuto(options?: StorageOptions): Promise<string> { async getCryptoMasterKeyAuto(options?: StorageOptions): Promise<string> {
options = this.reconcileOptions( options = this.reconcileOptions(
@ -767,7 +767,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKeyAuto instead * @deprecated Use UserKeyAuto instead
*/ */
async setCryptoMasterKeyAuto(value: string, options?: StorageOptions): Promise<void> { async setCryptoMasterKeyAuto(value: string, options?: StorageOptions): Promise<void> {
options = this.reconcileOptions( options = this.reconcileOptions(
@ -806,7 +806,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKeyBiometric instead * @deprecated Use UserKeyBiometric instead
*/ */
async getCryptoMasterKeyBiometric(options?: StorageOptions): Promise<string> { async getCryptoMasterKeyBiometric(options?: StorageOptions): Promise<string> {
options = this.reconcileOptions( options = this.reconcileOptions(
@ -823,7 +823,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKeyBiometric instead * @deprecated Use UserKeyBiometric instead
*/ */
async hasCryptoMasterKeyBiometric(options?: StorageOptions): Promise<boolean> { async hasCryptoMasterKeyBiometric(options?: StorageOptions): Promise<boolean> {
options = this.reconcileOptions( options = this.reconcileOptions(
@ -840,7 +840,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKeyBiometric instead * @deprecated Use UserKeyBiometric instead
*/ */
async setCryptoMasterKeyBiometric(value: BiometricKey, options?: StorageOptions): Promise<void> { async setCryptoMasterKeyBiometric(value: BiometricKey, options?: StorageOptions): Promise<void> {
options = this.reconcileOptions( options = this.reconcileOptions(
@ -890,7 +890,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKey instead * @deprecated Use UserKey instead
*/ */
async getDecryptedCryptoSymmetricKey(options?: StorageOptions): Promise<SymmetricCryptoKey> { async getDecryptedCryptoSymmetricKey(options?: StorageOptions): Promise<SymmetricCryptoKey> {
const account = await this.getAccount( const account = await this.getAccount(
@ -900,7 +900,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKey instead * @deprecated Use UserKey instead
*/ */
async setDecryptedCryptoSymmetricKey( async setDecryptedCryptoSymmetricKey(
value: SymmetricCryptoKey, value: SymmetricCryptoKey,
@ -1601,7 +1601,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKey instead * @deprecated Use UserKey instead
*/ */
async getEncryptedCryptoSymmetricKey(options?: StorageOptions): Promise<string> { async getEncryptedCryptoSymmetricKey(options?: StorageOptions): Promise<string> {
return ( return (
@ -1610,7 +1610,7 @@ export class StateService<
} }
/** /**
* @deprecated Use UserSymKey instead * @deprecated Use UserKey instead
*/ */
async setEncryptedCryptoSymmetricKey(value: string, options?: StorageOptions): Promise<void> { async setEncryptedCryptoSymmetricKey(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount( const account = await this.getAccount(
@ -3018,8 +3018,8 @@ export class StateService<
protected async removeAccountFromSecureStorage(userId: string = null): Promise<void> { protected async removeAccountFromSecureStorage(userId: string = null): Promise<void> {
userId = userId ?? (await this.state())?.activeUserId; userId = userId ?? (await this.state())?.activeUserId;
await this.setUserSymKeyAuto(null, { userId: userId }); await this.setUserKeyAuto(null, { userId: userId });
await this.setUserSymKeyBiometric(null, { userId: userId }); await this.setUserKeyBiometric(null, { userId: userId });
await this.setCryptoMasterKeyAuto(null, { userId: userId }); await this.setCryptoMasterKeyAuto(null, { userId: userId });
await this.setCryptoMasterKeyBiometric(null, { userId: userId }); await this.setCryptoMasterKeyBiometric(null, { userId: userId });
await this.setCryptoMasterKeyB64(null, { userId: userId }); await this.setCryptoMasterKeyB64(null, { userId: userId });

View File

@ -39,7 +39,7 @@ export class SystemService implements SystemServiceAbstraction {
} }
// User has set a PIN, with ask for master password on restart, to protect their vault // User has set a PIN, with ask for master password on restart, to protect their vault
const ephemeralPin = await this.stateService.getUserSymKeyPinEphemeral(); const ephemeralPin = await this.stateService.getUserKeyPinEphemeral();
if (ephemeralPin != null) { if (ephemeralPin != null) {
return; return;
} }

View File

@ -9,7 +9,7 @@ import { StateService } from "../platform/abstractions/state.service";
import { import {
SymmetricCryptoKey, SymmetricCryptoKey,
DeviceKey, DeviceKey,
UserSymKey, UserKey,
} from "../platform/models/domain/symmetric-crypto-key"; } from "../platform/models/domain/symmetric-crypto-key";
import { CsprngArray } from "../types/csprng"; import { CsprngArray } from "../types/csprng";
@ -24,11 +24,11 @@ export class DeviceCryptoService implements DeviceCryptoServiceAbstraction {
) {} ) {}
async trustDevice(): Promise<DeviceResponse> { async trustDevice(): Promise<DeviceResponse> {
// Attempt to get user symmetric key // Attempt to get user key
const userSymKey: UserSymKey = await this.cryptoService.getUserKeyFromMemory(); const userKey: UserKey = await this.cryptoService.getUserKeyFromMemory();
// If user symmetric key is not found, throw error // If user key is not found, throw error
if (!userSymKey) { if (!userKey) {
throw new Error("User symmetric key not found"); throw new Error("User symmetric key not found");
} }
@ -41,15 +41,15 @@ export class DeviceCryptoService implements DeviceCryptoServiceAbstraction {
); );
const [ const [
devicePublicKeyEncryptedUserSymKey, devicePublicKeyEncryptedUserKey,
userSymKeyEncryptedDevicePublicKey, userKeyEncryptedDevicePublicKey,
deviceKeyEncryptedDevicePrivateKey, deviceKeyEncryptedDevicePrivateKey,
] = await Promise.all([ ] = await Promise.all([
// Encrypt user symmetric key with the DevicePublicKey // Encrypt user key with the DevicePublicKey
this.cryptoService.rsaEncrypt(userSymKey.encKey, devicePublicKey), this.cryptoService.rsaEncrypt(userKey.encKey, devicePublicKey),
// Encrypt devicePublicKey with user symmetric key // Encrypt devicePublicKey with user key
this.encryptService.encrypt(devicePublicKey, userSymKey), this.encryptService.encrypt(devicePublicKey, userKey),
// Encrypt devicePrivateKey with deviceKey // Encrypt devicePrivateKey with deviceKey
this.encryptService.encrypt(devicePrivateKey, deviceKey), this.encryptService.encrypt(devicePrivateKey, deviceKey),
@ -59,8 +59,8 @@ export class DeviceCryptoService implements DeviceCryptoServiceAbstraction {
const deviceIdentifier = await this.appIdService.getAppId(); const deviceIdentifier = await this.appIdService.getAppId();
return this.devicesApiService.updateTrustedDeviceKeys( return this.devicesApiService.updateTrustedDeviceKeys(
deviceIdentifier, deviceIdentifier,
devicePublicKeyEncryptedUserSymKey.encryptedString, devicePublicKeyEncryptedUserKey.encryptedString,
userSymKeyEncryptedDevicePublicKey.encryptedString, userKeyEncryptedDevicePublicKey.encryptedString,
deviceKeyEncryptedDevicePrivateKey.encryptedString deviceKeyEncryptedDevicePrivateKey.encryptedString
); );
} }

View File

@ -11,7 +11,7 @@ import { EncString } from "../platform/models/domain/enc-string";
import { import {
SymmetricCryptoKey, SymmetricCryptoKey,
DeviceKey, DeviceKey,
UserSymKey, UserKey,
} from "../platform/models/domain/symmetric-crypto-key"; } from "../platform/models/domain/symmetric-crypto-key";
import { CryptoService } from "../platform/services/crypto.service"; import { CryptoService } from "../platform/services/crypto.service";
import { CsprngArray } from "../types/csprng"; import { CsprngArray } from "../types/csprng";
@ -51,7 +51,7 @@ describe("deviceCryptoService", () => {
describe("Trusted Device Encryption", () => { describe("Trusted Device Encryption", () => {
const deviceKeyBytesLength = 64; const deviceKeyBytesLength = 64;
const userSymKeyBytesLength = 64; const userKeyBytesLength = 64;
describe("getDeviceKey", () => { describe("getDeviceKey", () => {
let mockRandomBytes: CsprngArray; let mockRandomBytes: CsprngArray;
@ -128,15 +128,15 @@ describe("deviceCryptoService", () => {
let mockDeviceKeyRandomBytes: CsprngArray; let mockDeviceKeyRandomBytes: CsprngArray;
let mockDeviceKey: DeviceKey; let mockDeviceKey: DeviceKey;
let mockUserSymKeyRandomBytes: CsprngArray; let mockUserKeyRandomBytes: CsprngArray;
let mockUserSymKey: UserSymKey; let mockUserKey: UserKey;
const deviceRsaKeyLength = 2048; const deviceRsaKeyLength = 2048;
let mockDeviceRsaKeyPair: [ArrayBuffer, ArrayBuffer]; let mockDeviceRsaKeyPair: [ArrayBuffer, ArrayBuffer];
let mockDevicePrivateKey: ArrayBuffer; let mockDevicePrivateKey: ArrayBuffer;
let mockDevicePublicKey: ArrayBuffer; let mockDevicePublicKey: ArrayBuffer;
let mockDevicePublicKeyEncryptedUserSymKey: EncString; let mockDevicePublicKeyEncryptedUserKey: EncString;
let mockUserSymKeyEncryptedDevicePublicKey: EncString; let mockUserKeyEncryptedDevicePublicKey: EncString;
let mockDeviceKeyEncryptedDevicePrivateKey: EncString; let mockDeviceKeyEncryptedDevicePrivateKey: EncString;
const mockDeviceResponse: DeviceResponse = new DeviceResponse({ const mockDeviceResponse: DeviceResponse = new DeviceResponse({
@ -163,8 +163,8 @@ describe("deviceCryptoService", () => {
mockDeviceKeyRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray; mockDeviceKeyRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray;
mockDeviceKey = new SymmetricCryptoKey(mockDeviceKeyRandomBytes) as DeviceKey; mockDeviceKey = new SymmetricCryptoKey(mockDeviceKeyRandomBytes) as DeviceKey;
mockUserSymKeyRandomBytes = new Uint8Array(userSymKeyBytesLength).buffer as CsprngArray; mockUserKeyRandomBytes = new Uint8Array(userKeyBytesLength).buffer as CsprngArray;
mockUserSymKey = new SymmetricCryptoKey(mockUserSymKeyRandomBytes) as UserSymKey; mockUserKey = new SymmetricCryptoKey(mockUserKeyRandomBytes) as UserKey;
mockDeviceRsaKeyPair = [ mockDeviceRsaKeyPair = [
new ArrayBuffer(deviceRsaKeyLength), new ArrayBuffer(deviceRsaKeyLength),
@ -174,14 +174,14 @@ describe("deviceCryptoService", () => {
mockDevicePublicKey = mockDeviceRsaKeyPair[0]; mockDevicePublicKey = mockDeviceRsaKeyPair[0];
mockDevicePrivateKey = mockDeviceRsaKeyPair[1]; mockDevicePrivateKey = mockDeviceRsaKeyPair[1];
mockDevicePublicKeyEncryptedUserSymKey = new EncString( mockDevicePublicKeyEncryptedUserKey = new EncString(
EncryptionType.Rsa2048_OaepSha1_B64, EncryptionType.Rsa2048_OaepSha1_B64,
"mockDevicePublicKeyEncryptedUserSymKey" "mockDevicePublicKeyEncryptedUserKey"
); );
mockUserSymKeyEncryptedDevicePublicKey = new EncString( mockUserKeyEncryptedDevicePublicKey = new EncString(
EncryptionType.AesCbc256_HmacSha256_B64, EncryptionType.AesCbc256_HmacSha256_B64,
"mockUserSymKeyEncryptedDevicePublicKey" "mockUserKeyEncryptedDevicePublicKey"
); );
mockDeviceKeyEncryptedDevicePrivateKey = new EncString( mockDeviceKeyEncryptedDevicePrivateKey = new EncString(
@ -200,17 +200,17 @@ describe("deviceCryptoService", () => {
cryptoSvcGetUserKeyFromMemorySpy = jest cryptoSvcGetUserKeyFromMemorySpy = jest
.spyOn(cryptoService, "getUserKeyFromMemory") .spyOn(cryptoService, "getUserKeyFromMemory")
.mockResolvedValue(mockUserSymKey); .mockResolvedValue(mockUserKey);
cryptoSvcRsaEncryptSpy = jest cryptoSvcRsaEncryptSpy = jest
.spyOn(cryptoService, "rsaEncrypt") .spyOn(cryptoService, "rsaEncrypt")
.mockResolvedValue(mockDevicePublicKeyEncryptedUserSymKey); .mockResolvedValue(mockDevicePublicKeyEncryptedUserKey);
encryptServiceEncryptSpy = jest encryptServiceEncryptSpy = jest
.spyOn(encryptService, "encrypt") .spyOn(encryptService, "encrypt")
.mockImplementation((plainValue, key) => { .mockImplementation((plainValue, key) => {
if (plainValue === mockDevicePublicKey && key === mockUserSymKey) { if (plainValue === mockDevicePublicKey && key === mockUserKey) {
return Promise.resolve(mockUserSymKeyEncryptedDevicePublicKey); return Promise.resolve(mockUserKeyEncryptedDevicePublicKey);
} }
if (plainValue === mockDevicePrivateKey && key === mockDeviceKey) { if (plainValue === mockDevicePrivateKey && key === mockDeviceKey) {
return Promise.resolve(mockDeviceKeyEncryptedDevicePrivateKey); return Promise.resolve(mockDeviceKeyEncryptedDevicePrivateKey);
@ -240,8 +240,8 @@ describe("deviceCryptoService", () => {
expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledTimes(1); expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledTimes(1);
expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledWith( expect(devicesApiServiceUpdateTrustedDeviceKeysSpy).toHaveBeenCalledWith(
mockDeviceId, mockDeviceId,
mockDevicePublicKeyEncryptedUserSymKey.encryptedString, mockDevicePublicKeyEncryptedUserKey.encryptedString,
mockUserSymKeyEncryptedDevicePublicKey.encryptedString, mockUserKeyEncryptedDevicePublicKey.encryptedString,
mockDeviceKeyEncryptedDevicePrivateKey.encryptedString mockDeviceKeyEncryptedDevicePrivateKey.encryptedString
); );
@ -249,7 +249,7 @@ describe("deviceCryptoService", () => {
expect(response).toEqual(mockDeviceResponse); expect(response).toEqual(mockDeviceResponse);
}); });
it("throws specific error if user symmetric key is not found", async () => { it("throws specific error if user key is not found", async () => {
// setup the spy to return null // setup the spy to return null
cryptoSvcGetUserKeyFromMemorySpy.mockResolvedValue(null); cryptoSvcGetUserKeyFromMemorySpy.mockResolvedValue(null);
// check if the expected error is thrown // check if the expected error is thrown

View File

@ -41,13 +41,13 @@ export class DevicesApiServiceImplementation implements DevicesApiServiceAbstrac
async updateTrustedDeviceKeys( async updateTrustedDeviceKeys(
deviceIdentifier: string, deviceIdentifier: string,
devicePublicKeyEncryptedUserSymKey: string, devicePublicKeyEncryptedUserKey: string,
userSymKeyEncryptedDevicePublicKey: string, userKeyEncryptedDevicePublicKey: string,
deviceKeyEncryptedDevicePrivateKey: string deviceKeyEncryptedDevicePrivateKey: string
): Promise<DeviceResponse> { ): Promise<DeviceResponse> {
const request = new TrustedDeviceKeysRequest( const request = new TrustedDeviceKeysRequest(
devicePublicKeyEncryptedUserSymKey, devicePublicKeyEncryptedUserKey,
userSymKeyEncryptedDevicePublicKey, userKeyEncryptedDevicePublicKey,
deviceKeyEncryptedDevicePrivateKey deviceKeyEncryptedDevicePrivateKey
); );

View File

@ -72,7 +72,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
if (await this.keyConnectorService.getUsesKeyConnector()) { if (await this.keyConnectorService.getUsesKeyConnector()) {
const pinSet = await this.vaultTimeoutSettingsService.isPinLockSet(); const pinSet = await this.vaultTimeoutSettingsService.isPinLockSet();
let ephemeralPinSet = await this.stateService.getUserSymKeyPinEphemeral(); let ephemeralPinSet = await this.stateService.getUserKeyPinEphemeral();
ephemeralPinSet ||= await this.stateService.getDecryptedPinProtected(); ephemeralPinSet ||= await this.stateService.getDecryptedPinProtected();
const pinLock = (pinSet[0] && ephemeralPinSet != null) || pinSet[1]; const pinLock = (pinSet[0] && ephemeralPinSet != null) || pinSet[1];
@ -87,7 +87,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
} }
await this.stateService.setEverBeenUnlocked(true, { userId: userId }); await this.stateService.setEverBeenUnlocked(true, { userId: userId });
await this.stateService.setUserSymKeyAuto(null, { userId: userId }); await this.stateService.setUserKeyAuto(null, { userId: userId });
await this.stateService.setCryptoMasterKeyAuto(null, { userId: userId }); await this.stateService.setCryptoMasterKeyAuto(null, { userId: userId });
await this.cryptoService.clearUserKey(false, userId); await this.cryptoService.clearUserKey(false, userId);

View File

@ -48,12 +48,12 @@ export class VaultTimeoutSettingsService implements VaultTimeoutSettingsServiceA
// we can't check the protected pin for both because old accounts only // we can't check the protected pin for both because old accounts only
// used it for MP on Restart // used it for MP on Restart
const pinIsEnabled = !!(await this.stateService.getProtectedPin()); const pinIsEnabled = !!(await this.stateService.getProtectedPin());
const aUserSymKeyPinIsSet = !!(await this.stateService.getUserSymKeyPin()); const aUserKeyPinIsSet = !!(await this.stateService.getUserKeyPin());
const anOldUserSymKeyPinIsSet = !!(await this.stateService.getEncryptedPinProtected()); const anOldUserKeyPinIsSet = !!(await this.stateService.getEncryptedPinProtected());
return [ return [
pinIsEnabled && !aUserSymKeyPinIsSet && !anOldUserSymKeyPinIsSet, pinIsEnabled && !aUserKeyPinIsSet && !anOldUserKeyPinIsSet,
aUserSymKeyPinIsSet || anOldUserSymKeyPinIsSet, aUserKeyPinIsSet || anOldUserKeyPinIsSet,
]; ];
} }
@ -111,7 +111,7 @@ export class VaultTimeoutSettingsService implements VaultTimeoutSettingsServiceA
async clear(userId?: string): Promise<void> { async clear(userId?: string): Promise<void> {
await this.stateService.setEverBeenUnlocked(false, { userId: userId }); await this.stateService.setEverBeenUnlocked(false, { userId: userId });
await this.stateService.setUserSymKeyPinEphemeral(null, { userId: userId }); await this.stateService.setUserKeyPinEphemeral(null, { userId: userId });
await this.stateService.setProtectedPin(null, { userId: userId }); await this.stateService.setProtectedPin(null, { userId: userId });
await this.cryptoService.clearOldPinKeys(userId); await this.cryptoService.clearOldPinKeys(userId);
} }

View File

@ -303,7 +303,7 @@ export class SyncService implements SyncServiceAbstraction {
throw new Error("Stamp has changed"); throw new Error("Stamp has changed");
} }
await this.cryptoService.setUserSymKeyMasterKey(response.key); await this.cryptoService.setUserKeyMasterKey(response.key);
await this.cryptoService.setPrivateKey(response.privateKey); await this.cryptoService.setPrivateKey(response.privateKey);
await this.cryptoService.setProviderKeys(response.providers); await this.cryptoService.setProviderKeys(response.providers);
await this.cryptoService.setOrgKeys(response.organizations, response.providerOrganizations); await this.cryptoService.setOrgKeys(response.organizations, response.providerOrganizations);