1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-20 11:24:07 +00:00

Remove SymmetricCryptoKey buffer representation

This commit is contained in:
Bernd Schoolmann
2025-02-27 12:50:38 +01:00
parent 84daf34ae2
commit 05106055e6
24 changed files with 104 additions and 61 deletions

View File

@@ -60,7 +60,7 @@ export class OrganizationUserResetPasswordService
if (userKey == null) {
throw new Error("No user key found");
}
const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey);
const encryptedKey = await this.encryptService.rsaEncrypt(userKey.toEncoded(), publicKey);
return encryptedKey.encryptedString;
}

View File

@@ -4,6 +4,7 @@ import { mock, MockProxy } from "jest-mock-extended";
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { UserKey } from "@bitwarden/common/types/key";
import { KeyService } from "@bitwarden/key-management";
import { RotateableKeySetService } from "./rotateable-key-set.service";
@@ -34,7 +35,7 @@ describe("RotateableKeySetService", () => {
const encryptedPublicKey = Symbol();
const encryptedPrivateKey = Symbol();
keyService.makeKeyPair.mockResolvedValue(["publicKey", encryptedPrivateKey as any]);
keyService.getUserKey.mockResolvedValue({ key: userKey.key } as any);
keyService.getUserKey.mockResolvedValue(userKey as UserKey);
encryptService.rsaEncrypt.mockResolvedValue(encryptedUserKey as any);
encryptService.encrypt.mockResolvedValue(encryptedPublicKey as any);

View File

@@ -25,7 +25,10 @@ export class RotateableKeySetService {
const userKey = await this.keyService.getUserKey();
const rawPublicKey = Utils.fromB64ToArray(publicKey);
const encryptedUserKey = await this.encryptService.rsaEncrypt(userKey.key, rawPublicKey);
const encryptedUserKey = await this.encryptService.rsaEncrypt(
userKey.toEncoded(),
rawPublicKey,
);
const encryptedPublicKey = await this.encryptService.encrypt(rawPublicKey, userKey);
return new RotateableKeySet(encryptedUserKey, encryptedPublicKey, encryptedPrivateKey);
}
@@ -60,7 +63,10 @@ export class RotateableKeySetService {
throw new Error("failed to rotate key set: could not decrypt public key");
}
const newEncryptedPublicKey = await this.encryptService.encrypt(publicKey, newUserKey);
const newEncryptedUserKey = await this.encryptService.rsaEncrypt(newUserKey.key, publicKey);
const newEncryptedUserKey = await this.encryptService.rsaEncrypt(
newUserKey.toEncoded(),
publicKey,
);
const newRotateableKeySet = new RotateableKeySet<ExternalKey>(
newEncryptedUserKey,

View File

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

View File

@@ -212,7 +212,7 @@ describe("DefaultSetPasswordJitService", () => {
// Assert
expect(apiService.setPassword).toHaveBeenCalledWith(setPasswordRequest);
expect(organizationApiService.getKeys).toHaveBeenCalledWith(orgId);
expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(userKey.key, orgPublicKey);
expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(userKey.toEncoded(), orgPublicKey);
expect(
organizationUserApiService.putOrganizationUserResetPasswordEnrollment,
).toHaveBeenCalled();

View File

@@ -159,7 +159,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService {
throw new Error("userKey not found. Could not handle reset password auto enroll.");
}
const encryptedUserKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey);
const encryptedUserKey = await this.encryptService.rsaEncrypt(userKey.toEncoded(), publicKey);
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
resetRequest.masterPasswordHash = masterKeyHash;

View File

@@ -117,7 +117,9 @@ describe("AuthRequestService", () => {
});
it("should use the user key if the master key and hash do not exist", async () => {
keyService.getUserKey.mockResolvedValueOnce({ key: new Uint8Array(64) } as UserKey);
keyService.getUserKey.mockResolvedValueOnce(
new SymmetricCryptoKey(new Uint8Array(64)) as UserKey,
);
await sut.approveOrDenyAuthRequest(
true,

View File

@@ -117,7 +117,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
keyToEncrypt = (masterKey.inner() as Aes256CbcKey).encryptionKey;
} else {
const userKey = await this.keyService.getUserKey();
keyToEncrypt = userKey.key;
keyToEncrypt = userKey.toEncoded();
}
const encryptedKey = await this.encryptService.rsaEncrypt(keyToEncrypt, pubKey);

View File

@@ -10,7 +10,10 @@ import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/ke
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { EncString, EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import {
Aes256CbcKey,
SymmetricCryptoKey,
} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import {
PIN_DISK,
PIN_MEMORY,
@@ -193,7 +196,7 @@ export class PinService implements PinServiceAbstraction {
const pinKey = await this.makePinKey(pin, email, kdfConfig);
return await this.encryptService.encrypt(userKey.key, pinKey);
return await this.encryptService.encrypt(userKey.toEncoded(), pinKey);
}
async storePinKeyEncryptedUserKey(
@@ -258,7 +261,7 @@ export class PinService implements PinServiceAbstraction {
async makePinKey(pin: string, salt: string, kdfConfig: KdfConfig): Promise<PinKey> {
const pinKey = await this.keyGenerationService.deriveKeyFromPassword(pin, salt, kdfConfig);
return (await this.keyGenerationService.stretchKey(pinKey)) as PinKey;
return (await this.keyGenerationService.stretchKey(pinKey.inner() as Aes256CbcKey)) as PinKey;
}
async getPinLockType(userId: UserId): Promise<PinLockType> {

View File

@@ -189,7 +189,7 @@ describe("PinService", () => {
await sut.createPinKeyEncryptedUserKey(mockPin, mockUserKey, mockUserId);
// Assert
expect(encryptService.encrypt).toHaveBeenCalledWith(mockUserKey.key, mockPinKey);
expect(encryptService.encrypt).toHaveBeenCalledWith(mockUserKey.toEncoded(), mockPinKey);
});
});
@@ -327,7 +327,7 @@ describe("PinService", () => {
mockUserEmail,
DEFAULT_KDF_CONFIG,
);
expect(keyGenerationService.stretchKey).toHaveBeenCalledWith(mockPinKey);
expect(keyGenerationService.stretchKey).toHaveBeenCalledWith(mockPinKey.inner());
});
});
@@ -499,7 +499,7 @@ describe("PinService", () => {
async function mockDecryptAndMigrateOldPinKeyEncryptedMasterKeyFn() {
sut.makePinKey = jest.fn().mockResolvedValue(mockPinKey);
encryptService.decryptToBytes.mockResolvedValue(mockMasterKey.key);
encryptService.decryptToBytes.mockResolvedValue(mockMasterKey.toEncoded());
stateService.getEncryptedCryptoSymmetricKey.mockResolvedValue(mockUserKey.keyB64);
masterPasswordService.mock.decryptUserKeyWithMasterKey.mockResolvedValue(mockUserKey);
@@ -521,7 +521,7 @@ describe("PinService", () => {
.fn()
.mockResolvedValue(pinKeyEncryptedUserKeyPersistant);
sut.makePinKey = jest.fn().mockResolvedValue(mockPinKey);
encryptService.decryptToBytes.mockResolvedValue(mockUserKey.key);
encryptService.decryptToBytes.mockResolvedValue(mockUserKey.toEncoded());
}
function mockPinEncryptedKeyDataByPinLockType(

View File

@@ -156,7 +156,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
deviceKeyEncryptedDevicePrivateKey,
] = await Promise.all([
// Encrypt user key with the DevicePublicKey
this.encryptService.rsaEncrypt(userKey.key, devicePublicKey),
this.encryptService.rsaEncrypt(userKey.toEncoded(), devicePublicKey),
// Encrypt devicePublicKey with user key
this.encryptService.encrypt(devicePublicKey, userKey),
@@ -224,7 +224,7 @@ export class DeviceTrustService implements DeviceTrustServiceAbstraction {
// Encrypt the brand new user key with the now-decrypted public key for the device
const encryptedNewUserKey = await this.encryptService.rsaEncrypt(
newUserKey.key,
newUserKey.toEncoded(),
decryptedDevicePublicKey,
);

View File

@@ -731,8 +731,8 @@ describe("deviceTrustService", () => {
// Mock the decryption of the public key with the old user key
encryptService.decryptToBytes.mockImplementationOnce((_encValue, privateKeyValue) => {
expect(privateKeyValue.key.byteLength).toBe(64);
expect(new Uint8Array(privateKeyValue.key)[0]).toBe(FakeOldUserKeyMarker);
expect(privateKeyValue.inner().type).toBe(EncryptionType.AesCbc256_HmacSha256_B64);
expect(new Uint8Array(privateKeyValue.toEncoded())[0]).toBe(FakeOldUserKeyMarker);
const data = new Uint8Array(250);
data.fill(FakeDecryptedPublicKeyMarker, 0, 1);
return Promise.resolve(data);
@@ -752,7 +752,7 @@ describe("deviceTrustService", () => {
expect(plainValue).toBeInstanceOf(Uint8Array);
expect(new Uint8Array(plainValue as Uint8Array)[0]).toBe(FakeDecryptedPublicKeyMarker);
expect(new Uint8Array(key.key)[0]).toBe(FakeNewUserKeyMarker);
expect(new Uint8Array(key.toEncoded())[0]).toBe(FakeNewUserKeyMarker);
return Promise.resolve(
new EncString("2.ZW5jcnlwdGVkcHVibGlj|ZW5jcnlwdGVkcHVibGlj|ZW5jcnlwdGVkcHVibGlj"),
);

View File

@@ -8,7 +8,10 @@ import { LogService } from "../../../platform/abstractions/log.service";
import { StateService } from "../../../platform/abstractions/state.service";
import { EncryptionType } from "../../../platform/enums";
import { EncryptedString, EncString } from "../../../platform/models/domain/enc-string";
import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key";
import {
Aes256CbcKey,
SymmetricCryptoKey,
} from "../../../platform/models/domain/symmetric-crypto-key";
import {
MASTER_PASSWORD_DISK,
MASTER_PASSWORD_MEMORY,
@@ -185,7 +188,7 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr
"Content: User Key; Encrypting Key: Master Key",
);
} else if (userKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) {
const newKey = await this.keyGenerationService.stretchKey(masterKey);
const newKey = await this.keyGenerationService.stretchKey(masterKey.inner() as Aes256CbcKey);
decUserKey = await this.encryptService.decryptToBytes(
userKey,
newKey,

View File

@@ -2,6 +2,8 @@ import { mock, MockProxy } from "jest-mock-extended";
import { BehaviorSubject } from "rxjs";
import { OrganizationUserApiService } from "@bitwarden/admin-console/common";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { UserKey } from "@bitwarden/common/types/key";
import { KeyService } from "@bitwarden/key-management";
import { OrganizationApiServiceAbstraction } from "../../admin-console/abstractions/organization/organization-api.service.abstraction";
@@ -99,7 +101,9 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
};
activeAccountSubject.next(Object.assign(user1AccountInfo, { id: "userId" as UserId }));
keyService.getUserKey.mockResolvedValue({ key: "key" } as any);
keyService.getUserKey.mockResolvedValue(
new SymmetricCryptoKey(new Uint8Array(64)) as UserKey,
);
encryptService.rsaEncrypt.mockResolvedValue(encryptedKey as any);
await service.enroll("orgId");
@@ -124,7 +128,11 @@ describe("PasswordResetEnrollmentServiceImplementation", () => {
organizationApiService.getKeys.mockResolvedValue(orgKeyResponse as any);
encryptService.rsaEncrypt.mockResolvedValue(encryptedKey as any);
await service.enroll("orgId", "userId", { key: "key" } as any);
await service.enroll(
"orgId",
"userId",
new SymmetricCryptoKey(new Uint8Array(64)) as UserKey,
);
expect(
organizationUserApiService.putOrganizationUserResetPasswordEnrollment,

View File

@@ -51,7 +51,7 @@ export class PasswordResetEnrollmentServiceImplementation
userId ?? (await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))));
userKey = userKey ?? (await this.keyService.getUserKey(userId));
// RSA Encrypt user's userKey.key with organization public key
const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, orgPublicKey);
const encryptedKey = await this.encryptService.rsaEncrypt(userKey.toEncoded(), orgPublicKey);
const resetRequest = new OrganizationUserResetPasswordEnrollmentRequest();
resetRequest.resetPasswordKey = encryptedKey.encryptedString;

View File

@@ -1,5 +1,7 @@
import { mock, MockProxy } from "jest-mock-extended";
import { EncryptionType } from "@bitwarden/common/platform/enums";
import { CryptoFunctionService } from "../../../platform/abstractions/crypto-function.service";
import { WebAuthnLoginPrfKeyService } from "./webauthn-login-prf-key.service";
@@ -21,7 +23,7 @@ describe("WebAuthnLoginPrfKeyService", () => {
const result = await service.createSymmetricKeyFromPrf(randomBytes(32));
expect(result.key.length).toBe(64);
expect(result.inner().type).toBe(EncryptionType.AesCbc256_HmacSha256_B64);
});
});
});

View File

@@ -1,7 +1,7 @@
import { KdfConfig } from "@bitwarden/key-management";
import { CsprngArray } from "../../types/csprng";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
import { Aes256CbcKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
export abstract class KeyGenerationService {
/**
@@ -60,5 +60,5 @@ export abstract class KeyGenerationService {
* @param key 32 byte key.
* @returns 64 byte derived key.
*/
abstract stretchKey(key: SymmetricCryptoKey): Promise<SymmetricCryptoKey>;
abstract stretchKey(key: Aes256CbcKey): Promise<SymmetricCryptoKey>;
}

View File

@@ -19,7 +19,6 @@ describe("SymmetricCryptoKey", () => {
const cryptoKey = new SymmetricCryptoKey(key);
expect(cryptoKey).toEqual({
key: key,
keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
innerKey: {
type: EncryptionType.AesCbc256_B64,
@@ -33,7 +32,6 @@ describe("SymmetricCryptoKey", () => {
const cryptoKey = new SymmetricCryptoKey(key);
expect(cryptoKey).toEqual({
key: key,
keyB64:
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==",
innerKey: {

View File

@@ -24,7 +24,6 @@ export type Aes256CbcKey = {
export class SymmetricCryptoKey {
private innerKey: Aes256CbcHmacKey | Aes256CbcKey;
key: Uint8Array;
keyB64: string;
/**
@@ -40,7 +39,6 @@ export class SymmetricCryptoKey {
type: EncryptionType.AesCbc256_B64,
encryptionKey: key,
};
this.key = key;
this.keyB64 = this.toBase64();
} else if (key.byteLength === 64) {
this.innerKey = {
@@ -48,7 +46,6 @@ export class SymmetricCryptoKey {
encryptionKey: key.slice(0, 32),
authenticationKey: key.slice(32),
};
this.key = key;
this.keyB64 = this.toBase64();
} else {
throw new Error(`Unsupported encType/key length ${key.byteLength}`);

View File

@@ -4,6 +4,7 @@ import { PBKDF2KdfConfig, Argon2KdfConfig } from "@bitwarden/key-management";
import { CsprngArray } from "../../types/csprng";
import { CryptoFunctionService } from "../abstractions/crypto-function.service";
import { EncryptionType } from "../enums";
import { KeyGenerationService } from "./key-generation.service";
@@ -52,7 +53,7 @@ describe("KeyGenerationService", () => {
expect(salt).toEqual(inputSalt);
expect(material).toEqual(inputMaterial);
expect(derivedKey.key.length).toEqual(64);
expect(derivedKey.inner().type).toEqual(EncryptionType.AesCbc256_HmacSha256_B64);
},
);
});
@@ -67,7 +68,7 @@ describe("KeyGenerationService", () => {
const key = await sut.deriveKeyFromMaterial(material, salt, purpose);
expect(key.key.length).toEqual(64);
expect(key.inner().type).toEqual(EncryptionType.AesCbc256_HmacSha256_B64);
});
});
@@ -81,7 +82,7 @@ describe("KeyGenerationService", () => {
const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig);
expect(key.key.length).toEqual(32);
expect(key.inner().type).toEqual(EncryptionType.AesCbc256_B64);
});
it("should derive a 32 byte key from a password using argon2id", async () => {
@@ -94,7 +95,7 @@ describe("KeyGenerationService", () => {
const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig);
expect(key.key.length).toEqual(32);
expect(key.inner().type).toEqual(EncryptionType.AesCbc256_B64);
});
});
});

View File

@@ -6,7 +6,7 @@ import { CsprngArray } from "../../types/csprng";
import { CryptoFunctionService } from "../abstractions/crypto-function.service";
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "../abstractions/key-generation.service";
import { Utils } from "../misc/utils";
import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
import { Aes256CbcKey, SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key";
export class KeyGenerationService implements KeyGenerationServiceAbstraction {
constructor(private cryptoFunctionService: CryptoFunctionService) {}
@@ -78,10 +78,20 @@ export class KeyGenerationService implements KeyGenerationServiceAbstraction {
return new SymmetricCryptoKey(key);
}
async stretchKey(key: SymmetricCryptoKey): Promise<SymmetricCryptoKey> {
async stretchKey(key: Aes256CbcKey): Promise<SymmetricCryptoKey> {
const newKey = new Uint8Array(64);
const encKey = await this.cryptoFunctionService.hkdfExpand(key.key, "enc", 32, "sha256");
const macKey = await this.cryptoFunctionService.hkdfExpand(key.key, "mac", 32, "sha256");
const encKey = await this.cryptoFunctionService.hkdfExpand(
key.encryptionKey,
"enc",
32,
"sha256",
);
const macKey = await this.cryptoFunctionService.hkdfExpand(
key.encryptionKey,
"mac",
32,
"sha256",
);
newKey.set(new Uint8Array(encKey));
newKey.set(new Uint8Array(macKey), 32);

View File

@@ -271,7 +271,7 @@ export class CipherService implements CipherServiceAbstraction {
key,
).then(async () => {
if (model.key != null) {
attachment.key = await this.encryptService.encrypt(model.key.key, key);
attachment.key = await this.encryptService.encrypt(model.key.toEncoded(), key);
}
encAttachments.push(attachment);
});
@@ -1812,7 +1812,7 @@ export class CipherService implements CipherServiceAbstraction {
// Then, we have to encrypt the cipher key with the proper key.
cipher.key = await this.encryptService.encrypt(
decryptedCipherKey.key,
decryptedCipherKey.toEncoded(),
keyForCipherKeyEncryption,
);

View File

@@ -505,7 +505,7 @@ describe("keyService", () => {
const output = new Uint8Array(64);
output.set(encryptedPrivateKey.dataBytes);
output.set(
key.key.subarray(0, 64 - encryptedPrivateKey.dataBytes.length),
key.toEncoded().subarray(0, 64 - encryptedPrivateKey.dataBytes.length),
encryptedPrivateKey.dataBytes.length,
);
return output;
@@ -789,7 +789,7 @@ describe("keyService", () => {
masterPasswordService.masterKeyHashSubject.next(storedMasterKeyHash);
cryptoFunctionService.pbkdf2
.calledWith(masterKey.key, masterPassword as string, "sha256", 2)
.calledWith(masterKey.inner().encryptionKey, masterPassword as string, "sha256", 2)
.mockResolvedValue(Utils.fromB64ToArray(mockReturnedHash));
const actualDidMatch = await keyService.compareKeyHash(

View File

@@ -24,7 +24,7 @@ import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/ke
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { KeySuffixOptions, HashPurpose } from "@bitwarden/common/platform/enums";
import { KeySuffixOptions, HashPurpose, EncryptionType } from "@bitwarden/common/platform/enums";
import { convertValues } from "@bitwarden/common/platform/misc/convert-values";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EFFLongWordList } from "@bitwarden/common/platform/misc/wordlist";
@@ -232,7 +232,7 @@ export class DefaultKeyService implements KeyServiceAbstraction {
}
const newUserKey = await this.keyGenerationService.createKey(512);
return this.buildProtectedSymmetricKey(masterKey, newUserKey.key);
return this.buildProtectedSymmetricKey(masterKey, newUserKey);
}
/**
@@ -320,7 +320,7 @@ export class DefaultKeyService implements KeyServiceAbstraction {
userKey?: UserKey,
): Promise<[UserKey, EncString]> {
userKey ||= await this.getUserKey();
return await this.buildProtectedSymmetricKey(masterKey, userKey.key);
return await this.buildProtectedSymmetricKey(masterKey, userKey);
}
// TODO: move to MasterPasswordService
@@ -343,7 +343,12 @@ export class DefaultKeyService implements KeyServiceAbstraction {
}
const iterations = hashPurpose === HashPurpose.LocalAuthorization ? 2 : 1;
const hash = await this.cryptoFunctionService.pbkdf2(key.key, password, "sha256", iterations);
const hash = await this.cryptoFunctionService.pbkdf2(
key.inner().encryptionKey,
password,
"sha256",
iterations,
);
return Utils.fromBufferToB64(hash);
}
@@ -430,7 +435,7 @@ export class DefaultKeyService implements KeyServiceAbstraction {
}
const newSymKey = await this.keyGenerationService.createKey(512);
return this.buildProtectedSymmetricKey(key, newSymKey.key);
return this.buildProtectedSymmetricKey(key, newSymKey);
}
private async clearOrgKeys(userId: UserId): Promise<void> {
@@ -490,7 +495,7 @@ export class DefaultKeyService implements KeyServiceAbstraction {
throw new Error("No public key found.");
}
const encShareKey = await this.encryptService.rsaEncrypt(shareKey.key, publicKey);
const encShareKey = await this.encryptService.rsaEncrypt(shareKey.toEncoded(), publicKey);
return [encShareKey, shareKey as T];
}
@@ -821,19 +826,23 @@ export class DefaultKeyService implements KeyServiceAbstraction {
}
private async buildProtectedSymmetricKey<T extends SymmetricCryptoKey>(
encryptionKey: SymmetricCryptoKey,
newSymKey: Uint8Array,
protectingKey: SymmetricCryptoKey,
protectedKey: SymmetricCryptoKey,
): Promise<[T, EncString]> {
let protectedSymKey: EncString;
if (encryptionKey.key.byteLength === 32) {
const stretchedEncryptionKey = await this.keyGenerationService.stretchKey(encryptionKey);
protectedSymKey = await this.encryptService.encrypt(newSymKey, stretchedEncryptionKey);
} else if (encryptionKey.key.byteLength === 64) {
protectedSymKey = await this.encryptService.encrypt(newSymKey, encryptionKey);
const protectingKeyInner = protectingKey.inner();
if (protectingKeyInner.type === EncryptionType.AesCbc256_B64) {
const stretchedEncryptionKey = await this.keyGenerationService.stretchKey(protectingKeyInner);
protectedSymKey = await this.encryptService.encrypt(
protectedKey.toEncoded(),
stretchedEncryptionKey,
);
} else if (protectingKeyInner.type === EncryptionType.AesCbc256_HmacSha256_B64) {
protectedSymKey = await this.encryptService.encrypt(protectedKey.toEncoded(), protectingKey);
} else {
throw new Error("Invalid key size.");
throw new Error("Unsupported key type");
}
return [new SymmetricCryptoKey(newSymKey) as T, protectedSymKey];
return [new SymmetricCryptoKey(protectedKey.toEncoded()) as T, protectedSymKey];
}
// --LEGACY METHODS--