mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 01:03:35 +00:00
update change password components with new crypto service
This commit is contained in:
@@ -23,7 +23,10 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
|||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import {
|
||||||
|
SymmetricCryptoKey,
|
||||||
|
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";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -173,23 +176,29 @@ 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 userEncKey = new SymmetricCryptoKey(decValue);
|
const existingUserSymKey = new SymmetricCryptoKey(decValue) as UserSymKey;
|
||||||
|
|
||||||
// Create new key and hash new password
|
// Create new master key and hash new password
|
||||||
const newKey = await this.cryptoService.makeKey(
|
const newMasterKey = await this.cryptoService.makeMasterKey(
|
||||||
this.newPassword,
|
this.newPassword,
|
||||||
this.email.trim().toLowerCase(),
|
this.email.trim().toLowerCase(),
|
||||||
kdfType,
|
kdfType,
|
||||||
new KdfConfig(kdfIterations, kdfMemory, kdfParallelism)
|
new KdfConfig(kdfIterations, kdfMemory, kdfParallelism)
|
||||||
);
|
);
|
||||||
const newPasswordHash = await this.cryptoService.hashPassword(this.newPassword, newKey);
|
const newPasswordHash = await this.cryptoService.hashPassword(
|
||||||
|
this.newPassword,
|
||||||
|
newMasterKey
|
||||||
|
);
|
||||||
|
|
||||||
// Create new encKey for the User
|
// Create new encrypted user symmetric key for the User
|
||||||
const newEncKey = await this.cryptoService.remakeEncKey(newKey, userEncKey);
|
const newUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey(
|
||||||
|
newMasterKey,
|
||||||
|
existingUserSymKey
|
||||||
|
);
|
||||||
|
|
||||||
// Create request
|
// Create request
|
||||||
const request = new OrganizationUserResetPasswordRequest();
|
const request = new OrganizationUserResetPasswordRequest();
|
||||||
request.key = newEncKey[1].encryptedString;
|
request.key = newUserSymKey[1].encryptedString;
|
||||||
request.newMasterPasswordHash = newPasswordHash;
|
request.newMasterPasswordHash = newPasswordHash;
|
||||||
|
|
||||||
// Change user's password
|
// Change user's password
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export class ChangeEmailComponent implements OnInit {
|
|||||||
request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null);
|
request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null);
|
||||||
const kdf = await this.stateService.getKdfType();
|
const kdf = await this.stateService.getKdfType();
|
||||||
const kdfConfig = await this.stateService.getKdfConfig();
|
const kdfConfig = await this.stateService.getKdfConfig();
|
||||||
const newKey = await this.cryptoService.makeKey(
|
const newMasterKey = await this.cryptoService.makeMasterKey(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
this.newEmail,
|
this.newEmail,
|
||||||
kdf,
|
kdf,
|
||||||
@@ -75,10 +75,10 @@ export class ChangeEmailComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
request.newMasterPasswordHash = await this.cryptoService.hashPassword(
|
request.newMasterPasswordHash = await this.cryptoService.hashPassword(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
newKey
|
newMasterKey
|
||||||
);
|
);
|
||||||
const newEncKey = await this.cryptoService.remakeEncKey(newKey);
|
const newUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey(newMasterKey);
|
||||||
request.key = newEncKey[1].encryptedString;
|
request.key = newUserSymKey[1].encryptedString;
|
||||||
try {
|
try {
|
||||||
this.formPromise = this.apiService.postEmail(request);
|
this.formPromise = this.apiService.postEmail(request);
|
||||||
await this.formPromise;
|
await this.formPromise;
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ 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 { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import {
|
||||||
|
MasterKey,
|
||||||
|
SymmetricCryptoKey,
|
||||||
|
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 { 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";
|
||||||
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
|
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
|
||||||
@@ -137,8 +141,8 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
const hasEncKey = await this.cryptoService.hasEncKey();
|
const hasUserKey = await this.cryptoService.hasUserKey();
|
||||||
if (!hasEncKey) {
|
if (!hasUserKey) {
|
||||||
this.platformUtilsService.showToast("error", null, this.i18nService.t("updateKey"));
|
this.platformUtilsService.showToast("error", null, this.i18nService.t("updateKey"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -179,8 +183,8 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
|
|
||||||
async performSubmitActions(
|
async performSubmitActions(
|
||||||
newMasterPasswordHash: string,
|
newMasterPasswordHash: string,
|
||||||
newKey: SymmetricCryptoKey,
|
newMasterKey: MasterKey,
|
||||||
newEncKey: [SymmetricCryptoKey, EncString]
|
newUserKey: [UserSymKey, EncString]
|
||||||
) {
|
) {
|
||||||
const request = new PasswordRequest();
|
const request = new PasswordRequest();
|
||||||
request.masterPasswordHash = await this.cryptoService.hashPassword(
|
request.masterPasswordHash = await this.cryptoService.hashPassword(
|
||||||
@@ -189,12 +193,12 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
);
|
);
|
||||||
request.masterPasswordHint = this.masterPasswordHint;
|
request.masterPasswordHint = this.masterPasswordHint;
|
||||||
request.newMasterPasswordHash = newMasterPasswordHash;
|
request.newMasterPasswordHash = newMasterPasswordHash;
|
||||||
request.key = newEncKey[1].encryptedString;
|
request.key = newUserKey[1].encryptedString;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.rotateEncKey) {
|
if (this.rotateEncKey) {
|
||||||
this.formPromise = this.apiService.postPassword(request).then(() => {
|
this.formPromise = this.apiService.postPassword(request).then(() => {
|
||||||
return this.updateKey(newKey, request.newMasterPasswordHash);
|
return this.updateKey(newMasterKey, request.newMasterPasswordHash);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.formPromise = this.apiService.postPassword(request);
|
this.formPromise = this.apiService.postPassword(request);
|
||||||
@@ -213,16 +217,16 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateKey(key: SymmetricCryptoKey, masterPasswordHash: string) {
|
private async updateKey(masterKey: MasterKey, masterPasswordHash: string) {
|
||||||
const encKey = await this.cryptoService.makeEncKey(key);
|
const userSymKey = await this.cryptoService.makeUserSymKey(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, encKey[0]);
|
encPrivateKey = await this.cryptoService.encrypt(privateKey, userSymKey[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 = encKey[1].encryptedString;
|
request.key = userSymKey[1].encryptedString;
|
||||||
request.masterPasswordHash = masterPasswordHash;
|
request.masterPasswordHash = masterPasswordHash;
|
||||||
|
|
||||||
const folders = await firstValueFrom(this.folderService.folderViews$);
|
const folders = await firstValueFrom(this.folderService.folderViews$);
|
||||||
@@ -230,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], encKey[0]);
|
const folder = await this.folderService.encrypt(folders[i], userSymKey[0]);
|
||||||
request.folders.push(new FolderWithIdRequest(folder));
|
request.folders.push(new FolderWithIdRequest(folder));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,24 +244,24 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cipher = await this.cipherService.encrypt(ciphers[i], encKey[0]);
|
const cipher = await this.cipherService.encrypt(ciphers[i], userSymKey[0]);
|
||||||
request.ciphers.push(new CipherWithIdRequest(cipher));
|
request.ciphers.push(new CipherWithIdRequest(cipher));
|
||||||
}
|
}
|
||||||
|
|
||||||
const sends = await firstValueFrom(this.sendService.sends$);
|
const sends = await firstValueFrom(this.sendService.sends$);
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
sends.map(async (send) => {
|
sends.map(async (send) => {
|
||||||
const cryptoKey = await this.cryptoService.decryptToBytes(send.key, null);
|
const sendKey = await this.cryptoService.decryptToBytes(send.key, null);
|
||||||
send.key = (await this.cryptoService.encrypt(cryptoKey, encKey[0])) ?? send.key;
|
send.key = (await this.cryptoService.encrypt(sendKey, userSymKey[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(encKey[0]);
|
await this.updateEmergencyAccesses(userSymKey[0]);
|
||||||
|
|
||||||
await this.updateAllResetPasswordKeys(encKey[0], masterPasswordHash);
|
await this.updateAllResetPasswordKeys(userSymKey[0], masterPasswordHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateEmergencyAccesses(encKey: SymmetricCryptoKey) {
|
private async updateEmergencyAccesses(encKey: SymmetricCryptoKey) {
|
||||||
@@ -285,7 +289,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateAllResetPasswordKeys(encKey: SymmetricCryptoKey, masterPasswordHash: string) {
|
private async updateAllResetPasswordKeys(userSymKey: UserSymKey, masterPasswordHash: string) {
|
||||||
const orgs = await this.organizationService.getAll();
|
const orgs = await this.organizationService.getAll();
|
||||||
|
|
||||||
for (const org of orgs) {
|
for (const org of orgs) {
|
||||||
@@ -299,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(encKey.key, publicKey.buffer);
|
const encryptedKey = await this.cryptoService.rsaEncrypt(userSymKey.key, publicKey.buffer);
|
||||||
|
|
||||||
// Create/Execute request
|
// Create/Execute request
|
||||||
const request = new OrganizationUserResetPasswordEnrollmentRequest();
|
const request = new OrganizationUserResetPasswordEnrollmentRequest();
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ 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 { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import {
|
||||||
|
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";
|
||||||
@@ -79,23 +82,30 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
|
|||||||
if (this.kdfConfig == null) {
|
if (this.kdfConfig == null) {
|
||||||
this.kdfConfig = await this.stateService.getKdfConfig();
|
this.kdfConfig = await this.stateService.getKdfConfig();
|
||||||
}
|
}
|
||||||
const key = await this.cryptoService.makeKey(
|
|
||||||
|
// Create new master key
|
||||||
|
const newMasterKey = await this.cryptoService.makeMasterKey(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
email.trim().toLowerCase(),
|
email.trim().toLowerCase(),
|
||||||
this.kdf,
|
this.kdf,
|
||||||
this.kdfConfig
|
this.kdfConfig
|
||||||
);
|
);
|
||||||
const masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, key);
|
const newMasterPasswordHash = await this.cryptoService.hashPassword(
|
||||||
|
this.masterPassword,
|
||||||
|
newMasterKey
|
||||||
|
);
|
||||||
|
|
||||||
let encKey: [SymmetricCryptoKey, EncString] = null;
|
let newProtectedUserSymKey: [UserSymKey, EncString] = null;
|
||||||
const existingEncKey = await this.cryptoService.getEncKey();
|
const userSymKey = await this.cryptoService.getUserKeyFromMemory();
|
||||||
if (existingEncKey == null) {
|
if (userSymKey == null) {
|
||||||
encKey = await this.cryptoService.makeEncKey(key);
|
newProtectedUserSymKey = await this.cryptoService.makeUserSymKey(newMasterKey);
|
||||||
} else {
|
} else {
|
||||||
encKey = await this.cryptoService.remakeEncKey(key);
|
newProtectedUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey(
|
||||||
|
newMasterKey
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.performSubmitActions(masterPasswordHash, key, encKey);
|
await this.performSubmitActions(newMasterPasswordHash, newMasterKey, newProtectedUserSymKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setupSubmitActions(): Promise<boolean> {
|
async setupSubmitActions(): Promise<boolean> {
|
||||||
@@ -106,8 +116,8 @@ export class ChangePasswordComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
async performSubmitActions(
|
async performSubmitActions(
|
||||||
masterPasswordHash: string,
|
masterPasswordHash: string,
|
||||||
key: SymmetricCryptoKey,
|
masterKey: MasterKey,
|
||||||
encKey: [SymmetricCryptoKey, EncString]
|
userSymKey: [UserSymKey, EncString]
|
||||||
) {
|
) {
|
||||||
// Override in sub-class
|
// Override in sub-class
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,10 @@ 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 { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import {
|
||||||
|
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";
|
||||||
|
|
||||||
@@ -96,8 +99,8 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
|
|
||||||
async performSubmitActions(
|
async performSubmitActions(
|
||||||
masterPasswordHash: string,
|
masterPasswordHash: string,
|
||||||
key: SymmetricCryptoKey,
|
masterKey: MasterKey,
|
||||||
encKey: [SymmetricCryptoKey, EncString]
|
userSymKey: [UserSymKey, EncString]
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
// Create Request
|
// Create Request
|
||||||
@@ -107,7 +110,7 @@ export class UpdatePasswordComponent extends BaseChangePasswordComponent {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
request.newMasterPasswordHash = masterPasswordHash;
|
request.newMasterPasswordHash = masterPasswordHash;
|
||||||
request.key = encKey[1].encryptedString;
|
request.key = userSymKey[1].encryptedString;
|
||||||
|
|
||||||
// Update user's password
|
// Update user's password
|
||||||
this.apiService.postPassword(request);
|
this.apiService.postPassword(request);
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ 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 { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import {
|
||||||
|
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";
|
||||||
@@ -114,21 +117,27 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Create new key and hash new password
|
// Create new key and hash new password
|
||||||
const newKey = await this.cryptoService.makeKey(
|
const newMasterKey = await this.cryptoService.makeMasterKey(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
this.email.trim().toLowerCase(),
|
this.email.trim().toLowerCase(),
|
||||||
this.kdf,
|
this.kdf,
|
||||||
this.kdfConfig
|
this.kdfConfig
|
||||||
);
|
);
|
||||||
const newPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, newKey);
|
const newPasswordHash = await this.cryptoService.hashPassword(
|
||||||
|
this.masterPassword,
|
||||||
|
newMasterKey
|
||||||
|
);
|
||||||
|
|
||||||
// Grab user's current enc key
|
// Grab user's symmetric key
|
||||||
const userEncKey = await this.cryptoService.getEncKey();
|
const userKey = await this.cryptoService.getUserKeyFromMemory();
|
||||||
|
|
||||||
// Create new encKey for the User
|
// Encrypt user's symmetric key with new master key
|
||||||
const newEncKey = await this.cryptoService.remakeEncKey(newKey, userEncKey);
|
const newProtectedUserSymKey = await this.cryptoService.encryptUserSymKeyWithMasterKey(
|
||||||
|
newMasterKey,
|
||||||
|
userKey
|
||||||
|
);
|
||||||
|
|
||||||
await this.performSubmitActions(newPasswordHash, newKey, newEncKey);
|
await this.performSubmitActions(newPasswordHash, newMasterKey, newProtectedUserSymKey);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logService.error(e);
|
this.logService.error(e);
|
||||||
}
|
}
|
||||||
@@ -136,16 +145,16 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
|
|
||||||
async performSubmitActions(
|
async performSubmitActions(
|
||||||
masterPasswordHash: string,
|
masterPasswordHash: string,
|
||||||
key: SymmetricCryptoKey,
|
masterKey: MasterKey,
|
||||||
encKey: [SymmetricCryptoKey, EncString]
|
userSymKey: [UserSymKey, EncString]
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
switch (this.reason) {
|
switch (this.reason) {
|
||||||
case ForceResetPasswordReason.AdminForcePasswordReset:
|
case ForceResetPasswordReason.AdminForcePasswordReset:
|
||||||
this.formPromise = this.updateTempPassword(masterPasswordHash, encKey);
|
this.formPromise = this.updateTempPassword(masterPasswordHash, userSymKey);
|
||||||
break;
|
break;
|
||||||
case ForceResetPasswordReason.WeakMasterPassword:
|
case ForceResetPasswordReason.WeakMasterPassword:
|
||||||
this.formPromise = this.updatePassword(masterPasswordHash, encKey);
|
this.formPromise = this.updatePassword(masterPasswordHash, userSymKey);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,27 +178,24 @@ export class UpdateTempPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
}
|
}
|
||||||
private async updateTempPassword(
|
private async updateTempPassword(
|
||||||
masterPasswordHash: string,
|
masterPasswordHash: string,
|
||||||
encKey: [SymmetricCryptoKey, EncString]
|
userSymKey: [UserSymKey, EncString]
|
||||||
) {
|
) {
|
||||||
const request = new UpdateTempPasswordRequest();
|
const request = new UpdateTempPasswordRequest();
|
||||||
request.key = encKey[1].encryptedString;
|
request.key = userSymKey[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(
|
private async updatePassword(newMasterPasswordHash: string, userSymKey: [UserSymKey, EncString]) {
|
||||||
newMasterPasswordHash: string,
|
|
||||||
encKey: [SymmetricCryptoKey, 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 = encKey[1].encryptedString;
|
request.key = userSymKey[1].encryptedString;
|
||||||
|
|
||||||
return this.apiService.postPassword(request);
|
return this.apiService.postPassword(request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ 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 { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
import {
|
||||||
|
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";
|
||||||
|
|
||||||
@@ -101,16 +104,16 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
|
|
||||||
async performSubmitActions(
|
async performSubmitActions(
|
||||||
masterPasswordHash: string,
|
masterPasswordHash: string,
|
||||||
key: SymmetricCryptoKey,
|
masterKey: MasterKey,
|
||||||
encKey: [SymmetricCryptoKey, EncString]
|
userKey: [UserSymKey, EncString]
|
||||||
) {
|
) {
|
||||||
const keys = await this.cryptoService.makeKeyPair(encKey[0]);
|
const newKeyPair = await this.cryptoService.makeKeyPair(userKey[0]);
|
||||||
const request = new SetPasswordRequest(
|
const request = new SetPasswordRequest(
|
||||||
masterPasswordHash,
|
masterPasswordHash,
|
||||||
encKey[1].encryptedString,
|
userKey[1].encryptedString,
|
||||||
this.hint,
|
this.hint,
|
||||||
this.identifier,
|
this.identifier,
|
||||||
new KeysRequest(keys[0], keys[1].encryptedString),
|
new KeysRequest(newKeyPair[0], newKeyPair[1].encryptedString),
|
||||||
this.kdf,
|
this.kdf,
|
||||||
this.kdfConfig.iterations,
|
this.kdfConfig.iterations,
|
||||||
this.kdfConfig.memory,
|
this.kdfConfig.memory,
|
||||||
@@ -121,7 +124,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
this.formPromise = this.apiService
|
this.formPromise = this.apiService
|
||||||
.setPassword(request)
|
.setPassword(request)
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
await this.onSetPasswordSuccess(key, encKey, keys);
|
await this.onSetPasswordSuccess(masterKey, userKey, newKeyPair);
|
||||||
return this.organizationApiService.getKeys(this.orgId);
|
return this.organizationApiService.getKeys(this.orgId);
|
||||||
})
|
})
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
@@ -131,16 +134,16 @@ 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 encKey.key with organization public key
|
// RSA Encrypt user's symmetric key with organization public key
|
||||||
const userEncKey = await this.cryptoService.getEncKey();
|
const userKey = await this.cryptoService.getUserKeyFromMemory();
|
||||||
const encryptedKey = await this.cryptoService.rsaEncrypt(
|
const encryptedUserKey = await this.cryptoService.rsaEncrypt(
|
||||||
userEncKey.key,
|
userKey.key,
|
||||||
publicKey.buffer
|
publicKey.buffer
|
||||||
);
|
);
|
||||||
|
|
||||||
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
|
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
|
||||||
resetRequest.masterPasswordHash = masterPasswordHash;
|
resetRequest.masterPasswordHash = masterPasswordHash;
|
||||||
resetRequest.resetPasswordKey = encryptedKey.encryptedString;
|
resetRequest.resetPasswordKey = encryptedUserKey.encryptedString;
|
||||||
|
|
||||||
return this.organizationUserService.putOrganizationUserResetPasswordEnrollment(
|
return this.organizationUserService.putOrganizationUserResetPasswordEnrollment(
|
||||||
this.orgId,
|
this.orgId,
|
||||||
@@ -150,7 +153,7 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.formPromise = this.apiService.setPassword(request).then(async () => {
|
this.formPromise = this.apiService.setPassword(request).then(async () => {
|
||||||
await this.onSetPasswordSuccess(key, encKey, keys);
|
await this.onSetPasswordSuccess(masterKey, userKey, newKeyPair);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,19 +175,19 @@ export class SetPasswordComponent extends BaseChangePasswordComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async onSetPasswordSuccess(
|
private async onSetPasswordSuccess(
|
||||||
key: SymmetricCryptoKey,
|
masterKey: MasterKey,
|
||||||
encKey: [SymmetricCryptoKey, EncString],
|
userKey: [UserSymKey, EncString],
|
||||||
keys: [string, EncString]
|
keyPair: [string, EncString]
|
||||||
) {
|
) {
|
||||||
await this.stateService.setKdfType(this.kdf);
|
await this.stateService.setKdfType(this.kdf);
|
||||||
await this.stateService.setKdfConfig(this.kdfConfig);
|
await this.stateService.setKdfConfig(this.kdfConfig);
|
||||||
await this.cryptoService.setKey(key);
|
await this.cryptoService.setMasterKey(masterKey);
|
||||||
await this.cryptoService.setEncKey(encKey[1].encryptedString);
|
await this.cryptoService.setUserKey(userKey[0]);
|
||||||
await this.cryptoService.setEncPrivateKey(keys[1].encryptedString);
|
await this.cryptoService.setPrivateKey(keyPair[1].encryptedString);
|
||||||
|
|
||||||
const localKeyHash = await this.cryptoService.hashPassword(
|
const localKeyHash = await this.cryptoService.hashPassword(
|
||||||
this.masterPassword,
|
this.masterPassword,
|
||||||
key,
|
masterKey,
|
||||||
HashPurpose.LocalAuthorization
|
HashPurpose.LocalAuthorization
|
||||||
);
|
);
|
||||||
await this.cryptoService.setKeyHash(localKeyHash);
|
await this.cryptoService.setKeyHash(localKeyHash);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export abstract class CryptoService {
|
|||||||
keySuffix?: KeySuffixOptions.Auto | KeySuffixOptions.Biometric,
|
keySuffix?: KeySuffixOptions.Auto | KeySuffixOptions.Biometric,
|
||||||
userId?: string
|
userId?: string
|
||||||
) => Promise<boolean>;
|
) => Promise<boolean>;
|
||||||
makeUserSymKey: (key: SymmetricCryptoKey) => Promise<[UserSymKey, EncString]>;
|
makeUserSymKey: (key: MasterKey) => Promise<[UserSymKey, EncString]>;
|
||||||
clearUserKey: (clearSecretStorage?: boolean, userId?: string) => Promise<void>;
|
clearUserKey: (clearSecretStorage?: boolean, userId?: string) => Promise<void>;
|
||||||
setUserSymKeyMasterKey: (UserSymKeyMasterKey: string, userId?: string) => Promise<void>;
|
setUserSymKeyMasterKey: (UserSymKeyMasterKey: string, userId?: string) => Promise<void>;
|
||||||
setMasterKey: (key: MasterKey, userId?: string) => Promise<void>;
|
setMasterKey: (key: MasterKey, userId?: string) => Promise<void>;
|
||||||
|
|||||||
Reference in New Issue
Block a user