diff --git a/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts b/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts index 5f21d86bc6a..0359a9a0acc 100644 --- a/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts +++ b/libs/common/src/key-management/crypto/abstractions/encrypt.service.ts @@ -8,11 +8,11 @@ import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-cr export abstract class EncryptService { /** - * Encrypts a string or Uint8Array to an EncString + * Encrypts a string to an EncString * @param plainValue - The value to encrypt * @param key - The key to encrypt the value with */ - abstract encrypt(plainValue: string | Uint8Array, key: SymmetricCryptoKey): Promise; + abstract encrypt(plainValue: string, key: SymmetricCryptoKey): Promise; /** * Encrypts a value to a Uint8Array * @param plainValue - The value to encrypt @@ -77,6 +77,19 @@ export abstract class EncryptService { key: SymmetricCryptoKey, decryptTrace?: string, ): Promise; + /** + * Decrypts an encrypted file to a Uint8Array + * @param encryptedFileData - The Encrypted file data + * @param key - The key to decrypt the Encrypted object with + * @param decryptTrace - A string to identify the context of the object being decrypted. This can include: field name, encryption type, cipher id, key type, but should not include + * sensitive information like encryption keys or data. This is used for logging when decryption errors occur in order to identify what failed to decrypt + * @returns The decrypted Uint8Array + */ + abstract decryptFileData( + encryptedFileData: EncArrayBuffer, + key: SymmetricCryptoKey, + decryptTrace?: string, + ): Promise; /** * Encapsulates a symmetric key with an asymmetric public key diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts index f4318840515..3aa34d099fe 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts @@ -296,6 +296,22 @@ export class EncryptServiceImplementation implements EncryptService { } } + async decryptFileData( + encryptedFileData: EncArrayBuffer, + key: SymmetricCryptoKey, + decryptTrace?: string, + ): Promise { + if (key == null) { + throw new Error("No key provided for decryption."); + } + + if (encryptedFileData == null) { + throw new Error("No data provided for decryption."); + } + + return await this.decryptToBytes(encryptedFileData, key, decryptTrace); + } + async encapsulateKeyUnsigned( sharedKey: SymmetricCryptoKey, encapsulationKey: Uint8Array, diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts index 6b2851ad116..cd38ae73a9f 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts @@ -287,6 +287,32 @@ describe("EncryptService", () => { }); }); + describe("decryptFileData", () => { + it("throws if no key is provided", () => { + return expect(encryptService.decryptFileData(null, null)).rejects.toThrow( + "No key provided for decryption.", + ); + }); + it("throws if no data is provided", () => { + return expect( + encryptService.decryptFileData(null, new SymmetricCryptoKey(makeStaticByteArray(32))), + ).rejects.toThrow("No data provided for decryption."); + }); + it("calls decryptToBytes with the correct parameters", async () => { + const key = new SymmetricCryptoKey(makeStaticByteArray(32)); + const encBuffer = new EncArrayBuffer(makeStaticByteArray(60, EncryptionType.AesCbc256_B64)); + const decryptedBytes = makeStaticByteArray(10, 200); + + encryptService.decryptToBytes = jest.fn().mockResolvedValue(decryptedBytes); + + const actual = await encryptService.decryptFileData(encBuffer, key); + + expect(encryptService.decryptToBytes).toHaveBeenCalledWith(encBuffer, key, undefined); + + expect(actual).toEqualBuffer(decryptedBytes); + }); + }); + describe("decryptToBytes", () => { const encType = EncryptionType.AesCbc256_HmacSha256_B64; const key = new SymmetricCryptoKey(makeStaticByteArray(64, 100));