From a7cdb095d23c3af402d02a347fe8fd2b1ede0d0b Mon Sep 17 00:00:00 2001 From: MikeCAT Date: Mon, 4 Oct 2021 22:39:16 +0900 Subject: [PATCH 01/39] Added input validation to fromBase64() --- src/core/lib/Base64.mjs | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/core/lib/Base64.mjs b/src/core/lib/Base64.mjs index d9452575..c96e579e 100644 --- a/src/core/lib/Base64.mjs +++ b/src/core/lib/Base64.mjs @@ -95,6 +95,7 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r const output = []; let chr1, chr2, chr3, + encChr1, encChr2, encChr3, encChr4, enc1, enc2, enc3, enc4, i = 0; @@ -103,15 +104,39 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r data = data.replace(re, ""); } - while (i < data.length) { - enc1 = alphabet.indexOf(data.charAt(i++)); - enc2 = alphabet.indexOf(data.charAt(i++) || "="); - enc3 = alphabet.indexOf(data.charAt(i++) || "="); - enc4 = alphabet.indexOf(data.charAt(i++) || "="); + if (data.length % 4 === 1) { + throw new OperationError(`Invalid Base64 input length (${data.length}): it won't be 4n+1`); + } - enc2 = enc2 === -1 ? 64 : enc2; - enc3 = enc3 === -1 ? 64 : enc3; - enc4 = enc4 === -1 ? 64 : enc4; + if (alphabet.length === 65) { + const pad = alphabet.charAt(64); + const padPos = data.indexOf(pad); + if (padPos >= 0) { + // padding character should appear only at the end of the input + // there should be only one or two padding character(s) if it exists + if (padPos < data.length - 2 || data.charAt(data.length - 1) !== pad) { + throw new OperationError("Invalid Base64 input: padding character misused"); + } + if (data.length % 4 !== 0) { + throw new OperationError("Invalid Base64 input: padded not to multiple of 4"); + } + } + } + + while (i < data.length) { + encChr1 = data.charAt(i++); + encChr2 = data.charAt(i++); + encChr3 = data.charAt(i++); + encChr4 = data.charAt(i++); + + enc1 = alphabet.indexOf(encChr1); + enc2 = alphabet.indexOf(encChr2); + enc3 = alphabet.indexOf(encChr3); + enc4 = alphabet.indexOf(encChr4); + + if (enc1 < 0 || enc2 < 0 || enc3 < 0 || enc4 < 0) { + throw new OperationError("Invalid Base64 input: contains non-alphabet char(s)"); + } chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); @@ -119,10 +144,10 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r output.push(chr1); - if (enc3 !== 64) { + if (encChr3 !== "" && enc3 !== 64) { output.push(chr2); } - if (enc4 !== 64) { + if (encChr4 !== "" && enc4 !== 64) { output.push(chr3); } } From 1dbcd2ac8499bf37e6e12aef698e01c86f0d61e0 Mon Sep 17 00:00:00 2001 From: CPlusSharp Date: Sun, 7 Nov 2021 11:21:17 +0100 Subject: [PATCH 02/39] PEMtoHex: Support arbitrary PEMs previous implementation only supported some PEMs (e.g. Certificate) the new implementation is more general, it just extracts the base64 between header and footer and decodes that to hex --- src/core/operations/PEMToHex.mjs | 33 ++-- tests/operations/index.mjs | 1 + tests/operations/tests/PEMtoHex.mjs | 294 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+), 11 deletions(-) create mode 100644 tests/operations/tests/PEMtoHex.mjs diff --git a/src/core/operations/PEMToHex.mjs b/src/core/operations/PEMToHex.mjs index 095e2c56..575f6f77 100644 --- a/src/core/operations/PEMToHex.mjs +++ b/src/core/operations/PEMToHex.mjs @@ -1,11 +1,14 @@ /** * @author n1474335 [n1474335@gmail.com] + * @author cplussharp * @copyright Crown Copyright 2016 * @license Apache-2.0 */ -import r from "jsrsasign"; +import {fromBase64} from "../lib/Base64.mjs"; import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import Utils from "../Utils.mjs"; /** * PEM to Hex operation @@ -33,17 +36,25 @@ class PEMToHex extends Operation { * @returns {string} */ run(input, args) { - if (input.indexOf("-----BEGIN") < 0) { - // Add header so that the KEYUTIL function works - input = "-----BEGIN CERTIFICATE-----" + input; + let output = ""; + let match; + const regex = /-----BEGIN ([A-Z][A-Z ]+[A-Z])-----/g; + while ((match = regex.exec(input)) !== null) { + // find corresponding end tag + const indexBase64 = match.index + match[0].length; + const footer = `-----END ${match[1]}-----`; + const indexFooter = input.indexOf(footer, indexBase64); + if (indexFooter === -1) { + throw new OperationError(`PEM footer '${footer}' not found`); + } + + // decode base64 content + const base64 = input.substring(indexBase64, indexFooter); + const bytes = fromBase64(base64, "A-Za-z0-9+/=", "byteArray", true); + const hex = bytes.map(b => Utils.hex(b)).join(""); + output += hex; } - if (input.indexOf("-----END") < 0) { - // Add footer so that the KEYUTIL function works - input = input + "-----END CERTIFICATE-----"; - } - const cert = new r.X509(); - cert.readCertPEM(input); - return cert.hex; + return output; } } diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9add20b9..fede1441 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -66,6 +66,7 @@ import "./tests/PGP.mjs"; import "./tests/PHP.mjs"; import "./tests/ParseIPRange.mjs"; import "./tests/ParseQRCode.mjs"; +import "./tests/PEMtoHex.mjs"; import "./tests/PowerSet.mjs"; import "./tests/Regex.mjs"; import "./tests/Register.mjs"; diff --git a/tests/operations/tests/PEMtoHex.mjs b/tests/operations/tests/PEMtoHex.mjs new file mode 100644 index 00000000..7929bfdd --- /dev/null +++ b/tests/operations/tests/PEMtoHex.mjs @@ -0,0 +1,294 @@ +/** + * Test PEMtoHex with different inputs + * + * @author cplussharp + * + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +/** RSA 2048bit key pair as PKCS1 and PKCS8 and as certificate */ +const PEMS_RSA_PRIVATE_KEY_PKCS1 = `-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA5WykLKHiBAhmZh5WhocgpQQqZjdrApuRxRT21SJZx6Ce+Oz2 +V17/heozu5LEz63jCxW1NrBckzl/Ys8p9LeqYTu6x/LbKloTjfEWxlzXnzUSqn9J +HIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDhe2KnMGVDDg6kfCLokDdLo256LeQ4 +CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE3I8sSAzgoLMBamQ5m3MbiULAYtxs +kCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8vkzxLwe3t5Y4XgHL9TYQm1+BDnin +upIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz+wIDAQABAoIBACQu3jWr0lmQeZXh +cwQEi8F6xrUYSGhA4NyUUdmLcV1ql6fqt29QLDySk1Yh76hRZF17LvlRF0ig6NZM +lfFihhyPrwWZ57bmPe9E9rKSMe+KD0eUi5NVEVk/BmJpzxwZSfRC6NTDz8Zjp7po +FUwGkYlEJdocHlc5N/fcCZG1Jti/Z1AsZIjO6r6S0O7neC7icECBKHUyWa8/yE1N +++TVyMV+z53Ad1PC+SHMGDlbqJAM3o4wAzD/FAIzyVo6GSnnC+bFdgMtIwtwgYTH +rbr8M8j5fqAHTqNJeblqt/5KHEj2VVsIsHIuQ6lv4llESEqmH+N5KE4O33U7/Wmj +y/+VGAECgYEA9ysROHXOx1ofh3tI/r2C2FUan6/AAe4dc+8E4jMGI5T4xeqYHTRV +l1yS+ZKIxqclIoAmd6SJ7Nx2GdQ55MmokZdZRqsFN1flFOZw2kFH/I0zQZXdOjF+ +sf5Lu0FfcTw3VJhJ/YU3CVdlgdP4ekHbaJVFW5i/pTUf5vNs6AGBGxsCgYEA7Z9D +0qnF6GhxA8lJfwnyuktYnwIQoXE6Xp26/NZD7t7HzxHDf43LQxmTk+mDP/yIQHwb +xIx2NE/ncNxlUMl/g1PkJbKVkB8tdIZrLyiT4lebeqgT72Q07IsxRl/GHOr7CfN0 +61OBRCe44IlOtaNAZk4zWwuAwAYx+G8ifuOJ+KECgYBP5NvsJChyx+7pHDC8JwXk +Z53zgBvQg+eBUgGCHHwfhEflsa75wbDo/EOF6JfNnrmiLUpB4i2zIpAKSU9tZMHY +TdPNw/orqX2jA9n2sqNSP1ISIR8hcF5Dqq9QGBGByLUZ4yAHksf3fQiSrrHi0ubZ +J2cD9Jv+Cu4E+Sp61AGngQKBgHmuTPTbq1TP5s+hi9laJsnvO3pxfEKv0MwSyWYf +8rmnq3oGBq6S1buOpVvhAC0MDFm5NB76Lq2rHUFWGyu7g2ik1PfY823SCVzaWJjV +lqUZZ6zv1QWJsvBOdvUqpjC4w8TcvsqjAFb+YFXa+ktZRekdsn607UFn6r7laizA +KC8BAoGAZty7sIGMt1gDaoIjySgOox8x7AlY3QUyNQC5N8KW3MZ8KLC5UBtjhqLy +wYOJr+/1R/7ibiHrKkIE/dmg5QN1iS5tZmFvyLwJ+nHQZObFrlcKtpr+1lekQY/m +ly6YJFk3yj2nhYzt8eVXBX2lCoLG1gsrbpXvUfIGJ53L9m1mVAo= +-----END RSA PRIVATE KEY-----`; + +const PEMS_RSA_PRIVATE_KEY_PKCS8 = `-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDlbKQsoeIECGZm +HlaGhyClBCpmN2sCm5HFFPbVIlnHoJ747PZXXv+F6jO7ksTPreMLFbU2sFyTOX9i +zyn0t6phO7rH8tsqWhON8RbGXNefNRKqf0kcjGaYlDONen1fUP31OP41alEYQiII +UTsl8OF7YqcwZUMODqR8IuiQN0ujbnot5DgISRWLBjp35q3jEOUgfC9lmYbhKaTn +p4eG9ATcjyxIDOCgswFqZDmbcxuJQsBi3GyQKkJ+MXGsvpmJpqPsdmid4XjRHfQo +Ij3KAXy+TPEvB7e3ljheAcv1NhCbX4EOeKe6kgH/NN47XKAEYDrqbrOmaSa4bt3w +dch25zP7AgMBAAECggEAJC7eNavSWZB5leFzBASLwXrGtRhIaEDg3JRR2YtxXWqX +p+q3b1AsPJKTViHvqFFkXXsu+VEXSKDo1kyV8WKGHI+vBZnntuY970T2spIx74oP +R5SLk1URWT8GYmnPHBlJ9ELo1MPPxmOnumgVTAaRiUQl2hweVzk399wJkbUm2L9n +UCxkiM7qvpLQ7ud4LuJwQIEodTJZrz/ITU375NXIxX7PncB3U8L5IcwYOVuokAze +jjADMP8UAjPJWjoZKecL5sV2Ay0jC3CBhMetuvwzyPl+oAdOo0l5uWq3/kocSPZV +Wwiwci5DqW/iWURISqYf43koTg7fdTv9aaPL/5UYAQKBgQD3KxE4dc7HWh+He0j+ +vYLYVRqfr8AB7h1z7wTiMwYjlPjF6pgdNFWXXJL5kojGpyUigCZ3pIns3HYZ1Dnk +yaiRl1lGqwU3V+UU5nDaQUf8jTNBld06MX6x/ku7QV9xPDdUmEn9hTcJV2WB0/h6 +QdtolUVbmL+lNR/m82zoAYEbGwKBgQDtn0PSqcXoaHEDyUl/CfK6S1ifAhChcTpe +nbr81kPu3sfPEcN/jctDGZOT6YM//IhAfBvEjHY0T+dw3GVQyX+DU+QlspWQHy10 +hmsvKJPiV5t6qBPvZDTsizFGX8Yc6vsJ83TrU4FEJ7jgiU61o0BmTjNbC4DABjH4 +byJ+44n4oQKBgE/k2+wkKHLH7ukcMLwnBeRnnfOAG9CD54FSAYIcfB+ER+WxrvnB +sOj8Q4Xol82euaItSkHiLbMikApJT21kwdhN083D+iupfaMD2fayo1I/UhIhHyFw +XkOqr1AYEYHItRnjIAeSx/d9CJKuseLS5tknZwP0m/4K7gT5KnrUAaeBAoGAea5M +9NurVM/mz6GL2Vomye87enF8Qq/QzBLJZh/yuaeregYGrpLVu46lW+EALQwMWbk0 +HvourasdQVYbK7uDaKTU99jzbdIJXNpYmNWWpRlnrO/VBYmy8E529SqmMLjDxNy+ +yqMAVv5gVdr6S1lF6R2yfrTtQWfqvuVqLMAoLwECgYBm3LuwgYy3WANqgiPJKA6j +HzHsCVjdBTI1ALk3wpbcxnwosLlQG2OGovLBg4mv7/VH/uJuIesqQgT92aDlA3WJ +Lm1mYW/IvAn6cdBk5sWuVwq2mv7WV6RBj+aXLpgkWTfKPaeFjO3x5VcFfaUKgsbW +Cytule9R8gYnncv2bWZUCg== +-----END PRIVATE KEY-----`; + +const PEMS_RSA_PUBLIC_KEY_PKCS1 = `-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEA5WykLKHiBAhmZh5WhocgpQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/ +heozu5LEz63jCxW1NrBckzl/Ys8p9LeqYTu6x/LbKloTjfEWxlzXnzUSqn9JHIxm +mJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDhe2KnMGVDDg6kfCLokDdLo256LeQ4CEkV +iwY6d+at4xDlIHwvZZmG4Smk56eHhvQE3I8sSAzgoLMBamQ5m3MbiULAYtxskCpC +fjFxrL6Ziaaj7HZoneF40R30KCI9ygF8vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB +/zTeO1ygBGA66m6zpmkmuG7d8HXIducz+wIDAQAB +-----END RSA PUBLIC KEY-----`; + +const PEMS_RSA_PUBLIC_KEY_PKCS8 = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5WykLKHiBAhmZh5Whocg +pQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/heozu5LEz63jCxW1NrBckzl/Ys8p9Leq +YTu6x/LbKloTjfEWxlzXnzUSqn9JHIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDh +e2KnMGVDDg6kfCLokDdLo256LeQ4CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE +3I8sSAzgoLMBamQ5m3MbiULAYtxskCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8 +vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz ++wIDAQAB +-----END PUBLIC KEY-----`; + +const PEMS_RSA_CERT = `-----BEGIN CERTIFICATE----- +MIIDGzCCAgOgAwIBAgIUROs52CB3BsvEVLOCtALalnJG8tEwDQYJKoZIhvcNAQEL +BQAwHTEbMBkGA1UEAwwSUlNBIDIwNDggUHVibGljS2V5MB4XDTIxMDQxMzIxMDE0 +OVoXDTMxMDQxMTIxMDE0OVowHTEbMBkGA1UEAwwSUlNBIDIwNDggUHVibGljS2V5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5WykLKHiBAhmZh5Whocg +pQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/heozu5LEz63jCxW1NrBckzl/Ys8p9Leq +YTu6x/LbKloTjfEWxlzXnzUSqn9JHIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDh +e2KnMGVDDg6kfCLokDdLo256LeQ4CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE +3I8sSAzgoLMBamQ5m3MbiULAYtxskCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8 +vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz ++wIDAQABo1MwUTAdBgNVHQ4EFgQUcRhRB6H5JqlDHbymwqydW2/EAt8wHwYDVR0j +BBgwFoAUcRhRB6H5JqlDHbymwqydW2/EAt8wDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAQEALXBmDizTp/Uz4M2A4nCl0AVclrXEk+YjAKqZnvtj44Gs +CUcpxtcXu64ppsSYCwawvzIm6B2Mdmib422aInH0e0oNrn8cRzC144Hjnzxguamj +LyZXnH/0wN9SAjqCKt++urH9wbRMIl0v+g4CWjGyY+eYkMmd1UMQvdCCCv6RVm56 +7dBCijJIHg23JbgPJD72JCluXtTYWllv3duSwuWeYHo5EftU456pDcztkgn9XwFk +PFGnHLmbjpSzjE7u29qCjwHl3CiUsjfUlYFl/mf27oDXPqaWqPYv3fWH3H3ymiZQ +cqptUF4hDtPkaNkKWFmlljChN92o8g/jrv4DVDgJzQ== +-----END CERTIFICATE-----`; + +/** EC P-256 key pair and certificate */ +const PEMS_EC_P256_PRIVATE_KEY = `-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIhdQxQIcMnCHD3X4WqNv+VgycWmFoEZpRl9X0+dT9uHoAoGCCqGSM49 +AwEHoUQDQgAEFLQcBbzDweo6af4k3k0gKWMNWOZVn8+9hH2rv4DKKYZ7E1z64LBt +PnB1gMz++HDKySr2ozD3/46dIbQMXUZKpw== +-----END EC PRIVATE KEY-----`; + +const PEMS_EC_P256_PRIVATE_KEY_PKCS8 = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiF1DFAhwycIcPdfh +ao2/5WDJxaYWgRmlGX1fT51P24ehRANCAAQUtBwFvMPB6jpp/iTeTSApYw1Y5lWf +z72Efau/gMophnsTXPrgsG0+cHWAzP74cMrJKvajMPf/jp0htAxdRkqn +-----END PRIVATE KEY-----`; + +const PEMS_EC_P256_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFLQcBbzDweo6af4k3k0gKWMNWOZV +n8+9hH2rv4DKKYZ7E1z64LBtPnB1gMz++HDKySr2ozD3/46dIbQMXUZKpw== +-----END PUBLIC KEY-----`; + +const PEMS_FOO = `-----BEGIN FOO----- +Rk9P +-----END FOO-----`; +const PEMS_BAR = `-----BEGIN BAR----- +QkFS +-----END BAR-----`; + +TestRegister.addTests([ + { + name: "PEMtoHex: Nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: No footer", + input: PEMS_RSA_PRIVATE_KEY_PKCS1.substr(0, 200), + expectedOutput: "PEM footer '-----END RSA PRIVATE KEY-----' not found", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: Multiple PEMs", + input: PEMS_FOO + '\n' + PEMS_BAR, + expectedOutput: "FOOBAR", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "From Hex", + "args": ["None"] + } + ] + }, + { + name: "PEMtoHex: Single line PEM", + input: PEMS_FOO.replace(/(\n|\r)/gm,""), + expectedOutput: "FOO", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "From Hex", + "args": ["None"] + } + ] + }, + { + name: "PEMtoHex: EC P-256 Private Key", + input: PEMS_EC_P256_PRIVATE_KEY, + expectedOutput: "30770201010420885d43140870c9c21c3dd7e16a8dbfe560c9c5a6168119a5197d5f4f9d4fdb87a00a06082a8648ce3d030107a1440342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: EC P-256 Private Key PKCS8", + input: PEMS_EC_P256_PRIVATE_KEY_PKCS8, + expectedOutput: "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420885d43140870c9c21c3dd7e16a8dbfe560c9c5a6168119a5197d5f4f9d4fdb87a1440342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: EC P-256 Public Key", + input: PEMS_EC_P256_PUBLIC_KEY, + expectedOutput: "3059301306072a8648ce3d020106082a8648ce3d0301070342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Private Key PKCS1", + input: PEMS_RSA_PRIVATE_KEY_PKCS1, + expectedOutput: "fb49bd96ffc5d1351a35d773921fac03", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Private Key PKCS8", + input: PEMS_RSA_PRIVATE_KEY_PKCS8, + expectedOutput: "23086d03633689fee64680c3c24409eb", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Public Key PKCS1", + input: PEMS_RSA_PUBLIC_KEY_PKCS1, + expectedOutput: "5fc3f1f6c5d5806760b12eaad0c0292c", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Public Key PKCS8", + input: PEMS_RSA_PUBLIC_KEY_PKCS8, + expectedOutput: "30fbe8e9495d591232affebdd6206ea6", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: Certificate", + input: PEMS_RSA_CERT, + expectedOutput: "6694d8ca4a0ceb84c3951d25dc05ec6e", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + } +]); From b7a978505f8ea4f4d98dc5f166875db80bef0d8e Mon Sep 17 00:00:00 2001 From: CPlusSharp Date: Wed, 17 Nov 2021 20:19:42 +0100 Subject: [PATCH 03/39] PEMToHex: add magic check so it gets found --- src/core/operations/PEMToHex.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/operations/PEMToHex.mjs b/src/core/operations/PEMToHex.mjs index 575f6f77..1c42d6a9 100644 --- a/src/core/operations/PEMToHex.mjs +++ b/src/core/operations/PEMToHex.mjs @@ -28,6 +28,12 @@ class PEMToHex extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; + this.checks = [ + { + "pattern": "----BEGIN ([A-Z][A-Z ]+[A-Z])-----", + "args": [] + } + ]; } /** From 2574a63975ecced6e066ae673a986ad87394b7db Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Wed, 29 Dec 2021 19:32:39 +0000 Subject: [PATCH 04/39] Minor adjustments --- src/core/lib/Binary.mjs | 26 ++++++++++++---------- src/core/operations/ToUpperCase.mjs | 34 ++++++++++++++--------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/core/lib/Binary.mjs b/src/core/lib/Binary.mjs index dc63fc58..56db4c2a 100644 --- a/src/core/lib/Binary.mjs +++ b/src/core/lib/Binary.mjs @@ -19,27 +19,29 @@ import OperationError from "../errors/OperationError.mjs"; * @returns {string} * * @example - * // returns "00010000 00100000 00110000" + * // returns "00001010 00010100 00011110" * toBinary([10,20,30]); * - * // returns "00010000 00100000 00110000" - * toBinary([10,20,30], ":"); + * // returns "00001010:00010100:00011110" + * toBinary([10,20,30], "Colon"); + * + * // returns "1010:10100:11110" + * toBinary([10,20,30], "Colon", 0); */ export function toBinary(data, delim="Space", padding=8) { - if (!data) return ""; + if (!data) throw new OperationError("Empty input data enocuntered"); delim = Utils.charRep(delim); let output = ""; - for (let i = 0; i < data.length; i++) { - output += data[i].toString(2).padStart(padding, "0") + delim; + output += data[i].toString(2).padStart(padding, "0"); + if (i !== data.length - 1) output += delim; } - if (delim.length) { - return output.slice(0, -delim.length); - } else { - return output; + // Remove the delimiter from the end of the string. + output = output.slice(0, -delim.length); } + return output; } @@ -53,10 +55,10 @@ export function toBinary(data, delim="Space", padding=8) { * * @example * // returns [10,20,30] - * fromBinary("00010000 00100000 00110000"); + * fromBinary("00001010 00010100 00011110"); * * // returns [10,20,30] - * fromBinary("00010000:00100000:00110000", "Colon"); + * fromBinary("00001010:00010100:00011110", "Colon"); */ export function fromBinary(data, delim="Space", byteLen=8) { if (byteLen < 1 || Math.round(byteLen) !== byteLen) diff --git a/src/core/operations/ToUpperCase.mjs b/src/core/operations/ToUpperCase.mjs index 0bc9b5a9..eb0e315a 100644 --- a/src/core/operations/ToUpperCase.mjs +++ b/src/core/operations/ToUpperCase.mjs @@ -38,23 +38,23 @@ class ToUpperCase extends Operation { */ run(input, args) { const scope = args[0]; - - switch (scope) { - case "Word": - return input.replace(/(\b\w)/gi, function(m) { - return m.toUpperCase(); - }); - case "Sentence": - return input.replace(/(?:\.|^)\s*(\b\w)/gi, function(m) { - return m.toUpperCase(); - }); - case "Paragraph": - return input.replace(/(?:\n|^)\s*(\b\w)/gi, function(m) { - return m.toUpperCase(); - }); - case "All": /* falls through */ - default: - return input.toUpperCase(); + if (scope === "All") { + return input.toUpperCase(); + } + const scopeRegex = { + "Word": /(\b\w)/gi, + "Sentence": /(?:\.|^)\s*(\b\w)/gi, + "Paragraph": /(?:\n|^)\s*(\b\w)/gi + }[ scope ]; + if (scopeRegex !== undefined) { + // Use the regexes to capitalize the input. + return input.replace(scopeRegex, function(m) { + return m.toUpperCase(); + }); + } + else { + // The selected scope was invalid. + throw new OperationError("Unrecognized capitalization scope"); } } From ed542582f96541dd90fde52e4f0f07a9b6427ca6 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Wed, 29 Dec 2021 19:59:48 +0000 Subject: [PATCH 05/39] Added more error-handling to ToUpperCase() --- src/core/operations/ToUpperCase.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/operations/ToUpperCase.mjs b/src/core/operations/ToUpperCase.mjs index eb0e315a..08ffce87 100644 --- a/src/core/operations/ToUpperCase.mjs +++ b/src/core/operations/ToUpperCase.mjs @@ -37,6 +37,9 @@ class ToUpperCase extends Operation { * @returns {string} */ run(input, args) { + if (!args || args.length === 0) { + throw new OperationException("No capitalization scope was provided."); + } const scope = args[0]; if (scope === "All") { return input.toUpperCase(); From add745551b0d1ff8e58bc9f05f6f2c157c34cbb6 Mon Sep 17 00:00:00 2001 From: John L Date: Fri, 11 Feb 2022 16:56:58 +0000 Subject: [PATCH 06/39] WIP --- tests/browser/ops.js | 53 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 8d23cabd..8aa5e7ad 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -6,6 +6,9 @@ * @license Apache-2.0 */ +// import Images from "../operations/samples/Images.mjs"; +const Images = import("../operations/samples/Images.mjs"); + module.exports = { before: browser => { browser @@ -44,42 +47,42 @@ module.exports = { // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); // testOp(browser, "Bit shift left", "test input", "test_output"); // testOp(browser, "Bit shift right", "test input", "test_output"); - // testOp(browser, "Blowfish Decrypt", "test input", "test_output"); - // testOp(browser, "Blowfish Encrypt", "test input", "test_output"); - // testOp(browser, "Blur Image", "test input", "test_output"); + testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); + testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); + testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); // testOp(browser, "Bombe", "test input", "test_output"); - // testOp(browser, "Bzip2 Compress", "test input", "test_output"); - // testOp(browser, "Bzip2 Decompress", "test input", "test_output"); - // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); - // testOp(browser, "CSS Beautify", "test input", "test_output"); - // testOp(browser, "CSS Minify", "test input", "test_output"); - // testOp(browser, "CSS selector", "test input", "test_output"); + testOp(browser, "Bzip2 Compress", "test input", "test_output"); + testOp(browser, "Bzip2 Decompress", "test input", "test_output"); + testOp(browser, "CRC-16 Checksum", "test input", "test_output"); + testOp(browser, "CRC-32 Checksum", "test input", "test_output"); + testOp(browser, "CRC-8 Checksum", "test input", "test_output"); + testOp(browser, "CSS Beautify", "test input", "test_output"); + testOp(browser, "CSS Minify", "test input", "test_output"); + testOp(browser, "CSS selector", "test input", "test_output"); // testOp(browser, "CSV to JSON", "test input", "test_output"); - // testOp(browser, "CTPH", "test input", "test_output"); + testOp(browser, "CTPH", "test input", "test_output"); // testOp(browser, "Cartesian Product", "test input", "test_output"); // testOp(browser, "Change IP format", "test input", "test_output"); - // testOp(browser, "Chi Square", "test input", "test_output"); + testOp(browser, "Chi Square", "test input", "test_output"); // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); // testOp(browser, "Colossus", "test input", "test_output"); // testOp(browser, "Comment", "test input", "test_output"); - // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); - // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); - // testOp(browser, "Conditional Jump", "test input", "test_output"); - // testOp(browser, "Contain Image", "test input", "test_output"); - // testOp(browser, "Convert area", "test input", "test_output"); - // testOp(browser, "Convert co-ordinate format", "test input", "test_output"); - // testOp(browser, "Convert data units", "test input", "test_output"); - // testOp(browser, "Convert distance", "test input", "test_output"); + testOp(browser, "Compare CTPH hashes", "test input", "test_output"); + testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); + // /testOp(browser, "Conditional Jump", "test input", "test_output"); + testOp(browser, "Contain Image", "test input", "test_output"); + testOp(browser, "Convert area", "test input", "test_output"); + // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); + testOp(browser, "Convert data units", "test input", "test_output"); + testOp(browser, "Convert distance", "test input", "test_output"); // testOp(browser, "Convert Image Format", "test input", "test_output"); - // testOp(browser, "Convert mass", "test input", "test_output"); - // testOp(browser, "Convert speed", "test input", "test_output"); - // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); - // testOp(browser, "Count occurrences", "test input", "test_output"); + testOp(browser, "Convert mass", "test input", "test_output"); + testOp(browser, "Convert speed", "test input", "test_output"); + // /testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); + testOp(browser, "Count occurrences", "test input", "test_output"); // testOp(browser, "Cover Image", "test input", "test_output"); // testOp(browser, "Crop Image", "test input", "test_output"); // testOp(browser, "DES Decrypt", "test input", "test_output"); From 92767b107879b9611dc3d30b0c5db413a3858753 Mon Sep 17 00:00:00 2001 From: John L Date: Thu, 31 Mar 2022 19:32:41 +0100 Subject: [PATCH 07/39] Try import --- package-lock.json | 40 +- package.json | 2 +- tests/browser/ops.js | 799 +++++++++++++++------------- tests/operations/samples/Images.mjs | 6 + 4 files changed, 467 insertions(+), 380 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b8579b6..e4feff32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,7 +99,7 @@ "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^97.0.1", + "chromedriver": "^98.0.1", "cli-progress": "^3.9.0", "colors": "^1.4.0", "copy-webpack-plugin": "^9.0.1", @@ -4398,9 +4398,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true, "funding": { "type": "opencollective", @@ -4474,7 +4474,7 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", "dev": true, "dependencies": { "anymatch": "^2.0.0", @@ -4625,9 +4625,9 @@ } }, "node_modules/chromedriver": { - "version": "97.0.2", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-97.0.2.tgz", - "integrity": "sha512-sOAfKCR3WsHvmKedZoWa+3tBVGdPtxq4zKxgKZCoJ2c924olBTW4Bnha6SHl93Yo7+QqsNn6ZpAC0ojhutacAg==", + "version": "98.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-98.0.1.tgz", + "integrity": "sha512-/04KkHHE/K/lfwdPTQr5fxi1dWvM83p8T/IkYbyGK2PBlH7K49Dd71A9jrS+aWgXlZYkuHhbwiy2PA2QqZ5qQw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -7411,9 +7411,9 @@ } }, "node_modules/extract-zip/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -21682,9 +21682,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true }, "caseless": { @@ -21869,9 +21869,9 @@ "dev": true }, "chromedriver": { - "version": "97.0.2", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-97.0.2.tgz", - "integrity": "sha512-sOAfKCR3WsHvmKedZoWa+3tBVGdPtxq4zKxgKZCoJ2c924olBTW4Bnha6SHl93Yo7+QqsNn6ZpAC0ojhutacAg==", + "version": "98.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-98.0.1.tgz", + "integrity": "sha512-/04KkHHE/K/lfwdPTQr5fxi1dWvM83p8T/IkYbyGK2PBlH7K49Dd71A9jrS+aWgXlZYkuHhbwiy2PA2QqZ5qQw==", "dev": true, "requires": { "@testim/chrome-version": "^1.1.2", @@ -24109,9 +24109,9 @@ }, "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" diff --git a/package.json b/package.json index 8e7c1a2a..96d40c19 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^97.0.1", + "chromedriver": "^98.0.1", "cli-progress": "^3.9.0", "colors": "^1.4.0", "copy-webpack-plugin": "^9.0.1", diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 8aa5e7ad..49e7c63a 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -6,9 +6,6 @@ * @license Apache-2.0 */ -// import Images from "../operations/samples/Images.mjs"; -const Images = import("../operations/samples/Images.mjs"); - module.exports = { before: browser => { browser @@ -20,353 +17,367 @@ module.exports = { }, "Sanity check operations": browser => { - testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); - testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); - testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); - testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); - testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); - testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); - testOp(browser, "Add line numbers", "test input", "1 test input"); - // testOp(browser, "Add Text To Image", "test input", "test_output"); - testOp(browser, "Adler-32 Checksum", "test input", "16160411"); - testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); - testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); - testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); - testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); - // testOp(browser, "Avro to JSON", "test input", "test_output"); - // testOp(browser, "BLAKE2b", "test input", "test_output"); - // testOp(browser, "BLAKE2s", "test input", "test_output"); - // testOp(browser, "BSON deserialise", "test input", "test_output"); - // testOp(browser, "BSON serialise", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bcrypt", "test input", "test_output"); - // testOp(browser, "Bcrypt compare", "test input", "test_output"); - // testOp(browser, "Bcrypt parse", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bit shift left", "test input", "test_output"); - // testOp(browser, "Bit shift right", "test input", "test_output"); - testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); - testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); - testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); - // testOp(browser, "Bombe", "test input", "test_output"); - testOp(browser, "Bzip2 Compress", "test input", "test_output"); - testOp(browser, "Bzip2 Decompress", "test input", "test_output"); - testOp(browser, "CRC-16 Checksum", "test input", "test_output"); - testOp(browser, "CRC-32 Checksum", "test input", "test_output"); - testOp(browser, "CRC-8 Checksum", "test input", "test_output"); - testOp(browser, "CSS Beautify", "test input", "test_output"); - testOp(browser, "CSS Minify", "test input", "test_output"); - testOp(browser, "CSS selector", "test input", "test_output"); - // testOp(browser, "CSV to JSON", "test input", "test_output"); - testOp(browser, "CTPH", "test input", "test_output"); - // testOp(browser, "Cartesian Product", "test input", "test_output"); - // testOp(browser, "Change IP format", "test input", "test_output"); - testOp(browser, "Chi Square", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); - // testOp(browser, "Colossus", "test input", "test_output"); - // testOp(browser, "Comment", "test input", "test_output"); - testOp(browser, "Compare CTPH hashes", "test input", "test_output"); - testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); - // /testOp(browser, "Conditional Jump", "test input", "test_output"); - testOp(browser, "Contain Image", "test input", "test_output"); - testOp(browser, "Convert area", "test input", "test_output"); - // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); - testOp(browser, "Convert data units", "test input", "test_output"); - testOp(browser, "Convert distance", "test input", "test_output"); - // testOp(browser, "Convert Image Format", "test input", "test_output"); - testOp(browser, "Convert mass", "test input", "test_output"); - testOp(browser, "Convert speed", "test input", "test_output"); - // /testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); - testOp(browser, "Count occurrences", "test input", "test_output"); - // testOp(browser, "Cover Image", "test input", "test_output"); - // testOp(browser, "Crop Image", "test input", "test_output"); - // testOp(browser, "DES Decrypt", "test input", "test_output"); - // testOp(browser, "DES Encrypt", "test input", "test_output"); - // testOp(browser, "DNS over HTTPS", "test input", "test_output"); - // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); - // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Decode text", "test input", "test_output"); - // testOp(browser, "Defang IP Addresses", "test input", "test_output"); - // testOp(browser, "Defang URL", "test input", "test_output"); - // testOp(browser, "Derive EVP key", "test input", "test_output"); - // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); - // testOp(browser, "Detect File Type", "test input", "test_output"); - // testOp(browser, "Diff", "test input", "test_output"); - // testOp(browser, "Disassemble x86", "test input", "test_output"); - // testOp(browser, "Dither Image", "test input", "test_output"); - // testOp(browser, "Divide", "test input", "test_output"); - // testOp(browser, "Drop bytes", "test input", "test_output"); - // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Encode text", "test input", "test_output"); - // testOp(browser, "Enigma", "test input", "test_output"); - // testOp(browser, "Entropy", "test input", "test_output"); - // testOp(browser, "Escape string", "test input", "test_output"); - // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Expand alphabet range", "test input", "test_output"); - // testOp(browser, "Extract dates", "test input", "test_output"); - // testOp(browser, "Extract domains", "test input", "test_output"); - // testOp(browser, "Extract EXIF", "test input", "test_output"); - // testOp(browser, "Extract email addresses", "test input", "test_output"); - // testOp(browser, "Extract file paths", "test input", "test_output"); - // testOp(browser, "Extract Files", "test input", "test_output"); - // testOp(browser, "Extract IP addresses", "test input", "test_output"); - // testOp(browser, "Extract LSB", "test input", "test_output"); - // testOp(browser, "Extract MAC addresses", "test input", "test_output"); - // testOp(browser, "Extract RGBA", "test input", "test_output"); - // testOp(browser, "Extract URLs", "test input", "test_output"); - // testOp(browser, "Filter", "test input", "test_output"); - // testOp(browser, "Find / Replace", "test input", "test_output"); - // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); - // testOp(browser, "Flip Image", "test input", "test_output"); - // testOp(browser, "Fork", "test input", "test_output"); - // testOp(browser, "Format MAC addresses", "test input", "test_output"); - // testOp(browser, "Frequency distribution", "test input", "test_output"); - // testOp(browser, "From BCD", "test input", "test_output"); - // testOp(browser, "From Base", "test input", "test_output"); - // testOp(browser, "From Base32", "test input", "test_output"); - // testOp(browser, "From Base58", "test input", "test_output"); - // testOp(browser, "From Base62", "test input", "test_output"); - // testOp(browser, "From Base64", "test input", "test_output"); - // testOp(browser, "From Base85", "test input", "test_output"); - // testOp(browser, "From Binary", "test input", "test_output"); - // testOp(browser, "From Braille", "test input", "test_output"); - // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "From Charcode", "test input", "test_output"); - // testOp(browser, "From Decimal", "test input", "test_output"); - // testOp(browser, "From HTML Entity", "test input", "test_output"); - // testOp(browser, "From Hex", "test input", "test_output"); - // testOp(browser, "From Hex Content", "test input", "test_output"); - // testOp(browser, "From Hexdump", "test input", "test_output"); - // testOp(browser, "From MessagePack", "test input", "test_output"); - // testOp(browser, "From Morse Code", "test input", "test_output"); - // testOp(browser, "From Octal", "test input", "test_output"); - // testOp(browser, "From Punycode", "test input", "test_output"); - // testOp(browser, "From Quoted Printable", "test input", "test_output"); - // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "GOST hash", "test input", "test_output"); - // testOp(browser, "Generate all hashes", "test input", "test_output"); - // testOp(browser, "Generate HOTP", "test input", "test_output"); - // testOp(browser, "Generate Image", "test input", "test_output"); - // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); - // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); - // testOp(browser, "Generate QR Code", "test input", "test_output"); - // testOp(browser, "Generate TOTP", "test input", "test_output"); - // testOp(browser, "Generate UUID", "test input", "test_output"); - // testOp(browser, "Generic Code Beautify", "test input", "test_output"); - // testOp(browser, "Group IP addresses", "test input", "test_output"); - // testOp(browser, "Gunzip", "test input", "test_output"); - // testOp(browser, "Gzip", "test input", "test_output"); - // testOp(browser, "HAS-160", "test input", "test_output"); - // testOp(browser, "HMAC", "test input", "test_output"); - // testOp(browser, "HTML To Text", "test input", "test_output"); - // testOp(browser, "HTTP request", "test input", "test_output"); - // testOp(browser, "Hamming Distance", "test input", "test_output"); - // testOp(browser, "Haversine distance", "test input", "test_output"); - // testOp(browser, "Head", "test input", "test_output"); - // testOp(browser, "Heatmap chart", "test input", "test_output"); - // testOp(browser, "Hex Density chart", "test input", "test_output"); - // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); - // testOp(browser, "Hex to PEM", "test input", "test_output"); - // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); - // testOp(browser, "Image Filter", "test input", "test_output"); - // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); - // testOp(browser, "Image Opacity", "test input", "test_output"); - // testOp(browser, "Index of Coincidence", "test input", "test_output"); - // testOp(browser, "Invert Image", "test input", "test_output"); - // testOp(browser, "JPath expression", "test input", "test_output"); - // testOp(browser, "JSON Beautify", "test input", "test_output"); - // testOp(browser, "JSON Minify", "test input", "test_output"); - // testOp(browser, "JSON to CSV", "test input", "test_output"); - // testOp(browser, "JWT Decode", "test input", "test_output"); - // testOp(browser, "JWT Sign", "test input", "test_output"); - // testOp(browser, "JWT Verify", "test input", "test_output"); - // testOp(browser, "JavaScript Beautify", "test input", "test_output"); - // testOp(browser, "JavaScript Minify", "test input", "test_output"); - // testOp(browser, "JavaScript Parser", "test input", "test_output"); - // testOp(browser, "Jump", "test input", "test_output"); - // testOp(browser, "Keccak", "test input", "test_output"); - // testOp(browser, "Label", "test input", "test_output"); - // testOp(browser, "Lorenz", "test input", "test_output"); - // testOp(browser, "Luhn Checksum", "test input", "test_output"); - // testOp(browser, "MD2", "test input", "test_output"); - // testOp(browser, "MD4", "test input", "test_output"); - // testOp(browser, "MD5", "test input", "test_output"); - // testOp(browser, "MD6", "test input", "test_output"); - // testOp(browser, "Magic", "test input", "test_output"); - // testOp(browser, "Mean", "test input", "test_output"); - // testOp(browser, "Median", "test input", "test_output"); - // testOp(browser, "Merge", "test input", "test_output"); - // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); - // testOp(browser, "Multiple Bombe", "test input", "test_output"); - // testOp(browser, "Multiply", "test input", "test_output"); - // testOp(browser, "NOT", "test input", "test_output"); - // testOp(browser, "Normalise Image", "test input", "test_output"); - // testOp(browser, "Normalise Unicode", "test input", "test_output"); - // testOp(browser, "Numberwang", "test input", "test_output"); - // testOp(browser, "OR", "test input", "test_output"); - // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); - // testOp(browser, "Offset checker", "test input", "test_output"); - // testOp(browser, "Optical Character Recognition", "test input", "test_output"); - // testOp(browser, "PEM to Hex", "test input", "test_output"); - // testOp(browser, "PGP Decrypt", "test input", "test_output"); - // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); - // testOp(browser, "PGP Encrypt", "test input", "test_output"); - // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); - // testOp(browser, "PGP Verify", "test input", "test_output"); - // testOp(browser, "PHP Deserialize", "test input", "test_output"); - // testOp(browser, "Pad lines", "test input", "test_output"); - // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); - // testOp(browser, "Parse colour code", "test input", "test_output"); - // testOp(browser, "Parse DateTime", "test input", "test_output"); - // testOp(browser, "Parse IP range", "test input", "test_output"); - // testOp(browser, "Parse IPv4 header", "test input", "test_output"); - // testOp(browser, "Parse IPv6 address", "test input", "test_output"); - // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); - // testOp(browser, "Parse QR Code", "test input", "test_output"); - // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); - // testOp(browser, "Parse TLV", "test input", "test_output"); - // testOp(browser, "Parse UDP", "test input", "test_output"); - // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); - // testOp(browser, "Parse URI", "test input", "test_output"); - // testOp(browser, "Parse User Agent", "test input", "test_output"); - // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); - // testOp(browser, "Play Media", "test input", "test_output"); - // testOp(browser, "Power Set", "test input", "test_output"); - // testOp(browser, "Protobuf Decode", "test input", "test_output"); - // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); - // testOp(browser, "RC2 Decrypt", "test input", "test_output"); - // testOp(browser, "RC2 Encrypt", "test input", "test_output"); - // testOp(browser, "RC4", "test input", "test_output"); - // testOp(browser, "RC4 Drop", "test input", "test_output"); - // testOp(browser, "RIPEMD", "test input", "test_output"); - // testOp(browser, "ROT13", "test input", "test_output"); - // testOp(browser, "ROT47", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); - // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); - // testOp(browser, "Raw Deflate", "test input", "test_output"); - // testOp(browser, "Raw Inflate", "test input", "test_output"); - // testOp(browser, "Register", "test input", "test_output"); - // testOp(browser, "Regular expression", "test input", "test_output"); - // testOp(browser, "Remove Diacritics", "test input", "test_output"); - // testOp(browser, "Remove EXIF", "test input", "test_output"); - // testOp(browser, "Remove line numbers", "test input", "test_output"); - // testOp(browser, "Remove null bytes", "test input", "test_output"); - // testOp(browser, "Remove whitespace", "test input", "test_output"); - // testOp(browser, "Render Image", "test input", "test_output"); - // testOp(browser, "Render Markdown", "test input", "test_output"); - // testOp(browser, "Resize Image", "test input", "test_output"); - // testOp(browser, "Return", "test input", "test_output"); - // testOp(browser, "Reverse", "test input", "test_output"); - // testOp(browser, "Rotate Image", "test input", "test_output"); - // testOp(browser, "Rotate left", "test input", "test_output"); - // testOp(browser, "Rotate right", "test input", "test_output"); - // testOp(browser, "SHA0", "test input", "test_output"); - // testOp(browser, "SHA1", "test input", "test_output"); - // testOp(browser, "SHA2", "test input", "test_output"); - // testOp(browser, "SHA3", "test input", "test_output"); - // testOp(browser, "SQL Beautify", "test input", "test_output"); - // testOp(browser, "SQL Minify", "test input", "test_output"); - // testOp(browser, "SSDEEP", "test input", "test_output"); - // testOp(browser, "SUB", "test input", "test_output"); - // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); - // testOp(browser, "Scatter chart", "test input", "test_output"); - // testOp(browser, "Scrypt", "test input", "test_output"); - // testOp(browser, "Series chart", "test input", "test_output"); - // testOp(browser, "Set Difference", "test input", "test_output"); - // testOp(browser, "Set Intersection", "test input", "test_output"); - // testOp(browser, "Set Union", "test input", "test_output"); - // testOp(browser, "Shake", "test input", "test_output"); - // testOp(browser, "Sharpen Image", "test input", "test_output"); - // testOp(browser, "Show Base64 offsets", "test input", "test_output"); - // testOp(browser, "Show on map", "test input", "test_output"); - // testOp(browser, "Sleep", "test input", "test_output"); - // testOp(browser, "Snefru", "test input", "test_output"); - // testOp(browser, "Sort", "test input", "test_output"); - // testOp(browser, "Split", "test input", "test_output"); - // testOp(browser, "Split Colour Channels", "test input", "test_output"); - // testOp(browser, "Standard Deviation", "test input", "test_output"); - // testOp(browser, "Streebog", "test input", "test_output"); - // testOp(browser, "Strings", "test input", "test_output"); - // testOp(browser, "Strip HTML tags", "test input", "test_output"); - // testOp(browser, "Strip HTTP headers", "test input", "test_output"); - // testOp(browser, "Subsection", "test input", "test_output"); - // testOp(browser, "Substitute", "test input", "test_output"); - // testOp(browser, "Subtract", "test input", "test_output"); - // testOp(browser, "Sum", "test input", "test_output"); - // testOp(browser, "Swap endianness", "test input", "test_output"); - // testOp(browser, "Symmetric Difference", "test input", "test_output"); - // testOp(browser, "Syntax highlighter", "test input", "test_output"); - // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); - // testOp(browser, "Tail", "test input", "test_output"); - // testOp(browser, "Take bytes", "test input", "test_output"); - // testOp(browser, "Tar", "test input", "test_output"); - // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); - // testOp(browser, "To BCD", "test input", "test_output"); - // testOp(browser, "To Base", "test input", "test_output"); - // testOp(browser, "To Base32", "test input", "test_output"); - // testOp(browser, "To Base58", "test input", "test_output"); - // testOp(browser, "To Base62", "test input", "test_output"); - // testOp(browser, "To Base64", "test input", "test_output"); - // testOp(browser, "To Base85", "test input", "test_output"); - // testOp(browser, "To Binary", "test input", "test_output"); - // testOp(browser, "To Braille", "test input", "test_output"); - // testOp(browser, "To Camel case", "test input", "test_output"); - // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "To Charcode", "test input", "test_output"); - // testOp(browser, "To Decimal", "test input", "test_output"); - // testOp(browser, "To HTML Entity", "test input", "test_output"); - // testOp(browser, "To Hex", "test input", "test_output"); - // testOp(browser, "To Hex Content", "test input", "test_output"); - // testOp(browser, "To Hexdump", "test input", "test_output"); - // testOp(browser, "To Kebab case", "test input", "test_output"); - // testOp(browser, "To Lower case", "test input", "test_output"); - // testOp(browser, "To MessagePack", "test input", "test_output"); - // testOp(browser, "To Morse Code", "test input", "test_output"); - // testOp(browser, "To Octal", "test input", "test_output"); - // testOp(browser, "To Punycode", "test input", "test_output"); - // testOp(browser, "To Quoted Printable", "test input", "test_output"); - // testOp(browser, "To Snake case", "test input", "test_output"); - // testOp(browser, "To Table", "test input", "test_output"); - // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "To Upper case", "test input", "test_output"); - // testOp(browser, "Translate DateTime Format", "test input", "test_output"); - // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); - // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); - // testOp(browser, "Typex", "test input", "test_output"); - // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); - // testOp(browser, "URL Decode", "test input", "test_output"); - // testOp(browser, "URL Encode", "test input", "test_output"); - // testOp(browser, "Unescape string", "test input", "test_output"); - // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Unique", "test input", "test_output"); - // testOp(browser, "Untar", "test input", "test_output"); - // testOp(browser, "Unzip", "test input", "test_output"); - // testOp(browser, "VarInt Decode", "test input", "test_output"); - // testOp(browser, "VarInt Encode", "test input", "test_output"); - // testOp(browser, "View Bit Plane", "test input", "test_output"); - // testOp(browser, "Vigenère Decode", "test input", "test_output"); - // testOp(browser, "Vigenère Encode", "test input", "test_output"); - // testOp(browser, "Whirlpool", "test input", "test_output"); - // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "XKCD Random Number", "test input", "test_output"); - // testOp(browser, "XML Beautify", "test input", "test_output"); - // testOp(browser, "XML Minify", "test input", "test_output"); - // testOp(browser, "XOR", "test input", "test_output"); - // testOp(browser, "XOR Brute Force", "test input", "test_output"); - // testOp(browser, "XPath expression", "test input", "test_output"); - // testOp(browser, "YARA Rules", "test input", "test_output"); - // testOp(browser, "Zip", "test input", "test_output"); - // testOp(browser, "Zlib Deflate", "test input", "test_output"); - // testOp(browser, "Zlib Inflate", "test input", "test_output"); + import("../operations/samples/Images.mjs") + .then(Images => { + testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); + testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); + testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); + }); + }, + "Sanity check operations": browser => { + import("../operations/samples/Images.mjs").then(Images => { + testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); + testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); + testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); + testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); + testOp(browser, "Add line numbers", "test input", "1 test input"); + // testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); + // testOp(browser, "Add Text To Image", "test input", "test_output"); + testOp(browser, "Adler-32 Checksum", "test input", "16160411"); + testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); + testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); + testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); + testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); + // testOp(browser, "Avro to JSON", "test input", "test_output"); + // testOp(browser, "BLAKE2b", "test input", "test_output"); + // testOp(browser, "BLAKE2s", "test input", "test_output"); + // testOp(browser, "BSON deserialise", "test input", "test_output"); + // testOp(browser, "BSON serialise", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bcrypt", "test input", "test_output"); + // testOp(browser, "Bcrypt compare", "test input", "test_output"); + // testOp(browser, "Bcrypt parse", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bit shift left", "test input", "test_output"); + // testOp(browser, "Bit shift right", "test input", "test_output"); + testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); + testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); + // console.log(Images); + // testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); + // Imaged Error : Undefined ! Must be a way to Reference Exports + + // testOp(browser, "Bombe", "test input", "test_output"); + testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); + testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); + // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); + // testOp(browser, "CSS Beautify", "test input", "test_output"); + // testOp(browser, "CSS Minify", "test input", "test_output"); + // testOp(browser, "CSS selector", "test input", "test_output"); + // testOp(browser, "CSV to JSON", "test input", "test_output"); + // testOp(browser, "CTPH", "test input", "test_output"); + // testOp(browser, "Cartesian Product", "test input", "test_output"); + // testOp(browser, "Change IP format", "test input", "test_output"); + // testOp(browser, "Chi Square", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); + // testOp(browser, "Colossus", "test input", "test_output"); + // testOp(browser, "Comment", "test input", "test_output"); + // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); + // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); + // /testOp(browser, "Conditional Jump", "test input", "test_output"); + // testOp(browser, "Contain Image", "test input", "test_output"); + // testOp(browser, "Convert area", "test input", "test_output"); + // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); + // testOp(browser, "Convert data units", "test input", "test_output"); + // testOp(browser, "Convert distance", "test input", "test_output"); + // testOp(browser, "Convert Image Format", "test input", "test_output"); + // testOp(browser, "Convert mass", "test input", "test_output"); + // testOp(browser, "Convert speed", "test input", "test_output"); + // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); + // testOp(browser, "Count occurrences", "test input", "test_output"); + // testOp(browser, "Cover Image", "test input", "test_output"); + // testOp(browser, "Crop Image", "test input", "test_output"); + // testOp(browser, "DES Decrypt", "test input", "test_output"); + // testOp(browser, "DES Encrypt", "test input", "test_output"); + // testOp(browser, "DNS over HTTPS", "test input", "test_output"); + // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); + // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Decode text", "test input", "test_output"); + // testOp(browser, "Defang IP Addresses", "test input", "test_output"); + // testOp(browser, "Defang URL", "test input", "test_output"); + // testOp(browser, "Derive EVP key", "test input", "test_output"); + // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); + // testOp(browser, "Detect File Type", "test input", "test_output"); + // testOp(browser, "Diff", "test input", "test_output"); + // testOp(browser, "Disassemble x86", "test input", "test_output"); + // testOp(browser, "Dither Image", "test input", "test_output"); + // testOp(browser, "Divide", "test input", "test_output"); + // testOp(browser, "Drop bytes", "test input", "test_output"); + // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Encode text", "test input", "test_output"); + // testOp(browser, "Enigma", "test input", "test_output"); + // testOp(browser, "Entropy", "test input", "test_output"); + // testOp(browser, "Escape string", "test input", "test_output"); + // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Expand alphabet range", "test input", "test_output"); + // testOp(browser, "Extract dates", "test input", "test_output"); + // testOp(browser, "Extract domains", "test input", "test_output"); + // testOp(browser, "Extract EXIF", "test input", "test_output"); + // testOp(browser, "Extract email addresses", "test input", "test_output"); + // testOp(browser, "Extract file paths", "test input", "test_output"); + // testOp(browser, "Extract Files", "test input", "test_output"); + // testOp(browser, "Extract IP addresses", "test input", "test_output"); + // testOp(browser, "Extract LSB", "test input", "test_output"); + // testOp(browser, "Extract MAC addresses", "test input", "test_output"); + // testOp(browser, "Extract RGBA", "test input", "test_output"); + // testOp(browser, "Extract URLs", "test input", "test_output"); + // testOp(browser, "Filter", "test input", "test_output"); + // testOp(browser, "Find / Replace", "test input", "test_output"); + // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); + // testOp(browser, "Flip Image", "test input", "test_output"); + // testOp(browser, "Fork", "test input", "test_output"); + // testOp(browser, "Format MAC addresses", "test input", "test_output"); + // testOp(browser, "Frequency distribution", "test input", "test_output"); + // testOp(browser, "From BCD", "test input", "test_output"); + // testOp(browser, "From Base", "test input", "test_output"); + // testOp(browser, "From Base32", "test input", "test_output"); + // testOp(browser, "From Base58", "test input", "test_output"); + // testOp(browser, "From Base62", "test input", "test_output"); + // testOp(browser, "From Base64", "test input", "test_output"); + // testOp(browser, "From Base85", "test input", "test_output"); + // testOp(browser, "From Binary", "test input", "test_output"); + // testOp(browser, "From Braille", "test input", "test_output"); + // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "From Charcode", "test input", "test_output"); + // testOp(browser, "From Decimal", "test input", "test_output"); + // testOp(browser, "From HTML Entity", "test input", "test_output"); + // testOp(browser, "From Hex", "test input", "test_output"); + // testOp(browser, "From Hex Content", "test input", "test_output"); + // testOp(browser, "From Hexdump", "test input", "test_output"); + // testOp(browser, "From MessagePack", "test input", "test_output"); + // testOp(browser, "From Morse Code", "test input", "test_output"); + // testOp(browser, "From Octal", "test input", "test_output"); + // testOp(browser, "From Punycode", "test input", "test_output"); + // testOp(browser, "From Quoted Printable", "test input", "test_output"); + // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "GOST hash", "test input", "test_output"); + // testOp(browser, "Generate all hashes", "test input", "test_output"); + // testOp(browser, "Generate HOTP", "test input", "test_output"); + // testOp(browser, "Generate Image", "test input", "test_output"); + // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); + // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); + // testOp(browser, "Generate QR Code", "test input", "test_output"); + // testOp(browser, "Generate TOTP", "test input", "test_output"); + // testOp(browser, "Generate UUID", "test input", "test_output"); + // testOp(browser, "Generic Code Beautify", "test input", "test_output"); + // testOp(browser, "Group IP addresses", "test input", "test_output"); + // testOp(browser, "Gunzip", "test input", "test_output"); + // testOp(browser, "Gzip", "test input", "test_output"); + // testOp(browser, "HAS-160", "test input", "test_output"); + // testOp(browser, "HMAC", "test input", "test_output"); + // testOp(browser, "HTML To Text", "test input", "test_output"); + // testOp(browser, "HTTP request", "test input", "test_output"); + // testOp(browser, "Hamming Distance", "test input", "test_output"); + // testOp(browser, "Haversine distance", "test input", "test_output"); + // testOp(browser, "Head", "test input", "test_output"); + // testOp(browser, "Heatmap chart", "test input", "test_output"); + // testOp(browser, "Hex Density chart", "test input", "test_output"); + // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); + // testOp(browser, "Hex to PEM", "test input", "test_output"); + // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); + // testOp(browser, "Image Filter", "test input", "test_output"); + // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); + // testOp(browser, "Image Opacity", "test input", "test_output"); + // testOp(browser, "Index of Coincidence", "test input", "test_output"); + // testOp(browser, "Invert Image", "test input", "test_output"); + // testOp(browser, "JPath expression", "test input", "test_output"); + // testOp(browser, "JSON Beautify", "test input", "test_output"); + // testOp(browser, "JSON Minify", "test input", "test_output"); + // testOp(browser, "JSON to CSV", "test input", "test_output"); + // testOp(browser, "JWT Decode", "test input", "test_output"); + // testOp(browser, "JWT Sign", "test input", "test_output"); + // testOp(browser, "JWT Verify", "test input", "test_output"); + // testOp(browser, "JavaScript Beautify", "test input", "test_output"); + // testOp(browser, "JavaScript Minify", "test input", "test_output"); + // testOp(browser, "JavaScript Parser", "test input", "test_output"); + // testOp(browser, "Jump", "test input", "test_output"); + // testOp(browser, "Keccak", "test input", "test_output"); + // testOp(browser, "Label", "test input", "test_output"); + // testOp(browser, "Lorenz", "test input", "test_output"); + // testOp(browser, "Luhn Checksum", "test input", "test_output"); + // testOp(browser, "MD2", "test input", "test_output"); + // testOp(browser, "MD4", "test input", "test_output"); + // testOp(browser, "MD5", "test input", "test_output"); + // testOp(browser, "MD6", "test input", "test_output"); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:nth-of-type(1) td:nth-of-type(2)", "Result snippet"); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:eq(1) td:eq(1)", "test_output"); + // testOp(browser, "Mean", "test input", "test_output"); + // testOp(browser, "Median", "test input", "test_output");` + // testOp(browser, "Merge", "test input", "test_output");` + // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); + // testOp(browser, "Multiple Bombe", "test input", "test_output"); + // testOp(browser, "Multiply", "test input", "test_output"); + // testOp(browser, "NOT", "test input", "test_output"); + // testOp(browser, "Normalise Image", "test input", "test_output"); + // testOp(browser, "Normalise Unicode", "test input", "test_output"); + // testOp(browser, "Numberwang", "test input", "test_output"); + // testOp(browser, "OR", "test input", "test_output"); + // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); + // testOp(browser, "Offset checker", "test input", "test_output"); + // testOp(browser, "Optical Character Recognition", "test input", "test_output"); + // testOp(browser, "PEM to Hex", "test input", "test_output"); + // testOp(browser, "PGP Decrypt", "test input", "test_output"); + // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); + // testOp(browser, "PGP Encrypt", "test input", "test_output"); + // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); + // testOp(browser, "PGP Verify", "test input", "test_output"); + // testOp(browser, "PHP Deserialize", "test input", "test_output"); + // testOp(browser, "Pad lines", "test input", "test_output"); + // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); + // testOp(browser, "Parse colour code", "test input", "test_output"); + // testOp(browser, "Parse DateTime", "test input", "test_output"); + // testOp(browser, "Parse IP range", "test input", "test_output"); + // testOp(browser, "Parse IPv4 header", "test input", "test_output"); + // testOp(browser, "Parse IPv6 address", "test input", "test_output"); + // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); + // testOp(browser, "Parse QR Code", "test input", "test_output"); + // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); + // testOp(browser, "Parse TLV", "test input", "test_output"); + // testOp(browser, "Parse UDP", "test input", "test_output"); + // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); + // testOp(browser, "Parse URI", "test input", "test_output"); + // testOp(browser, "Parse User Agent", "test input", "test_output"); + // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); + // testOp(browser, "Play Media", "test input", "test_output"); + // testOp(browser, "Power Set", "test input", "test_output"); + // testOp(browser, "Protobuf Decode", "test input", "test_output"); + // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); + // testOp(browser, "RC2 Decrypt", "test input", "test_output"); + // testOp(browser, "RC2 Encrypt", "test input", "test_output"); + // testOp(browser, "RC4", "test input", "test_output"); + // testOp(browser, "RC4 Drop", "test input", "test_output"); + // testOp(browser, "RIPEMD", "test input", "test_output"); + // testOp(browser, "ROT13", "test input", "test_output"); + // testOp(browser, "ROT47", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); + // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); + // testOp(browser, "Raw Deflate", "test input", "test_output"); + // testOp(browser, "Raw Inflate", "test input", "test_output"); + // testOp(browser, "Register", "test input", "test_output"); + // testOp(browser, "Regular expression", "test input", "test_output"); + // testOp(browser, "Remove Diacritics", "test input", "test_output"); + // testOp(browser, "Remove EXIF", "test input", "test_output"); + // testOp(browser, "Remove line numbers", "test input", "test_output"); + // testOp(browser, "Remove null bytes", "test input", "test_output"); + // testOp(browser, "Remove whitespace", "test input", "test_output"); + // testOp(browser, "Render Image", "test input", "test_output"); + // testOp(browser, "Render Markdown", "test input", "test_output"); + // testOp(browser, "Resize Image", "test input", "test_output"); + // testOp(browser, "Return", "test input", "test_output"); + // testOp(browser, "Reverse", "test input", "test_output"); + // testOp(browser, "Rotate Image", "test input", "test_output"); + // testOp(browser, "Rotate left", "test input", "test_output"); + // testOp(browser, "Rotate right", "test input", "test_output"); + // testOp(browser, "SHA0", "test input", "test_output"); + // testOp(browser, "SHA1", "test input", "test_output"); + // testOp(browser, "SHA2", "test input", "test_output"); + // testOp(browser, "SHA3", "test input", "test_output"); + // testOp(browser, "SQL Beautify", "test input", "test_output"); + // testOp(browser, "SQL Minify", "test input", "test_output"); + // testOp(browser, "SSDEEP", "test input", "test_output"); + // testOp(browser, "SUB", "test input", "test_output"); + // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); + // testOp(browser, "Scatter chart", "test input", "test_output"); + // testOp(browser, "Scrypt", "test input", "test_output"); + // testOp(browser, "Series chart", "test input", "test_output"); + // testOp(browser, "Set Difference", "test input", "test_output"); + // testOp(browser, "Set Intersection", "test input", "test_output"); + // testOp(browser, "Set Union", "test input", "test_output"); + // testOp(browser, "Shake", "test input", "test_output"); + // testOp(browser, "Sharpen Image", "test input", "test_output"); + // testOp(browser, "Show Base64 offsets", "test input", "test_output"); + // testOp(browser, "Show on map", "test input", "test_output"); + // testOp(browser, "Sleep", "test input", "test_output"); + // testOp(browser, "Snefru", "test input", "test_output"); + // testOp(browser, "Sort", "test input", "test_output"); + // testOp(browser, "Split", "test input", "test_output"); + // testOp(browser, "Split Colour Channels", "test input", "test_output"); + // testOp(browser, "Standard Deviation", "test input", "test_output"); + // testOp(browser, "Streebog", "test input", "test_output"); + // testOp(browser, "Strings", "test input", "test_output"); + // testOp(browser, "Strip HTML tags", "test input", "test_output"); + // testOp(browser, "Strip HTTP headers", "test input", "test_output"); + // testOp(browser, "Subsection", "test input", "test_output"); + // testOp(browser, "Substitute", "test input", "test_output"); + // testOp(browser, "Subtract", "test input", "test_output"); + // testOp(browser, "Sum", "test input", "test_output"); + // testOp(browser, "Swap endianness", "test input", "test_output"); + // testOp(browser, "Symmetric Difference", "test input", "test_output"); + // testOp(browser, "Syntax highlighter", "test input", "test_output"); + // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); + // testOp(browser, "Tail", "test input", "test_output"); + // testOp(browser, "Take bytes", "test input", "test_output"); + // testOp(browser, "Tar", "test input", "test_output"); + // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); + // testOp(browser, "To BCD", "test input", "test_output"); + // testOp(browser, "To Base", "test input", "test_output"); + // testOp(browser, "To Base32", "test input", "test_output"); + // testOp(browser, "To Base58", "test input", "test_output"); + // testOp(browser, "To Base62", "test input", "test_output"); + // testOp(browser, "To Base64", "test input", "test_output"); + // testOp(browser, "To Base85", "test input", "test_output"); + // testOp(browser, "To Binary", "test input", "test_output"); + // testOp(browser, "To Braille", "test input", "test_output"); + // testOp(browser, "To Camel case", "test input", "test_output"); + // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "To Charcode", "test input", "test_output"); + // testOp(browser, "To Decimal", "test input", "test_output"); + // testOp(browser, "To HTML Entity", "test input", "test_output"); + // testOp(browser, "To Hex", "test input", "test_output"); + // testOp(browser, "To Hex Content", "test input", "test_output"); + // testOp(browser, "To Hexdump", "test input", "test_output"); + // testOp(browser, "To Kebab case", "test input", "test_output"); + // testOp(browser, "To Lower case", "test input", "test_output"); + // testOp(browser, "To MessagePack", "test input", "test_output"); + // testOp(browser, "To Morse Code", "test input", "test_output"); + // testOp(browser, "To Octal", "test input", "test_output"); + // testOp(browser, "To Punycode", "test input", "test_output"); + // testOp(browser, "To Quoted Printable", "test input", "test_output"); + // testOp(browser, "To Snake case", "test input", "test_output"); + // testOp(browser, "To Table", "test input", "test_output"); + // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "To Upper case", "test input", "test_output"); + // testOp(browser, "Translate DateTime Format", "test input", "test_output"); + // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); + // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); + // testOp(browser, "Typex", "test input", "test_output"); + // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); + // testOp(browser, "URL Decode", "test input", "test_output"); + // testOp(browser, "URL Encode", "test input", "test_output"); + // testOp(browser, "Unescape string", "test input", "test_output"); + // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Unique", "test input", "test_output"); + // testOp(browser, "Untar", "test input", "test_output"); + // testOp(browser, "Unzip", "test input", "test_output"); + // testOp(browser, "VarInt Decode", "test input", "test_output"); + // testOp(browser, "VarInt Encode", "test input", "test_output"); + // testOp(browser, "View Bit Plane", "test input", "test_output"); + // testOp(browser, "Vigenère Decode", "test input", "test_output"); + // testOp(browser, "Vigenère Encode", "test input", "test_output"); + // testOp(browser, "Whirlpool", "test input", "test_output"); + // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "XKCD Random Number", "test input", "test_output"); + // testOp(browser, "XML Beautify", "test input", "test_output"); + // testOp(browser, "XML Minify", "test input", "test_output"); + // testOp(browser, "XOR", "test input", "test_output"); + // testOp(browser, "XOR Brute Force", "test input", "test_output"); + // testOp(browser, "XPath expression", "test input", "test_output"); + // testOp(browser, "YARA Rules", "test input", "test_output"); + // testOp(browser, "Zip", "test input", "test_output"); + // testOp(browser, "Zlib Deflate", "test input", "test_output"); + // testOp(browser, "Zlib Inflate", "test input", "test_output"); + }); }, @@ -376,22 +387,47 @@ module.exports = { }; /** - * Clears the current recipe and tests a new operation. + * Clears the current recipe and bakes a new operation. * * @param {string} opName * @param {Browser} browser */ -function testOp(browser, opName, input, output, args=[]) { +function bakeOp(browser, opName, input, args=[]) { - const recipeConfig = JSON.stringify([{ - "op": opName, - "args": args - }]); + let recipeConfig; + /* + * Create recipeConfig as single operation + * or wrapped with a pre-op and + * possibly a post-op too + */ + if (typeof(opName) === "string") { + recipeConfig = JSON.stringify([{ + "op": opName, + "args": args + }]); + } else if (opName.length === 2) { + recipeConfig = JSON.stringify([{ + "op": opName[0], + "args": [] + }, { + "op": opName[1], + "args": args + }]); + } else { + recipeConfig = JSON.stringify([{ + "op": opName[0], + "args": [] + }, { + "op": opName[1], + "args": args + }, { + "op": opName[2], + "args": [] + + }]); + } browser - .perform(function() { - console.log(opName); - }) .useCss() .click("#clr-recipe") .click("#clr-io") @@ -400,6 +436,14 @@ function testOp(browser, opName, input, output, args=[]) { browser .urlHash("recipe=" + recipeConfig) + .url(function(result) { + currentUrl = result; + }) + .perform(function() { + console.log(currentUrl); + console.log(opName); + console.log(recipeConfig); + }) .setValue("#input-text", input) .waitForElementPresent("#rec-list li.operation") .expect.element("#input-text").to.have.value.that.equals(input); @@ -412,9 +456,46 @@ function testOp(browser, opName, input, output, args=[]) { .waitForElementPresent("#stale-indicator.hidden", 5000) .waitForElementNotVisible("#output-loader", 5000); + let currentUrl=""; + browser + .url(function(result) { + currentUrl = result; + }) + .perform(function() { + console.log(currentUrl.value); + }); +} + +/** + * Clears the current recipe and tests a new operation. + * + * @param {string} opName + * @param {Browser} browser + */ +function testOp(browser, opName, input, output, args=[]) { + + bakeOp(browser, opName, input, args); + if (typeof output === "string") { browser.expect.element("#output-text").to.have.value.that.equals(output); } else if (output instanceof RegExp) { browser.expect.element("#output-text").to.have.value.that.matches(output); } } + +/** + * Clears the current recipe and tests a new operation. + * + * @param {string} opName + * @param {Browser} browser + */ +function testOpHtml(browser, opName, input, element, output, args=[]) { + + bakeOp(browser, opName, input, args); + browser.waitForElementPresent("#output-html", 5000); + if (typeof output === "string") { + browser.expect.element("#output-html " + element).to.have.value.that.equals(output); + } else if (output instanceof RegExp) { + browser.expect.element("#output-html " + element).to.have.value.that.matches(output); + } +} diff --git a/tests/operations/samples/Images.mjs b/tests/operations/samples/Images.mjs index 663fa201..396e9f7d 100644 --- a/tests/operations/samples/Images.mjs +++ b/tests/operations/samples/Images.mjs @@ -18,6 +18,12 @@ export const GIF_ANIMATED_HEX = "4749463839610f000f00b30b00424242ffe700ffef00ffc */ export const PNG_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082"; +/** + * The CyberChef logo with 'chef' + * 32x32 + */ +export const PNG_CHEF_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000006e4494441547801a5c17d6c947701c0f1efeff73cf7debbbed0d2a3c7515e5ae81bd1c2601bd0256685e29808a84c9bc00cfec14b8448b205636234997f2ca8c1f9075163c8d61582246b9913df161184a6c46a24a3a1b4bb513aeee8fb95bb722fcf5def797c6a21e5e55abaf9f9083e1fa5b9b9b9c6ebf5ae4b24124a3018bcb27ffffeff003a200103d09903c1dc084002c6c183073dfbf6edfb555e5ede37a2d128b1584c0246341afd606c6ceca3a2a2a22d9aa65ddbb871e31e20c353a8cc4eb4b4b43cbb7cf9f203369bad4ad7f518e070bbdd6b98a23345783c9ead6eb7fb2bc264b3d9caac56ebf79a9a9abe64b7db0bb66ddb7602d0c9423033d1d6d67660f1e2c5c7841016b28844227a2c169364914c266fdb6c361fa66030b867fbf6edef9085ca0c5a5a5a9e292d2d3d2684b0f039d8ed763f530c5dd79989243b515e5ebe5f4a69e1ffa469dad0ae5dbbce02822c14b2530e1f3efc03abd5ea6316a9548a542a259885aaaa39df32eddcb9d3dfdcdcfc218f51c9ce3025793ac11cd8edf6d24c26f33c20810c0f9164a7c762b18b3c9dc11c689a164a24121d80ce631466b068d1a2ae9a9a9a464551dcdc97c964300c0329259392c9a4914ea705b3d0346da8a1a1a1eac48913bf070ca6496081c2a316017540d5f9f3e78b2a2b2bff585a5aba5a55d579985a5b5b0904025454543049d334239d4e0b66a1aaaaabbebebeeff4e9d31d4c73027b81f592699b815701158803b97bf7ee5d5557577748d7f534264551501485b9482412bd8661640cc3d04d291eb50e70026fa94c59013c0b9c006e33ad2e140a6d8d442296fcfc7ce62a93c9c45f78e185d5274f9eac733a9d453b76ec789b47f9818f8188ca94e7804ee0368ffa27f0b54020c09a356b7820994cd2dddd4d2412910e87039fcfc7c3344dd30dc358d1d8d83804dc649a0aac053c80049e9380022c003ee5491a70b4baba9a07464646686e6ea6b7b7974020c0b973e7e8eeeee681f1f171ce9e3d9b036c0096029b80ef00164001ca003b900f2c530107e00286c92e62b7db53801553341aa5b1b191c2c242229188ded2d2223b3b3b59b16205932e5fbe8ccbe5c2741c88032e601fb01ab80234017b8061e00395290230c82ed1d6d6f637b7dbfde5bebe3ea49404834182c12077eedc21180c12080470b95c4c4c4c70e1c2052a2b2b3b8134a00049e026b014b8c23481490574200338c9ce52565656ae280a797979a8aa4a49490993ac562be17098bb77ef525151c1c0c000f3e7cfa7bfbfbf0678134833450706c94205e24014980f74f190aa62977d7da5ffd4e0bfff5ae62b2e428cf4225405d1f72f1c050b8d5c87db4824128c8e8ed2d3d36384c361313232426d6d2d757575572e5dbaf427a6e96421997203a80604d3e4d76b4b7e674875bbd1db810c5c420cde400c7421039729713a854b5184896030487b7bbbe8eaea22180cd2d1d1416e6eeec98686061f700f880371b2904c69030a8097012ba6576abd55b7c7e25b0d2d8eb7681e0f24523a0b9ed981abb094496eb71bdf721f5abe8694128fc743381c46d7f54fc2a6fafafa9552ca5dc02ab2509892046e016b804d409dd7637ba3c065295ce97550d7f8238a2bd6f1c63b2d8cbbfd2c29aba1b8a0806bd7af33343e2edeed7f17e72b4e6ad7d6b279f9662c160b3d3d3d85baaebfae69dafe850b17e68442a15f02134c5905c4816e856911a003b8feedb5beb117cb0b5e2b2b744a4c351bb6e329282692d0f83418e49b2fbd8448a709f4f60ae976b3e0f905b4c5dad8e6d986dfeea7a4a4243c3a3a7ab7b8b8d85d5c5c4c6e6eeef16bd7ae5d62da2de026905279d2f02a9ffb87393645e5318776efe6d0eedd64749dd8c00093a2d128f5f3eaa9cfa98704ff63b3d9462391c86b3e9feffd582cf6db53a74efd82478d719fe449d2a28a55cc42d334ecaacaa4d1d1511ea7ebbaccc9c9d980c966b3addfb469d31266207992a1eb0c320b9bcd460a931046341ac5300c1e964c26977a3c9ed731a9aa5ae9f57abfcb0c549e640cdf4bfdda69757c550814b250a4c4555444f9ca9548af1721048f11a954ea6a341afd89dbedde1a0a858e3103952c7efc974f3e7cf3e5f203f373ac3f053cdca7eb3aa1681497c381a2aa7c74e386f8f3850bc6c4c4042e972bb365cb16c52430a5d3e9bfb7b6b6be07bcc72c54b233beff878f7fb3f38bdef797cc736c56ad8eb7805c29255e8783a14080c4e82899c141c3eff71b252525f8fd7e45983059add6dba150e8e7cc81ca2cce5c1d18049a760f0d6b654ed7cfac168bcf62b3e1abae6652babfdfc81b1e963c2493c9dc89c7e3072f5ebc18620e14e6e0785353a7aeeb6f572c5b366eb35a17ab8a928f69e4de3d632c1e179832994c301e8f1f6b6f6f7ff5c89123579923c16724a5b4fee3cc99aad2850bbf702b1ccebd393c7ccfd479f4e8d1ab7d7d7d293ea3ff02d269af2f0fa7289f0000000049454e44ae426082"; + /** * Sunglasses smiley * 32x32 From 7b497181fdceea62dccfab846c41247a14abc2ff Mon Sep 17 00:00:00 2001 From: John L Date: Mon, 4 Apr 2022 17:40:58 +0100 Subject: [PATCH 08/39] refactor samples, and more tests --- tests/browser/ops.js | 712 ++++++++++----------- tests/operations/tests/Image.mjs | 2 +- tests/operations/tests/Magic.mjs | 2 +- tests/operations/tests/PGP.mjs | 2 +- tests/operations/tests/RSA.mjs | 2 +- tests/{operations => }/samples/Ciphers.mjs | 0 tests/{operations => }/samples/Images.mjs | 8 +- 7 files changed, 361 insertions(+), 367 deletions(-) rename tests/{operations => }/samples/Ciphers.mjs (100%) rename tests/{operations => }/samples/Images.mjs (90%) diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 49e7c63a..90747aef 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -16,368 +16,356 @@ module.exports = { .click("#auto-bake-label"); }, - "Sanity check operations": browser => { - import("../operations/samples/Images.mjs") - .then(Images => { - testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); - testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); - testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); - }); - }, - "Sanity check operations": browser => { - import("../operations/samples/Images.mjs").then(Images => { - testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); - testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); - testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); - testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); - testOp(browser, "Add line numbers", "test input", "1 test input"); - // testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); - // testOp(browser, "Add Text To Image", "test input", "test_output"); - testOp(browser, "Adler-32 Checksum", "test input", "16160411"); - testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); - testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); - testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); - testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); - // testOp(browser, "Avro to JSON", "test input", "test_output"); - // testOp(browser, "BLAKE2b", "test input", "test_output"); - // testOp(browser, "BLAKE2s", "test input", "test_output"); - // testOp(browser, "BSON deserialise", "test input", "test_output"); - // testOp(browser, "BSON serialise", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bcrypt", "test input", "test_output"); - // testOp(browser, "Bcrypt compare", "test input", "test_output"); - // testOp(browser, "Bcrypt parse", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bit shift left", "test input", "test_output"); - // testOp(browser, "Bit shift right", "test input", "test_output"); - testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); - testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); - // console.log(Images); - // testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); - // Imaged Error : Undefined ! Must be a way to Reference Exports - - // testOp(browser, "Bombe", "test input", "test_output"); - testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); - testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); - // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); - // testOp(browser, "CSS Beautify", "test input", "test_output"); - // testOp(browser, "CSS Minify", "test input", "test_output"); - // testOp(browser, "CSS selector", "test input", "test_output"); - // testOp(browser, "CSV to JSON", "test input", "test_output"); - // testOp(browser, "CTPH", "test input", "test_output"); - // testOp(browser, "Cartesian Product", "test input", "test_output"); - // testOp(browser, "Change IP format", "test input", "test_output"); - // testOp(browser, "Chi Square", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); - // testOp(browser, "Colossus", "test input", "test_output"); - // testOp(browser, "Comment", "test input", "test_output"); - // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); - // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); - // /testOp(browser, "Conditional Jump", "test input", "test_output"); - // testOp(browser, "Contain Image", "test input", "test_output"); - // testOp(browser, "Convert area", "test input", "test_output"); - // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); - // testOp(browser, "Convert data units", "test input", "test_output"); - // testOp(browser, "Convert distance", "test input", "test_output"); - // testOp(browser, "Convert Image Format", "test input", "test_output"); - // testOp(browser, "Convert mass", "test input", "test_output"); - // testOp(browser, "Convert speed", "test input", "test_output"); - // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); - // testOp(browser, "Count occurrences", "test input", "test_output"); - // testOp(browser, "Cover Image", "test input", "test_output"); - // testOp(browser, "Crop Image", "test input", "test_output"); - // testOp(browser, "DES Decrypt", "test input", "test_output"); - // testOp(browser, "DES Encrypt", "test input", "test_output"); - // testOp(browser, "DNS over HTTPS", "test input", "test_output"); - // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); - // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Decode text", "test input", "test_output"); - // testOp(browser, "Defang IP Addresses", "test input", "test_output"); - // testOp(browser, "Defang URL", "test input", "test_output"); - // testOp(browser, "Derive EVP key", "test input", "test_output"); - // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); - // testOp(browser, "Detect File Type", "test input", "test_output"); - // testOp(browser, "Diff", "test input", "test_output"); - // testOp(browser, "Disassemble x86", "test input", "test_output"); - // testOp(browser, "Dither Image", "test input", "test_output"); - // testOp(browser, "Divide", "test input", "test_output"); - // testOp(browser, "Drop bytes", "test input", "test_output"); - // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Encode text", "test input", "test_output"); - // testOp(browser, "Enigma", "test input", "test_output"); - // testOp(browser, "Entropy", "test input", "test_output"); - // testOp(browser, "Escape string", "test input", "test_output"); - // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Expand alphabet range", "test input", "test_output"); - // testOp(browser, "Extract dates", "test input", "test_output"); - // testOp(browser, "Extract domains", "test input", "test_output"); - // testOp(browser, "Extract EXIF", "test input", "test_output"); - // testOp(browser, "Extract email addresses", "test input", "test_output"); - // testOp(browser, "Extract file paths", "test input", "test_output"); - // testOp(browser, "Extract Files", "test input", "test_output"); - // testOp(browser, "Extract IP addresses", "test input", "test_output"); - // testOp(browser, "Extract LSB", "test input", "test_output"); - // testOp(browser, "Extract MAC addresses", "test input", "test_output"); - // testOp(browser, "Extract RGBA", "test input", "test_output"); - // testOp(browser, "Extract URLs", "test input", "test_output"); - // testOp(browser, "Filter", "test input", "test_output"); - // testOp(browser, "Find / Replace", "test input", "test_output"); - // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); - // testOp(browser, "Flip Image", "test input", "test_output"); - // testOp(browser, "Fork", "test input", "test_output"); - // testOp(browser, "Format MAC addresses", "test input", "test_output"); - // testOp(browser, "Frequency distribution", "test input", "test_output"); - // testOp(browser, "From BCD", "test input", "test_output"); - // testOp(browser, "From Base", "test input", "test_output"); - // testOp(browser, "From Base32", "test input", "test_output"); - // testOp(browser, "From Base58", "test input", "test_output"); - // testOp(browser, "From Base62", "test input", "test_output"); - // testOp(browser, "From Base64", "test input", "test_output"); - // testOp(browser, "From Base85", "test input", "test_output"); - // testOp(browser, "From Binary", "test input", "test_output"); - // testOp(browser, "From Braille", "test input", "test_output"); - // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "From Charcode", "test input", "test_output"); - // testOp(browser, "From Decimal", "test input", "test_output"); - // testOp(browser, "From HTML Entity", "test input", "test_output"); - // testOp(browser, "From Hex", "test input", "test_output"); - // testOp(browser, "From Hex Content", "test input", "test_output"); - // testOp(browser, "From Hexdump", "test input", "test_output"); - // testOp(browser, "From MessagePack", "test input", "test_output"); - // testOp(browser, "From Morse Code", "test input", "test_output"); - // testOp(browser, "From Octal", "test input", "test_output"); - // testOp(browser, "From Punycode", "test input", "test_output"); - // testOp(browser, "From Quoted Printable", "test input", "test_output"); - // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "GOST hash", "test input", "test_output"); - // testOp(browser, "Generate all hashes", "test input", "test_output"); - // testOp(browser, "Generate HOTP", "test input", "test_output"); - // testOp(browser, "Generate Image", "test input", "test_output"); - // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); - // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); - // testOp(browser, "Generate QR Code", "test input", "test_output"); - // testOp(browser, "Generate TOTP", "test input", "test_output"); - // testOp(browser, "Generate UUID", "test input", "test_output"); - // testOp(browser, "Generic Code Beautify", "test input", "test_output"); - // testOp(browser, "Group IP addresses", "test input", "test_output"); - // testOp(browser, "Gunzip", "test input", "test_output"); - // testOp(browser, "Gzip", "test input", "test_output"); - // testOp(browser, "HAS-160", "test input", "test_output"); - // testOp(browser, "HMAC", "test input", "test_output"); - // testOp(browser, "HTML To Text", "test input", "test_output"); - // testOp(browser, "HTTP request", "test input", "test_output"); - // testOp(browser, "Hamming Distance", "test input", "test_output"); - // testOp(browser, "Haversine distance", "test input", "test_output"); - // testOp(browser, "Head", "test input", "test_output"); - // testOp(browser, "Heatmap chart", "test input", "test_output"); - // testOp(browser, "Hex Density chart", "test input", "test_output"); - // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); - // testOp(browser, "Hex to PEM", "test input", "test_output"); - // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); - // testOp(browser, "Image Filter", "test input", "test_output"); - // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); - // testOp(browser, "Image Opacity", "test input", "test_output"); - // testOp(browser, "Index of Coincidence", "test input", "test_output"); - // testOp(browser, "Invert Image", "test input", "test_output"); - // testOp(browser, "JPath expression", "test input", "test_output"); - // testOp(browser, "JSON Beautify", "test input", "test_output"); - // testOp(browser, "JSON Minify", "test input", "test_output"); - // testOp(browser, "JSON to CSV", "test input", "test_output"); - // testOp(browser, "JWT Decode", "test input", "test_output"); - // testOp(browser, "JWT Sign", "test input", "test_output"); - // testOp(browser, "JWT Verify", "test input", "test_output"); - // testOp(browser, "JavaScript Beautify", "test input", "test_output"); - // testOp(browser, "JavaScript Minify", "test input", "test_output"); - // testOp(browser, "JavaScript Parser", "test input", "test_output"); - // testOp(browser, "Jump", "test input", "test_output"); - // testOp(browser, "Keccak", "test input", "test_output"); - // testOp(browser, "Label", "test input", "test_output"); - // testOp(browser, "Lorenz", "test input", "test_output"); - // testOp(browser, "Luhn Checksum", "test input", "test_output"); - // testOp(browser, "MD2", "test input", "test_output"); - // testOp(browser, "MD4", "test input", "test_output"); - // testOp(browser, "MD5", "test input", "test_output"); - // testOp(browser, "MD6", "test input", "test_output"); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:nth-of-type(1) td:nth-of-type(2)", "Result snippet"); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:eq(1) td:eq(1)", "test_output"); - // testOp(browser, "Mean", "test input", "test_output"); - // testOp(browser, "Median", "test input", "test_output");` - // testOp(browser, "Merge", "test input", "test_output");` - // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); - // testOp(browser, "Multiple Bombe", "test input", "test_output"); - // testOp(browser, "Multiply", "test input", "test_output"); - // testOp(browser, "NOT", "test input", "test_output"); - // testOp(browser, "Normalise Image", "test input", "test_output"); - // testOp(browser, "Normalise Unicode", "test input", "test_output"); - // testOp(browser, "Numberwang", "test input", "test_output"); - // testOp(browser, "OR", "test input", "test_output"); - // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); - // testOp(browser, "Offset checker", "test input", "test_output"); - // testOp(browser, "Optical Character Recognition", "test input", "test_output"); - // testOp(browser, "PEM to Hex", "test input", "test_output"); - // testOp(browser, "PGP Decrypt", "test input", "test_output"); - // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); - // testOp(browser, "PGP Encrypt", "test input", "test_output"); - // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); - // testOp(browser, "PGP Verify", "test input", "test_output"); - // testOp(browser, "PHP Deserialize", "test input", "test_output"); - // testOp(browser, "Pad lines", "test input", "test_output"); - // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); - // testOp(browser, "Parse colour code", "test input", "test_output"); - // testOp(browser, "Parse DateTime", "test input", "test_output"); - // testOp(browser, "Parse IP range", "test input", "test_output"); - // testOp(browser, "Parse IPv4 header", "test input", "test_output"); - // testOp(browser, "Parse IPv6 address", "test input", "test_output"); - // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); - // testOp(browser, "Parse QR Code", "test input", "test_output"); - // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); - // testOp(browser, "Parse TLV", "test input", "test_output"); - // testOp(browser, "Parse UDP", "test input", "test_output"); - // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); - // testOp(browser, "Parse URI", "test input", "test_output"); - // testOp(browser, "Parse User Agent", "test input", "test_output"); - // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); - // testOp(browser, "Play Media", "test input", "test_output"); - // testOp(browser, "Power Set", "test input", "test_output"); - // testOp(browser, "Protobuf Decode", "test input", "test_output"); - // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); - // testOp(browser, "RC2 Decrypt", "test input", "test_output"); - // testOp(browser, "RC2 Encrypt", "test input", "test_output"); - // testOp(browser, "RC4", "test input", "test_output"); - // testOp(browser, "RC4 Drop", "test input", "test_output"); - // testOp(browser, "RIPEMD", "test input", "test_output"); - // testOp(browser, "ROT13", "test input", "test_output"); - // testOp(browser, "ROT47", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); - // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); - // testOp(browser, "Raw Deflate", "test input", "test_output"); - // testOp(browser, "Raw Inflate", "test input", "test_output"); - // testOp(browser, "Register", "test input", "test_output"); - // testOp(browser, "Regular expression", "test input", "test_output"); - // testOp(browser, "Remove Diacritics", "test input", "test_output"); - // testOp(browser, "Remove EXIF", "test input", "test_output"); - // testOp(browser, "Remove line numbers", "test input", "test_output"); - // testOp(browser, "Remove null bytes", "test input", "test_output"); - // testOp(browser, "Remove whitespace", "test input", "test_output"); - // testOp(browser, "Render Image", "test input", "test_output"); - // testOp(browser, "Render Markdown", "test input", "test_output"); - // testOp(browser, "Resize Image", "test input", "test_output"); - // testOp(browser, "Return", "test input", "test_output"); - // testOp(browser, "Reverse", "test input", "test_output"); - // testOp(browser, "Rotate Image", "test input", "test_output"); - // testOp(browser, "Rotate left", "test input", "test_output"); - // testOp(browser, "Rotate right", "test input", "test_output"); - // testOp(browser, "SHA0", "test input", "test_output"); - // testOp(browser, "SHA1", "test input", "test_output"); - // testOp(browser, "SHA2", "test input", "test_output"); - // testOp(browser, "SHA3", "test input", "test_output"); - // testOp(browser, "SQL Beautify", "test input", "test_output"); - // testOp(browser, "SQL Minify", "test input", "test_output"); - // testOp(browser, "SSDEEP", "test input", "test_output"); - // testOp(browser, "SUB", "test input", "test_output"); - // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); - // testOp(browser, "Scatter chart", "test input", "test_output"); - // testOp(browser, "Scrypt", "test input", "test_output"); - // testOp(browser, "Series chart", "test input", "test_output"); - // testOp(browser, "Set Difference", "test input", "test_output"); - // testOp(browser, "Set Intersection", "test input", "test_output"); - // testOp(browser, "Set Union", "test input", "test_output"); - // testOp(browser, "Shake", "test input", "test_output"); - // testOp(browser, "Sharpen Image", "test input", "test_output"); - // testOp(browser, "Show Base64 offsets", "test input", "test_output"); - // testOp(browser, "Show on map", "test input", "test_output"); - // testOp(browser, "Sleep", "test input", "test_output"); - // testOp(browser, "Snefru", "test input", "test_output"); - // testOp(browser, "Sort", "test input", "test_output"); - // testOp(browser, "Split", "test input", "test_output"); - // testOp(browser, "Split Colour Channels", "test input", "test_output"); - // testOp(browser, "Standard Deviation", "test input", "test_output"); - // testOp(browser, "Streebog", "test input", "test_output"); - // testOp(browser, "Strings", "test input", "test_output"); - // testOp(browser, "Strip HTML tags", "test input", "test_output"); - // testOp(browser, "Strip HTTP headers", "test input", "test_output"); - // testOp(browser, "Subsection", "test input", "test_output"); - // testOp(browser, "Substitute", "test input", "test_output"); - // testOp(browser, "Subtract", "test input", "test_output"); - // testOp(browser, "Sum", "test input", "test_output"); - // testOp(browser, "Swap endianness", "test input", "test_output"); - // testOp(browser, "Symmetric Difference", "test input", "test_output"); - // testOp(browser, "Syntax highlighter", "test input", "test_output"); - // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); - // testOp(browser, "Tail", "test input", "test_output"); - // testOp(browser, "Take bytes", "test input", "test_output"); - // testOp(browser, "Tar", "test input", "test_output"); - // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); - // testOp(browser, "To BCD", "test input", "test_output"); - // testOp(browser, "To Base", "test input", "test_output"); - // testOp(browser, "To Base32", "test input", "test_output"); - // testOp(browser, "To Base58", "test input", "test_output"); - // testOp(browser, "To Base62", "test input", "test_output"); - // testOp(browser, "To Base64", "test input", "test_output"); - // testOp(browser, "To Base85", "test input", "test_output"); - // testOp(browser, "To Binary", "test input", "test_output"); - // testOp(browser, "To Braille", "test input", "test_output"); - // testOp(browser, "To Camel case", "test input", "test_output"); - // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "To Charcode", "test input", "test_output"); - // testOp(browser, "To Decimal", "test input", "test_output"); - // testOp(browser, "To HTML Entity", "test input", "test_output"); - // testOp(browser, "To Hex", "test input", "test_output"); - // testOp(browser, "To Hex Content", "test input", "test_output"); - // testOp(browser, "To Hexdump", "test input", "test_output"); - // testOp(browser, "To Kebab case", "test input", "test_output"); - // testOp(browser, "To Lower case", "test input", "test_output"); - // testOp(browser, "To MessagePack", "test input", "test_output"); - // testOp(browser, "To Morse Code", "test input", "test_output"); - // testOp(browser, "To Octal", "test input", "test_output"); - // testOp(browser, "To Punycode", "test input", "test_output"); - // testOp(browser, "To Quoted Printable", "test input", "test_output"); - // testOp(browser, "To Snake case", "test input", "test_output"); - // testOp(browser, "To Table", "test input", "test_output"); - // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "To Upper case", "test input", "test_output"); - // testOp(browser, "Translate DateTime Format", "test input", "test_output"); - // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); - // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); - // testOp(browser, "Typex", "test input", "test_output"); - // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); - // testOp(browser, "URL Decode", "test input", "test_output"); - // testOp(browser, "URL Encode", "test input", "test_output"); - // testOp(browser, "Unescape string", "test input", "test_output"); - // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Unique", "test input", "test_output"); - // testOp(browser, "Untar", "test input", "test_output"); - // testOp(browser, "Unzip", "test input", "test_output"); - // testOp(browser, "VarInt Decode", "test input", "test_output"); - // testOp(browser, "VarInt Encode", "test input", "test_output"); - // testOp(browser, "View Bit Plane", "test input", "test_output"); - // testOp(browser, "Vigenère Decode", "test input", "test_output"); - // testOp(browser, "Vigenère Encode", "test input", "test_output"); - // testOp(browser, "Whirlpool", "test input", "test_output"); - // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "XKCD Random Number", "test input", "test_output"); - // testOp(browser, "XML Beautify", "test input", "test_output"); - // testOp(browser, "XML Minify", "test input", "test_output"); - // testOp(browser, "XOR", "test input", "test_output"); - // testOp(browser, "XOR Brute Force", "test input", "test_output"); - // testOp(browser, "XPath expression", "test input", "test_output"); - // testOp(browser, "YARA Rules", "test input", "test_output"); - // testOp(browser, "Zip", "test input", "test_output"); - // testOp(browser, "Zlib Deflate", "test input", "test_output"); - // testOp(browser, "Zlib Inflate", "test input", "test_output"); - }); + "Sanity check operations": async browser => { + const Images = await import("../samples/Images.mjs"); + testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); + testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); + testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); + testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); + testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); + testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); + testOp(browser, "Add line numbers", "test input", "1 test input"); + testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, ["Chef", "Center", "Middle", 0, 0, 16]); + testOp(browser, "Adler-32 Checksum", "test input", "16160411"); + testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); + testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); + testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); + testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); + // testOp(browser, "Avro to JSON", "test input", "test_output"); + // testOp(browser, "BLAKE2b", "test input", "test_output"); + // testOp(browser, "BLAKE2s", "test input", "test_output"); + // testOp(browser, "BSON deserialise", "test input", "test_output"); + // testOp(browser, "BSON serialise", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bcrypt", "test input", "test_output"); + // testOp(browser, "Bcrypt compare", "test input", "test_output"); + // testOp(browser, "Bcrypt parse", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bit shift left", "test input", "test_output"); + // testOp(browser, "Bit shift right", "test input", "test_output"); + testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); + testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); + testOp(browser, ["From Hex", "Blur Image", "To Base64"], Images.PNG_HEX, Images.PNG_BLUR_B64); + // testOp(browser, "Bombe", "test input", "test_output"); + testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); + testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); + // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); + // testOp(browser, "CSS Beautify", "test input", "test_output"); + // testOp(browser, "CSS Minify", "test input", "test_output"); + // testOp(browser, "CSS selector", "test input", "test_output"); + // testOp(browser, "CSV to JSON", "test input", "test_output"); + // testOp(browser, "CTPH", "test input", "test_output"); + // testOp(browser, "Cartesian Product", "test input", "test_output"); + // testOp(browser, "Change IP format", "test input", "test_output"); + // testOp(browser, "Chi Square", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); + // testOp(browser, "Colossus", "test input", "test_output"); + // testOp(browser, "Comment", "test input", "test_output"); + // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); + // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); + // /testOp(browser, "Conditional Jump", "test input", "test_output"); + // testOp(browser, "Contain Image", "test input", "test_output"); + // testOp(browser, "Convert area", "test input", "test_output"); + // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); + // testOp(browser, "Convert data units", "test input", "test_output"); + // testOp(browser, "Convert distance", "test input", "test_output"); + // testOp(browser, "Convert Image Format", "test input", "test_output"); + // testOp(browser, "Convert mass", "test input", "test_output"); + // testOp(browser, "Convert speed", "test input", "test_output"); + // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); + // testOp(browser, "Count occurrences", "test input", "test_output"); + // testOp(browser, "Cover Image", "test input", "test_output"); + // testOp(browser, "Crop Image", "test input", "test_output"); + // testOp(browser, "DES Decrypt", "test input", "test_output"); + // testOp(browser, "DES Encrypt", "test input", "test_output"); + // testOp(browser, "DNS over HTTPS", "test input", "test_output"); + // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); + // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Decode text", "test input", "test_output"); + // testOp(browser, "Defang IP Addresses", "test input", "test_output"); + // testOp(browser, "Defang URL", "test input", "test_output"); + // testOp(browser, "Derive EVP key", "test input", "test_output"); + // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); + // testOp(browser, "Detect File Type", "test input", "test_output"); + // testOp(browser, "Diff", "test input", "test_output"); + // testOp(browser, "Disassemble x86", "test input", "test_output"); + // testOp(browser, "Dither Image", "test input", "test_output"); + // testOp(browser, "Divide", "test input", "test_output"); + // testOp(browser, "Drop bytes", "test input", "test_output"); + // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Encode text", "test input", "test_output"); + // testOp(browser, "Enigma", "test input", "test_output"); + // testOp(browser, "Entropy", "test input", "test_output"); + // testOp(browser, "Escape string", "test input", "test_output"); + // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Expand alphabet range", "test input", "test_output"); + // testOp(browser, "Extract dates", "test input", "test_output"); + // testOp(browser, "Extract domains", "test input", "test_output"); + // testOp(browser, "Extract EXIF", "test input", "test_output"); + // testOp(browser, "Extract email addresses", "test input", "test_output"); + // testOp(browser, "Extract file paths", "test input", "test_output"); + // testOp(browser, "Extract Files", "test input", "test_output"); + // testOp(browser, "Extract IP addresses", "test input", "test_output"); + // testOp(browser, "Extract LSB", "test input", "test_output"); + // testOp(browser, "Extract MAC addresses", "test input", "test_output"); + // testOp(browser, "Extract RGBA", "test input", "test_output"); + // testOp(browser, "Extract URLs", "test input", "test_output"); + // testOp(browser, "Filter", "test input", "test_output"); + // testOp(browser, "Find / Replace", "test input", "test_output"); + // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); + // testOp(browser, "Flip Image", "test input", "test_output"); + // testOp(browser, "Fork", "test input", "test_output"); + // testOp(browser, "Format MAC addresses", "test input", "test_output"); + // testOp(browser, "Frequency distribution", "test input", "test_output"); + // testOp(browser, "From BCD", "test input", "test_output"); + // testOp(browser, "From Base", "test input", "test_output"); + // testOp(browser, "From Base32", "test input", "test_output"); + // testOp(browser, "From Base58", "test input", "test_output"); + // testOp(browser, "From Base62", "test input", "test_output"); + // testOp(browser, "From Base64", "test input", "test_output"); + // testOp(browser, "From Base85", "test input", "test_output"); + // testOp(browser, "From Binary", "test input", "test_output"); + // testOp(browser, "From Braille", "test input", "test_output"); + // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "From Charcode", "test input", "test_output"); + // testOp(browser, "From Decimal", "test input", "test_output"); + // testOp(browser, "From HTML Entity", "test input", "test_output"); + // testOp(browser, "From Hex", "test input", "test_output"); + // testOp(browser, "From Hex Content", "test input", "test_output"); + // testOp(browser, "From Hexdump", "test input", "test_output"); + // testOp(browser, "From MessagePack", "test input", "test_output"); + // testOp(browser, "From Morse Code", "test input", "test_output"); + // testOp(browser, "From Octal", "test input", "test_output"); + // testOp(browser, "From Punycode", "test input", "test_output"); + // testOp(browser, "From Quoted Printable", "test input", "test_output"); + // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "GOST hash", "test input", "test_output"); + // testOp(browser, "Generate all hashes", "test input", "test_output"); + // testOp(browser, "Generate HOTP", "test input", "test_output"); + // testOp(browser, "Generate Image", "test input", "test_output"); + // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); + // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); + // testOp(browser, "Generate QR Code", "test input", "test_output"); + // testOp(browser, "Generate TOTP", "test input", "test_output"); + // testOp(browser, "Generate UUID", "test input", "test_output"); + // testOp(browser, "Generic Code Beautify", "test input", "test_output"); + // testOp(browser, "Group IP addresses", "test input", "test_output"); + // testOp(browser, "Gunzip", "test input", "test_output"); + // testOp(browser, "Gzip", "test input", "test_output"); + // testOp(browser, "HAS-160", "test input", "test_output"); + // testOp(browser, "HMAC", "test input", "test_output"); + // testOp(browser, "HTML To Text", "test input", "test_output"); + // testOp(browser, "HTTP request", "test input", "test_output"); + // testOp(browser, "Hamming Distance", "test input", "test_output"); + // testOp(browser, "Haversine distance", "test input", "test_output"); + // testOp(browser, "Head", "test input", "test_output"); + // testOp(browser, "Heatmap chart", "test input", "test_output"); + // testOp(browser, "Hex Density chart", "test input", "test_output"); + // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); + // testOp(browser, "Hex to PEM", "test input", "test_output"); + // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); + // testOp(browser, "Image Filter", "test input", "test_output"); + // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); + // testOp(browser, "Image Opacity", "test input", "test_output"); + // testOp(browser, "Index of Coincidence", "test input", "test_output"); + // testOp(browser, "Invert Image", "test input", "test_output"); + // testOp(browser, "JPath expression", "test input", "test_output"); + // testOp(browser, "JSON Beautify", "test input", "test_output"); + // testOp(browser, "JSON Minify", "test input", "test_output"); + // testOp(browser, "JSON to CSV", "test input", "test_output"); + // testOp(browser, "JWT Decode", "test input", "test_output"); + // testOp(browser, "JWT Sign", "test input", "test_output"); + // testOp(browser, "JWT Verify", "test input", "test_output"); + // testOp(browser, "JavaScript Beautify", "test input", "test_output"); + // testOp(browser, "JavaScript Minify", "test input", "test_output"); + // testOp(browser, "JavaScript Parser", "test input", "test_output"); + // testOp(browser, "Jump", "test input", "test_output"); + // testOp(browser, "Keccak", "test input", "test_output"); + // testOp(browser, "Label", "test input", "test_output"); + // testOp(browser, "Lorenz", "test input", "test_output"); + // testOp(browser, "Luhn Checksum", "test input", "test_output"); + // testOp(browser, "MD2", "test input", "test_output"); + // testOp(browser, "MD4", "test input", "test_output"); + // testOp(browser, "MD5", "test input", "test_output"); + // testOp(browser, "MD6", "test input", "test_output"); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); + testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:{1} td:{2}", "Result snippet"); + // testOp(browser, "Mean", "test input", "test_output"); + // testOp(browser, "Median", "test input", "test_output");` + // testOp(browser, "Merge", "test input", "test_output");` + // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); + // testOp(browser, "Multiple Bombe", "test input", "test_output"); + // testOp(browser, "Multiply", "test input", "test_output"); + // testOp(browser, "NOT", "test input", "test_output"); + // testOp(browser, "Normalise Image", "test input", "test_output"); + // testOp(browser, "Normalise Unicode", "test input", "test_output"); + // testOp(browser, "Numberwang", "test input", "test_output"); + // testOp(browser, "OR", "test input", "test_output"); + // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); + // testOp(browser, "Offset checker", "test input", "test_output"); + // testOp(browser, "Optical Character Recognition", "test input", "test_output"); + // testOp(browser, "PEM to Hex", "test input", "test_output"); + // testOp(browser, "PGP Decrypt", "test input", "test_output"); + // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); + // testOp(browser, "PGP Encrypt", "test input", "test_output"); + // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); + // testOp(browser, "PGP Verify", "test input", "test_output"); + // testOp(browser, "PHP Deserialize", "test input", "test_output"); + // testOp(browser, "Pad lines", "test input", "test_output"); + // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); + // testOp(browser, "Parse colour code", "test input", "test_output"); + // testOp(browser, "Parse DateTime", "test input", "test_output"); + // testOp(browser, "Parse IP range", "test input", "test_output"); + // testOp(browser, "Parse IPv4 header", "test input", "test_output"); + // testOp(browser, "Parse IPv6 address", "test input", "test_output"); + // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); + // testOp(browser, "Parse QR Code", "test input", "test_output"); + // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); + // testOp(browser, "Parse TLV", "test input", "test_output"); + // testOp(browser, "Parse UDP", "test input", "test_output"); + // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); + // testOp(browser, "Parse URI", "test input", "test_output"); + // testOp(browser, "Parse User Agent", "test input", "test_output"); + // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); + // testOp(browser, "Play Media", "test input", "test_output"); + // testOp(browser, "Power Set", "test input", "test_output"); + // testOp(browser, "Protobuf Decode", "test input", "test_output"); + // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); + // testOp(browser, "RC2 Decrypt", "test input", "test_output"); + // testOp(browser, "RC2 Encrypt", "test input", "test_output"); + // testOp(browser, "RC4", "test input", "test_output"); + // testOp(browser, "RC4 Drop", "test input", "test_output"); + // testOp(browser, "RIPEMD", "test input", "test_output"); + // testOp(browser, "ROT13", "test input", "test_output"); + // testOp(browser, "ROT47", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); + // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); + // testOp(browser, "Raw Deflate", "test input", "test_output"); + // testOp(browser, "Raw Inflate", "test input", "test_output"); + // testOp(browser, "Register", "test input", "test_output"); + // testOp(browser, "Regular expression", "test input", "test_output"); + // testOp(browser, "Remove Diacritics", "test input", "test_output"); + // testOp(browser, "Remove EXIF", "test input", "test_output"); + // testOp(browser, "Remove line numbers", "test input", "test_output"); + // testOp(browser, "Remove null bytes", "test input", "test_output"); + // testOp(browser, "Remove whitespace", "test input", "test_output"); + // testOp(browser, "Render Image", "test input", "test_output"); + // testOp(browser, "Render Markdown", "test input", "test_output"); + // testOp(browser, "Resize Image", "test input", "test_output"); + // testOp(browser, "Return", "test input", "test_output"); + // testOp(browser, "Reverse", "test input", "test_output"); + // testOp(browser, "Rotate Image", "test input", "test_output"); + // testOp(browser, "Rotate left", "test input", "test_output"); + // testOp(browser, "Rotate right", "test input", "test_output"); + // testOp(browser, "SHA0", "test input", "test_output"); + // testOp(browser, "SHA1", "test input", "test_output"); + // testOp(browser, "SHA2", "test input", "test_output"); + // testOp(browser, "SHA3", "test input", "test_output"); + // testOp(browser, "SQL Beautify", "test input", "test_output"); + // testOp(browser, "SQL Minify", "test input", "test_output"); + // testOp(browser, "SSDEEP", "test input", "test_output"); + // testOp(browser, "SUB", "test input", "test_output"); + // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); + // testOp(browser, "Scatter chart", "test input", "test_output"); + // testOp(browser, "Scrypt", "test input", "test_output"); + // testOp(browser, "Series chart", "test input", "test_output"); + // testOp(browser, "Set Difference", "test input", "test_output"); + // testOp(browser, "Set Intersection", "test input", "test_output"); + // testOp(browser, "Set Union", "test input", "test_output"); + // testOp(browser, "Shake", "test input", "test_output"); + // testOp(browser, "Sharpen Image", "test input", "test_output"); + // testOp(browser, "Show Base64 offsets", "test input", "test_output"); + // testOp(browser, "Show on map", "test input", "test_output"); + // testOp(browser, "Sleep", "test input", "test_output"); + // testOp(browser, "Snefru", "test input", "test_output"); + // testOp(browser, "Sort", "test input", "test_output"); + // testOp(browser, "Split", "test input", "test_output"); + // testOp(browser, "Split Colour Channels", "test input", "test_output"); + // testOp(browser, "Standard Deviation", "test input", "test_output"); + // testOp(browser, "Streebog", "test input", "test_output"); + // testOp(browser, "Strings", "test input", "test_output"); + // testOp(browser, "Strip HTML tags", "test input", "test_output"); + // testOp(browser, "Strip HTTP headers", "test input", "test_output"); + // testOp(browser, "Subsection", "test input", "test_output"); + // testOp(browser, "Substitute", "test input", "test_output"); + // testOp(browser, "Subtract", "test input", "test_output"); + // testOp(browser, "Sum", "test input", "test_output"); + // testOp(browser, "Swap endianness", "test input", "test_output"); + // testOp(browser, "Symmetric Difference", "test input", "test_output"); + // testOp(browser, "Syntax highlighter", "test input", "test_output"); + // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); + // testOp(browser, "Tail", "test input", "test_output"); + // testOp(browser, "Take bytes", "test input", "test_output"); + // testOp(browser, "Tar", "test input", "test_output"); + // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); + // testOp(browser, "To BCD", "test input", "test_output"); + // testOp(browser, "To Base", "test input", "test_output"); + // testOp(browser, "To Base32", "test input", "test_output"); + // testOp(browser, "To Base58", "test input", "test_output"); + // testOp(browser, "To Base62", "test input", "test_output"); + // testOp(browser, "To Base64", "test input", "test_output"); + // testOp(browser, "To Base85", "test input", "test_output"); + // testOp(browser, "To Binary", "test input", "test_output"); + // testOp(browser, "To Braille", "test input", "test_output"); + // testOp(browser, "To Camel case", "test input", "test_output"); + // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "To Charcode", "test input", "test_output"); + // testOp(browser, "To Decimal", "test input", "test_output"); + // testOp(browser, "To HTML Entity", "test input", "test_output"); + // testOp(browser, "To Hex", "test input", "test_output"); + // testOp(browser, "To Hex Content", "test input", "test_output"); + // testOp(browser, "To Hexdump", "test input", "test_output"); + // testOp(browser, "To Kebab case", "test input", "test_output"); + // testOp(browser, "To Lower case", "test input", "test_output"); + // testOp(browser, "To MessagePack", "test input", "test_output"); + // testOp(browser, "To Morse Code", "test input", "test_output"); + // testOp(browser, "To Octal", "test input", "test_output"); + // testOp(browser, "To Punycode", "test input", "test_output"); + // testOp(browser, "To Quoted Printable", "test input", "test_output"); + // testOp(browser, "To Snake case", "test input", "test_output"); + // testOp(browser, "To Table", "test input", "test_output"); + // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "To Upper case", "test input", "test_output"); + // testOp(browser, "Translate DateTime Format", "test input", "test_output"); + // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); + // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); + // testOp(browser, "Typex", "test input", "test_output"); + // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); + // testOp(browser, "URL Decode", "test input", "test_output"); + // testOp(browser, "URL Encode", "test input", "test_output"); + // testOp(browser, "Unescape string", "test input", "test_output"); + // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Unique", "test input", "test_output"); + // testOp(browser, "Untar", "test input", "test_output"); + // testOp(browser, "Unzip", "test input", "test_output"); + // testOp(browser, "VarInt Decode", "test input", "test_output"); + // testOp(browser, "VarInt Encode", "test input", "test_output"); + // testOp(browser, "View Bit Plane", "test input", "test_output"); + // testOp(browser, "Vigenère Decode", "test input", "test_output"); + // testOp(browser, "Vigenère Encode", "test input", "test_output"); + // testOp(browser, "Whirlpool", "test input", "test_output"); + // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "XKCD Random Number", "test input", "test_output"); + // testOp(browser, "XML Beautify", "test input", "test_output"); + // testOp(browser, "XML Minify", "test input", "test_output"); + // testOp(browser, "XOR", "test input", "test_output"); + // testOp(browser, "XOR Brute Force", "test input", "test_output"); + // testOp(browser, "XPath expression", "test input", "test_output"); + // testOp(browser, "YARA Rules", "test input", "test_output"); + // testOp(browser, "Zip", "test input", "test_output"); + // testOp(browser, "Zlib Deflate", "test input", "test_output"); + // testOp(browser, "Zlib Inflate", "test input", "test_output"); }, diff --git a/tests/operations/tests/Image.mjs b/tests/operations/tests/Image.mjs index 2ca363b8..1f450433 100644 --- a/tests/operations/tests/Image.mjs +++ b/tests/operations/tests/Image.mjs @@ -9,7 +9,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../samples/Images.mjs"; +import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../../samples/Images.mjs"; TestRegister.addTests([ { diff --git a/tests/operations/tests/Magic.mjs b/tests/operations/tests/Magic.mjs index 3ae143d2..24353565 100644 --- a/tests/operations/tests/Magic.mjs +++ b/tests/operations/tests/Magic.mjs @@ -7,7 +7,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import { JPG_RAW } from "../samples/Images.mjs"; +import { JPG_RAW } from "../../samples/Images.mjs"; TestRegister.addTests([ { diff --git a/tests/operations/tests/PGP.mjs b/tests/operations/tests/PGP.mjs index 9748f937..8df05fe9 100644 --- a/tests/operations/tests/PGP.mjs +++ b/tests/operations/tests/PGP.mjs @@ -6,7 +6,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs"; +import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../../samples/Ciphers.mjs"; // RSA-1024 const ALICE_PRIVATE = `-----BEGIN PGP PRIVATE KEY BLOCK----- diff --git a/tests/operations/tests/RSA.mjs b/tests/operations/tests/RSA.mjs index 33e7139f..42bc7246 100644 --- a/tests/operations/tests/RSA.mjs +++ b/tests/operations/tests/RSA.mjs @@ -6,7 +6,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs"; +import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../../samples/Ciphers.mjs"; const PEM_PRIV_2048 = `-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAwfaUOpUEutKyU3wkCv6kYunz4MqxzSuTSckRz1IxwZtwIiqq diff --git a/tests/operations/samples/Ciphers.mjs b/tests/samples/Ciphers.mjs similarity index 100% rename from tests/operations/samples/Ciphers.mjs rename to tests/samples/Ciphers.mjs diff --git a/tests/operations/samples/Images.mjs b/tests/samples/Images.mjs similarity index 90% rename from tests/operations/samples/Images.mjs rename to tests/samples/Images.mjs index 396e9f7d..c9aff915 100644 --- a/tests/operations/samples/Images.mjs +++ b/tests/samples/Images.mjs @@ -22,7 +22,13 @@ export const PNG_HEX = "89504e470d0a1a0a0000000d49484452000000200000002008060000 * The CyberChef logo with 'chef' * 32x32 */ -export const PNG_CHEF_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000006e4494441547801a5c17d6c947701c0f1efeff73cf7debbbed0d2a3c7515e5ae81bd1c2601bd0256685e29808a84c9bc00cfec14b8448b205636234997f2ca8c1f9075163c8d61582246b9913df161184a6c46a24a3a1b4bb513aeee8fb95bb722fcf5def797c6a21e5e55abaf9f9083e1fa5b9b9b9c6ebf5ae4b24124a3018bcb27ffffeff003a200103d09903c1dc084002c6c183073dfbf6edfb555e5ede37a2d128b1584c0246341afd606c6ceca3a2a2a22d9aa65ddbb871e31e20c353a8cc4eb4b4b43cbb7cf9f203369bad4ad7f518e070bbdd6b98a23345783c9ead6eb7fb2bc264b3d9caac56ebf79a9a9abe64b7db0bb66ddb7602d0c9423033d1d6d67660f1e2c5c7841016b28844227a2c169364914c266fdb6c361fa66030b867fbf6edef9085ca0c5a5a5a9e292d2d3d2684b0f039d8ed763f530c5dd79989243b515e5ebe5f4a69e1ffa469dad0ae5dbbce02822c14b2530e1f3efc03abd5ea6316a9548a542a259885aaaa39df32eddcb9d3dfdcdcfc218f51c9ce3025793ac11cd8edf6d24c26f33c20810c0f9164a7c762b18b3c9dc11c689a164a24121d80ce631466b068d1a2ae9a9a9a464551dcdc97c964300c0329259392c9a4914ea705b3d0346da8a1a1a1eac48913bf070ca6496081c2a316017540d5f9f3e78b2a2b2bff585a5aba5a55d579985a5b5b0904025454543049d334239d4e0b66a1aaaaabbebebeeff4e9d31d4c73027b81f592699b815701158803b97bf7ee5d5557577748d7f534264551501485b9482412bd8661640cc3d04d291eb50e70026fa94c59013c0b9c006e33ad2e140a6d8d442296fcfc7ce62a93c9c45f78e185d5274f9eac733a9d453b76ec789b47f9818f8188ca94e7804ee0368ffa27f0b54020c09a356b7820994cd2dddd4d2412910e87039fcfc7c3344dd30dc358d1d8d83804dc649a0aac053c80049e9380022c003ee5491a70b4baba9a07464646686e6ea6b7b7974020c0b973e7e8eeeee681f1f171ce9e3d9b036c0096029b80ef00164001ca003b900f2c530107e00286c92e62b7db53801553341aa5b1b191c2c242229188ded2d2223b3b3b59b16205932e5fbe8ccbe5c2741c88032e601fb01ab80234017b8061e00395290230c82ed1d6d6f637b7dbfde5bebe3ea49404834182c12077eedc21180c12080470b95c4c4c4c70e1c2052a2b2b3b8134a00049e026b014b8c23481490574200338c9ce52565656ae280a797979a8aa4a49490993ac562be17098bb77ef525151c1c0c000f3e7cfa7bfbfbf0678134833450706c94205e24014980f74f190aa62977d7da5ffd4e0bfff5ae62b2e428cf4225405d1f72f1c050b8d5c87db4824128c8e8ed2d3d36384c361313232426d6d2d757575572e5dbaf427a6e96421997203a80604d3e4d76b4b7e674875bbd1db810c5c420cde400c7421039729713a854b5184896030487b7bbbe8eaea22180cd2d1d1416e6eeec98686061f700f880371b2904c69030a8097012ba6576abd55b7c7e25b0d2d8eb7681e0f24523a0b9ed981abb094496eb71bdf721f5abe8694128fc743381c46d7f54fc2a6fafafa9552ca5dc02ab2509892046e016b804d409dd7637ba3c065295ce97550d7f8238a2bd6f1c63b2d8cbbfd2c29aba1b8a0806bd7af33343e2edeed7f17e72b4e6ad7d6b279f9662c160b3d3d3d85baaebfae69dafe850b17e68442a15f02134c5905c4816e856911a003b8feedb5beb117cb0b5e2b2b744a4c351bb6e329282692d0f83418e49b2fbd8448a709f4f60ae976b3e0f905b4c5dad8e6d986dfeea7a4a4243c3a3a7ab7b8b8d85d5c5c4c6e6eeef16bd7ae5d62da2de026905279d2f02a9ffb87393645e5318776efe6d0eedd64749dd8c00093a2d128f5f3eaa9cfa98704ff63b3d9462391c86b3e9feffd582cf6db53a74efd82478d719fe449d2a28a55cc42d334ecaacaa4d1d1511ea7ebbaccc9c9d980c966b3addfb469d31266207992a1eb0c320b9bcd460a931046341ac5300c1e964c26977a3c9ed731a9aa5ae9f57abfcb0c549e640cdf4bfdda69757c550814b250a4c4555444f9ca9548af1721048f11a954ea6a341afd89dbedde1a0a858e3103952c7efc974f3e7cf3e5f203f373ac3f053cdca7eb3aa1681497c381a2aa7c74e386f8f3850bc6c4c4042e972bb365cb16c52430a5d3e9bfb7b6b6be07bcc72c54b233beff878f7fb3f38bdef797cc736c56ad8eb7805c29255e8783a14080c4e82899c141c3eff71b252525f8fd7e45983059add6dba150e8e7cc81ca2cce5c1d18049a760f0d6b654ed7cfac168bcf62b3e1abae6652babfdfc81b1e963c2493c9dc89c7e3072f5ebc18620e14e6e0785353a7aeeb6f572c5b366eb35a17ab8a928f69e4de3d632c1e179832994c301e8f1f6b6f6f7ff5c89123579923c16724a5b4fee3cc99aad2850bbf702b1ccebd393c7ccfd479f4e8d1ab7d7d7d293ea3ff02d269af2f0fa7289f0000000049454e44ae426082"; +export const PNG_CHEF_B64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAH40lEQVR4AaXBfVAU5wEH4N/77t7ufXAnHlwE5MuK1uApVo1ppNBxgpJKKyijaewYJzRj0eokjBpbp3HQ0VpN1fqHndCxNkW4UWf8KHZaa0yR1hPH04QGGwm9Ata7KN/c5m5v9+52t8tIp1QPJOnzEHw5TF1dnTMlJWVxOBxmfD7fjY0bN34EQAVAAWgAVEwAwcQQABSAtmXLFltlZeW7iYmJqwVBQCgUogA0QRAuDg4OfuxwOEpkWW5dunRpBQAFT8FifOTcuXPPz5w5cxPP87mqqoYAmKxW63N4RMUjxGazrbBard8hOp7ncziOe7O2tnaJ0Wi0l5WVnQCgIg6CsRG3270pOzv7CCHEgDgCgYAaCoUo4pAk6T7P81Oh8/l8FStXrvwt4mAxhnPnzi3Myso6Qggx4EswGo0ZeERTVRVjoYiPzJgxYyOl1ID/kyzLPevWrbsAgCAOBvExVVVVOzmOm4pxRCIRRCIRgnGwLJvwim7NmjUZdXV17+MxLOLTdBKejmACjEZjlqIoLwCgABSMQhGfGgqFmvB0GiZAlmV/OBz2AFDxGAZjyMzMvOt0OtcyDGPFiEgkAkVRwDAMhkmSpEWjUYJxyLLcU1xcnHvixIkGABpGEEIM6enpLxCMkpOT82JpaenLHMc9IwiCv6CgoG3RokWbjUbjTOh4nofX60VGRgaGBQIBNRQKUTyFz+fbWFZW9i5GmM3m9IaGhsb8/PxsihHbtm071traeikpKYnz+/2fLFiwILu8vPwXBw4cOK+qahQ6RVGgaRomIhwOd2qapmiapuoiGKWiomJbZmbm5OTk5K+y0BUUFHx33759P8jLy1vW1tb2Z+hqa2vR3Ny87/Dhwzs7OjrgcDgwUYqiiIWFhQvq6+sLzGazY9WqVe9hlPLy8rzTp097QqFQBwPd3r17a65evfo3l8u1H6O0tbW17t69e3t7ezvsdjsopRgcHITZbEYoFMLQ0BCRJAkcx2E0SZKI3+9/0NXVNd3j8fR1dna2K4oSYxjGuH79+h8WFxcXWSwWo8Fg4BldQk1NzaHjx4//+s6dOzcwSjQaFevr6z+orKys4DgOlFLwPA+bzQZVVWGz2TB37lx4vV5wHIdhQ0NDcDqddP78+Xmpqal07dq1r5WUlKw6pSOEsOvWrdvtdDqn2e1229DQUCLL83xCcnKy2e/3P0QcXq/3I5PJFAHAQWe329HV1YXk5GQEAgH19u3b1OFwQBRFaJoGq9WKvr4+LF68+NlYLCZYrdYUj8fTunz58sqGhoZ3qqqqlsybN6/x8uXLgf3795dRAAQ6RVFUxBd2u90ftLS0QBAEeDwe+Hw+tLS0wO12w+PxIC0tDZcuXcLFixexcOFCnDp1CoqiRAkhfDAYHLxy5cq1/Pz8ZRiFUkqgY1VVVaBLSkqyIj5DTk7ODIZhYDQaYTAYkJSUhGEcx6Gvrw8Mw2DWrFkQRRGUUlRXV6O6ulrEKC6X60PEwcqyPHD37t3eaTo8JneKxfjW1jdD/X9vplMmGQHL10Gkz0EG22Gyp2uTTFbtQTQKTdPQ3t6uASDQ7dq1C263u+rmzZt/xIhYLCYjDqppWuzChQt/WLFixcuUUh7/Rb//0iLP+u17qfbwLqj3ryChASAcAPVeQ5rZTCwMQ6BTVRXNzc3k+vXriMVi0DQNZrP5YH5+PoLB4KeiKHZIktSFOCh0R48e/emcOXNSt27desxoNCZC99o3Zy158fUfO1uuN8LORPAfiqohdeEqWJKzMMxkMoFSCnmyDEIIampqsGHDBjgcDjqgW758+WKXy3WpqKhoC+Jgoevu7m4vLCz81smTJ3+zZ8+eXlEUowkWs+nTm024VrMTqzcfgsXE48N+AYMw45MBBc+lyrjf2UlgMCBGYugv70chWwj+Mx49PT2oqalhJEnq4TgObrcbN27ceBVxEIxCCGHT09Odq/JSv+ZMZk8YIgKkmIrVb52A3ZGK42fP4tqtW9j7xhuwMAyabt2CYDKhK7MLxx4ew9uOt5EdzkYwGBxobGy0chxngG5gYGCby+U6hBFTpkyZJkmSEggE/sXgf6mCIDz83mxrhZlGn4cupmqYnV8Kk8WK+bm5KCsqgsVsRkwQ0NndjR5RRK4lF6VcKRJjiRhGCPE1NTW9brFYXhEE4bjL5foJAA0jQqHQkCzLAegonkQNLJmPcciyDCPLYlh/fz8ep6oqTUhI+AZ0PM/nL1u2bBrGQPEkTVXRjXHwPI8IdIRogiBA0zSMJknSV2w223boWJZ9NiUlZTPGwOJJWm8wUmPmTKWEgEEcDKWwOByYMWcOaEoKCCF4DIlEIi2CIOy1Wq0r/H7/EYyBRRzVf/rn+z/79oxNzyRw7wCwYYSqqvALAiwmExiWxcdtbeTS1ataLBaDxWJRSkpKGB2BLhqNNp4/f/4sgLMYB4v4tB/9/h+/WjMv5XfTkkwvsZzpKIBJlFKkmEzo8XoR7u+H0t2tZWRkaGlpacjIyGCIDjqO4+77/f5DmAAW4zjT8rAbQO2rPb1yjtnyc85gmGrgeUydPRvDog8eaIm9vRSjKIrymSiKW5qamvyYAAYT8Mva2juqqr43a/r0z3mOy2YZZjJ0fcGgNiiKBDpFUXyiKB5pbm5ev2PHjhZMEMEXRCnl/nLmTG5Wenpe18DApI7e3qDuzsGDB1vu3bsXwRf0bxUQXc2aUJWHAAAAAElFTkSuQmCC"; + +/** + * The CyberChef logo with blur + * 32x32 + */ +export const PNG_BLUR_B64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAANT0lEQVR4AS3BC5CV1X0A8P8553s/7mMvyz5gWUFApEKpEtloSQdLDDDoREXMDK1Zx8dg4xjHqdWpQwgI29QoFrE6gyFJ6YhmoDNMapIBYhzHqgg1ZAvRdIVld5Vl9+597N17v+8779NNJ78fklL6GzdutJ955hnnrbfect98803vxIkTwccffxwdOnQoGhoaihuNRiilDKvValCr1XzGmNtqtdz29naru7sburq6dG9vr1i6dClbtWoV7evryzZv3pw8/PDDSX9/f+vIkSPN/fv3t86cOZMYY7KBgQFarVY5AAjr4MGD6KOPPsK1Wg0bY4ht25Y9q1gs2h0dHW6apm5PT4/HGPMrlYpv23aQJIk3y8nn85bneYgQopVSglJq1et1Mjk5iS5fvqzPnz+vzp49K44fP85uueUW++jRozalVDz77LOkUCjg/v5+hI8dO4YajQZSSuE0TYnW2rJneZ7nlEolt7293SuVSn5nZ6ff1tYWtrW1hcViMczn81EYhpHjOBFCKNJah5TSsNVqBZVKJRgdHQ0uXLjgnzt3znv77bfdo0ePOkeOHLEPHTpkHThwgKxbt46sWLECk4sXL3ozMzPWmTNnnEaj4QwPD3vbt2/3a7VaeOXKlVBKGRFCIsdxIilluGPHjnDXrl0BQsh3Xdf3PM8dGBiwXNe1fN/Hvu8jz/MgjmP98ssvq3379qkoiuTrr78ub731VvHhhx+qbdu2qf7+frV69WqNq9UqmpycxK7rYtu2ied5VhAEdj6ftwuFglssFr1SqeTncrkgn88HuVwuCMMwCsMw8jwvtCwrJISExpiQcx6maRq0Wi2/Uqn4X375pTcyMuIODg46586ds9977z373LlzZHx8HJ8+fRoXCgVEDh486D755JN2uVx2xsfH3eHhYf+JJ57wa7VaVC6XIyFERAiJACBijEWMscgYE+zcuTPYs2ePZ9u2Y9u25TgOdl0XeZ4HnufpKIpUHMfqtddeEwMDA2LZsmX85MmTYnx8XGit5djYmHznnXcUNsagKIqQbdvYsixSKBRIGIZWGIZ2oVBwCoWCm8vlvCiK/GBWGIbBrDAIgtBxnJAQEgJAqJQKpZQB59xPksRvNptuvV53JiYmnMuXL9vDw8PW+Pg4GRoaIrVaDc+dOxeVSiWE169fD3PnzkVdXV2oVCqhfD6P4zgm+Xye5PN5K45jO5fLObNcjLFHCPEAwEMIeUopXwjhc869LMu8VqvlzszMOI1Gw6nX6061WrUbjYY1PT1Nrl69SkZGRvDZs2fxBx98gF599VX0/vvvg3XvvffCyMgILFiwADzPQ/l8HsVBgKMowgBAQGsiGLNZltmcMZtS6lBKXZplLmXMUlIiTDC2bQdmScdx7DiOSZqmmDGG0zTFjDEkhEBSSlQqlaC3txd6e3vhtttuA7xo/U3w1W+uN/kFeQgLIfixBcR3QAFHQDQSWmHGKU7ThCRJy8rS1Mqy1KKUWlma2hmlVpZRizFGKKWEMYYZpVgIgYQQIIQwWmswsxhjptFomMnJSTMxMWFGR0cN/un3vmX65gLc3NtrlnTnTGQBBJYCDzT4WANIhjRniGUJZlmGGU0Jp5QwmhEhOBaMYc4Z5oxhKTkSgiMuBCiljBDCKKU0xlgbY7SUUgshtBBC53I5PTg4aPC2mwEe2txjruuYhqXzjJmf12ZOwE3B48ZDythGGC0YSEpB8AxxRpHgDEkhkOQcCcmRFAIJKUBKZaSURv8JIUTZtq3iOFBxHKv29nbl+77u7OzU9XrdvPTSSxofe+4ec20nwI2LPFOEFnQEyrR5yoRYGFdnAJKB4RQES0EyCkowkIKDksJIJY1S0mgltdZSKyW11koBAomQkRiDJDaRYZyTxWJRBkGg2tvblW3buqurS1+6dMngB5ZWIPnlHLN9QwPuukmba4t1mAMzUCDceIoZWzEDghkpqJGcghLCKMGNUsJoKYxWSisttVZaaa2UBiOVlkoDSESIAAAZBZG0bVs5gaOKxaJatmyZWrBggR4YGND4ujv/F368+HO4zxuBlfAFdMsyBGwSSFIFyJogswaIrAkqS0FxaiSnoJUwWnKjlDBKCaOU0lJJrZTUUkqt1Syp/h8QkEEcSMdxlOu6KteeU8YY3dHRoc+cOWPw/i9+jrak/42+VZiG7mQUdcsy5NIKqOkJBHQadNYEmTaBpy0ksxRpRkEwiiQXoIQwUgijpDBKcCOl1FJyLaVUUnOllFCUUi200MY1iraoHjo/ZJIk0fPnz9eHDx/W+HH/12gd/gA5w+/iztZFBONDmE2N4GxyDNPaBGb1Ck4bVcyTJhI0QYJlSHEKklOkBAfJOXDOQChhhOBGcGY4Zyaj1LSyluFZpgFAN5tNM1GdMIwxff78efPuu++aU6dOgfVt979QbvBXeKU8iMbGz2OYvIhVdQyLX43jrDpJ0ukqyWamMU9nMM+qmNMUS8aQ5BQJqZAEZLAhIAgBJhhwLkxKU6BZZrI0MzNJYrjgZmZmxkxVpsyJ/zwBr7zyCnz66adw3333GXz29ZfwzewjhC++jxuffkySkQskHf2cVL8Ytmh9ktDpCskadUJbM0RkCRY0xZJnWAqOpOBIco6E5CAEA8E4MMaAMgpZlkCz2YR6ow6N6QZUK1UYGx2Der1uyq2y4ZybO+64A/BN079GldO/wJfOvEPY+CCuj1wg5dE/WDMTo2RmatLKGjXCZupEZgmWNMWKUywZw5JzrKRASnKkhEBCCCQlBy4yxBmFJElQo9lA1WoVVWtlNDE5AZ999hkc/tlh9MjfPIKGhobQ7t27AV/+xXEMnw3i4MolTEcvEqt2FaNqGbNKhdBalfCZBmFZiwhKsRQcGyGRURIZJUEribRWoLQGrRVorUAqDZxzxIWAjGbQSmZQlmZQmaqgNE2h2WxCpVKBsbExGB8fB3wDrqP6l5/hrDqC82wa6Zk6pq0Gps0ZTFtNLFmGNOfIaIlAKQBjAAEYBAaQAYMAGYSMQQjMHwFoAwBGSA5SStAKIOMcwaxas4bK5TKCP7nzzjuR1YMFKhhAJZCo2qKYMIkMk0hQgUBrwNoAwdhYCBvHsnSVSG0RrW3LKI0MQoCUsSxlWZayLEtb2NKEEI3nYYPAzJJGKWVaSQsajQZUKhX4zUe/QfPa5qGTJ08CXpJJdG9vAW4qRtDrW9DmAoQA4CNsbGwZxyLGd2zl25byHVsFriN9x5G+6wrf9YTneSJwPRF4vgh8XwS+LwPPU0HgKdfxtesF2nd843u+ieLItOfazZL5S8ymTZsMzMLJvwHA+wA9dd8sJLF2pWdsJ9DY97Tju8oLA+n5vgziiHthyP0wYn4UMtcPeRCGLA5DFoUxi4KQ5+KYx1Ek4lxO5OKcbCsU5JxiUXV1zVVd87r00oVLdU9PjwmCAP7o2LFjhry3d2N4+O57rHXXbrceXFN12r7ZdNY8IJwNZeVeyoxzRex2ptCAXdu5x2ruskn6nIWetmwQjqvBcRXxfGEHAQtzuSzOFdK2A6WkY25H0tXdnSy8ZnFy3fLl6e8G/yfp+0pftmHDBlq+WmYHDhzg99xzj5yamlLk0Z9sCcJ3P7YW5bZbz94urTm/Z/aND0rnzjo4f5va9rhy7Wnjkgb+J9zAe3HzuQFI93haOp4CJxA4iJgd5TK/WMj2zfnXpK2jM5nX29vqXXRta8Wfr2itX7eudfHzS+mWLVvSx7/7OH3hn19gfX19or+/X65evVpZA3/do89vvVHNt1dKtuoTma4SYskKwntO+WxOo0Bj08hcXHeQk1nIaWLldxk6l0tFhUW0QTYQ5bou87u6szn5Qlrq6Uk7FvRmi66/Plu+chW7Zc0tfNfePeL2zbfLPd/fo3bs2KFaqKURQnrFihXGemP9Tfr03YPq9xNfqN1fvUGOfh+LNZditvgvYtZZLdO8PZ15uGwTr0mM30Ki0TKMSoEYt4hQiBBL2a7L/TkhzRXb0tKSpen8xQuzJStW0r6vraUbH3iQbd26lX9y7hOx43s7JG1QFcexPn78uFm7dq0h8Vs/cb+9Zht56FSAH97yPH7hoX3kuvJu646nI3L3EzEZsfJ4nNl4yg3RlBPCd93I1N1QGz9SVhALLy6yuNROCws6s+6enuSalSuT6//shuTmvjXJ3Z/8Lnnq0UfS3c/tyfYO7KXLFy9nzWaT7927V7744oty06ZNmtzK1zul+/4R/3uvwVu3tuOd93vkmseeJxv4D8iG7+wn255rw2MU4yt2iCZIgL7j5syUH2vsx8rLFbmfL/GX2jtp+7Xzsnm916SLb1ydrl79leT2D7+e3L/l3nTgqX/Ifvyjn2Zv/OwN+tsLv+Wff/q5LJfLIgxDjTHWZN8f9ts3tp5HT/3gGXz6/g789GNz8DWPReSvdkTk1OUfki279uPhp3bii8jDV6wAHvYiMxHntRXmlBvlZVTsYP/S3sU6li3IehYuypavXZv+5dfeSU5//RvZ3//do+nCMMiOHv0PeuKXJ9iVkSvirv67xOGfH5aPP/i4unr1qv4/bGwpHb1ZNmYAAAAASUVORK5CYII="; /** * Sunglasses smiley From 1c048484808b63ad01160b51d666daf061e64ac4 Mon Sep 17 00:00:00 2001 From: John L Date: Wed, 6 Apr 2022 10:51:52 +0100 Subject: [PATCH 09/39] added log_path --- nightwatch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nightwatch.json b/nightwatch.json index 072e6c52..5b33631b 100644 --- a/nightwatch.json +++ b/nightwatch.json @@ -10,7 +10,7 @@ "start_process": true, "server_path": "./node_modules/.bin/chromedriver", "port": 9515, - "log_path": false + "log_path": "tests/browser/output" }, "desiredCapabilities": { "browserName": "chrome" From c431fb30c5a8225c1fc6a63adfc40350a4d3a5d6 Mon Sep 17 00:00:00 2001 From: John L Date: Wed, 6 Apr 2022 10:54:20 +0100 Subject: [PATCH 10/39] added logging & jsdoc --- tests/browser/ops.js | 65 ++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 09740cc8..34fd6a5b 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -198,8 +198,9 @@ module.exports = { // testOp(browser, "MD4", "test input", "test_output"); // testOp(browser, "MD5", "test input", "test_output"); // testOp(browser, "MD6", "test input", "test_output"); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); - testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:{1} td:{2}", "Result snippet"); + testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(1) th:nth-of-type(2)", "Result snippet"); + testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(2) td:nth-of-type(2)", "test_output"); + testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(2) td:nth-of-type(1)", /Base64/); // testOp(browser, "Mean", "test input", "test_output"); // testOp(browser, "Median", "test input", "test_output");` // testOp(browser, "Merge", "test input", "test_output");` @@ -374,26 +375,30 @@ module.exports = { } }; -/** +/** @function * Clears the current recipe and bakes a new operation. * - * @param {string} opName - * @param {Browser} browser + * @param {Browser} browser - Nightwatch client + * @param {string|Array} opName - name of operation to be tested, array for pre & post ops + * @param {string} input - input text for test + * @param {Array.} args - arguments for test */ function bakeOp(browser, opName, input, args=[]) { - let recipeConfig; + let op, recipeConfig; /* * Create recipeConfig as single operation * or wrapped with a pre-op and * possibly a post-op too */ if (typeof(opName) === "string") { + op = opName; recipeConfig = JSON.stringify([{ "op": opName, "args": args }]); } else if (opName.length === 2) { + op = opName[1]; recipeConfig = JSON.stringify([{ "op": opName[0], "args": [] @@ -402,6 +407,7 @@ function bakeOp(browser, opName, input, args=[]) { "args": args }]); } else { + op = opName[1]; recipeConfig = JSON.stringify([{ "op": opName[0], "args": [] @@ -411,7 +417,6 @@ function bakeOp(browser, opName, input, args=[]) { }, { "op": opName[2], "args": [] - }]); } @@ -419,18 +424,22 @@ function bakeOp(browser, opName, input, args=[]) { .useCss() .click("#clr-recipe") .click("#clr-io") + .perform(function() { + console.log("\nCurrent Operation: ", op); + }) .waitForElementNotPresent("#rec-list li.operation") .expect.element("#input-text").to.have.property("value").that.equals(""); + let currentUrl; browser .urlHash("recipe=" + recipeConfig) + // get the current URL .url(function(result) { currentUrl = result; }) + // and put it out .perform(function() { - console.log(currentUrl); - console.log(opName); - console.log(recipeConfig); + console.log("Current URL: ", currentUrl.value); }) .setValue("#input-text", input) .waitForElementPresent("#rec-list li.operation") @@ -443,22 +452,16 @@ function bakeOp(browser, opName, input, args=[]) { .pause(100) .waitForElementPresent("#stale-indicator.hidden", 5000) .waitForElementNotVisible("#output-loader", 5000); - - let currentUrl=""; - browser - .url(function(result) { - currentUrl = result; - }) - .perform(function() { - console.log(currentUrl.value); - }); } -/** +/** @function * Clears the current recipe and tests a new operation. * - * @param {string} opName - * @param {Browser} browser + * @param {Browser} browser - Nightwatch client + * @param {string|Array} opName - name of operation to be tested, array for pre & post ops + * @param {string} input - input text for test + * @param {string} output - expected output + * @param {Array.} args - arguments for test */ function testOp(browser, opName, input, output, args=[]) { @@ -471,19 +474,23 @@ function testOp(browser, opName, input, output, args=[]) { } } -/** +/** @function * Clears the current recipe and tests a new operation. * - * @param {string} opName - * @param {Browser} browser + * @param {Browser} browser - Nightwatch client + * @param {string} opName - name of operation to be tested + * @param {string} input - input text for test + * @param {string} cssSelector - CSS selector for HTML output + * @param {string} output - expected output + * @param {Array.} args - arguments for test */ -function testOpHtml(browser, opName, input, element, output, args=[]) { +function testOpHtml(browser, opName, input, cssSelector, output, args=[]) { bakeOp(browser, opName, input, args); - browser.waitForElementPresent("#output-html", 5000); + if (typeof output === "string") { - browser.expect.element("#output-html " + element).to.have.value.that.equals(output); + browser.expect.element("#output-html " + cssSelector).text.that.equals(output); } else if (output instanceof RegExp) { - browser.expect.element("#output-html " + element).to.have.value.that.matches(output); + browser.expect.element("#output-html " + cssSelector).text.that.matches(output); } } From ccaabfaee8ddf618badc243cb088c27f52b97f71 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 11:55:34 +0100 Subject: [PATCH 11/39] Fixed incorrect wording for RC4 Drop argument. --- src/core/operations/RC4Drop.mjs | 4 ++-- tests/node/tests/operations.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/RC4Drop.mjs b/src/core/operations/RC4Drop.mjs index 3d87f4cb..c6bb536a 100644 --- a/src/core/operations/RC4Drop.mjs +++ b/src/core/operations/RC4Drop.mjs @@ -43,9 +43,9 @@ class RC4Drop extends Operation { "value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"] }, { - "name": "Number of bytes to drop", + "name": "Number of dwords to drop", "type": "number", - "value": 768 + "value": 192 } ]; } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 3f5631bd..305debfb 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -816,7 +816,7 @@ pCGTErs= it("RC4 Drop", () => { assert.strictEqual( chef.RC4Drop("Go Out On a Limb", {passphrase: {string: "Under Your Nose", option: "UTF8"}, inputFormat: "UTF8", outputFormat: "Hex"}).toString(), - "8fa5f2751d34476a0c857439f43816cf"); + "b85cb1c4ed6bed8f260ab92829bba942"); }), it("Regular Expression", () => { From fb3eceaee04ed11ca9e80aa0e2ecacf0ba4d3206 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 13:16:36 +0100 Subject: [PATCH 12/39] Tidied up UI tests --- nightwatch.json | 3 +- tests/browser/ops.js | 74 ++++++++++++++------------------------------ 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/nightwatch.json b/nightwatch.json index 5b33631b..21836547 100644 --- a/nightwatch.json +++ b/nightwatch.json @@ -14,7 +14,8 @@ }, "desiredCapabilities": { "browserName": "chrome" - } + }, + "enable_fail_fast": true }, "dev": { diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 34fd6a5b..bb18dc5d 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -25,7 +25,7 @@ module.exports = { testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); testOp(browser, "Add line numbers", "test input", "1 test input"); - testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, ["Chef", "Center", "Middle", 0, 0, 16]); + testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, [[], ["Chef", "Center", "Middle", 0, 0, 16], []]); testOp(browser, "Adler-32 Checksum", "test input", "16160411"); testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); @@ -49,8 +49,8 @@ module.exports = { testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); testOp(browser, ["From Hex", "Blur Image", "To Base64"], Images.PNG_HEX, Images.PNG_BLUR_B64); // testOp(browser, "Bombe", "test input", "test_output"); - testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); - testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); + testOp(browser, ["Bzip2 Compress", "To Hex"], "test input", "42 5a 68 39 31 41 59 26 53 59 cf 96 82 1d 00 00 03 91 80 40 00 02 21 4e 00 20 00 21 90 c2 10 c0 88 33 92 8e df 17 72 45 38 50 90 cf 96 82 1d"); + testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]); // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); @@ -379,68 +379,43 @@ module.exports = { * Clears the current recipe and bakes a new operation. * * @param {Browser} browser - Nightwatch client - * @param {string|Array} opName - name of operation to be tested, array for pre & post ops + * @param {string|Array} opName - name of operation to be tested, array for multiple ops * @param {string} input - input text for test - * @param {Array.} args - arguments for test + * @param {Array|Array>} args - aarguments, nested if multiple ops */ function bakeOp(browser, opName, input, args=[]) { + let recipeConfig; - let op, recipeConfig; - /* - * Create recipeConfig as single operation - * or wrapped with a pre-op and - * possibly a post-op too - */ if (typeof(opName) === "string") { - op = opName; recipeConfig = JSON.stringify([{ "op": opName, "args": args }]); - } else if (opName.length === 2) { - op = opName[1]; - recipeConfig = JSON.stringify([{ - "op": opName[0], - "args": [] - }, { - "op": opName[1], - "args": args - }]); + } else if (opName instanceof Array) { + recipeConfig = JSON.stringify( + opName.map((op, i) => { + return { + op: op, + args: args.length ? args[i] : [] + }; + }) + ); } else { - op = opName[1]; - recipeConfig = JSON.stringify([{ - "op": opName[0], - "args": [] - }, { - "op": opName[1], - "args": args - }, { - "op": opName[2], - "args": [] - }]); + throw new Error("Invalid operation type. Must be string or array of strings. Received: " + typeof(opName)); } browser .useCss() .click("#clr-recipe") .click("#clr-io") - .perform(function() { - console.log("\nCurrent Operation: ", op); - }) .waitForElementNotPresent("#rec-list li.operation") .expect.element("#input-text").to.have.property("value").that.equals(""); - let currentUrl; browser - .urlHash("recipe=" + recipeConfig) - // get the current URL - .url(function(result) { - currentUrl = result; - }) - // and put it out .perform(function() { - console.log("Current URL: ", currentUrl.value); + console.log(`Current test: ${opName}`); }) + .urlHash("recipe=" + recipeConfig) .setValue("#input-text", input) .waitForElementPresent("#rec-list li.operation") .expect.element("#input-text").to.have.property("value").that.equals(input); @@ -458,10 +433,10 @@ function bakeOp(browser, opName, input, args=[]) { * Clears the current recipe and tests a new operation. * * @param {Browser} browser - Nightwatch client - * @param {string|Array} opName - name of operation to be tested, array for pre & post ops - * @param {string} input - input text for test + * @param {string|Array} opName - name of operation to be tested, array for multiple ops + * @param {string} input - input text * @param {string} output - expected output - * @param {Array.} args - arguments for test + * @param {Array|Array>} args - arguments, nested if multiple ops */ function testOp(browser, opName, input, output, args=[]) { @@ -478,14 +453,13 @@ function testOp(browser, opName, input, output, args=[]) { * Clears the current recipe and tests a new operation. * * @param {Browser} browser - Nightwatch client - * @param {string} opName - name of operation to be tested - * @param {string} input - input text for test + * @param {string|Array} opName - name of operation to be tested array for multiple ops + * @param {string} input - input text * @param {string} cssSelector - CSS selector for HTML output * @param {string} output - expected output - * @param {Array.} args - arguments for test + * @param {Array|Array>} args - arguments, nested if multiple ops */ function testOpHtml(browser, opName, input, cssSelector, output, args=[]) { - bakeOp(browser, opName, input, args); if (typeof output === "string") { From f77633cee95fdf2460de82acadfaa8605b0e604f Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 13:17:43 +0100 Subject: [PATCH 13/39] 9.37.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0f0453b..36dcbd88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.0", + "version": "9.37.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.0", + "version": "9.37.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 02be5cbc..5f774478 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.0", + "version": "9.37.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From f5fe79326a92a16fd466aeadfb84a514c233ed4c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 16:57:46 +0100 Subject: [PATCH 14/39] CodeQL fixes --- src/core/Utils.mjs | 4 ++-- src/core/operations/ToBase45.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index c48c484c..66a98c36 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -723,8 +723,8 @@ class Utils { } if (removeScriptAndStyle) { - htmlStr = recursiveRemove(/]*>.*?<\/script>/gi, htmlStr); - htmlStr = recursiveRemove(/]*>.*?<\/style>/gi, htmlStr); + htmlStr = recursiveRemove(/]*>.*?<\/script[^>]*>/gi, htmlStr); + htmlStr = recursiveRemove(/]*>.*?<\/style[^>]*>/gi, htmlStr); } return htmlStr.replace(/<[^>]+>/g, ""); } diff --git a/src/core/operations/ToBase45.mjs b/src/core/operations/ToBase45.mjs index 40dd96de..3246ab4e 100644 --- a/src/core/operations/ToBase45.mjs +++ b/src/core/operations/ToBase45.mjs @@ -43,9 +43,9 @@ class ToBase45 extends Operation { * @returns {string} */ run(input, args) { + if (!input) return ""; input = new Uint8Array(input); const alphabet = Utils.expandAlphRange(args[0]); - if (!input) return ""; const res = []; From 6959e2cf01737ea2adc5ceb2d6435d4142cc0480 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 16:57:51 +0100 Subject: [PATCH 15/39] 9.37.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36dcbd88..352c54e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.1", + "version": "9.37.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.1", + "version": "9.37.2", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 5f774478..45e732fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.1", + "version": "9.37.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 9a982f05ac7065a2253f8f2d963f6e636d79783a Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 18:08:16 +0100 Subject: [PATCH 16/39] Extract operations now offer built-in Sort and Unique options. Unique operation offers option to count occurances. Closes #1334. --- src/core/lib/Extract.mjs | 27 +++-- src/core/lib/Sort.mjs | 105 +++++++++++++++++ src/core/operations/ExtractDates.mjs | 8 +- src/core/operations/ExtractDomains.mjs | 34 +++++- src/core/operations/ExtractEmailAddresses.mjs | 34 +++++- src/core/operations/ExtractFilePaths.mjs | 52 ++++++--- src/core/operations/ExtractIPAddresses.mjs | 71 ++++++----- src/core/operations/ExtractMACAddresses.mjs | 34 +++++- src/core/operations/ExtractURLs.mjs | 33 +++++- src/core/operations/Sort.mjs | 110 +----------------- src/core/operations/Strings.mjs | 50 +++++--- src/core/operations/Unique.mjs | 30 ++++- tests/node/tests/operations.mjs | 7 +- .../tests/ExtractEmailAddresses.mjs | 8 +- 14 files changed, 397 insertions(+), 206 deletions(-) create mode 100644 src/core/lib/Sort.mjs diff --git a/src/core/lib/Extract.mjs b/src/core/lib/Extract.mjs index 8b9f957e..18fec28c 100644 --- a/src/core/lib/Extract.mjs +++ b/src/core/lib/Extract.mjs @@ -12,15 +12,15 @@ * * @param {string} input * @param {RegExp} searchRegex - * @param {RegExp} removeRegex - A regular expression defining results to remove from the + * @param {RegExp} [removeRegex=null] - A regular expression defining results to remove from the * final list - * @param {boolean} includeTotal - Whether or not to include the total number of results + * @param {Function} [sortBy=null] - The sorting comparison function to apply + * @param {boolean} [unique=false] - Whether to unique the results * @returns {string} */ -export function search (input, searchRegex, removeRegex, includeTotal) { - let output = "", - total = 0, - match; +export function search(input, searchRegex, removeRegex=null, sortBy=null, unique=false) { + let results = []; + let match; while ((match = searchRegex.exec(input))) { // Moves pointer when an empty string is matched (prevents infinite loop) @@ -30,14 +30,19 @@ export function search (input, searchRegex, removeRegex, includeTotal) { if (removeRegex && removeRegex.test(match[0])) continue; - total++; - output += match[0] + "\n"; + + results.push(match[0]); } - if (includeTotal) - output = "Total found: " + total + "\n\n" + output; + if (sortBy) { + results = results.sort(sortBy); + } - return output; + if (unique) { + results = results.unique(); + } + + return results; } diff --git a/src/core/lib/Sort.mjs b/src/core/lib/Sort.mjs new file mode 100644 index 00000000..46bbebd9 --- /dev/null +++ b/src/core/lib/Sort.mjs @@ -0,0 +1,105 @@ +/** + * Sorting functions + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + * + */ + +/** + * Comparison operation for sorting of strings ignoring case. + * + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function caseInsensitiveSort(a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); +} + + +/** + * Comparison operation for sorting of IPv4 addresses. + * + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function ipSort(a, b) { + let a_ = a.split("."), + b_ = b.split("."); + + a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1; + b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1; + + if (isNaN(a_) && !isNaN(b_)) return 1; + if (!isNaN(a_) && isNaN(b_)) return -1; + if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b); + + return a_ - b_; +} + +/** + * Comparison operation for sorting of numeric values. + * + * @author Chris van Marle + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function numericSort(a, b) { + const a_ = a.split(/([^\d]+)/), + b_ = b.split(/([^\d]+)/); + + for (let i = 0; i < a_.length && i < b.length; ++i) { + if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers + if (!isNaN(a_[i]) && isNaN(b_[i])) return -1; + if (isNaN(a_[i]) && isNaN(b_[i])) { + const ret = a_[i].localeCompare(b_[i]); // Compare strings + if (ret !== 0) return ret; + } + if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers + if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; + } + } + + return a.localeCompare(b); +} + +/** + * Comparison operation for sorting of hexadecimal values. + * + * @author Chris van Marle + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function hexadecimalSort(a, b) { + let a_ = a.split(/([^\da-f]+)/i), + b_ = b.split(/([^\da-f]+)/i); + + a_ = a_.map(v => { + const t = parseInt(v, 16); + return isNaN(t) ? v : t; + }); + + b_ = b_.map(v => { + const t = parseInt(v, 16); + return isNaN(t) ? v : t; + }); + + for (let i = 0; i < a_.length && i < b.length; ++i) { + if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers + if (!isNaN(a_[i]) && isNaN(b_[i])) return -1; + if (isNaN(a_[i]) && isNaN(b_[i])) { + const ret = a_[i].localeCompare(b_[i]); // Compare strings + if (ret !== 0) return ret; + } + if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers + if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; + } + } + + return a.localeCompare(b); +} diff --git a/src/core/operations/ExtractDates.mjs b/src/core/operations/ExtractDates.mjs index dfe93c88..74c177d3 100644 --- a/src/core/operations/ExtractDates.mjs +++ b/src/core/operations/ExtractDates.mjs @@ -44,7 +44,13 @@ class ExtractDates extends Operation { date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig"); - return search(input, regex, null, displayTotal); + const results = search(input, regex); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractDomains.mjs b/src/core/operations/ExtractDomains.mjs index ea9aa3af..c28efbb5 100644 --- a/src/core/operations/ExtractDomains.mjs +++ b/src/core/operations/ExtractDomains.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search, DOMAIN_REGEX } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract domains operation @@ -25,9 +26,19 @@ class ExtractDomains extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": true + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,8 +49,21 @@ class ExtractDomains extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0]; - return search(input, DOMAIN_REGEX, null, displayTotal); + const [displayTotal, sort, unique] = args; + + const results = search( + input, + DOMAIN_REGEX, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractEmailAddresses.mjs b/src/core/operations/ExtractEmailAddresses.mjs index 43bf3b64..f50e1aaf 100644 --- a/src/core/operations/ExtractEmailAddresses.mjs +++ b/src/core/operations/ExtractEmailAddresses.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract email addresses operation @@ -25,9 +26,19 @@ class ExtractEmailAddresses extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,10 +49,23 @@ class ExtractEmailAddresses extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0], + const [displayTotal, sort, unique] = args, // email regex from: https://www.regextester.com/98066 regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig; - return search(input, regex, null, displayTotal); + + const results = search( + input, + regex, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractFilePaths.mjs b/src/core/operations/ExtractFilePaths.mjs index 04d3f73e..5de76fe5 100644 --- a/src/core/operations/ExtractFilePaths.mjs +++ b/src/core/operations/ExtractFilePaths.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract file paths operation @@ -25,19 +26,29 @@ class ExtractFilePaths extends Operation { this.outputType = "string"; this.args = [ { - "name": "Windows", - "type": "boolean", - "value": true + name: "Windows", + type: "boolean", + value: true }, { - "name": "UNIX", - "type": "boolean", - "value": true + name: "UNIX", + type: "boolean", + value: true }, { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -48,7 +59,7 @@ class ExtractFilePaths extends Operation { * @returns {string} */ run(input, args) { - const [includeWinPath, includeUnixPath, displayTotal] = args, + const [includeWinPath, includeUnixPath, displayTotal, sort, unique] = args, winDrive = "[A-Z]:\\\\", winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}", winExt = "[A-Z\\d]{1,6}", @@ -65,12 +76,25 @@ class ExtractFilePaths extends Operation { filePaths = unixPath; } - if (filePaths) { - const regex = new RegExp(filePaths, "ig"); - return search(input, regex, null, displayTotal); - } else { + if (!filePaths) { return ""; } + + const regex = new RegExp(filePaths, "ig"); + const results = search( + input, + regex, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } + } } diff --git a/src/core/operations/ExtractIPAddresses.mjs b/src/core/operations/ExtractIPAddresses.mjs index 8d36a783..95e0a50f 100644 --- a/src/core/operations/ExtractIPAddresses.mjs +++ b/src/core/operations/ExtractIPAddresses.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { ipSort } from "../lib/Sort.mjs"; /** * Extract IP addresses operation @@ -25,24 +26,34 @@ class ExtractIPAddresses extends Operation { this.outputType = "string"; this.args = [ { - "name": "IPv4", - "type": "boolean", - "value": true + name: "IPv4", + type: "boolean", + value: true }, { - "name": "IPv6", - "type": "boolean", - "value": false + name: "IPv6", + type: "boolean", + value: false }, { - "name": "Remove local IPv4 addresses", - "type": "boolean", - "value": false + name: "Remove local IPv4 addresses", + type: "boolean", + value: false }, { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -53,7 +64,7 @@ class ExtractIPAddresses extends Operation { * @returns {string} */ run(input, args) { - const [includeIpv4, includeIpv6, removeLocal, displayTotal] = args, + const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args, ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?", ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})"; let ips = ""; @@ -66,23 +77,29 @@ class ExtractIPAddresses extends Operation { ips = ipv6; } - if (ips) { - const regex = new RegExp(ips, "ig"); + if (!ips) return ""; - if (removeLocal) { - const ten = "10\\..+", - oneninetwo = "192\\.168\\..+", - oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+", - onetwoseven = "127\\..+", - removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo + - "|" + oneseventwo + "|" + onetwoseven + ")"); + const regex = new RegExp(ips, "ig"); - return search(input, regex, removeRegex, displayTotal); - } else { - return search(input, regex, null, displayTotal); - } + const ten = "10\\..+", + oneninetwo = "192\\.168\\..+", + oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+", + onetwoseven = "127\\..+", + removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo + + "|" + oneseventwo + "|" + onetwoseven + ")"); + + const results = search( + input, + regex, + removeLocal ? removeRegex : null, + sort ? ipSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; } else { - return ""; + return results.join("\n"); } } diff --git a/src/core/operations/ExtractMACAddresses.mjs b/src/core/operations/ExtractMACAddresses.mjs index d75b1a69..1689d18f 100644 --- a/src/core/operations/ExtractMACAddresses.mjs +++ b/src/core/operations/ExtractMACAddresses.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { hexadecimalSort } from "../lib/Sort.mjs"; /** * Extract MAC addresses operation @@ -25,9 +26,19 @@ class ExtractMACAddresses extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,10 +49,21 @@ class ExtractMACAddresses extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0], - regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig; + const [displayTotal, sort, unique] = args, + regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig, + results = search( + input, + regex, + null, + sort ? hexadecimalSort : null, + unique + ); - return search(input, regex, null, displayTotal); + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractURLs.mjs b/src/core/operations/ExtractURLs.mjs index a5b26515..32cdb3a7 100644 --- a/src/core/operations/ExtractURLs.mjs +++ b/src/core/operations/ExtractURLs.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search, URL_REGEX } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract URLs operation @@ -25,9 +26,19 @@ class ExtractURLs extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,8 +49,20 @@ class ExtractURLs extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0]; - return search(input, URL_REGEX, null, displayTotal); + const [displayTotal, sort, unique] = args; + const results = search( + input, + URL_REGEX, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/Sort.mjs b/src/core/operations/Sort.mjs index a1148f7c..19e4cbb2 100644 --- a/src/core/operations/Sort.mjs +++ b/src/core/operations/Sort.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation.mjs"; import Utils from "../Utils.mjs"; import {INPUT_DELIM_OPTIONS} from "../lib/Delim.mjs"; +import {caseInsensitiveSort, ipSort, numericSort, hexadecimalSort} from "../lib/Sort.mjs"; /** * Sort operation @@ -57,120 +58,19 @@ class Sort extends Operation { if (order === "Alphabetical (case sensitive)") { sorted = sorted.sort(); } else if (order === "Alphabetical (case insensitive)") { - sorted = sorted.sort(Sort._caseInsensitiveSort); + sorted = sorted.sort(caseInsensitiveSort); } else if (order === "IP address") { - sorted = sorted.sort(Sort._ipSort); + sorted = sorted.sort(ipSort); } else if (order === "Numeric") { - sorted = sorted.sort(Sort._numericSort); + sorted = sorted.sort(numericSort); } else if (order === "Numeric (hexadecimal)") { - sorted = sorted.sort(Sort._hexadecimalSort); + sorted = sorted.sort(hexadecimalSort); } if (sortReverse) sorted.reverse(); return sorted.join(delim); } - /** - * Comparison operation for sorting of strings ignoring case. - * - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _caseInsensitiveSort(a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()); - } - - - /** - * Comparison operation for sorting of IPv4 addresses. - * - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _ipSort(a, b) { - let a_ = a.split("."), - b_ = b.split("."); - - a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1; - b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1; - - if (isNaN(a_) && !isNaN(b_)) return 1; - if (!isNaN(a_) && isNaN(b_)) return -1; - if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b); - - return a_ - b_; - } - - /** - * Comparison operation for sorting of numeric values. - * - * @author Chris van Marle - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _numericSort(a, b) { - const a_ = a.split(/([^\d]+)/), - b_ = b.split(/([^\d]+)/); - - for (let i = 0; i < a_.length && i < b.length; ++i) { - if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers - if (!isNaN(a_[i]) && isNaN(b_[i])) return -1; - if (isNaN(a_[i]) && isNaN(b_[i])) { - const ret = a_[i].localeCompare(b_[i]); // Compare strings - if (ret !== 0) return ret; - } - if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers - if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; - } - } - - return a.localeCompare(b); - } - - /** - * Comparison operation for sorting of hexadecimal values. - * - * @author Chris van Marle - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _hexadecimalSort(a, b) { - let a_ = a.split(/([^\da-f]+)/i), - b_ = b.split(/([^\da-f]+)/i); - - a_ = a_.map(v => { - const t = parseInt(v, 16); - return isNaN(t) ? v : t; - }); - - b_ = b_.map(v => { - const t = parseInt(v, 16); - return isNaN(t) ? v : t; - }); - - for (let i = 0; i < a_.length && i < b.length; ++i) { - if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers - if (!isNaN(a_[i]) && isNaN(b_[i])) return -1; - if (isNaN(a_[i]) && isNaN(b_[i])) { - const ret = a_[i].localeCompare(b_[i]); // Compare strings - if (ret !== 0) return ret; - } - if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers - if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; - } - } - - return a.localeCompare(b); - } - } export default Sort; diff --git a/src/core/operations/Strings.mjs b/src/core/operations/Strings.mjs index ddf1d49d..dca2433a 100644 --- a/src/core/operations/Strings.mjs +++ b/src/core/operations/Strings.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation.mjs"; import XRegExp from "xregexp"; import { search } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Strings operation @@ -27,27 +28,37 @@ class Strings extends Operation { this.outputType = "string"; this.args = [ { - "name": "Encoding", - "type": "option", - "value": ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"] + name: "Encoding", + type: "option", + value: ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"] }, { - "name": "Minimum length", - "type": "number", - "value": 4 + name: "Minimum length", + type: "number", + value: 4 }, { - "name": "Match", - "type": "option", - "value": [ + name: "Match", + type: "option", + value: [ "[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)", "[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)" ] }, { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -58,7 +69,7 @@ class Strings extends Operation { * @returns {string} */ run(input, args) { - const [encoding, minLen, matchType, displayTotal] = args, + const [encoding, minLen, matchType, displayTotal, sort, unique] = args, alphanumeric = "A-Z\\d", punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@", printable = "\x20-\x7e", @@ -108,8 +119,19 @@ class Strings extends Operation { } const regex = new XRegExp(strings, "ig"); + const results = search( + input, + regex, + null, + sort ? caseInsensitiveSort : null, + unique + ); - return search(input, regex, null, displayTotal); + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/Unique.mjs b/src/core/operations/Unique.mjs index 89de74c2..7ca2db66 100644 --- a/src/core/operations/Unique.mjs +++ b/src/core/operations/Unique.mjs @@ -26,9 +26,14 @@ class Unique extends Operation { this.outputType = "string"; this.args = [ { - "name": "Delimiter", - "type": "option", - "value": INPUT_DELIM_OPTIONS + name: "Delimiter", + type: "option", + value: INPUT_DELIM_OPTIONS + }, + { + name: "Display count", + type: "boolean", + value: false } ]; } @@ -39,8 +44,23 @@ class Unique extends Operation { * @returns {string} */ run(input, args) { - const delim = Utils.charRep(args[0]); - return input.split(delim).unique().join(delim); + const delim = Utils.charRep(args[0]), + count = args[1]; + + if (count) { + const valMap = input.split(delim).reduce((acc, curr) => { + if (Object.prototype.hasOwnProperty.call(acc, curr)) { + acc[curr]++; + } else { + acc[curr] = 1; + } + return acc; + }, {}); + + return Object.keys(valMap).map(val => `${valMap[val]} ${val}`).join(delim); + } else { + return input.split(delim).unique().join(delim); + } } } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 305debfb..783bd00a 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -471,7 +471,7 @@ color: white; }), it("Extract dates", () => { - assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992\n"); + assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992"); }), it("Filter", () => { @@ -859,7 +859,7 @@ pCGTErs= }), it("SQL Beautify", () => { - const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F + const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F FROM STATS;`); const expected = `SELECT MONTH, ID, @@ -879,8 +879,7 @@ FROM STATS;`; const result = chef.strings("smothering ampersand abreast", {displayTotal: true}); const expected = `Total found: 1 -smothering ampersand abreast -`; +smothering ampersand abreast`; assert.strictEqual(result.toString(), expected); }), diff --git a/tests/operations/tests/ExtractEmailAddresses.mjs b/tests/operations/tests/ExtractEmailAddresses.mjs index a0a01f67..658484cf 100644 --- a/tests/operations/tests/ExtractEmailAddresses.mjs +++ b/tests/operations/tests/ExtractEmailAddresses.mjs @@ -11,7 +11,7 @@ TestRegister.addTests([ { name: "Extract email address", input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com", - expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n", + expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com", recipeConfig: [ { "op": "Extract email addresses", @@ -22,7 +22,7 @@ TestRegister.addTests([ { name: "Extract email address - Display total", input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com", - expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n", + expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com", recipeConfig: [ { "op": "Extract email addresses", @@ -33,7 +33,7 @@ TestRegister.addTests([ { name: "Extract email address (Internationalized)", input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", - expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n", + expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", recipeConfig: [ { "op": "Extract email addresses", @@ -44,7 +44,7 @@ TestRegister.addTests([ { name: "Extract email address - Display total (Internationalized)", input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", - expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n", + expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", recipeConfig: [ { "op": "Extract email addresses", From 477e4a7421756c461293a8f0714fb75ee3ac1736 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 18:08:23 +0100 Subject: [PATCH 17/39] 9.37.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 352c54e1..d956ea2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.2", + "version": "9.37.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.2", + "version": "9.37.3", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 45e732fb..73d2d19a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.2", + "version": "9.37.3", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 5b68bad18568450cbbd2d42d40799e62185c2cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luke=20Sern=C3=A9?= Date: Fri, 13 May 2022 17:35:50 +0200 Subject: [PATCH 18/39] Support UTF8 encoded characters in Substitution operation This adds support for UTF8-encoded characters in the input and the parameters. --- src/core/operations/Substitute.mjs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/operations/Substitute.mjs b/src/core/operations/Substitute.mjs index 39f13e89..1afe1f42 100644 --- a/src/core/operations/Substitute.mjs +++ b/src/core/operations/Substitute.mjs @@ -44,8 +44,8 @@ class Substitute extends Operation { * @returns {string} */ run(input, args) { - const plaintext = Utils.expandAlphRange(args[0]).join(""), - ciphertext = Utils.expandAlphRange(args[1]).join(""); + const plaintext = Utils.expandAlphRange([...args[0]]), + ciphertext = Utils.expandAlphRange([...args[1]]); let output = "", index = -1; @@ -53,9 +53,9 @@ class Substitute extends Operation { output = "Warning: Plaintext and Ciphertext lengths differ\n\n"; } - for (let i = 0; i < input.length; i++) { - index = plaintext.indexOf(input[i]); - output += index > -1 && index < ciphertext.length ? ciphertext[index] : input[i]; + for (const character of input) { + index = plaintext.indexOf(character); + output += index > -1 && index < ciphertext.length ? ciphertext[index] : character; } return output; From 11da4188ee7d96df6ca96726f0d6321137294f94 Mon Sep 17 00:00:00 2001 From: MikeCAT Date: Fri, 20 May 2022 11:59:04 +0000 Subject: [PATCH 19/39] fix "To Base45" ( #1351 ) --- src/core/operations/ToBase45.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/operations/ToBase45.mjs b/src/core/operations/ToBase45.mjs index 3246ab4e..a1cd9d2f 100644 --- a/src/core/operations/ToBase45.mjs +++ b/src/core/operations/ToBase45.mjs @@ -65,6 +65,10 @@ class ToBase45 extends Operation { if (chars < 2) { res.push("0"); + chars++; + } + if (pair.length > 1 && chars < 3) { + res.push("0"); } } From a895d1d82a2f92d440a0c5eca2bc7c898107b737 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 18:06:15 +0100 Subject: [PATCH 20/39] Added 'Parse TCP' operation --- Gruntfile.js | 3 +- package-lock.json | 14 +- package.json | 2 +- src/core/config/Categories.json | 1 + src/core/lib/Binary.mjs | 14 +- src/core/lib/FileSignatures.mjs | 24 +-- src/core/lib/Protocol.mjs | 47 +++++ src/core/lib/Stream.mjs | 34 ++-- src/core/operations/ParseTCP.mjs | 245 +++++++++++++++++++++++++++ src/core/operations/ParseUDP.mjs | 53 +++--- src/web/waiters/OperationsWaiter.mjs | 6 +- tests/operations/index.mjs | 1 + tests/operations/tests/ParseTCP.mjs | 44 +++++ tests/operations/tests/ParseUDP.mjs | 23 +-- 14 files changed, 430 insertions(+), 81 deletions(-) create mode 100644 src/core/lib/Protocol.mjs create mode 100644 src/core/operations/ParseTCP.mjs create mode 100644 tests/operations/tests/ParseTCP.mjs diff --git a/Gruntfile.js b/Gruntfile.js index f073a136..78c26532 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -217,7 +217,8 @@ module.exports = function (grunt) { client: { logging: "error", overlay: true - } + }, + hot: "only" }, plugins: [ new webpack.DefinePlugin(BUILD_CONSTANTS), diff --git a/package-lock.json b/package-lock.json index d956ea2f..16c88c1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -98,7 +98,7 @@ "autoprefixer": "^10.4.4", "babel-loader": "^8.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^99.0.0", + "chromedriver": "^101.0.0", "cli-progress": "^3.10.0", "colors": "^1.4.0", "copy-webpack-plugin": "^10.2.4", @@ -4467,9 +4467,9 @@ } }, "node_modules/chromedriver": { - "version": "99.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-99.0.0.tgz", - "integrity": "sha512-pyB+5LuyZdb7EBPL3i5D5yucZUD+SlkdiUtmpjaEnLd9zAXp+SvD/hP5xF4l/ZmWvUo/1ZLxAI1YBdhazGTpgA==", + "version": "101.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", + "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -19171,9 +19171,9 @@ "dev": true }, "chromedriver": { - "version": "99.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-99.0.0.tgz", - "integrity": "sha512-pyB+5LuyZdb7EBPL3i5D5yucZUD+SlkdiUtmpjaEnLd9zAXp+SvD/hP5xF4l/ZmWvUo/1ZLxAI1YBdhazGTpgA==", + "version": "101.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", + "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", "dev": true, "requires": { "@testim/chrome-version": "^1.1.2", diff --git a/package.json b/package.json index 73d2d19a..d2d71272 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "autoprefixer": "^10.4.4", "babel-loader": "^8.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^99.0.0", + "chromedriver": "^101.0.0", "cli-progress": "^3.10.0", "colors": "^1.4.0", "copy-webpack-plugin": "^10.2.4", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 9540f8a3..c15ec3d2 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -190,6 +190,7 @@ "Parse IP range", "Parse IPv6 address", "Parse IPv4 header", + "Parse TCP", "Parse UDP", "Parse SSH Host Key", "Parse URI", diff --git a/src/core/lib/Binary.mjs b/src/core/lib/Binary.mjs index dc63fc58..4e41d2a1 100644 --- a/src/core/lib/Binary.mjs +++ b/src/core/lib/Binary.mjs @@ -13,7 +13,7 @@ import OperationError from "../errors/OperationError.mjs"; /** * Convert a byte array into a binary string. * - * @param {Uint8Array|byteArray} data + * @param {Uint8Array|byteArray|number} data * @param {string} [delim="Space"] * @param {number} [padding=8] * @returns {string} @@ -26,13 +26,17 @@ import OperationError from "../errors/OperationError.mjs"; * toBinary([10,20,30], ":"); */ export function toBinary(data, delim="Space", padding=8) { - if (!data) return ""; - delim = Utils.charRep(delim); let output = ""; - for (let i = 0; i < data.length; i++) { - output += data[i].toString(2).padStart(padding, "0") + delim; + if (data.length) { // array + for (let i = 0; i < data.length; i++) { + output += data[i].toString(2).padStart(padding, "0") + delim; + } + } else if (typeof data === "number") { // Single value + return data.toString(2).padStart(padding, "0"); + } else { + return ""; } if (delim.length) { diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index a515a9e6..7b77f2d9 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -3778,8 +3778,8 @@ function parseDEFLATE(stream) { while (!finalBlock) { // Read header - finalBlock = stream.readBits(1); - const blockType = stream.readBits(2); + finalBlock = stream.readBits(1, "le"); + const blockType = stream.readBits(2, "le"); if (blockType === 0) { /* No compression */ @@ -3798,16 +3798,16 @@ function parseDEFLATE(stream) { /* Dynamic Huffman */ // Read the number of liternal and length codes - const hlit = stream.readBits(5) + 257; + const hlit = stream.readBits(5, "le") + 257; // Read the number of distance codes - const hdist = stream.readBits(5) + 1; + const hdist = stream.readBits(5, "le") + 1; // Read the number of code lengths - const hclen = stream.readBits(4) + 4; + const hclen = stream.readBits(4, "le") + 4; // Parse code lengths const codeLengths = new Uint8Array(huffmanOrder.length); for (let i = 0; i < hclen; i++) { - codeLengths[huffmanOrder[i]] = stream.readBits(3); + codeLengths[huffmanOrder[i]] = stream.readBits(3, "le"); } // Parse length table @@ -3819,16 +3819,16 @@ function parseDEFLATE(stream) { code = readHuffmanCode(stream, codeLengthsTable); switch (code) { case 16: - repeat = 3 + stream.readBits(2); + repeat = 3 + stream.readBits(2, "le"); while (repeat--) lengthTable[i++] = prev; break; case 17: - repeat = 3 + stream.readBits(3); + repeat = 3 + stream.readBits(3, "le"); while (repeat--) lengthTable[i++] = 0; prev = 0; break; case 18: - repeat = 11 + stream.readBits(7); + repeat = 11 + stream.readBits(7, "le"); while (repeat--) lengthTable[i++] = 0; prev = 0; break; @@ -3886,11 +3886,11 @@ function parseHuffmanBlock(stream, litTab, distTab) { if (code < 256) continue; // Length code - stream.readBits(lengthExtraTable[code - 257]); + stream.readBits(lengthExtraTable[code - 257], "le"); // Dist code code = readHuffmanCode(stream, distTab); - stream.readBits(distanceExtraTable[code]); + stream.readBits(distanceExtraTable[code], "le"); } } @@ -3948,7 +3948,7 @@ function readHuffmanCode(stream, table) { const [codeTable, maxCodeLength] = table; // Read max length - const bitsBuf = stream.readBits(maxCodeLength); + const bitsBuf = stream.readBits(maxCodeLength, "le"); const codeWithLength = codeTable[bitsBuf & ((1 << maxCodeLength) - 1)]; const codeLength = codeWithLength >>> 16; diff --git a/src/core/lib/Protocol.mjs b/src/core/lib/Protocol.mjs new file mode 100644 index 00000000..57d2374a --- /dev/null +++ b/src/core/lib/Protocol.mjs @@ -0,0 +1,47 @@ +/** + * Protocol parsing functions. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import {toHexFast} from "../lib/Hex.mjs"; + +/** + * Recursively displays a JSON object as an HTML table + * + * @param {Object} obj + * @returns string + */ +export function objToTable(obj, nested=false) { + let html = ``; + if (!nested) + html += ` + + + `; + + for (const key in obj) { + html += ``; + if (typeof obj[key] === "object") + html += ``; + else + html += ``; + html += ""; + } + html += "
FieldValue
${key}${objToTable(obj[key], true)}${obj[key]}
"; + return html; +} + +/** + * Converts bytes into a BigNumber string + * @param {Uint8Array} bs + * @returns {string} + */ +export function bytesToLargeNumber(bs) { + return BigNumber(toHexFast(bs), 16).toString(); +} diff --git a/src/core/lib/Stream.mjs b/src/core/lib/Stream.mjs index f332f908..b2a183f4 100644 --- a/src/core/lib/Stream.mjs +++ b/src/core/lib/Stream.mjs @@ -27,15 +27,17 @@ export default class Stream { } /** - * Get a number of bytes from the current position. + * Get a number of bytes from the current position, or all remaining bytes. * - * @param {number} numBytes + * @param {number} [numBytes=null] * @returns {Uint8Array} */ - getBytes(numBytes) { + getBytes(numBytes=null) { if (this.position > this.length) return undefined; - const newPosition = this.position + numBytes; + const newPosition = numBytes !== null ? + this.position + numBytes : + this.length; const bytes = this.bytes.slice(this.position, newPosition); this.position = newPosition; this.bitPos = 0; @@ -91,34 +93,40 @@ export default class Stream { } /** - * Reads a number of bits from the buffer. - * - * @TODO Add endianness + * Reads a number of bits from the buffer in big or little endian. * * @param {number} numBits + * @param {string} [endianness="be"] * @returns {number} */ - readBits(numBits) { + readBits(numBits, endianness="be") { if (this.position > this.length) return undefined; let bitBuf = 0, bitBufLen = 0; // Add remaining bits from current byte - bitBuf = (this.bytes[this.position++] & bitMask(this.bitPos)) >>> this.bitPos; + bitBuf = this.bytes[this.position++] & bitMask(this.bitPos); + if (endianness !== "be") bitBuf >>>= this.bitPos; bitBufLen = 8 - this.bitPos; this.bitPos = 0; // Not enough bits yet while (bitBufLen < numBits) { - bitBuf |= this.bytes[this.position++] << bitBufLen; + if (endianness === "be") + bitBuf = (bitBuf << bitBufLen) | this.bytes[this.position++]; + else + bitBuf |= this.bytes[this.position++] << bitBufLen; bitBufLen += 8; } // Reverse back to numBits if (bitBufLen > numBits) { const excess = bitBufLen - numBits; - bitBuf &= (1 << numBits) - 1; + if (endianness === "be") + bitBuf >>>= excess; + else + bitBuf &= (1 << numBits) - 1; bitBufLen -= excess; this.position--; this.bitPos = 8 - excess; @@ -133,7 +141,9 @@ export default class Stream { * @returns {number} The bit mask */ function bitMask(bitPos) { - return 256 - (1 << bitPos); + return endianness === "be" ? + (1 << (8 - bitPos)) - 1 : + 256 - (1 << bitPos); } } diff --git a/src/core/operations/ParseTCP.mjs b/src/core/operations/ParseTCP.mjs new file mode 100644 index 00000000..7adb37e0 --- /dev/null +++ b/src/core/operations/ParseTCP.mjs @@ -0,0 +1,245 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Stream from "../lib/Stream.mjs"; +import {toHexFast, fromHex} from "../lib/Hex.mjs"; +import {toBinary} from "../lib/Binary.mjs"; +import {objToTable, bytesToLargeNumber} from "../lib/Protocol.mjs"; +import Utils from "../Utils.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import BigNumber from "bignumber.js"; + +/** + * Parse TCP operation + */ +class ParseTCP extends Operation { + + /** + * ParseTCP constructor + */ + constructor() { + super(); + + this.name = "Parse TCP"; + this.module = "Default"; + this.description = "Parses a TCP header and payload (if present)."; + this.infoURL = "https://wikipedia.org/wiki/Transmission_Control_Protocol"; + this.inputType = "string"; + this.outputType = "json"; + this.presentType = "html"; + this.args = [ + { + name: "Input format", + type: "option", + value: ["Hex", "Raw"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const format = args[0]; + + if (format === "Hex") { + input = fromHex(input); + } else if (format === "Raw") { + input = Utils.strToArrayBuffer(input); + } else { + throw new OperationError("Unrecognised input format."); + } + + const s = new Stream(new Uint8Array(input)); + if (s.length < 20) { + throw new OperationError("Need at least 20 bytes for a TCP Header"); + } + + // Parse Header + const TCPPacket = { + "Source port": s.readInt(2), + "Destination port": s.readInt(2), + "Sequence number": bytesToLargeNumber(s.getBytes(4)), + "Acknowledgement number": s.readInt(4), + "Data offset": s.readBits(4), + "Flags": { + "Reserved": toBinary(s.readBits(3), "", 3), + "NS": s.readBits(1), + "CWR": s.readBits(1), + "ECE": s.readBits(1), + "URG": s.readBits(1), + "ACK": s.readBits(1), + "PSH": s.readBits(1), + "RST": s.readBits(1), + "SYN": s.readBits(1), + "FIN": s.readBits(1), + }, + "Window size": s.readInt(2), + "Checksum": "0x" + toHexFast(s.getBytes(2)), + "Urgent pointer": "0x" + toHexFast(s.getBytes(2)) + }; + + // Parse options if present + let windowScaleShift = 0; + if (TCPPacket["Data offset"] > 5) { + let remainingLength = TCPPacket["Data offset"] * 4 - 20; + + const options = {}; + while (remainingLength > 0) { + const option = { + "Kind": s.readInt(1) + }; + + let opt = { name: "Reserved", length: true }; + if (Object.prototype.hasOwnProperty.call(TCP_OPTION_KIND_LOOKUP, option.Kind)) { + opt = TCP_OPTION_KIND_LOOKUP[option.Kind]; + } + + // Add Length and Value fields + if (opt.length) { + option.Length = s.readInt(1); + + if (option.Length > 2) { + if (Object.prototype.hasOwnProperty.call(opt, "parser")) { + option.Value = opt.parser(s.getBytes(option.Length - 2)); + } else { + option.Value = option.Length <= 6 ? + s.readInt(option.Length - 2): + "0x" + toHexFast(s.getBytes(option.Length - 2)); + } + + // Store Window Scale shift for later + if (option.Kind === 3 && option.Value) { + windowScaleShift = option.Value["Shift count"]; + } + } + } + options[opt.name] = option; + + const length = option.Length || 1; + remainingLength -= length; + } + TCPPacket.Options = options; + } + + if (s.hasMore()) { + TCPPacket.Data = "0x" + toHexFast(s.getBytes()); + } + + // Improve values + TCPPacket["Data offset"] = `${TCPPacket["Data offset"]} (${TCPPacket["Data offset"] * 4} bytes)`; + const trueWndSize = BigNumber(TCPPacket["Window size"]).multipliedBy(BigNumber(2).pow(BigNumber(windowScaleShift))); + TCPPacket["Window size"] = `${TCPPacket["Window size"]} (Scaled: ${trueWndSize})`; + + return TCPPacket; + } + + /** + * Displays the TCP Packet in a tabular style + * @param {Object} data + * @returns {html} + */ + present(data) { + return objToTable(data); + } + +} + +// Taken from https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml +// on 2022-05-30 +const TCP_OPTION_KIND_LOOKUP = { + 0: { name: "End of Option List", length: false }, + 1: { name: "No-Operation", length: false }, + 2: { name: "Maximum Segment Size", length: true }, + 3: { name: "Window Scale", length: true, parser: windowScaleParser }, + 4: { name: "SACK Permitted", length: true }, + 5: { name: "SACK", length: true }, + 6: { name: "Echo (obsoleted by option 8)", length: true }, + 7: { name: "Echo Reply (obsoleted by option 8)", length: true }, + 8: { name: "Timestamps", length: true, parser: tcpTimestampParser }, + 9: { name: "Partial Order Connection Permitted (obsolete)", length: true }, + 10: { name: "Partial Order Service Profile (obsolete)", length: true }, + 11: { name: "CC (obsolete)", length: true }, + 12: { name: "CC.NEW (obsolete)", length: true }, + 13: { name: "CC.ECHO (obsolete)", length: true }, + 14: { name: "TCP Alternate Checksum Request (obsolete)", length: true, parser: tcpAlternateChecksumParser }, + 15: { name: "TCP Alternate Checksum Data (obsolete)", length: true }, + 16: { name: "Skeeter", length: true }, + 17: { name: "Bubba", length: true }, + 18: { name: "Trailer Checksum Option", length: true }, + 19: { name: "MD5 Signature Option (obsoleted by option 29)", length: true }, + 20: { name: "SCPS Capabilities", length: true }, + 21: { name: "Selective Negative Acknowledgements", length: true }, + 22: { name: "Record Boundaries", length: true }, + 23: { name: "Corruption experienced", length: true }, + 24: { name: "SNAP", length: true }, + 25: { name: "Unassigned (released 2000-12-18)", length: true }, + 26: { name: "TCP Compression Filter", length: true }, + 27: { name: "Quick-Start Response", length: true }, + 28: { name: "User Timeout Option (also, other known unauthorized use)", length: true }, + 29: { name: "TCP Authentication Option (TCP-AO)", length: true }, + 30: { name: "Multipath TCP (MPTCP)", length: true }, + 69: { name: "Encryption Negotiation (TCP-ENO)", length: true }, + 70: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 76: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 77: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 78: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 253: { name: "RFC3692-style Experiment 1 (also improperly used for shipping products) ", length: true }, + 254: { name: "RFC3692-style Experiment 2 (also improperly used for shipping products) ", length: true } +}; + +/** + * Parses the TCP Alternate Checksum Request field + * @param {Uint8Array} data + */ +function tcpAlternateChecksumParser(data) { + const lookup = { + 0: "TCP Checksum", + 1: "8-bit Fletchers's algorithm", + 2: "16-bit Fletchers's algorithm", + 3: "Redundant Checksum Avoidance" + }[data[0]]; + + return `${lookup} (0x${toHexFast(data)})`; +} + +/** + * Parses the TCP Timestamp field + * @param {Uint8Array} data + */ +function tcpTimestampParser(data) { + const s = new Stream(data); + + if (s.length !== 8) + return `Error: Timestamp field should be 8 bytes long (received 0x${toHexFast(data)})`; + + const tsval = bytesToLargeNumber(s.getBytes(4)), + tsecr = bytesToLargeNumber(s.getBytes(4)); + + return { + "Current Timestamp": tsval, + "Echo Reply": tsecr + }; +} + +/** + * Parses the Window Scale field + * @param {Uint8Array} data + */ +function windowScaleParser(data) { + if (data.length !== 1) + return `Error: Window Scale should be one byte long (received 0x${toHexFast(data)})`; + + return { + "Shift count": data[0], + "Multiplier": 1 << data[0] + }; +} + +export default ParseTCP; diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index 0a88fd5d..2aa762ae 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -6,7 +6,9 @@ import Operation from "../Operation.mjs"; import Stream from "../lib/Stream.mjs"; -import {toHex} from "../lib/Hex.mjs"; +import {toHexFast, fromHex} from "../lib/Hex.mjs"; +import {objToTable} from "../lib/Protocol.mjs"; +import Utils from "../Utils.mjs"; import OperationError from "../errors/OperationError.mjs"; /** @@ -24,58 +26,61 @@ class ParseUDP extends Operation { this.module = "Default"; this.description = "Parses a UDP header and payload (if present)."; this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; - this.inputType = "ArrayBuffer"; + this.inputType = "string"; this.outputType = "json"; this.presentType = "html"; - this.args = []; + this.args = [ + { + name: "Input format", + type: "option", + value: ["Hex", "Raw"] + } + ]; } /** - * @param {ArrayBuffer} input + * @param {string} input + * @param {Object[]} args * @returns {Object} */ run(input, args) { - if (input.byteLength < 8) { - throw new OperationError("Need 8 bytes for a UDP Header"); + const format = args[0]; + + if (format === "Hex") { + input = fromHex(input); + } else if (format === "Raw") { + input = Utils.strToArrayBuffer(input); + } else { + throw new OperationError("Unrecognised input format."); } const s = new Stream(new Uint8Array(input)); + if (s.length < 8) { + throw new OperationError("Need 8 bytes for a UDP Header"); + } + // Parse Header const UDPPacket = { "Source port": s.readInt(2), "Destination port": s.readInt(2), "Length": s.readInt(2), - "Checksum": toHex(s.getBytes(2), "") + "Checksum": "0x" + toHexFast(s.getBytes(2)) }; // Parse data if present if (s.hasMore()) { - UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), ""); + UDPPacket.Data = "0x" + toHexFast(s.getBytes(UDPPacket.Length - 8)); } return UDPPacket; } /** - * Displays the UDP Packet in a table style + * Displays the UDP Packet in a tabular style * @param {Object} data * @returns {html} */ present(data) { - const html = []; - html.push(""); - html.push(""); - html.push(""); - html.push(""); - html.push(""); - - for (const key in data) { - html.push(""); - html.push(""); - html.push(""); - html.push(""); - } - html.push("
FieldValue
" + key + "" + data[key] + "
"); - return html.join(""); + return objToTable(data); } } diff --git a/src/web/waiters/OperationsWaiter.mjs b/src/web/waiters/OperationsWaiter.mjs index 6efbab72..dee0dd06 100755 --- a/src/web/waiters/OperationsWaiter.mjs +++ b/src/web/waiters/OperationsWaiter.mjs @@ -109,11 +109,15 @@ class OperationsWaiter { const matchedOps = []; const matchedDescs = []; + // Create version with no whitespace for the fuzzy match + // Helps avoid missing matches e.g. query "TCP " would not find "Parse TCP" + const inStrNWS = inStr.replace(/\s/g, ""); + for (const opName in this.app.operations) { const op = this.app.operations[opName]; // Match op name using fuzzy match - const [nameMatch, score, idxs] = fuzzyMatch(inStr, opName); + const [nameMatch, score, idxs] = fuzzyMatch(inStrNWS, opName); // Match description based on exact match const descPos = op.description.toLowerCase().indexOf(inStr.toLowerCase()); diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 4dd469ce..67d16ab5 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -96,6 +96,7 @@ import "./tests/Protobuf.mjs"; import "./tests/ParseSSHHostKey.mjs"; import "./tests/DefangIP.mjs"; import "./tests/ParseUDP.mjs"; +import "./tests/ParseTCP.mjs"; import "./tests/AvroToJSON.mjs"; import "./tests/Lorenz.mjs"; import "./tests/LuhnChecksum.mjs"; diff --git a/tests/operations/tests/ParseTCP.mjs b/tests/operations/tests/ParseTCP.mjs new file mode 100644 index 00000000..acecb5d7 --- /dev/null +++ b/tests/operations/tests/ParseTCP.mjs @@ -0,0 +1,44 @@ +/** + * Parse TCP tests. + * + * @author n1474335 + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Parse TCP: No options", + input: "c2eb0050a138132e70dc9fb9501804025ea70000", + expectedMatch: /1026 \(Scaled: 1026\)/, + recipeConfig: [ + { + op: "Parse TCP", + args: ["Hex"], + } + ], + }, + { + name: "Parse TCP: Options", + input: "c2eb0050a1380c1f000000008002faf080950000020405b40103030801010402", + expectedMatch: /1460/, + recipeConfig: [ + { + op: "Parse TCP", + args: ["Hex"], + } + ], + }, + { + name: "Parse TCP: Timestamps", + input: "9e90e11574d57b2c00000000a002ffffe5740000020405b40402080aa4e8c8f50000000001030308", + expectedMatch: /2766719221/, + recipeConfig: [ + { + op: "Parse TCP", + args: ["Hex"], + } + ], + } +]); diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs index 2c519232..6d1b5518 100644 --- a/tests/operations/tests/ParseUDP.mjs +++ b/tests/operations/tests/ParseUDP.mjs @@ -2,7 +2,6 @@ * Parse UDP tests. * * @author h345983745 - * * @copyright Crown Copyright 2019 * @license Apache-2.0 */ @@ -12,15 +11,11 @@ TestRegister.addTests([ { name: "Parse UDP: No Data - JSON", input: "04 89 00 35 00 2c 01 01", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x0101\"}", recipeConfig: [ - { - op: "From Hex", - args: ["Auto"], - }, { op: "Parse UDP", - args: [], + args: ["Hex"], }, { op: "JSON Minify", @@ -30,15 +25,11 @@ TestRegister.addTests([ }, { name: "Parse UDP: With Data - JSON", input: "04 89 00 35 00 2c 01 01 02 02", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\",\"Data\":\"0202\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x0101\",\"Data\":\"0x0202\"}", recipeConfig: [ - { - op: "From Hex", - args: ["Auto"], - }, { op: "Parse UDP", - args: [], + args: ["Hex"], }, { op: "JSON Minify", @@ -51,13 +42,9 @@ TestRegister.addTests([ input: "04 89 00", expectedOutput: "Need 8 bytes for a UDP Header", recipeConfig: [ - { - op: "From Hex", - args: ["Auto"], - }, { op: "Parse UDP", - args: [], + args: ["Hex"], }, { op: "JSON Minify", From cf2b54e8c03788f3a1c15876048fd942168f7623 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 18:14:41 +0100 Subject: [PATCH 21/39] Update CHANGELOG --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a90b36de..7ad241ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ All major and minor version changes will be documented in this file. Details of ## Details +### [9.38.0] - 2022-05-30 +- Added 'Parse TCP' operation [@n1474335] | [a895d1d] + ### [9.37.0] - 2022-03-29 - 'SM4 Encrypt' and 'SM4 Decrypt' operations added [@swesven] | [#1189] - NoPadding options added for CBC and ECB modes in AES, DES and Triple DES Decrypt operations [@swesven] | [#1189] @@ -135,7 +138,7 @@ All major and minor version changes will be documented in this file. Details of
Click to expand v8 minor versions - + ### [8.38.0] - 2019-07-03 - 'Streebog' and 'GOST hash' operations added [@MShwed] [@n1474335] | [#530] @@ -288,6 +291,7 @@ All major and minor version changes will be documented in this file. Details of +[9.38.0]: https://github.com/gchq/CyberChef/releases/tag/v9.38.0 [9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0 [9.36.0]: https://github.com/gchq/CyberChef/releases/tag/v9.36.0 [9.35.0]: https://github.com/gchq/CyberChef/releases/tag/v9.35.0 @@ -416,6 +420,7 @@ All major and minor version changes will be documented in this file. Details of [289a417]: https://github.com/gchq/CyberChef/commit/289a417dfb5923de5e1694354ec42a08d9395bfe [e9ca4dc]: https://github.com/gchq/CyberChef/commit/e9ca4dc9caf98f33fd986431cd400c88082a42b8 [dd18e52]: https://github.com/gchq/CyberChef/commit/dd18e529939078b89867297b181a584e8b2cc7da +[a895d1d]: https://github.com/gchq/CyberChef/commit/a895d1d82a2f92d440a0c5eca2bc7c898107b737 [#95]: https://github.com/gchq/CyberChef/pull/299 [#173]: https://github.com/gchq/CyberChef/pull/173 @@ -502,4 +507,4 @@ All major and minor version changes will be documented in this file. Details of [#1242]: https://github.com/gchq/CyberChef/pull/1242 [#1244]: https://github.com/gchq/CyberChef/pull/1244 [#1313]: https://github.com/gchq/CyberChef/pull/1313 -[#1326]: https://github.com/gchq/CyberChef/pull/1326 \ No newline at end of file +[#1326]: https://github.com/gchq/CyberChef/pull/1326 From cc9d51b7be8437602f32769efec6fb8f9e3652d3 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 18:14:46 +0100 Subject: [PATCH 22/39] 9.38.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 16c88c1b..12bf39a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.3", + "version": "9.38.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.3", + "version": "9.38.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index d2d71272..eabfaed7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.3", + "version": "9.38.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From ec577fc075380dfec5dfa33a82251e08528e599f Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 19:25:41 +0100 Subject: [PATCH 23/39] Fixed CSS for maximising output pane --- src/web/html/index.html | 22 ++++++++++++---------- src/web/stylesheets/components/_pane.css | 15 +++++++++++---- src/web/stylesheets/layout/_controls.css | 4 ++++ src/web/stylesheets/layout/_io.css | 3 +-- src/web/waiters/OutputWaiter.mjs | 2 ++ 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/web/html/index.html b/src/web/html/index.html index 8a7adac7..d222fee1 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -176,7 +176,7 @@
Recipe - + @@ -190,7 +190,7 @@
    -
    +
    @@ -236,9 +239,7 @@ view_compact -
    -
    -
    +