UNPKG

cloudworker-proxy

Version:
181 lines (180 loc) 10.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const assert = require("assert"); const pvtsutils_1 = require("pvtsutils"); const webcrypto_core_1 = require("webcrypto-core"); function isKeyEqual(a, b) { if (a instanceof webcrypto_core_1.CryptoKey && b instanceof webcrypto_core_1.CryptoKey) { return a.data.equals(b.data); } return false; } exports.isKeyEqual = isKeyEqual; async function getKeys(crypto, key) { const keys = {}; if ("privateKey" in key) { keys.privateKey = await crypto.subtle.importKey(key.privateKey.format, key.privateKey.data, key.privateKey.algorithm, key.privateKey.extractable, key.privateKey.keyUsages); keys.publicKey = await crypto.subtle.importKey(key.publicKey.format, key.publicKey.data, key.publicKey.algorithm, key.publicKey.extractable, key.publicKey.keyUsages); } else { keys.privateKey = keys.publicKey = await crypto.subtle.importKey(key.format, key.data, key.algorithm, key.extractable, key.keyUsages); } return keys; } async function wrapTest(promise, action, index) { const test = action.skip ? it.skip : action.only ? it.only : it; test(action.name || `#${index + 1}`, async () => { if (action.error) { await assert.rejects(promise(), action.error); } else { await promise(); } }); } function testCrypto(crypto, params) { params.forEach((param) => { context(param.name, () => { if (param.actions.generateKey) { context("Generate Key", () => { param.actions.generateKey.forEach((action, index) => { wrapTest(async () => { const algorithm = Object.assign({}, action.algorithm); algorithm.name = algorithm.name.toLowerCase(); const key = await crypto.subtle.generateKey(algorithm, action.extractable, action.keyUsages); assert(key); if (key instanceof webcrypto_core_1.CryptoKey) { assert.equal(key.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); assert.equal(key.extractable, action.extractable); assert.deepEqual(key.usages, action.keyUsages); } else { assert(key.privateKey); assert.equal(key.privateKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); assert.equal(key.privateKey.extractable, action.extractable); assert(key.publicKey); assert.equal(key.publicKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); assert.equal(key.publicKey.extractable, true); } }, action, index); }); }); } if (param.actions.encrypt) { context("Encrypt/Decrypt", () => { param.actions.encrypt.forEach((action, index) => { wrapTest(async () => { const keys = await getKeys(crypto, action.key); const encKey = keys.publicKey; const decKey = keys.privateKey; const algorithm = Object.assign({}, action.algorithm); algorithm.name = algorithm.name.toLowerCase(); const enc = await crypto.subtle.encrypt(algorithm, encKey, action.data); let dec = await crypto.subtle.decrypt(algorithm, decKey, enc); assert.equal(pvtsutils_1.Convert.ToHex(dec), pvtsutils_1.Convert.ToHex(action.data)); dec = await crypto.subtle.decrypt(algorithm, decKey, action.encData); assert.equal(pvtsutils_1.Convert.ToHex(dec), pvtsutils_1.Convert.ToHex(action.data)); }, action, index); }); }); } if (param.actions.import) { context("Import/Export", () => { param.actions.import.forEach((action, index) => { wrapTest(async () => { const importedKey = await crypto.subtle.importKey(action.format, action.data, action.algorithm, action.extractable, action.keyUsages); const exportedData = await crypto.subtle.exportKey(action.format, importedKey); if (action.format === "jwk") { assert.deepEqual(exportedData, action.data); } else { assert.equal(Buffer.from(exportedData).toString("hex"), Buffer.from(action.data).toString("hex")); } }, action, index); }); }); } if (param.actions.sign) { context("Sign/Verify", () => { param.actions.sign.forEach((action, index) => { wrapTest(async () => { const keys = await getKeys(crypto, action.key); const verifyKey = keys.publicKey; const signKey = keys.privateKey; const algorithm = Object.assign({}, action.algorithm); algorithm.name = algorithm.name.toLowerCase(); const signature = await crypto.subtle.sign(algorithm, signKey, action.data); let ok = await crypto.subtle.verify(algorithm, verifyKey, signature, action.data); assert.equal(true, ok, "Cannot verify signature from Action data"); ok = await crypto.subtle.verify(algorithm, verifyKey, action.signature, action.data); if (!ok) { assert.equal(pvtsutils_1.Convert.ToHex(signature), pvtsutils_1.Convert.ToHex(action.signature)); } assert.equal(true, ok); }, action, index); }); }); } if (param.actions.deriveBits) { context("Derive bits", () => { param.actions.deriveBits.forEach((action, index) => { wrapTest(async () => { const keys = await getKeys(crypto, action.key); const algorithm = Object.assign({}, action.algorithm, { public: keys.publicKey }); algorithm.name = algorithm.name.toLowerCase(); const derivedBits = await crypto.subtle.deriveBits(algorithm, keys.privateKey, action.length); assert.equal(pvtsutils_1.Convert.ToHex(derivedBits), pvtsutils_1.Convert.ToHex(action.data)); }, action, index); }); }); } if (param.actions.deriveKey) { context("Derive key", () => { param.actions.deriveKey.forEach((action, index) => { wrapTest(async () => { const keys = await getKeys(crypto, action.key); const algorithm = Object.assign({}, action.algorithm, { public: keys.publicKey }); algorithm.name = algorithm.name.toLowerCase(); const derivedKey = await crypto.subtle.deriveKey(algorithm, keys.privateKey, action.derivedKeyType, true, action.keyUsages); const keyData = await crypto.subtle.exportKey(action.format, derivedKey); if (action.format === "jwk") { assert.deepEqual(keyData, action.keyData); } else { assert.equal(pvtsutils_1.Convert.ToHex(keyData), pvtsutils_1.Convert.ToHex(action.keyData)); } }, action, index); }); }); } if (param.actions.digest) { context("Digest", () => { param.actions.digest.forEach((action, index) => { wrapTest(async () => { const hash = await crypto.subtle.digest(action.algorithm, action.data); assert.equal(pvtsutils_1.Convert.ToHex(hash), pvtsutils_1.Convert.ToHex(action.hash)); }, action, index); }); }); } if (param.actions.wrapKey) { context("Wrap/Unwrap key", () => { param.actions.wrapKey.forEach((action, index) => { wrapTest(async () => { const wKey = (await getKeys(crypto, action.wKey)).privateKey; const key = await getKeys(crypto, action.key); const wrappedKey = await crypto.subtle.wrapKey(action.wKey.format, wKey, key.publicKey, action.algorithm); const unwrappedKey = await crypto.subtle.unwrapKey(action.wKey.format, wrappedKey, key.privateKey, action.algorithm, action.wKey.algorithm, action.wKey.extractable, action.wKey.keyUsages); assert.deepEqual(unwrappedKey.algorithm, wKey.algorithm); }, action, index); }); }); } }); }); } exports.testCrypto = testCrypto;