diff --git a/jslib/common/spec/domain/symmetricCryptoKey.spec.ts b/jslib/common/spec/domain/symmetricCryptoKey.spec.ts index 5d379129..6bd9def3 100644 --- a/jslib/common/spec/domain/symmetricCryptoKey.spec.ts +++ b/jslib/common/spec/domain/symmetricCryptoKey.spec.ts @@ -17,45 +17,48 @@ describe("SymmetricCryptoKey", () => { const key = makeStaticByteArray(32); const cryptoKey = new SymmetricCryptoKey(key); - expect(cryptoKey).toEqual({ - encKey: key, - encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - encType: 0, - key: key, - keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - macKey: null, - }); + expect(cryptoKey.encType).toBe(0); + expect(cryptoKey.keyB64).toBe("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="); + expect(cryptoKey.encKeyB64).toBe("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="); + expect(cryptoKey.macKey).toBeNull(); + expect(cryptoKey.key).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.encKey).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.key.byteLength).toBe(32); + expect(cryptoKey.encKey.byteLength).toBe(32); }); it("AesCbc128_HmacSha256_B64", () => { const key = makeStaticByteArray(32); const cryptoKey = new SymmetricCryptoKey(key, EncryptionType.AesCbc128_HmacSha256_B64); - expect(cryptoKey).toEqual({ - encKey: key.slice(0, 16), - encKeyB64: "AAECAwQFBgcICQoLDA0ODw==", - encType: 1, - key: key, - keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - macKey: key.slice(16, 32), - macKeyB64: "EBESExQVFhcYGRobHB0eHw==", - }); + // After TS 5.9 upgrade, properties are ArrayBuffer not Uint8Array + expect(cryptoKey.encType).toBe(1); + expect(cryptoKey.keyB64).toBe("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="); + expect(cryptoKey.encKeyB64).toBe("AAECAwQFBgcICQoLDA0ODw=="); + expect(cryptoKey.macKeyB64).toBe("EBESExQVFhcYGRobHB0eHw=="); + expect(cryptoKey.key).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.encKey).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.macKey).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.key.byteLength).toBe(32); + expect(cryptoKey.encKey.byteLength).toBe(16); + expect(cryptoKey.macKey.byteLength).toBe(16); }); it("AesCbc256_HmacSha256_B64", () => { const key = makeStaticByteArray(64); const cryptoKey = new SymmetricCryptoKey(key); - expect(cryptoKey).toEqual({ - encKey: key.slice(0, 32), - encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - encType: 2, - key: key, - keyB64: - "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==", - macKey: key.slice(32, 64), - macKeyB64: "ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8=", - }); + // After TS 5.9 upgrade, properties are ArrayBuffer not Uint8Array + expect(cryptoKey.encType).toBe(2); + expect(cryptoKey.keyB64).toBe("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw=="); + expect(cryptoKey.encKeyB64).toBe("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="); + expect(cryptoKey.macKeyB64).toBe("ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8="); + expect(cryptoKey.key).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.encKey).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.macKey).toBeInstanceOf(ArrayBuffer); + expect(cryptoKey.key.byteLength).toBe(64); + expect(cryptoKey.encKey.byteLength).toBe(32); + expect(cryptoKey.macKey.byteLength).toBe(32); }); it("unknown length", () => { diff --git a/jslib/common/src/misc/utils.ts b/jslib/common/src/misc/utils.ts index 00aa62a1..38a83960 100644 --- a/jslib/common/src/misc/utils.ts +++ b/jslib/common/src/misc/utils.ts @@ -92,7 +92,11 @@ class Utils { static fromBufferToB64(buffer: BufferSource): string { if (Utils.isNode) { - return Buffer.from(buffer as ArrayBuffer).toString("base64"); + if (ArrayBuffer.isView(buffer)) { + return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength).toString("base64"); + } else { + return Buffer.from(buffer).toString("base64"); + } } else { let binary = ""; const bytes = ArrayBuffer.isView(buffer) ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) : new Uint8Array(buffer); diff --git a/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts b/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts index 812bc92f..f6007066 100644 --- a/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts +++ b/jslib/node/spec/services/nodeCryptoFunction.service.spec.ts @@ -95,7 +95,7 @@ describe("NodeCrypto Function Service", () => { const cryptoFunctionService = new NodeCryptoFunctionService(); const prk = Utils.fromB64ToArray(prk16Byte); const f = cryptoFunctionService.hkdfExpand( - prk.buffer as ArrayBuffer, + prk.buffer, "info", 32, "sha256", @@ -107,7 +107,7 @@ describe("NodeCrypto Function Service", () => { const cryptoFunctionService = new NodeCryptoFunctionService(); const prk = Utils.fromB64ToArray(prk32Byte); const f = cryptoFunctionService.hkdfExpand( - prk.buffer as ArrayBuffer, + prk.buffer, "info", 8161, "sha256", @@ -181,16 +181,16 @@ describe("NodeCrypto Function Service", () => { it("should successfully encrypt and then decrypt data", async () => { const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); + const iv = makeStaticByteArray(16).buffer; + const key = makeStaticByteArray(32).buffer; const value = "EncryptMe!"; - const data = Utils.fromUtf8ToArray(value); + const data = Utils.fromUtf8ToArray(value).buffer; const encValue = await nodeCryptoFunctionService.aesEncrypt( - data.buffer, - iv.buffer, - key.buffer, + data, + iv, + key ); - const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv.buffer, key.buffer); + const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv, key); expect(Utils.fromBufferToUtf8(decValue)).toBe(value); }); }); @@ -198,8 +198,9 @@ describe("NodeCrypto Function Service", () => { describe("aesDecryptFast", () => { it("should successfully decrypt data", async () => { const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = Utils.fromBufferToB64(makeStaticByteArray(16).buffer); - const symKey = new SymmetricCryptoKey(makeStaticByteArray(32).buffer); + const ivArray = makeStaticByteArray(16); + const iv = Utils.fromBufferToB64(ivArray); + const symKey = new SymmetricCryptoKey(makeStaticByteArray(32)); const data = "ByUF8vhyX4ddU9gcooznwA=="; const params = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey); const decValue = await nodeCryptoFunctionService.aesDecryptFast(params); @@ -210,13 +211,13 @@ describe("NodeCrypto Function Service", () => { describe("aesDecrypt", () => { it("should successfully decrypt data", async () => { const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const iv = makeStaticByteArray(16); - const key = makeStaticByteArray(32); - const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA=="); + const iv = makeStaticByteArray(16).buffer; + const key = makeStaticByteArray(32).buffer; + const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA==").buffer; const decValue = await nodeCryptoFunctionService.aesDecrypt( - data.buffer, - iv.buffer, - key.buffer, + data, + iv, + key, ); expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!"); }); @@ -226,7 +227,7 @@ describe("NodeCrypto Function Service", () => { it("should successfully encrypt and then decrypt data", async () => { const nodeCryptoFunctionService = new NodeCryptoFunctionService(); const pubKey = Utils.fromB64ToArray(RsaPublicKey); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); + const privKey = Utils.fromB64ToArray(RsaPrivateKey).buffer; const value = "EncryptMe!"; const data = Utils.fromUtf8ToArray(value); const encValue = await nodeCryptoFunctionService.rsaEncrypt( @@ -234,7 +235,7 @@ describe("NodeCrypto Function Service", () => { pubKey.buffer, "sha1", ); - const decValue = await nodeCryptoFunctionService.rsaDecrypt(encValue, privKey.buffer, "sha1"); + const decValue = await nodeCryptoFunctionService.rsaDecrypt(encValue, privKey, "sha1"); expect(Utils.fromBufferToUtf8(decValue)).toBe(value); }); }); @@ -261,8 +262,8 @@ describe("NodeCrypto Function Service", () => { describe("rsaExtractPublicKey", () => { it("should successfully extract key", async () => { const nodeCryptoFunctionService = new NodeCryptoFunctionService(); - const privKey = Utils.fromB64ToArray(RsaPrivateKey); - const publicKey = await nodeCryptoFunctionService.rsaExtractPublicKey(privKey.buffer); + const privKey = Utils.fromB64ToArray(RsaPrivateKey).buffer; + const publicKey = await nodeCryptoFunctionService.rsaExtractPublicKey(privKey); expect(Utils.fromBufferToB64(publicKey)).toBe(RsaPublicKey); }); }); @@ -343,8 +344,7 @@ function testHkdf( utf8Key: string, unicodeKey: string, ) { - const ikmArray = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ=="); - const ikm = ikmArray.buffer as ArrayBuffer; + const ikm = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ=="); const regularSalt = "salt"; const utf8Salt = "üser_salt"; @@ -356,26 +356,26 @@ function testHkdf( it("should create valid " + algorithm + " key from regular input", async () => { const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, regularSalt, regularInfo, 32, algorithm); + const key = await cryptoFunctionService.hkdf(ikm.buffer, regularSalt, regularInfo, 32, algorithm); expect(Utils.fromBufferToB64(key)).toBe(regularKey); }); it("should create valid " + algorithm + " key from utf8 input", async () => { const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, utf8Salt, utf8Info, 32, algorithm); + const key = await cryptoFunctionService.hkdf(ikm.buffer, utf8Salt, utf8Info, 32, algorithm); expect(Utils.fromBufferToB64(key)).toBe(utf8Key); }); it("should create valid " + algorithm + " key from unicode input", async () => { const cryptoFunctionService = new NodeCryptoFunctionService(); - const key = await cryptoFunctionService.hkdf(ikm, unicodeSalt, unicodeInfo, 32, algorithm); + const key = await cryptoFunctionService.hkdf(ikm.buffer, unicodeSalt, unicodeInfo, 32, algorithm); expect(Utils.fromBufferToB64(key)).toBe(unicodeKey); }); it("should create valid " + algorithm + " key from array buffer input", async () => { const cryptoFunctionService = new NodeCryptoFunctionService(); const key = await cryptoFunctionService.hkdf( - ikm, + ikm.buffer, Utils.fromUtf8ToArray(regularSalt).buffer, Utils.fromUtf8ToArray(regularInfo).buffer, 32, @@ -397,7 +397,7 @@ function testHkdfExpand( const cryptoFunctionService = new NodeCryptoFunctionService(); const prk = Utils.fromB64ToArray(b64prk); const okm = await cryptoFunctionService.hkdfExpand( - prk.buffer as ArrayBuffer, + prk.buffer, info, outputByteSize, algorithm, diff --git a/jslib/node/src/services/nodeCryptoFunction.service.ts b/jslib/node/src/services/nodeCryptoFunction.service.ts index 48d9e88f..8e45cb70 100644 --- a/jslib/node/src/services/nodeCryptoFunction.service.ts +++ b/jslib/node/src/services/nodeCryptoFunction.service.ts @@ -147,19 +147,22 @@ export class NodeCryptoFunctionService implements CryptoFunctionService { ): DecryptParameters { const p = new DecryptParameters(); p.encKey = key.encKey; - p.data = Utils.fromB64ToArray(data).buffer; - p.iv = Utils.fromB64ToArray(iv).buffer; + const dataArr = Utils.fromB64ToArray(data); + p.data = dataArr.buffer.slice(dataArr.byteOffset, dataArr.byteOffset + dataArr.byteLength) as ArrayBuffer; + const ivArr = Utils.fromB64ToArray(iv); + p.iv = ivArr.buffer.slice(ivArr.byteOffset, ivArr.byteOffset + ivArr.byteLength) as ArrayBuffer; const macData = new Uint8Array(p.iv.byteLength + p.data.byteLength); macData.set(new Uint8Array(p.iv), 0); macData.set(new Uint8Array(p.data), p.iv.byteLength); - p.macData = macData.buffer; + p.macData = macData.buffer.slice(macData.byteOffset, macData.byteOffset + macData.byteLength) as ArrayBuffer; if (key.macKey != null) { p.macKey = key.macKey; } if (mac != null) { - p.mac = Utils.fromB64ToArray(mac).buffer; + const macArr = Utils.fromB64ToArray(mac); + p.mac = macArr.buffer.slice(macArr.byteOffset, macArr.byteOffset + macArr.byteLength) as ArrayBuffer; } return p; @@ -277,9 +280,12 @@ export class NodeCryptoFunctionService implements CryptoFunctionService { private toArrayBuffer(value: Buffer | string | ArrayBuffer): ArrayBuffer { let buf: ArrayBuffer; if (typeof value === "string") { - buf = Utils.fromUtf8ToArray(value).buffer; + const arr = Utils.fromUtf8ToArray(value); + buf = arr.buffer.slice(arr.byteOffset, arr.byteOffset + arr.byteLength) as ArrayBuffer; + } else if (Buffer.isBuffer(value)) { + buf = value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength) as ArrayBuffer; } else { - buf = new Uint8Array(value).buffer; + buf = value; } return buf; } diff --git a/scripts/notarize.js b/scripts/notarize.js index cc51e576..351086ed 100644 --- a/scripts/notarize.js +++ b/scripts/notarize.js @@ -1,10 +1,9 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ import { notarize } from "@electron/notarize"; import { config } from "dotenv"; config(); -exports.default = async function notarizing(context) { +export default async function notarizing(context) { const { electronPlatformName, appOutDir } = context; if (electronPlatformName !== "darwin") { return; @@ -35,4 +34,4 @@ exports.default = async function notarizing(context) { appleIdPassword: appleIdPassword, }); } -}; +} diff --git a/scripts/sign.js b/scripts/sign.js index 985167e1..ab195331 100644 --- a/scripts/sign.js +++ b/scripts/sign.js @@ -1,8 +1,11 @@ -/* eslint-disable @typescript-eslint/no-var-requires, no-console */ +/* eslint-disable no-console */ import { execSync } from "child_process"; -exports.default = async function (configuration) { - if (parseInt(process.env.ELECTRON_BUILDER_SIGN) === 1 && configuration.path.slice(-4) == ".exe") { +export default async function (configuration) { + if ( + parseInt(process.env.ELECTRON_BUILDER_SIGN) === 1 && + configuration.path.slice(-4) === ".exe" + ) { console.log(`[*] Signing file: ${configuration.path}`); execSync( `azuresigntool sign ` + @@ -20,4 +23,4 @@ exports.default = async function (configuration) { }, ); } -}; +}