cloudworker-proxy
Version:
An api gateway for cloudflare workers
181 lines (180 loc) • 10.2 kB
JavaScript
;
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;