From be2080259ec9ae7d64945fc5640188ec4b773ba6 Mon Sep 17 00:00:00 2001 From: Kyle Parrish Date: Wed, 2 Oct 2019 09:57:50 -0400 Subject: [PATCH 01/52] Add Fang URL to categories --- src/core/config/Categories.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 94f7fd30..18fc19ff 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -183,6 +183,7 @@ "Encode NetBIOS Name", "Decode NetBIOS Name", "Defang URL", + "Fang URL", "Defang IP Addresses" ] }, From cd15a8c406726bf06d55b879d271ac3f79b3ba99 Mon Sep 17 00:00:00 2001 From: Kyle Parrish Date: Wed, 2 Oct 2019 09:58:28 -0400 Subject: [PATCH 02/52] Create FangURL.mjs --- src/core/operations/FangURL.mjs | 77 +++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/core/operations/FangURL.mjs diff --git a/src/core/operations/FangURL.mjs b/src/core/operations/FangURL.mjs new file mode 100644 index 00000000..5badaae7 --- /dev/null +++ b/src/core/operations/FangURL.mjs @@ -0,0 +1,77 @@ +/** + * @author arnydo [github@arnydo.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * FangURL operation + */ +class FangURL extends Operation { + + /** + * FangURL constructor + */ + constructor() { + super(); + + this.name = "Fang URL"; + this.module = "Default"; + this.description = "Takes a 'Defanged' Universal Resource Locator (URL) and 'Fangs' it. Meaning, it removes the alterations (defanged) that render it useless so that it can be used again."; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Escape [.]", + type: "boolean", + value: true + }, + { + name: "Escape hxxp", + type: "boolean", + value: true + }, + { + name: "Escape ://", + type: "boolean", + value: true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [dots, http, slashes] = args; + + input = fangURL(input, dots, http, slashes); + + return input; + } + +} + + +/** + * Defangs a given URL + * + * @param {string} url + * @param {boolean} dots + * @param {boolean} http + * @param {boolean} slashes + * @returns {string} + */ +function fangURL(url, dots, http, slashes) { + if (dots) url = url.replace(/\[\.\]/g, "."); + if (http) url = url.replace(/hxxp/g, "http"); + if (slashes) url = url.replace(/\[\:\/\/\]/g, "://"); + + return url; +} + +export default FangURL; From 794e0effba5ed4193265ddc6429ba55f6dac33d4 Mon Sep 17 00:00:00 2001 From: Alan C Date: Mon, 7 Oct 2019 20:02:28 +0800 Subject: [PATCH 03/52] Add "To Float" and "From Float" operations --- package-lock.json | 6 +- package.json | 1 + src/core/config/Categories.json | 2 + src/core/operations/FromFloat.mjs | 78 ++++++++++++++ src/core/operations/ToFloat.mjs | 80 +++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/Float.mjs | 164 ++++++++++++++++++++++++++++++ 7 files changed, 329 insertions(+), 3 deletions(-) create mode 100644 src/core/operations/FromFloat.mjs create mode 100644 src/core/operations/ToFloat.mjs create mode 100644 tests/operations/tests/Float.mjs diff --git a/package-lock.json b/package-lock.json index 11c80ca0..930dfc40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7657,9 +7657,9 @@ "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==" }, "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, "iferr": { "version": "0.1.5", diff --git a/package.json b/package.json index e9c33484..1283f545 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "file-saver": "^2.0.2", "geodesy": "^1.1.3", "highlight.js": "^9.15.10", + "ieee754": "^1.1.13", "jimp": "^0.6.4", "jquery": "3.4.1", "js-crc": "^0.2.0", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 94f7fd30..939aa22e 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -14,6 +14,8 @@ "From Charcode", "To Decimal", "From Decimal", + "To Float", + "From Float", "To Binary", "From Binary", "To Octal", diff --git a/src/core/operations/FromFloat.mjs b/src/core/operations/FromFloat.mjs new file mode 100644 index 00000000..4fe5990e --- /dev/null +++ b/src/core/operations/FromFloat.mjs @@ -0,0 +1,78 @@ +/** + * @author tcode2k16 [tcode2k16@gmail.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Utils from "../Utils.mjs"; +import ieee754 from "ieee754"; +import {DELIM_OPTIONS} from "../lib/Delim.mjs"; + +/** + * From Float operation + */ +class FromFloat extends Operation { + + /** + * FromFloat constructor + */ + constructor() { + super(); + + this.name = "From Float"; + this.module = "Default"; + this.description = "Convert from EEE754 Floating Point Numbers"; + this.infoURL = "https://en.wikipedia.org/wiki/IEEE_754"; + this.inputType = "string"; + this.outputType = "byteArray"; + this.args = [ + { + "name": "Endianness", + "type": "option", + "value": [ + "Big Endian", + "Little Endian" + ] + }, + { + "name": "Size", + "type": "option", + "value": [ + "Float (4 bytes)", + "Double (8 bytes)" + ] + }, + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + if (input.length === 0) return []; + + const [endianness, size, delimiterName] = args; + const delim = Utils.charRep(delimiterName || "Space"); + const byteSize = size === "Double (8 bytes)" ? 8 : 4; + const isLE = endianness === "Little Endian"; + const mLen = byteSize === 4 ? 23 : 52; + const floats = input.split(delim); + + const output = new Array(floats.length*byteSize); + for (let i = 0; i < floats.length; i++) { + ieee754.write(output, parseFloat(floats[i]), i*byteSize, isLE, mLen, byteSize); + } + return output; + } + +} + +export default FromFloat; diff --git a/src/core/operations/ToFloat.mjs b/src/core/operations/ToFloat.mjs new file mode 100644 index 00000000..b9aef638 --- /dev/null +++ b/src/core/operations/ToFloat.mjs @@ -0,0 +1,80 @@ +/** + * @author tcode2k16 [tcode2k16@gmail.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import Utils from "../Utils.mjs"; +import ieee754 from "ieee754"; +import {DELIM_OPTIONS} from "../lib/Delim.mjs"; + +/** + * To Float operation + */ +class ToFloat extends Operation { + + /** + * ToFloat constructor + */ + constructor() { + super(); + + this.name = "To Float"; + this.module = "Default"; + this.description = "Convert to EEE754 Floating Point Numbers"; + this.infoURL = "https://en.wikipedia.org/wiki/IEEE_754"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Endianness", + "type": "option", + "value": [ + "Big Endian", + "Little Endian" + ] + }, + { + "name": "Size", + "type": "option", + "value": [ + "Float (4 bytes)", + "Double (8 bytes)" + ] + }, + { + "name": "Delimiter", + "type": "option", + "value": DELIM_OPTIONS + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [endianness, size, delimiterName] = args; + const delim = Utils.charRep(delimiterName || "Space"); + const byteSize = size === "Double (8 bytes)" ? 8 : 4; + const isLE = endianness === "Little Endian"; + const mLen = byteSize === 4 ? 23 : 52; + + if (input.length % byteSize !== 0) { + throw new OperationError(`Input is not a multiple of ${byteSize}`); + } + + const output = []; + for (let i = 0; i < input.length; i+=byteSize) { + output.push(ieee754.read(input, i, isLE, mLen, byteSize)); + } + return output.join(delim); + } + +} + +export default ToFloat; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 14c7408e..b77f16a9 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -39,6 +39,7 @@ import "./tests/Crypt.mjs"; import "./tests/CSV.mjs"; import "./tests/DateTime.mjs"; import "./tests/ExtractEmailAddresses.mjs"; +import "./tests/Float.mjs"; import "./tests/Fork.mjs"; import "./tests/FromDecimal.mjs"; import "./tests/Hash.mjs"; diff --git a/tests/operations/tests/Float.mjs b/tests/operations/tests/Float.mjs new file mode 100644 index 00000000..3977834c --- /dev/null +++ b/tests/operations/tests/Float.mjs @@ -0,0 +1,164 @@ +/** + * Float tests. + * + * @author tcode2k16 [tcode2k16@gmail.com] + * + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + + +TestRegister.addTests([ + { + name: "To Float: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"] + }, + { + op: "To Float", + args: ["Big Endian", "Float (4 bytes)", "Space"] + } + ], + }, + { + name: "To Float (Big Endian, 4 bytes): 0.5", + input: "3f0000003f000000", + expectedOutput: "0.5 0.5", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"] + }, + { + op: "To Float", + args: ["Big Endian", "Float (4 bytes)", "Space"] + } + ] + }, + { + name: "To Float (Little Endian, 4 bytes): 0.5", + input: "0000003f0000003f", + expectedOutput: "0.5 0.5", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"] + }, + { + op: "To Float", + args: ["Little Endian", "Float (4 bytes)", "Space"] + } + ] + }, + { + name: "To Float (Big Endian, 8 bytes): 0.5", + input: "3fe00000000000003fe0000000000000", + expectedOutput: "0.5 0.5", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"] + }, + { + op: "To Float", + args: ["Big Endian", "Double (8 bytes)", "Space"] + } + ] + }, + { + name: "To Float (Little Endian, 8 bytes): 0.5", + input: "000000000000e03f000000000000e03f", + expectedOutput: "0.5 0.5", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"] + }, + { + op: "To Float", + args: ["Little Endian", "Double (8 bytes)", "Space"] + } + ] + }, + { + name: "From Float: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "From Float", + args: ["Big Endian", "Float (4 bytes)", "Space"] + }, + { + op: "To Hex", + args: ["None"] + } + ] + }, + { + name: "From Float (Big Endian, 4 bytes): 0.5", + input: "0.5 0.5", + expectedOutput: "3f0000003f000000", + recipeConfig: [ + { + op: "From Float", + args: ["Big Endian", "Float (4 bytes)", "Space"] + }, + { + op: "To Hex", + args: ["None"] + } + ] + }, + { + name: "From Float (Little Endian, 4 bytes): 0.5", + input: "0.5 0.5", + expectedOutput: "0000003f0000003f", + recipeConfig: [ + { + op: "From Float", + args: ["Little Endian", "Float (4 bytes)", "Space"] + }, + { + op: "To Hex", + args: ["None"] + } + ] + }, + { + name: "From Float (Big Endian, 8 bytes): 0.5", + input: "0.5 0.5", + expectedOutput: "3fe00000000000003fe0000000000000", + recipeConfig: [ + { + op: "From Float", + args: ["Big Endian", "Double (8 bytes)", "Space"] + }, + { + op: "To Hex", + args: ["None"] + } + ] + }, + { + name: "From Float (Little Endian, 8 bytes): 0.5", + input: "0.5 0.5", + expectedOutput: "000000000000e03f000000000000e03f", + recipeConfig: [ + { + op: "From Float", + args: ["Little Endian", "Double (8 bytes)", "Space"] + }, + { + op: "To Hex", + args: ["None"] + } + ] + } +]); From 3546ee30a22611f6af16c00532a31eb08fdd2501 Mon Sep 17 00:00:00 2001 From: Kyle Parrish Date: Mon, 7 Oct 2019 16:09:22 -0400 Subject: [PATCH 04/52] Update escaped chars --- src/core/operations/FangURL.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/FangURL.mjs b/src/core/operations/FangURL.mjs index 5badaae7..7390c1a9 100644 --- a/src/core/operations/FangURL.mjs +++ b/src/core/operations/FangURL.mjs @@ -69,7 +69,7 @@ class FangURL extends Operation { function fangURL(url, dots, http, slashes) { if (dots) url = url.replace(/\[\.\]/g, "."); if (http) url = url.replace(/hxxp/g, "http"); - if (slashes) url = url.replace(/\[\:\/\/\]/g, "://"); + if (slashes) url = url.replace(/[://]/g, "://"); return url; } From c689cf7f134df8e8309302c88e8b9bf1a22e94f8 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Thu, 9 Jan 2020 15:14:33 +0000 Subject: [PATCH 05/52] Fix #930 by allowing variable key sizes --- src/core/operations/BlowfishDecrypt.mjs | 8 ++++++-- src/core/operations/BlowfishEncrypt.mjs | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/operations/BlowfishDecrypt.mjs b/src/core/operations/BlowfishDecrypt.mjs index 07b6a0ff..83236327 100644 --- a/src/core/operations/BlowfishDecrypt.mjs +++ b/src/core/operations/BlowfishDecrypt.mjs @@ -70,10 +70,14 @@ class BlowfishDecrypt extends Operation { inputType = args[3], outputType = args[4]; - if (key.length !== 8) { + if (key.length < 4 || key.length > 56) { throw new OperationError(`Invalid key length: ${key.length} bytes -Blowfish uses a key length of 8 bytes (64 bits).`); +Blowfish's key length needs to between 4 and 56 bytes (32-448 bits).`); + } + + if (iv.length !== 8) { + throw new OperationError(`Invalid IV length: ${iv.length} bytes. Expected 8 bytes`); } input = Utils.convertToByteString(input, inputType); diff --git a/src/core/operations/BlowfishEncrypt.mjs b/src/core/operations/BlowfishEncrypt.mjs index e7e558cd..ebf5e5c2 100644 --- a/src/core/operations/BlowfishEncrypt.mjs +++ b/src/core/operations/BlowfishEncrypt.mjs @@ -70,10 +70,14 @@ class BlowfishEncrypt extends Operation { inputType = args[3], outputType = args[4]; - if (key.length !== 8) { + if (key.length < 4 || key.length > 56) { throw new OperationError(`Invalid key length: ${key.length} bytes + +Blowfish's key length needs to between 4 and 56 bytes (32-448 bits).`); + } -Blowfish uses a key length of 8 bytes (64 bits).`); + if (iv.length !== 8) { + throw new OperationError(`Invalid IV length: ${iv.length} bytes. Expected 8 bytes`); } input = Utils.convertToByteString(input, inputType); From 9e17825b53b371ed1c8671472ef6585f96a29d86 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Thu, 9 Jan 2020 15:15:01 +0000 Subject: [PATCH 06/52] Add variable key size tests --- tests/operations/tests/Crypt.mjs | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/operations/tests/Crypt.mjs b/tests/operations/tests/Crypt.mjs index b56f9cf8..a6b9e2ac 100644 --- a/tests/operations/tests/Crypt.mjs +++ b/tests/operations/tests/Crypt.mjs @@ -1751,4 +1751,38 @@ DES uses a key length of 8 bytes (64 bits).`, } ], }, + { + name: "Blowfish Encrypt with variable key length: CBC, ASCII, 4 bytes", + input: "The quick brown fox jumps over the lazy dog.", + expectedOutput: "823f337a53ecf121aa9ec1b111bd5064d1d7586abbdaaa0c8fd0c6cc43c831c88bf088ee3e07287e3f36cf2e45f9c7e6", + recipeConfig: [ + { + "op": "Blowfish Encrypt", + "args": [ + {"option": "Hex", "string": "00112233"}, // Key + {"option": "Hex", "string": "0000000000000000"}, // IV + "CBC", // Mode + "Raw", // Input + "Hex" // Output + ] + } + ], + }, + { + name: "Blowfish Encrypt with variable key length: CBC, ASCII, 42 bytes", + input: "The quick brown fox jumps over the lazy dog.", + expectedOutput: "19f5a68145b34321cfba72226b0f33922ce44dd6e7869fe328db64faae156471216f12ed2a37fd0bdd7cebf867b3cff0", + recipeConfig: [ + { + "op": "Blowfish Encrypt", + "args": [ + {"option": "Hex", "string": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"}, // Key + {"option": "Hex", "string": "0000000000000000"}, // IV + "CBC", // Mode + "Raw", // Input + "Hex" // Output + ] + } + ], + } ]); From 81605b2222e2a4b9b41198651da3abc9f2156082 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 11 Jan 2020 10:47:40 +0000 Subject: [PATCH 07/52] Grammar typo --- src/core/operations/BlowfishDecrypt.mjs | 2 +- src/core/operations/BlowfishEncrypt.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/BlowfishDecrypt.mjs b/src/core/operations/BlowfishDecrypt.mjs index 83236327..a80fdb2b 100644 --- a/src/core/operations/BlowfishDecrypt.mjs +++ b/src/core/operations/BlowfishDecrypt.mjs @@ -73,7 +73,7 @@ class BlowfishDecrypt extends Operation { if (key.length < 4 || key.length > 56) { throw new OperationError(`Invalid key length: ${key.length} bytes -Blowfish's key length needs to between 4 and 56 bytes (32-448 bits).`); +Blowfish's key length needs to be between 4 and 56 bytes (32-448 bits).`); } if (iv.length !== 8) { diff --git a/src/core/operations/BlowfishEncrypt.mjs b/src/core/operations/BlowfishEncrypt.mjs index ebf5e5c2..7d550d46 100644 --- a/src/core/operations/BlowfishEncrypt.mjs +++ b/src/core/operations/BlowfishEncrypt.mjs @@ -73,7 +73,7 @@ class BlowfishEncrypt extends Operation { if (key.length < 4 || key.length > 56) { throw new OperationError(`Invalid key length: ${key.length} bytes -Blowfish's key length needs to between 4 and 56 bytes (32-448 bits).`); +Blowfish's key length needs to be between 4 and 56 bytes (32-448 bits).`); } if (iv.length !== 8) { From cd4e70b24b7f11bbdfdebb374650781f42479370 Mon Sep 17 00:00:00 2001 From: Evan Reichard Date: Mon, 3 May 2021 21:07:58 -0400 Subject: [PATCH 08/52] Fixed right shift 32 problem --- src/core/vendor/DisassembleX86-64.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/vendor/DisassembleX86-64.mjs b/src/core/vendor/DisassembleX86-64.mjs index 5f0ac65d..bbaf7a9b 100644 --- a/src/core/vendor/DisassembleX86-64.mjs +++ b/src/core/vendor/DisassembleX86-64.mjs @@ -4054,7 +4054,7 @@ function DecodeImmediate( type, BySize, SizeSetting ) //Sign bit adjust. - if( V32 >= ( n >> 1 ) ) { V32 -= n; } + if( V32 >= ( n / 2 ) ) { V32 -= n; } //Add position. From 3ea12a2e1be11805837dad8b620b73662f5fa8ce Mon Sep 17 00:00:00 2001 From: Luis Martinez Date: Sat, 28 May 2022 00:17:59 -0500 Subject: [PATCH 09/52] xxtea encryption added --- src/core/config/Categories.json | 3 +- src/core/operations/XXTEA.mjs | 182 ++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/XXTEA.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 9540f8a3..a55d5ddd 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -123,7 +123,8 @@ "Typex", "Lorenz", "Colossus", - "SIGABA" + "SIGABA", + "XXTEA" ] }, { diff --git a/src/core/operations/XXTEA.mjs b/src/core/operations/XXTEA.mjs new file mode 100644 index 00000000..e8264c4d --- /dev/null +++ b/src/core/operations/XXTEA.mjs @@ -0,0 +1,182 @@ +/** + * @author devcydo [devcydo@gmail.com] + * @author Ma Bingyao [mabingyao@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import {toBase64} from "../lib/Base64.mjs"; +import Utils from "../Utils.mjs"; + +/** + * XXTEA Encrypt operation + */ +class XXTEAEncrypt extends Operation { + + /** + * XXTEAEncrypt constructor + */ + constructor() { + super(); + + this.name = "XXTEA"; + this.module = "Default"; + this.description = "Corrected Block TEA (often referred to as XXTEA) is a block cipher designed to correct weaknesses in the original Block TEA. XXTEA operates on variable-length blocks that are some arbitrary multiple of 32 bits in size (minimum 64 bits). The number of full cycles depends on the block size, but there are at least six (rising to 32 for small block sizes). The original Block TEA applies the XTEA round function to each word in the block and combines it additively with its leftmost neighbour. Slow diffusion rate of the decryption process was immediately exploited to break the cipher. Corrected Block TEA uses a more involved round function which makes use of both immediate neighbours in processing each word in the block."; + this.infoURL = "https://wikipedia.org/wiki/XXTEA"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "string", + "value": "", + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let key = args[0]; + + if (input === undefined || input === null || input.length === 0) { + throw new OperationError("Invalid input length (0)"); + } + + if (key === undefined || key === null || key.length === 0) { + throw new OperationError("Invalid key length (0)"); + } + + input = Utils.convertToByteString(input, "utf8"); + key = Utils.convertToByteString(key, "utf8"); + + input = this.convertToUint32Array(input, true); + key = this.fixLength(this.convertToUint32Array(key, false)); + + let encrypted = this.encryptUint32Array(input, key); + + encrypted = toBase64(this.toBinaryString(encrypted, false)); + + return encrypted; + } + + /** + * Convert Uint32Array to binary string + * + * @param {Uint32Array} v + * @param {Boolean} includeLength + * @returns {string} + */ + toBinaryString(v, includeLENGTH) { + const LENGTH = v.LENGTH; + let n = LENGTH << 2; + if (includeLENGTH) { + const M = v[LENGTH - 1]; + n -= 4; + if ((M < n - 3) || (M > n)) { + return null; + } + n = M; + } + for (let i = 0; i < LENGTH; i++) { + v[i] = String.fromCharCode( + v[i] & 0xFF, + v[i] >>> 8 & 0xFF, + v[i] >>> 16 & 0xFF, + v[i] >>> 24 & 0xFF + ); + } + const RESULT = v.join(""); + if (includeLENGTH) { + return RESULT.substring(0, n); + } + return RESULT; + } + + /** + * @param {number} sum + * @param {number} y + * @param {number} z + * @param {number} p + * @param {number} e + * @param {number} k + * @returns {number} + */ + mx(sum, y, z, p, e, k) { + return ((z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4)) ^ ((sum ^ y) + (k[p & 3 ^ e] ^ z)); + } + + + /** + * Encrypt Uint32Array + * + * @param {Uint32Array} v + * @param {number} k + * @returns {Uint32Array} + */ + encryptUint32Array(v, k) { + const LENGTH = v.LENGTH; + const N = LENGTH - 1; + let y, z, sum, e, p, q; + z = v[N]; + sum = 0; + for (q = Math.floor(6 + 52 / LENGTH) | 0; q > 0; --q) { + sum = (sum + 0x9E3779B9) & 0xFFFFFFFF; + e = sum >>> 2 & 3; + for (p = 0; p < N; ++p) { + y = v[p + 1]; + z = v[p] = (v[p] + this.mx(sum, y, z, p, e, k)) & 0xFFFFFFFF; + } + y = v[0]; + z = v[N] = (v[N] + this.mx(sum, y, z, N, e, k)) & 0xFFFFFFFF; + } + return v; + } + + /** + * Fixes the Uint32Array lenght to 4 + * + * @param {Uint32Array} k + * @returns {Uint32Array} + */ + fixLength(k) { + if (k.length < 4) { + k.length = 4; + } + return k; + } + + /** + * Convert string to Uint32Array + * + * @param {string} bs + * @param {Boolean} includeLength + * @returns {Uint32Array} + */ + convertToUint32Array(bs, includeLength) { + const LENGTH = bs.LENGTH; + let n = LENGTH >> 2; + if ((LENGTH & 3) !== 0) { + ++n; + } + let v; + if (includeLength) { + v = new Array(n + 1); + v[n] = LENGTH; + } else { + v = new Array(n); + } + for (let i = 0; i < LENGTH; ++i) { + v[i >> 2] |= bs.charCodeAt(i) << ((i & 3) << 3); + } + return v; + } + +} + +export default XXTEAEncrypt; From 19423cc4372ed5d901d65afb21b8620ca188d881 Mon Sep 17 00:00:00 2001 From: Luis Martinez Date: Sat, 28 May 2022 00:20:51 -0500 Subject: [PATCH 10/52] xxtea encryption added --- src/core/operations/XXTEA.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XXTEA.mjs b/src/core/operations/XXTEA.mjs index e8264c4d..4fa0706d 100644 --- a/src/core/operations/XXTEA.mjs +++ b/src/core/operations/XXTEA.mjs @@ -98,7 +98,7 @@ class XXTEAEncrypt extends Operation { return RESULT; } - /** + /** * @param {number} sum * @param {number} y * @param {number} z From 893b84d0426754d0b21647ef25564f6d9b19f95e Mon Sep 17 00:00:00 2001 From: Luis Martinez Date: Sat, 28 May 2022 00:17:59 -0500 Subject: [PATCH 11/52] xxtea encryption added --- src/core/config/Categories.json | 3 +- src/core/operations/XXTEA.mjs | 182 ++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/XXTEA.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 8ac60048..26e56905 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -131,7 +131,8 @@ "Typex", "Lorenz", "Colossus", - "SIGABA" + "SIGABA", + "XXTEA" ] }, { diff --git a/src/core/operations/XXTEA.mjs b/src/core/operations/XXTEA.mjs new file mode 100644 index 00000000..e8264c4d --- /dev/null +++ b/src/core/operations/XXTEA.mjs @@ -0,0 +1,182 @@ +/** + * @author devcydo [devcydo@gmail.com] + * @author Ma Bingyao [mabingyao@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import {toBase64} from "../lib/Base64.mjs"; +import Utils from "../Utils.mjs"; + +/** + * XXTEA Encrypt operation + */ +class XXTEAEncrypt extends Operation { + + /** + * XXTEAEncrypt constructor + */ + constructor() { + super(); + + this.name = "XXTEA"; + this.module = "Default"; + this.description = "Corrected Block TEA (often referred to as XXTEA) is a block cipher designed to correct weaknesses in the original Block TEA. XXTEA operates on variable-length blocks that are some arbitrary multiple of 32 bits in size (minimum 64 bits). The number of full cycles depends on the block size, but there are at least six (rising to 32 for small block sizes). The original Block TEA applies the XTEA round function to each word in the block and combines it additively with its leftmost neighbour. Slow diffusion rate of the decryption process was immediately exploited to break the cipher. Corrected Block TEA uses a more involved round function which makes use of both immediate neighbours in processing each word in the block."; + this.infoURL = "https://wikipedia.org/wiki/XXTEA"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Key", + "type": "string", + "value": "", + }, + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let key = args[0]; + + if (input === undefined || input === null || input.length === 0) { + throw new OperationError("Invalid input length (0)"); + } + + if (key === undefined || key === null || key.length === 0) { + throw new OperationError("Invalid key length (0)"); + } + + input = Utils.convertToByteString(input, "utf8"); + key = Utils.convertToByteString(key, "utf8"); + + input = this.convertToUint32Array(input, true); + key = this.fixLength(this.convertToUint32Array(key, false)); + + let encrypted = this.encryptUint32Array(input, key); + + encrypted = toBase64(this.toBinaryString(encrypted, false)); + + return encrypted; + } + + /** + * Convert Uint32Array to binary string + * + * @param {Uint32Array} v + * @param {Boolean} includeLength + * @returns {string} + */ + toBinaryString(v, includeLENGTH) { + const LENGTH = v.LENGTH; + let n = LENGTH << 2; + if (includeLENGTH) { + const M = v[LENGTH - 1]; + n -= 4; + if ((M < n - 3) || (M > n)) { + return null; + } + n = M; + } + for (let i = 0; i < LENGTH; i++) { + v[i] = String.fromCharCode( + v[i] & 0xFF, + v[i] >>> 8 & 0xFF, + v[i] >>> 16 & 0xFF, + v[i] >>> 24 & 0xFF + ); + } + const RESULT = v.join(""); + if (includeLENGTH) { + return RESULT.substring(0, n); + } + return RESULT; + } + + /** + * @param {number} sum + * @param {number} y + * @param {number} z + * @param {number} p + * @param {number} e + * @param {number} k + * @returns {number} + */ + mx(sum, y, z, p, e, k) { + return ((z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4)) ^ ((sum ^ y) + (k[p & 3 ^ e] ^ z)); + } + + + /** + * Encrypt Uint32Array + * + * @param {Uint32Array} v + * @param {number} k + * @returns {Uint32Array} + */ + encryptUint32Array(v, k) { + const LENGTH = v.LENGTH; + const N = LENGTH - 1; + let y, z, sum, e, p, q; + z = v[N]; + sum = 0; + for (q = Math.floor(6 + 52 / LENGTH) | 0; q > 0; --q) { + sum = (sum + 0x9E3779B9) & 0xFFFFFFFF; + e = sum >>> 2 & 3; + for (p = 0; p < N; ++p) { + y = v[p + 1]; + z = v[p] = (v[p] + this.mx(sum, y, z, p, e, k)) & 0xFFFFFFFF; + } + y = v[0]; + z = v[N] = (v[N] + this.mx(sum, y, z, N, e, k)) & 0xFFFFFFFF; + } + return v; + } + + /** + * Fixes the Uint32Array lenght to 4 + * + * @param {Uint32Array} k + * @returns {Uint32Array} + */ + fixLength(k) { + if (k.length < 4) { + k.length = 4; + } + return k; + } + + /** + * Convert string to Uint32Array + * + * @param {string} bs + * @param {Boolean} includeLength + * @returns {Uint32Array} + */ + convertToUint32Array(bs, includeLength) { + const LENGTH = bs.LENGTH; + let n = LENGTH >> 2; + if ((LENGTH & 3) !== 0) { + ++n; + } + let v; + if (includeLength) { + v = new Array(n + 1); + v[n] = LENGTH; + } else { + v = new Array(n); + } + for (let i = 0; i < LENGTH; ++i) { + v[i >> 2] |= bs.charCodeAt(i) << ((i & 3) << 3); + } + return v; + } + +} + +export default XXTEAEncrypt; From 653af6a3005f872d98ca0d59f0aa118e48f88bb7 Mon Sep 17 00:00:00 2001 From: Luis Martinez Date: Sat, 28 May 2022 00:20:51 -0500 Subject: [PATCH 12/52] xxtea encryption added --- src/core/operations/XXTEA.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XXTEA.mjs b/src/core/operations/XXTEA.mjs index e8264c4d..4fa0706d 100644 --- a/src/core/operations/XXTEA.mjs +++ b/src/core/operations/XXTEA.mjs @@ -98,7 +98,7 @@ class XXTEAEncrypt extends Operation { return RESULT; } - /** + /** * @param {number} sum * @param {number} y * @param {number} z From c14098a27c47bf345f1f119b970248fd573fa9d6 Mon Sep 17 00:00:00 2001 From: Luis Martinez Date: Mon, 11 Jul 2022 19:38:59 -0500 Subject: [PATCH 13/52] tests added and XXTEA not working correctly fixed --- src/core/operations/XXTEA.mjs | 6 ++-- tests/operations/tests/XXTEA.mjs | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 tests/operations/tests/XXTEA.mjs diff --git a/src/core/operations/XXTEA.mjs b/src/core/operations/XXTEA.mjs index 4fa0706d..1a0a4368 100644 --- a/src/core/operations/XXTEA.mjs +++ b/src/core/operations/XXTEA.mjs @@ -73,7 +73,7 @@ class XXTEAEncrypt extends Operation { * @returns {string} */ toBinaryString(v, includeLENGTH) { - const LENGTH = v.LENGTH; + const LENGTH = v.length; let n = LENGTH << 2; if (includeLENGTH) { const M = v[LENGTH - 1]; @@ -120,7 +120,7 @@ class XXTEAEncrypt extends Operation { * @returns {Uint32Array} */ encryptUint32Array(v, k) { - const LENGTH = v.LENGTH; + const LENGTH = v.length; const N = LENGTH - 1; let y, z, sum, e, p, q; z = v[N]; @@ -159,7 +159,7 @@ class XXTEAEncrypt extends Operation { * @returns {Uint32Array} */ convertToUint32Array(bs, includeLength) { - const LENGTH = bs.LENGTH; + const LENGTH = bs.length; let n = LENGTH >> 2; if ((LENGTH & 3) !== 0) { ++n; diff --git a/tests/operations/tests/XXTEA.mjs b/tests/operations/tests/XXTEA.mjs new file mode 100644 index 00000000..4787f086 --- /dev/null +++ b/tests/operations/tests/XXTEA.mjs @@ -0,0 +1,62 @@ +/** + * Base64 tests. + * + * @author devcydo [devcydo@gmail.com] + * + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "XXTEA", + input: "Hello World! 你好,中国!", + expectedOutput: "QncB1C0rHQoZ1eRiPM4dsZtRi9pNrp7sqvX76cFXvrrIHXL6", + reecipeConfig: [ + { + args: "1234567890" + }, + ], + }, + { + name: "XXTEA", + input: "ნუ პანიკას", + expectedOutput: "PbWjnbFmP8Apu2MKOGNbjeW/72IZLlLMS/g82ozLxwE=", + reecipeConfig: [ + { + args: "1234567890" + }, + ], + }, + { + name: "XXTEA", + input: "ნუ პანიკას", + expectedOutput: "dHrOJ4ClIx6gH33NPSafYR2GG7UqsazY6Xfb0iekBY4=", + reecipeConfig: [ + { + args: "ll3kj209d2" + }, + ], + }, + { + name: "XXTEA", + input: "", + expectedOutput: "Invalid input length (0)", + reecipeConfig: [ + { + args: "1234567890" + }, + ], + }, + { + name: "XXTEA", + input: "", + expectedOutput: "Invalid input length (0)", + reecipeConfig: [ + { + args: "" + }, + ], + }, +]); From cb986725497ba14d8352d5ac194b868153281aa7 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Sun, 30 Jul 2023 17:02:36 +0200 Subject: [PATCH 14/52] Fix ChaCha operation Raw output Previously, an array type error prevented any output when selecting the 'Raw' output option for the ChaCha operation. This did not show up in tests, as they all compared to hex values. This also adds a test (relying on the 'To Hex' operation) that catches this. --- src/core/operations/ChaCha.mjs | 2 +- tests/operations/tests/ChaCha.mjs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/core/operations/ChaCha.mjs b/src/core/operations/ChaCha.mjs index 166c1663..40ba46dc 100644 --- a/src/core/operations/ChaCha.mjs +++ b/src/core/operations/ChaCha.mjs @@ -191,7 +191,7 @@ ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).`); if (outputType === "Hex") { return toHex(output); } else { - return Utils.arrayBufferToStr(output); + return Utils.arrayBufferToStr(Uint8Array.from(output).buffer); } } diff --git a/tests/operations/tests/ChaCha.mjs b/tests/operations/tests/ChaCha.mjs index 44b39a67..d194390d 100644 --- a/tests/operations/tests/ChaCha.mjs +++ b/tests/operations/tests/ChaCha.mjs @@ -58,6 +58,25 @@ ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).`, } ], }, + { + name: "ChaCha: RFC8439 Raw output", + input: "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.", + expectedOutput: "6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81 e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57 16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8 07 ca 0d bf 50 0d 6a 61 56 a3 8e 08 8a 22 b6 5e 52 bc 51 4d 16 cc f8 06 81 8c e9 1a b7 79 37 36 5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42 87 4d", + recipeConfig: [ + { + "op": "ChaCha", + "args": [ + {"option": "Hex", "string": "00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f"}, + {"option": "Hex", "string": "00:00:00:00:00:00:00:4a:00:00:00:00"}, + 1, "20", "Raw", "Raw", + ] + }, + { + "op": "To Hex", + "args": [] + }, + ], + }, { name: "ChaCha: draft-strombergson-chacha-test-vectors-01 TC7.1", input: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", From d2ff03cea49e37a71b7d1e90eeeac60625eb7241 Mon Sep 17 00:00:00 2001 From: tomgond Date: Wed, 21 Feb 2024 19:55:09 +0200 Subject: [PATCH 15/52] Update DateTime.mjs Add test for time-delta --- tests/operations/tests/DateTime.mjs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/operations/tests/DateTime.mjs b/tests/operations/tests/DateTime.mjs index 6276890d..df6d6677 100644 --- a/tests/operations/tests/DateTime.mjs +++ b/tests/operations/tests/DateTime.mjs @@ -31,4 +31,26 @@ TestRegister.addTests([ }, ], }, + { + name: "DateTime Delta Positive", + input: "20/02/2024 13:36:00", + expectedOutput: "20/02/2024 13:37:00", + recipeConfig: [ + { + op: "DateTime Delta", + args: ["Standard date and time", "DD/MM/YYYY HH:mm:ss", "+0.0:01:0"], + }, + ], + }, + { + name: "DateTime Delta Negative", + input: "20/02/2024 14:37:00", + expectedOutput: "20/02/2024 13:37:00", + recipeConfig: [ + { + op: "DateTime Delta", + args: ["Standard date and time", "DD/MM/YYYY HH:mm:ss", "-0.1:00:0"], + }, + ], + }, ]); From 4dc4c7edd2a388792a5915d3abf2b4969620e17c Mon Sep 17 00:00:00 2001 From: tomgond Date: Wed, 21 Feb 2024 19:56:42 +0200 Subject: [PATCH 16/52] Update Categories.json Add DateTime Delta to categories --- src/core/config/Categories.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 4f1b3328..d68c1713 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -312,6 +312,7 @@ "To UNIX Timestamp", "Windows Filetime to UNIX Timestamp", "UNIX Timestamp to Windows Filetime", + "DateTime Delta", "Extract dates", "Get Time", "Sleep" From 6331c203064563c628fe38f58cffb2206ce97afa Mon Sep 17 00:00:00 2001 From: tomgond Date: Wed, 21 Feb 2024 19:58:13 +0200 Subject: [PATCH 17/52] Add code for DateTime Delta to calculate operation --- src/core/operations/DateTimeDelta.mjs | 109 ++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/core/operations/DateTimeDelta.mjs diff --git a/src/core/operations/DateTimeDelta.mjs b/src/core/operations/DateTimeDelta.mjs new file mode 100644 index 00000000..6a7b8f7a --- /dev/null +++ b/src/core/operations/DateTimeDelta.mjs @@ -0,0 +1,109 @@ +/** + * @author tomgond [tom.gonda@gmail.com] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import moment from "moment-timezone"; +import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime.mjs"; + +/** + * @param {string} timeString + * @returns {string} +*/ +function parseTimeString(timeString) { + // Split the string into its components + const parts = timeString.split(":"); + // Extract the sign, days, hours, minutes, and seconds + const sign = parts[0][0] === "-" ? "-" : "+"; + const days = parseInt(parts[0].split(".")[0].slice(1), 10); + const hours = parseInt(parts[0].split(".")[1], 10); + const minutes = parseInt(parts[1], 10); + const seconds = parseInt(parts[2], 10); + + return { + sign, + days, + hours, + minutes, + seconds + }; +} + +/** + * DateTime Delta operation + */ +class DateTimeDelta extends Operation { + + /** + * DateTimeDelta constructor + */ + constructor() { + super(); + + this.name = "DateTime Delta"; + this.module = "Default"; + this.description = "Calculates a new DateTime value given an input DateTime value and a time difference (delta) from the input DateTime value."; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Built in formats", + "type": "populateOption", + "value": DATETIME_FORMATS, + "target": 1 + }, + { + "name": "Input format string", + "type": "binaryString", + "value": "DD/MM/YYYY HH:mm:ss" + }, + { + "name": "Time Delta", + "type": "binaryString", + "value": "+0.00:00:00" + } + + ]; + } + + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const inputFormat = args[1], + inputTimezone = "UTC"; + const deltaStr = args[2]; + + let date = ""; + try { + date = moment.tz(input, inputFormat, inputTimezone); + if (!date || date.format() === "Invalid date") throw Error; + } catch (err) { + return `Invalid format.\n\n${FORMAT_EXAMPLES}`; + } + + const deltaDict = parseTimeString(deltaStr); + let newDate; + if (deltaDict.sign === "-") { + newDate = date.add(-deltaDict.days, "days") + .add(-deltaDict.hours, "hours") + .add(-deltaDict.minutes, "minutes") + .add(-deltaDict.seconds, "seconds"); + + } else { + newDate = date.add(deltaDict.days, "days") + .add(deltaDict.hours, "hours") + .add(deltaDict.minutes, "minutes") + .add(deltaDict.seconds, "seconds"); + } + return newDate.tz(inputTimezone).format(inputFormat.replace(/[<>]/g, "")); + } +} + +export default DateTimeDelta; From 4e9567f5396d1d700cb204655c6793bdaf2221ff Mon Sep 17 00:00:00 2001 From: tomgond Date: Thu, 22 Feb 2024 21:49:24 +0200 Subject: [PATCH 18/52] Update DateTimeDelta.mjs Some change to re-run tests. --- src/core/operations/DateTimeDelta.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/DateTimeDelta.mjs b/src/core/operations/DateTimeDelta.mjs index 6a7b8f7a..585ee370 100644 --- a/src/core/operations/DateTimeDelta.mjs +++ b/src/core/operations/DateTimeDelta.mjs @@ -10,7 +10,7 @@ import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime.mjs"; /** * @param {string} timeString - * @returns {string} + * @returns {string} */ function parseTimeString(timeString) { // Split the string into its components From e85acee509757df7bc750ad99ce8a8aca089d182 Mon Sep 17 00:00:00 2001 From: tomgond Date: Fri, 23 Feb 2024 07:09:04 +0200 Subject: [PATCH 19/52] Update DateTimeDelta.mjs Another commit for re-build --- src/core/operations/DateTimeDelta.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/DateTimeDelta.mjs b/src/core/operations/DateTimeDelta.mjs index 585ee370..66949ace 100644 --- a/src/core/operations/DateTimeDelta.mjs +++ b/src/core/operations/DateTimeDelta.mjs @@ -32,7 +32,7 @@ function parseTimeString(timeString) { } /** - * DateTime Delta operation + * DateTime Delta operation */ class DateTimeDelta extends Operation { From 2784978eb5088a5e1c21102680ad0ba90fa99e51 Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:20:28 +0000 Subject: [PATCH 20/52] Fix slash regular expression bug --- src/core/operations/FangURL.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/operations/FangURL.mjs b/src/core/operations/FangURL.mjs index 7390c1a9..93e01770 100644 --- a/src/core/operations/FangURL.mjs +++ b/src/core/operations/FangURL.mjs @@ -24,17 +24,17 @@ class FangURL extends Operation { this.outputType = "string"; this.args = [ { - name: "Escape [.]", + name: "Restore [.]", type: "boolean", value: true }, { - name: "Escape hxxp", + name: "Restore hxxp", type: "boolean", value: true }, { - name: "Escape ://", + name: "Restore ://", type: "boolean", value: true } @@ -69,7 +69,7 @@ class FangURL extends Operation { function fangURL(url, dots, http, slashes) { if (dots) url = url.replace(/\[\.\]/g, "."); if (http) url = url.replace(/hxxp/g, "http"); - if (slashes) url = url.replace(/[://]/g, "://"); + if (slashes) url = url.replace(/\[:\/\/\]/g, "://"); return url; } From 7ccf8cbacd6142994631da9b7d4d33868c2e310e Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:34:12 +0000 Subject: [PATCH 21/52] 10.13.0 --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0a53c48..ae93c914 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 +### [10.13.0] - 2024-03-30 +- Added 'FangURL' operation [@breakersall] [@arnydo] | [#1591] [#654] + ### [10.12.0] - 2024-03-29 - Added 'Salsa20' and 'XSalsa20' operation [@joostrijneveld] | [#1750] @@ -400,6 +403,7 @@ All major and minor version changes will be documented in this file. Details of ## [4.0.0] - 2016-11-28 - Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306) +[10.13.0]: https://github.com/gchq/CyberChef/releases/tag/v10.13.0 [10.12.0]: https://github.com/gchq/CyberChef/releases/tag/v10.12.0 [10.11.0]: https://github.com/gchq/CyberChef/releases/tag/v10.11.0 [10.10.0]: https://github.com/gchq/CyberChef/releases/tag/v10.10.0 @@ -571,6 +575,7 @@ All major and minor version changes will be documented in this file. Details of [@AshCorr]: https://github.com/AshCorr [@simonw]: https://github.com/simonw [@chriswhite199]: https://github.com/chriswhite199 +[@breakersall]: https://github.com/breakersall [8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7 @@ -703,3 +708,5 @@ All major and minor version changes will be documented in this file. Details of [#1752]: https://github.com/gchq/CyberChef/issues/1752 [#1753]: https://github.com/gchq/CyberChef/issues/1753 [#1750]: https://github.com/gchq/CyberChef/issues/1750 +[#1591]: https://github.com/gchq/CyberChef/issues/1591 +[#654]: https://github.com/gchq/CyberChef/issues/654 diff --git a/package-lock.json b/package-lock.json index 701b6f64..3b47a914 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "10.10.0", + "version": "10.13.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "10.10.0", + "version": "10.13.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index c77548ca..1ec0218a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "10.12.1", + "version": "10.13.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 6677317e27a1673a49813f06dde241476cd4bb87 Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Sun, 31 Mar 2024 01:21:17 +0000 Subject: [PATCH 22/52] update x86 disassembly tests --- tests/node/tests/operations.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 86dbee50..a092ef69 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -432,7 +432,7 @@ color: white; it("Disassemble x86", () => { const result = chef.disassembleX86(chef.toBase64("one two three")); const expected = `0000000000000000 0000 ADD BYTE PTR [RAX],AL\r -0000000000000002 0B250000000B OR ESP,DWORD PTR [0000000-F4FFFFF8]\r +0000000000000002 0B250000000B OR ESP,DWORD PTR [000000000B000008]\r `; assert.strictEqual(result.toString(), expected); }), From 866c9a94aed2db851c5fd93937158844374170ff Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Sun, 31 Mar 2024 02:24:39 +0000 Subject: [PATCH 23/52] 10.14.0 --- CHANGELOG.md | 15 +++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae93c914..9b6497a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,13 @@ All major and minor version changes will be documented in this file. Details of ## Details +### [10.14.0] - 2024-03-31 +- Added 'To Float' and 'From Float' operations [@tcode2k16] | [#1762] +- Fix ChaCha raw export option [@joostrijneveld] | [#1606] +- Update x86 disassembler vendor library [@evanreichard] | [#1197] +- Allow variable Blowfish key sizes [@cbeuw] | [#933] +- Added 'XXTEA' operation [@devcydo] | [#1361] + ### [10.13.0] - 2024-03-30 - Added 'FangURL' operation [@breakersall] [@arnydo] | [#1591] [#654] @@ -403,6 +410,7 @@ All major and minor version changes will be documented in this file. Details of ## [4.0.0] - 2016-11-28 - Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306) +[10.14.0]: https://github.com/gchq/CyberChef/releases/tag/v10.14.0 [10.13.0]: https://github.com/gchq/CyberChef/releases/tag/v10.13.0 [10.12.0]: https://github.com/gchq/CyberChef/releases/tag/v10.12.0 [10.11.0]: https://github.com/gchq/CyberChef/releases/tag/v10.11.0 @@ -576,6 +584,8 @@ All major and minor version changes will be documented in this file. Details of [@simonw]: https://github.com/simonw [@chriswhite199]: https://github.com/chriswhite199 [@breakersall]: https://github.com/breakersall +[@evanreichard]: https://github.com/evanreichard +[@devcydo]: https://github.com/devcydo [8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7 @@ -710,3 +720,8 @@ All major and minor version changes will be documented in this file. Details of [#1750]: https://github.com/gchq/CyberChef/issues/1750 [#1591]: https://github.com/gchq/CyberChef/issues/1591 [#654]: https://github.com/gchq/CyberChef/issues/654 +[#1762]: https://github.com/gchq/CyberChef/issues/1762 +[#1606]: https://github.com/gchq/CyberChef/issues/1606 +[#1197]: https://github.com/gchq/CyberChef/issues/1197 +[#933]: https://github.com/gchq/CyberChef/issues/933 +[#1361]: https://github.com/gchq/CyberChef/issues/1361 diff --git a/package-lock.json b/package-lock.json index 2649c07b..122a2990 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "10.13.0", + "version": "10.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "10.13.0", + "version": "10.14.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index f9fac9d4..6e2965f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "10.13.0", + "version": "10.14.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 1b16c26699d4f53917a2267308b2d8c4efbf3a13 Mon Sep 17 00:00:00 2001 From: mshwed Date: Mon, 11 Mar 2019 09:32:44 -0400 Subject: [PATCH 24/52] Operation: Added extract hash feature --- src/core/config/Categories.json | 1 + src/core/operations/ExtractHashes.mjs | 81 +++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/core/operations/ExtractHashes.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 2dd9f29f..2d7b30ff 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -337,6 +337,7 @@ "Extract domains", "Extract file paths", "Extract dates", + "Extract Hashes", "Regular expression", "XPath expression", "JPath expression", diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs new file mode 100644 index 00000000..ed186fb3 --- /dev/null +++ b/src/core/operations/ExtractHashes.mjs @@ -0,0 +1,81 @@ +/** + * @author mshwed [m@ttshwed.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import { search } from "../lib/Extract"; + +/** + * Extract Hash Values operation + */ +class ExtractHashes extends Operation { + + /** + * ExtractHashValues constructor + */ + constructor() { + super(); + + this.name = "Extract Hashes"; + this.module = "Default"; + this.description = "Extracts hash values based on hash byte length"; + this.infoURL = "https://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Hash length", + type: "number", + value: 32 + }, + { + name: "All hashes", + type: "boolean", + value: false + }, + { + name: "Display Total", + type: "boolean", + value: false + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let results = []; + let hashCount = 0; + + const hashLength = args[0]; + const searchAllHashes = args[1]; + const showDisplayTotal = args[2]; + + let hashLengths = [hashLength]; + if (searchAllHashes) hashLengths = [4, 8, 16, 32, 64, 128, 160, 192, 224, 256, 320, 384, 512, 1024]; + + for (let hashLength of hashLengths) { + const regex = new RegExp(`(\\b|^)[a-f0-9]{${hashLength}}(\\b|$)`, "g"); + const searchResults = search(input, regex, null, false); + + hashCount += searchResults.split("\n").length - 1; + results.push(searchResults); + } + + let output = ""; + if (showDisplayTotal) { + output = `Total Results: ${hashCount}\n\n`; + } + + output = output + results.join(""); + return output; + } + +} + +export default ExtractHashes; From 98edef389ca7100d1b3dde6ac39062550be7d90c Mon Sep 17 00:00:00 2001 From: mshwed Date: Mon, 11 Mar 2019 09:53:12 -0400 Subject: [PATCH 25/52] Corrected module type --- src/core/operations/ExtractHashes.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index ed186fb3..27402835 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -19,7 +19,7 @@ class ExtractHashes extends Operation { super(); this.name = "Extract Hashes"; - this.module = "Default"; + this.module = "Regex"; this.description = "Extracts hash values based on hash byte length"; this.infoURL = "https://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions"; this.inputType = "string"; From de8ed6962d99cc11b632da39753581b70e950846 Mon Sep 17 00:00:00 2001 From: mshwed Date: Mon, 11 Mar 2019 20:02:49 -0400 Subject: [PATCH 26/52] Improved description of operation --- src/core/operations/ExtractHashes.mjs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index 27402835..f411f12d 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -20,13 +20,13 @@ class ExtractHashes extends Operation { this.name = "Extract Hashes"; this.module = "Regex"; - this.description = "Extracts hash values based on hash byte length"; + this.description = "Extracts potential hashes based on hash character length"; this.infoURL = "https://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions"; this.inputType = "string"; this.outputType = "string"; this.args = [ { - name: "Hash length", + name: "Hash character length", type: "number", value: 32 }, @@ -56,11 +56,16 @@ class ExtractHashes extends Operation { const searchAllHashes = args[1]; const showDisplayTotal = args[2]; - let hashLengths = [hashLength]; - if (searchAllHashes) hashLengths = [4, 8, 16, 32, 64, 128, 160, 192, 224, 256, 320, 384, 512, 1024]; + // Convert character length to bit length + let hashBitLengths = [(hashLength / 2) * 8]; - for (let hashLength of hashLengths) { - const regex = new RegExp(`(\\b|^)[a-f0-9]{${hashLength}}(\\b|$)`, "g"); + if (searchAllHashes) hashBitLengths = [4, 8, 16, 32, 64, 128, 160, 192, 224, 256, 320, 384, 512, 1024]; + + for (let hashBitLength of hashBitLengths) { + // Convert bit length to character length + let hashCharacterLength = (hashBitLength / 8) * 2; + + const regex = new RegExp(`(\\b|^)[a-f0-9]{${hashCharacterLength}}(\\b|$)`, "g"); const searchResults = search(input, regex, null, false); hashCount += searchResults.split("\n").length - 1; From a6b774da8168a86442d8a3240defaa7b154f4ddf Mon Sep 17 00:00:00 2001 From: mshwed Date: Tue, 12 Mar 2019 10:13:28 -0400 Subject: [PATCH 27/52] Fixed issues with const/let and changed default character length --- src/core/operations/ExtractHashes.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index f411f12d..ac4765ec 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -28,7 +28,7 @@ class ExtractHashes extends Operation { { name: "Hash character length", type: "number", - value: 32 + value: 40 }, { name: "All hashes", @@ -49,7 +49,7 @@ class ExtractHashes extends Operation { * @returns {string} */ run(input, args) { - let results = []; + const results = []; let hashCount = 0; const hashLength = args[0]; @@ -61,9 +61,9 @@ class ExtractHashes extends Operation { if (searchAllHashes) hashBitLengths = [4, 8, 16, 32, 64, 128, 160, 192, 224, 256, 320, 384, 512, 1024]; - for (let hashBitLength of hashBitLengths) { + for (const hashBitLength of hashBitLengths) { // Convert bit length to character length - let hashCharacterLength = (hashBitLength / 8) * 2; + const hashCharacterLength = (hashBitLength / 8) * 2; const regex = new RegExp(`(\\b|^)[a-f0-9]{${hashCharacterLength}}(\\b|$)`, "g"); const searchResults = search(input, regex, null, false); From 3983e1a8e23ca4bf8e7c5d52b0bbb562b77d946f Mon Sep 17 00:00:00 2001 From: mshwed Date: Sun, 31 Mar 2024 10:57:03 -0400 Subject: [PATCH 28/52] Updated imports --- src/core/operations/ExtractHashes.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index ac4765ec..ba31164f 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -4,8 +4,8 @@ * @license Apache-2.0 */ -import Operation from "../Operation"; -import { search } from "../lib/Extract"; +import Operation from "../Operation.mjs"; +import { search } from "../lib/Extract.mjs"; /** * Extract Hash Values operation From 4c6200f2331328df62e59575c8f196f3578293da Mon Sep 17 00:00:00 2001 From: zb3 Date: Mon, 1 Apr 2024 17:31:36 +0200 Subject: [PATCH 29/52] Fix Base58 handling of strings with only null characters --- src/core/operations/FromBase58.mjs | 8 +++----- src/core/operations/ToBase58.mjs | 8 +++----- tests/operations/tests/Base58.mjs | 22 ++++++++++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/core/operations/FromBase58.mjs b/src/core/operations/FromBase58.mjs index f5a9ac3d..cb491159 100644 --- a/src/core/operations/FromBase58.mjs +++ b/src/core/operations/FromBase58.mjs @@ -60,7 +60,7 @@ class FromBase58 extends Operation { run(input, args) { let alphabet = args[0] || ALPHABET_OPTIONS[0].value; const removeNonAlphaChars = args[1] === undefined ? true : args[1], - result = [0]; + result = []; alphabet = Utils.expandAlphRange(alphabet).join(""); @@ -87,11 +87,9 @@ class FromBase58 extends Operation { } } - let carry = result[0] * 58 + index; - result[0] = carry & 0xFF; - carry = carry >> 8; + let carry = index; - for (let i = 1; i < result.length; i++) { + for (let i = 0; i < result.length; i++) { carry += result[i] * 58; result[i] = carry & 0xFF; carry = carry >> 8; diff --git a/src/core/operations/ToBase58.mjs b/src/core/operations/ToBase58.mjs index 5353c40e..2e71b20e 100644 --- a/src/core/operations/ToBase58.mjs +++ b/src/core/operations/ToBase58.mjs @@ -43,7 +43,7 @@ class ToBase58 extends Operation { run(input, args) { input = new Uint8Array(input); let alphabet = args[0] || ALPHABET_OPTIONS[0].value, - result = [0]; + result = []; alphabet = Utils.expandAlphRange(alphabet).join(""); @@ -60,11 +60,9 @@ class ToBase58 extends Operation { } input.forEach(function(b) { - let carry = (result[0] << 8) + b; - result[0] = carry % 58; - carry = (carry / 58) | 0; + let carry = b; - for (let i = 1; i < result.length; i++) { + for (let i = 0; i < result.length; i++) { carry += result[i] << 8; result[i] = carry % 58; carry = (carry / 58) | 0; diff --git a/tests/operations/tests/Base58.mjs b/tests/operations/tests/Base58.mjs index c23ba9ab..8090b84b 100644 --- a/tests/operations/tests/Base58.mjs +++ b/tests/operations/tests/Base58.mjs @@ -53,6 +53,28 @@ TestRegister.addTests([ }, ], }, + { + name: "To Base58 all null", + input: "\0\0\0\0\0\0", + expectedOutput: "111111", + recipeConfig: [ + { + op: "To Base58", + args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"], + }, + ], + }, + { + name: "From Base58 all null", + input: "111111", + expectedOutput: "\0\0\0\0\0\0", + recipeConfig: [ + { + op: "From Base58", + args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"], + }, + ], + }, { name: "To Base58 with null prefix and suffix", input: "\0\0\0Hello\0\0\0", From 0717407beaca592502630b74cb10337a0c633d6e Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:59:49 +0000 Subject: [PATCH 30/52] Disable 'Extract ID3' Nightwatch tests --- tests/browser/02_ops.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/browser/02_ops.js b/tests/browser/02_ops.js index 7cb0e941..e2b9b28a 100644 --- a/tests/browser/02_ops.js +++ b/tests/browser/02_ops.js @@ -126,8 +126,8 @@ module.exports = { // testOp(browser, "Extract email addresses", "test input", "test_output"); // testOp(browser, "Extract file paths", "test input", "test_output"); testOpFile(browser, "Extract Files", "files/Hitchhikers_Guide.jpeg", ".card:last-child .collapsed", "extracted_at_0x3d38.zlib"); - testOpFile(browser, "Extract ID3", "files/mp3example.mp3", "tr:last-child td:last-child", "Kevin MacLeod"); - // testOp(browser, "Extract IP addresses", "test input", "test_output"); + // This test seems unreliable on GitHub Actions, not reproducible locally. + // testOpFile(browser, "Extract ID3", "files/mp3example.mp3", "tr:last-child td:last-child", "Kevin MacLeod"); // 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"); From 61295a968ef932cb7d9b0f0f9a3b742feee0b700 Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:01:48 +0000 Subject: [PATCH 31/52] Lower case 'hash' --- src/core/config/Categories.json | 2 +- src/core/operations/ExtractHashes.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 2d7b30ff..cfbe99e0 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -337,7 +337,7 @@ "Extract domains", "Extract file paths", "Extract dates", - "Extract Hashes", + "Extract hashes", "Regular expression", "XPath expression", "JPath expression", diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index ba31164f..abba0b54 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -18,7 +18,7 @@ class ExtractHashes extends Operation { constructor() { super(); - this.name = "Extract Hashes"; + this.name = "Extract hashes"; this.module = "Regex"; this.description = "Extracts potential hashes based on hash character length"; this.infoURL = "https://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions"; From 6b95ba7dd6f9afdfe39b8fe57d12f61064ed827a Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:10:42 +0000 Subject: [PATCH 32/52] Fix regular expresion crash in extract hashes --- src/core/operations/ExtractHashes.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index abba0b54..3f15e53c 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -68,8 +68,8 @@ class ExtractHashes extends Operation { const regex = new RegExp(`(\\b|^)[a-f0-9]{${hashCharacterLength}}(\\b|$)`, "g"); const searchResults = search(input, regex, null, false); - hashCount += searchResults.split("\n").length - 1; - results.push(searchResults); + hashCount += searchResults.length; + results.push(...searchResults); } let output = ""; @@ -77,7 +77,7 @@ class ExtractHashes extends Operation { output = `Total Results: ${hashCount}\n\n`; } - output = output + results.join(""); + output = output + results.join("\n"); return output; } From 52709f0ecb24d509241c1ab03cc98027d78d1c77 Mon Sep 17 00:00:00 2001 From: zb3 Date: Mon, 1 Apr 2024 18:40:00 +0200 Subject: [PATCH 33/52] Fix Ciphersaber2 key concatenation The concat method does not handle typed arrays as arguments. --- src/core/lib/CipherSaber2.mjs | 2 +- tests/operations/tests/CipherSaber2.mjs | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/lib/CipherSaber2.mjs b/src/core/lib/CipherSaber2.mjs index bf3954e9..8189d961 100644 --- a/src/core/lib/CipherSaber2.mjs +++ b/src/core/lib/CipherSaber2.mjs @@ -4,7 +4,7 @@ * @license Apache-2.0 */ export function encode(tempIVP, key, rounds, input) { - const ivp = new Uint8Array(key.concat(tempIVP)); + const ivp = new Uint8Array([...key, ...tempIVP]); const state = new Array(256).fill(0); let j = 0, i = 0; const result = []; diff --git a/tests/operations/tests/CipherSaber2.mjs b/tests/operations/tests/CipherSaber2.mjs index dd675d45..9872c7ef 100644 --- a/tests/operations/tests/CipherSaber2.mjs +++ b/tests/operations/tests/CipherSaber2.mjs @@ -21,13 +21,16 @@ TestRegister.addTests([ ], }, { + // input taken from https://ciphersaber.gurus.org/ name: "CipherSaber2 Decrypt", - input: "\x5d\xd9\x7f\xeb\x77\x3c\x42\x9d\xfe\x9c\x3b\x21\x63\xbd\x53\x38\x18\x7c\x36\x37", - expectedOutput: "helloworld", + input: "\x6f\x6d\x0b\xab\xf3\xaa\x67\x19\x03\x15\x30\xed\xb6\x77" + + "\xca\x74\xe0\x08\x9d\xd0\xe7\xb8\x85\x43\x56\xbb\x14\x48\xe3" + + "\x7c\xdb\xef\xe7\xf3\xa8\x4f\x4f\x5f\xb3\xfd", + expectedOutput: "This is a test of CipherSaber.", recipeConfig: [ { op: "CipherSaber2 Decrypt", - args: [{ "option": "Latin1", "string": "test" }, 20], + args: [{ "option": "Latin1", "string": "asdfg" }, 1], }, ], }, From 56f92afbf4b15b27ac6f20a1e3621841ed838f55 Mon Sep 17 00:00:00 2001 From: tomgond Date: Mon, 1 Apr 2024 19:41:44 +0300 Subject: [PATCH 34/52] Change time-delta argument to be per time unit Day, hour, minute, second. Instead of a single string. --- src/core/operations/DateTimeDelta.mjs | 83 +++++++++++++-------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/core/operations/DateTimeDelta.mjs b/src/core/operations/DateTimeDelta.mjs index 66949ace..c923374d 100644 --- a/src/core/operations/DateTimeDelta.mjs +++ b/src/core/operations/DateTimeDelta.mjs @@ -9,30 +9,7 @@ import moment from "moment-timezone"; import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime.mjs"; /** - * @param {string} timeString - * @returns {string} -*/ -function parseTimeString(timeString) { - // Split the string into its components - const parts = timeString.split(":"); - // Extract the sign, days, hours, minutes, and seconds - const sign = parts[0][0] === "-" ? "-" : "+"; - const days = parseInt(parts[0].split(".")[0].slice(1), 10); - const hours = parseInt(parts[0].split(".")[1], 10); - const minutes = parseInt(parts[1], 10); - const seconds = parseInt(parts[2], 10); - - return { - sign, - days, - hours, - minutes, - seconds - }; -} - -/** - * DateTime Delta operation + * DateTime Delta operation */ class DateTimeDelta extends Operation { @@ -61,9 +38,29 @@ class DateTimeDelta extends Operation { "value": "DD/MM/YYYY HH:mm:ss" }, { - "name": "Time Delta", - "type": "binaryString", - "value": "+0.00:00:00" + "name": "Time Operation", + "type": "option", + "value": ["Add", "Subtract"] + }, + { + "name": "Days", + "type": "number", + "value": 0 + }, + { + "name": "Hours", + "type": "number", + "value": 0 + }, + { + "name": "Minutes", + "type": "number", + "value": 0 + }, + { + "name": "Seconds", + "type": "number", + "value": 0 } ]; @@ -76,31 +73,33 @@ class DateTimeDelta extends Operation { * @returns {string} */ run(input, args) { - const inputFormat = args[1], - inputTimezone = "UTC"; - const deltaStr = args[2]; - + const inputTimezone = "UTC"; + const inputFormat = args[1]; + const operationType = args[2]; + const daysDelta = args[3]; + const hoursDelta = args[4]; + const minutesDelta = args[5]; + const secondsDelta = args[6]; let date = ""; + try { date = moment.tz(input, inputFormat, inputTimezone); if (!date || date.format() === "Invalid date") throw Error; } catch (err) { return `Invalid format.\n\n${FORMAT_EXAMPLES}`; } - - const deltaDict = parseTimeString(deltaStr); let newDate; - if (deltaDict.sign === "-") { - newDate = date.add(-deltaDict.days, "days") - .add(-deltaDict.hours, "hours") - .add(-deltaDict.minutes, "minutes") - .add(-deltaDict.seconds, "seconds"); + if (operationType === "Add") { + newDate = date.add(daysDelta, "days") + .add(hoursDelta, "hours") + .add(minutesDelta, "minutes") + .add(secondsDelta, "seconds"); } else { - newDate = date.add(deltaDict.days, "days") - .add(deltaDict.hours, "hours") - .add(deltaDict.minutes, "minutes") - .add(deltaDict.seconds, "seconds"); + newDate = date.add(-daysDelta, "days") + .add(-hoursDelta, "hours") + .add(-minutesDelta, "minutes") + .add(-secondsDelta, "seconds"); } return newDate.tz(inputTimezone).format(inputFormat.replace(/[<>]/g, "")); } From dfedfa9f4cab634d7c332580e133116ab33a2c48 Mon Sep 17 00:00:00 2001 From: tomgond Date: Mon, 1 Apr 2024 19:42:56 +0300 Subject: [PATCH 35/52] Fix test to fit new time-delta format --- tests/operations/tests/DateTime.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/operations/tests/DateTime.mjs b/tests/operations/tests/DateTime.mjs index df6d6677..16848bcc 100644 --- a/tests/operations/tests/DateTime.mjs +++ b/tests/operations/tests/DateTime.mjs @@ -38,7 +38,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "DateTime Delta", - args: ["Standard date and time", "DD/MM/YYYY HH:mm:ss", "+0.0:01:0"], + args: ["Standard date and time", "DD/MM/YYYY HH:mm:ss", "Add", 0, 0, 1, 0], }, ], }, @@ -49,7 +49,7 @@ TestRegister.addTests([ recipeConfig: [ { op: "DateTime Delta", - args: ["Standard date and time", "DD/MM/YYYY HH:mm:ss", "-0.1:00:0"], + args: ["Standard date and time", "DD/MM/YYYY HH:mm:ss", "Subtract", 0, 1, 0, 0], }, ], }, From c5e5ed2b4d9a38d2b97231fb6d38faf38ee8b541 Mon Sep 17 00:00:00 2001 From: Janne Kataja Date: Sun, 22 Jan 2023 01:48:49 +0100 Subject: [PATCH 36/52] add Certificate Signing Request (CSR) parse action --- src/core/config/Categories.json | 3 +- src/core/operations/ParseCSR.mjs | 268 ++++++++++++++++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/ParseCSR.mjs | 215 ++++++++++++++++++++++ 4 files changed, 486 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/ParseCSR.mjs create mode 100644 tests/operations/tests/ParseCSR.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 2dd9f29f..6b0b727c 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -179,7 +179,8 @@ "RSA Verify", "RSA Encrypt", "RSA Decrypt", - "Parse SSH Host Key" + "Parse SSH Host Key", + "Parse CSR" ] }, { diff --git a/src/core/operations/ParseCSR.mjs b/src/core/operations/ParseCSR.mjs new file mode 100644 index 00000000..15baa2c0 --- /dev/null +++ b/src/core/operations/ParseCSR.mjs @@ -0,0 +1,268 @@ +/** + * @author jkataja + * @copyright Crown Copyright 2023 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import forge from "node-forge"; +import Utils from "../Utils.mjs"; + +/** + * Parse CSR operation + */ +class ParseCSR extends Operation { + + /** + * ParseCSR constructor + */ + constructor() { + super(); + + this.name = "Parse CSR"; + this.module = "PublicKey"; + this.description = "Parse Certificate Signing Request (CSR) for an X.509 certificate"; + this.infoURL = "https://en.wikipedia.org/wiki/Certificate_signing_request"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + "name": "Input format", + "type": "option", + "value": ["PEM"] + }, + { + "name": "Strict ASN.1 value lengths", + "type": "boolean", + "value": true + } + ]; + this.checks = [ + { + "pattern": "^-+BEGIN CERTIFICATE REQUEST-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE REQUEST-+\\r?\\n?$", + "flags": "i", + "args": ["PEM"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} Human-readable description of a Certificate Signing Request (CSR). + */ + run(input, args) { + if (!input.length) { + return "No input"; + } + + const csr = forge.pki.certificationRequestFromPem(input, args[1]); + + // RSA algorithm is the only one supported for CSR in node-forge as of 1.3.1 + return `Version: ${1 + csr.version} (0x${Utils.hex(csr.version)}) +Subject${formatSubject(csr.subject)} +Subject Alternative Names${formatSubjectAlternativeNames(csr)} +Public Key + Algorithm: RSA + Length: ${csr.publicKey.n.bitLength()} bits + Modulus: ${formatMultiLine(chop(csr.publicKey.n.toString(16).replace(/(..)/g, "$&:")))} + Exponent: ${csr.publicKey.e} (0x${Utils.hex(csr.publicKey.e)}) +Signature + Algorithm: ${forge.pki.oids[csr.signatureOid]} + Signature: ${formatMultiLine(Utils.strToByteArray(csr.signature).map(b => Utils.hex(b)).join(":"))} +Extensions${formatExtensions(csr)}`; + } +} + +/** + * Format Subject of the request as a multi-line string + * @param {*} subject CSR Subject + * @returns Multi-line string describing Subject + */ +function formatSubject(subject) { + let out = "\n"; + + for (const attribute of subject.attributes) { + out += ` ${attribute.shortName} = ${attribute.value}\n`; + } + + return chop(out); +} + + +/** + * Format Subject Alternative Names from the name `subjectAltName` extension + * @param {*} extension CSR object + * @returns Multi-line string describing Subject Alternative Names + */ +function formatSubjectAlternativeNames(csr) { + let out = "\n"; + + for (const attribute of csr.attributes) { + for (const extension of attribute.extensions) { + if (extension.name === "subjectAltName") { + const names = []; + for (const altName of extension.altNames) { + switch (altName.type) { + case 1: + names.push(`EMAIL: ${altName.value}`); + break; + case 2: + names.push(`DNS: ${altName.value}`); + break; + case 6: + names.push(`URI: ${altName.value}`); + break; + case 7: + names.push(`IP: ${altName.ip}`); + break; + default: + names.push(`(unable to format type ${altName.type} name)\n`); + } + } + out += indent(2, names); + } + } + } + + return chop(out); +} + +/** + * Format known extensions of a CSR + * @param {*} csr CSR object + * @returns Multi-line string describing attributes + */ +function formatExtensions(csr) { + let out = "\n"; + + for (const attribute of csr.attributes) { + for (const extension of attribute.extensions) { + // formatted separately + if (extension.name === "subjectAltName") { + continue; + } + out += ` ${extension.name}${(extension.critical ? " CRITICAL" : "")}:\n`; + let parts = []; + switch (extension.name) { + case "basicConstraints" : + parts = describeBasicConstraints(extension); + break; + case "keyUsage" : + parts = describeKeyUsage(extension); + break; + case "extKeyUsage" : + parts = describeExtendedKeyUsage(extension); + break; + default : + parts = ["(unable to format extension)"]; + } + out += indent(4, parts); + } + } + + return chop(out); +} + + +/** + * Format hex string onto multiple lines + * @param {*} longStr + * @returns Hex string as a multi-line hex string + */ +function formatMultiLine(longStr) { + const lines = []; + + for (let remain = longStr ; remain !== "" ; remain = remain.substring(48)) { + lines.push(remain.substring(0, 48)); + } + + return lines.join("\n "); +} + +/** + * Describe Basic Constraints + * @see RFC 5280 4.2.1.9. Basic Constraints https://www.ietf.org/rfc/rfc5280.txt + * @param {*} extension CSR extension with the name `basicConstraints` + * @returns Array of strings describing Basic Constraints + */ +function describeBasicConstraints(extension) { + const constraints = []; + + constraints.push(`CA = ${extension.cA}`); + if (extension.pathLenConstraint !== undefined) constraints.push(`PathLenConstraint = ${extension.pathLenConstraint}`); + + return constraints; +} + +/** + * Describe Key Usage extension permitted use cases + * @see RFC 5280 4.2.1.3. Key Usage https://www.ietf.org/rfc/rfc5280.txt + * @param {*} extension CSR extension with the name `keyUsage` + * @returns Array of strings describing Key Usage extension permitted use cases + */ +function describeKeyUsage(extension) { + const usage = []; + + if (extension.digitalSignature) usage.push("Digital signature"); + if (extension.nonRepudiation) usage.push("Non-repudiation"); + if (extension.keyEncipherment) usage.push("Key encipherment"); + if (extension.dataEncipherment) usage.push("Data encipherment"); + if (extension.keyAgreement) usage.push("Key agreement"); + if (extension.keyCertSign) usage.push("Key certificate signing"); + if (extension.cRLSign) usage.push("CRL signing"); + if (extension.encipherOnly) usage.push("Encipher only"); + if (extension.decipherOnly) usage.push("Decipher only"); + + if (usage.length === 0) usage.push("(none)"); + + return usage; +} + +/** + * Describe Extended Key Usage extension permitted use cases + * @see RFC 5280 4.2.1.12. Extended Key Usage https://www.ietf.org/rfc/rfc5280.txt + * @param {*} extension CSR extension with the name `extendedKeyUsage` + * @returns Array of strings describing Extended Key Usage extension permitted use cases + */ +function describeExtendedKeyUsage(extension) { + const usage = []; + + if (extension.serverAuth) usage.push("TLS Web Server Authentication"); + if (extension.clientAuth) usage.push("TLS Web Client Authentication"); + if (extension.codeSigning) usage.push("Code signing"); + if (extension.emailProtection) usage.push("E-mail Protection (S/MIME)"); + if (extension.timeStamping) usage.push("Trusted Timestamping"); + if (extension.msCodeInd) usage.push("Microsoft Individual Code Signing"); + if (extension.msCodeCom) usage.push("Microsoft Commercial Code Signing"); + if (extension.msCTLSign) usage.push("Microsoft Trust List Signing"); + if (extension.msSGC) usage.push("Microsoft Server Gated Crypto"); + if (extension.msEFS) usage.push("Microsoft Encrypted File System"); + if (extension.nsSGC) usage.push("Netscape Server Gated Crypto"); + + if (usage.length === 0) usage.push("(none)"); + + return usage; +} + +/** + * Join an array of strings and add leading spaces to each line. + * @param {*} n How many leading spaces + * @param {*} parts Array of strings + * @returns Joined and indented string. + */ +function indent(n, parts) { + const fluff = " ".repeat(n); + return fluff + parts.join("\n" + fluff) + "\n"; +} + +/** + * Remove last character from a string. + * @param {*} s String + * @returns Chopped string. + */ +function chop(s) { + return s.substring(0, s.length - 1); +} + +export default ParseCSR; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9f9be2b7..3851e8d9 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -147,6 +147,7 @@ import "./tests/Typex.mjs"; import "./tests/UnescapeString.mjs"; import "./tests/Unicode.mjs"; import "./tests/YARA.mjs"; +import "./tests/ParseCSR.mjs"; const testStatus = { allTestsPassing: true, diff --git a/tests/operations/tests/ParseCSR.mjs b/tests/operations/tests/ParseCSR.mjs new file mode 100644 index 00000000..1ba7e73f --- /dev/null +++ b/tests/operations/tests/ParseCSR.mjs @@ -0,0 +1,215 @@ +/** + * Parse CSR tests. + * + * @author jkataja + * @copyright Crown Copyright 2023 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +// openssl req -newkey rsa:1024 -keyout test-rsa-1024.key -out test-rsa-1024.csr \ +// -subj "/C=CH/ST=Zurich/L=Zurich/O=Example RE/OU=IT Department/CN=example.com" \ +// -addext "subjectAltName = DNS:example.com,DNS:www.example.com" \ +// -addext "basicConstraints = critical,CA:FALSE" \ +// -addext "keyUsage = critical,digitalSignature,keyEncipherment" \ +// -addext "extendedKeyUsage = serverAuth" +const IN_EXAMPLE_COM_RSA_1024 = `-----BEGIN CERTIFICATE REQUEST----- +MIICHzCCAYgCAQAwcjELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBlp1cmljaDEPMA0G +A1UEBwwGWnVyaWNoMRMwEQYDVQQKDApFeGFtcGxlIFJFMRYwFAYDVQQLDA1JVCBE +ZXBhcnRtZW50MRQwEgYDVQQDDAtleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEArrTrLI6FkzjX8FZfclt2ox1Dz7KRwt5f6ffZic7twLAKJ4ao +/H3APjwoFVUXGjiNj/XF2RlId4UxB1b6CgWjujBb9W51rTdvfWLyAHsrLcptpVz+ +V9Y8X9kEFCRGGDyG5+X+Nu6COzTpUPDj4bIIX/uPk3fDYDEqLClVy8/VS48CAwEA +AaBtMGsGCSqGSIb3DQEJDjFeMFwwJwYDVR0RBCAwHoILZXhhbXBsZS5jb22CD3d3 +dy5leGFtcGxlLmNvbTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNV +HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOBgQB0mUlPgt6pt/kjD0pz +OUNk5e9nBFQYQGuGIHGYbPX3mi4Wd9vUCdPixtPSTunHWs2cxX2nM8+MdcNTY+7Q +NFgFNIvSXhbqMYoHAAApMHJOxiWpBFdYKp3tESnlgh2lUh7lQtmOjD4a1dzfU8PU +oViyp+UJGasN2WRd+4VtaPw64w== +-----END CERTIFICATE REQUEST-----`; + +const OUT_EXAMPLE_COM_RSA_1024 = `Version: 1 (0x00) +Subject + C = CH + ST = Zurich + L = Zurich + O = Example RE + OU = IT Department + CN = example.com +Subject Alternative Names + DNS: example.com + DNS: www.example.com +Public Key + Algorithm: RSA + Length: 1024 bits + Modulus: ae:b4:eb:2c:8e:85:93:38:d7:f0:56:5f:72:5b:76:a3: + 1d:43:cf:b2:91:c2:de:5f:e9:f7:d9:89:ce:ed:c0:b0: + 0a:27:86:a8:fc:7d:c0:3e:3c:28:15:55:17:1a:38:8d: + 8f:f5:c5:d9:19:48:77:85:31:07:56:fa:0a:05:a3:ba: + 30:5b:f5:6e:75:ad:37:6f:7d:62:f2:00:7b:2b:2d:ca: + 6d:a5:5c:fe:57:d6:3c:5f:d9:04:14:24:46:18:3c:86: + e7:e5:fe:36:ee:82:3b:34:e9:50:f0:e3:e1:b2:08:5f: + fb:8f:93:77:c3:60:31:2a:2c:29:55:cb:cf:d5:4b:8f + Exponent: 65537 (0x10001) +Signature + Algorithm: sha256WithRSAEncryption + Signature: 74:99:49:4f:82:de:a9:b7:f9:23:0f:4a:73:39:43:64: + e5:ef:67:04:54:18:40:6b:86:20:71:98:6c:f5:f7:9a: + 2e:16:77:db:d4:09:d3:e2:c6:d3:d2:4e:e9:c7:5a:cd: + 9c:c5:7d:a7:33:cf:8c:75:c3:53:63:ee:d0:34:58:05: + 34:8b:d2:5e:16:ea:31:8a:07:00:00:29:30:72:4e:c6: + 25:a9:04:57:58:2a:9d:ed:11:29:e5:82:1d:a5:52:1e: + e5:42:d9:8e:8c:3e:1a:d5:dc:df:53:c3:d4:a1:58:b2: + a7:e5:09:19:ab:0d:d9:64:5d:fb:85:6d:68:fc:3a:e3 +Extensions + basicConstraints CRITICAL: + CA = false + keyUsage CRITICAL: + Digital signature + Key encipherment + extKeyUsage: + TLS Web Server Authentication`; + +// openssl req -newkey rsa:2048 -keyout test-rsa-2048.key -out test-rsa-2048.csr \ +// -subj "/C=CH/ST=Zurich/L=Zurich/O=Example RE/OU=IT Department/CN=example.com" \ +// -addext "subjectAltName = DNS:example.com,DNS:www.example.com" \ +// -addext "basicConstraints = critical,CA:FALSE" \ +// -addext "keyUsage = critical,digitalSignature,keyEncipherment" \ +// -addext "extendedKeyUsage = serverAuth" +const IN_EXAMPLE_COM_RSA_2048 = `-----BEGIN CERTIFICATE REQUEST----- +MIIDJDCCAgwCAQAwcjELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBlp1cmljaDEPMA0G +A1UEBwwGWnVyaWNoMRMwEQYDVQQKDApFeGFtcGxlIFJFMRYwFAYDVQQLDA1JVCBE +ZXBhcnRtZW50MRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKPogLmWPuK/IGdct2v/3MFKVaVeKp2Hl5at/zDFLCAe +51bwh7BqNVJEci4ApwlXA1WVmQPBFBJlYwQZVjz5UAN2CmNHxud5nV03YmZ2/Iml +RzpKcZMPqU+liJCC04L+XIbOdx+Vz52dF++Cc+FuSFq803yW+qefK8JsJNO9KuPx +RLYKSAADa9MIJisru1PzcBAOcimOmNnFWuo+LKsd4lU30OExDdKHwtyt62Mj1c3o +lO1JjvkjtWWjwHI+0EgTjvkeXlcUYZvvLlysdKERMRozvMTGqqoHWCgWl+Rq9Z6P +TgNsRO4CKug1Zwmh8y6acZ7sYb/dar8HOeqJnc0pCv8CAwEAAaBtMGsGCSqGSIb3 +DQEJDjFeMFwwJwYDVR0RBCAwHoILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNv +bTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEF +BQcDATANBgkqhkiG9w0BAQsFAAOCAQEAG0cjfRBY1pBzu+jf7yMQrK5mQrh72air +VuXHmochmyUxyt0G7ovnNhKEr+X9snShJLi5qlyvnb2roiwlCmuwGIZxErN1svQL +Z3kQNZgH+Vyu5IRL2DlPs5AAxVmzPpbnbXNhMHyAK/ziLcU031O1PoCpxwfvPsjW +HWOCjbZUVaJnxdp8AHqImoGAiVhJwc37feFvb2UQlLedUypQkPg/poNWduaRDoj8 +m9cpVxuxGLtONBnohzohnFECytSXWEXPIj8L9SpYK97G02nJYYCAcb5BF11Alfux +sNxtsr6zgPaLRrvOBT11WxJVKerbhfezAJ3naem1eM3VLxCGWwMwxg== +-----END CERTIFICATE REQUEST-----`; + +const OUT_EXAMPLE_COM_RSA_2048 = `Version: 1 (0x00) +Subject + C = CH + ST = Zurich + L = Zurich + O = Example RE + OU = IT Department + CN = example.com +Subject Alternative Names + DNS: example.com + DNS: www.example.com +Public Key + Algorithm: RSA + Length: 2048 bits + Modulus: a3:e8:80:b9:96:3e:e2:bf:20:67:5c:b7:6b:ff:dc:c1: + 4a:55:a5:5e:2a:9d:87:97:96:ad:ff:30:c5:2c:20:1e: + e7:56:f0:87:b0:6a:35:52:44:72:2e:00:a7:09:57:03: + 55:95:99:03:c1:14:12:65:63:04:19:56:3c:f9:50:03: + 76:0a:63:47:c6:e7:79:9d:5d:37:62:66:76:fc:89:a5: + 47:3a:4a:71:93:0f:a9:4f:a5:88:90:82:d3:82:fe:5c: + 86:ce:77:1f:95:cf:9d:9d:17:ef:82:73:e1:6e:48:5a: + bc:d3:7c:96:fa:a7:9f:2b:c2:6c:24:d3:bd:2a:e3:f1: + 44:b6:0a:48:00:03:6b:d3:08:26:2b:2b:bb:53:f3:70: + 10:0e:72:29:8e:98:d9:c5:5a:ea:3e:2c:ab:1d:e2:55: + 37:d0:e1:31:0d:d2:87:c2:dc:ad:eb:63:23:d5:cd:e8: + 94:ed:49:8e:f9:23:b5:65:a3:c0:72:3e:d0:48:13:8e: + f9:1e:5e:57:14:61:9b:ef:2e:5c:ac:74:a1:11:31:1a: + 33:bc:c4:c6:aa:aa:07:58:28:16:97:e4:6a:f5:9e:8f: + 4e:03:6c:44:ee:02:2a:e8:35:67:09:a1:f3:2e:9a:71: + 9e:ec:61:bf:dd:6a:bf:07:39:ea:89:9d:cd:29:0a:ff + Exponent: 65537 (0x10001) +Signature + Algorithm: sha256WithRSAEncryption + Signature: 1b:47:23:7d:10:58:d6:90:73:bb:e8:df:ef:23:10:ac: + ae:66:42:b8:7b:d9:a8:ab:56:e5:c7:9a:87:21:9b:25: + 31:ca:dd:06:ee:8b:e7:36:12:84:af:e5:fd:b2:74:a1: + 24:b8:b9:aa:5c:af:9d:bd:ab:a2:2c:25:0a:6b:b0:18: + 86:71:12:b3:75:b2:f4:0b:67:79:10:35:98:07:f9:5c: + ae:e4:84:4b:d8:39:4f:b3:90:00:c5:59:b3:3e:96:e7: + 6d:73:61:30:7c:80:2b:fc:e2:2d:c5:34:df:53:b5:3e: + 80:a9:c7:07:ef:3e:c8:d6:1d:63:82:8d:b6:54:55:a2: + 67:c5:da:7c:00:7a:88:9a:81:80:89:58:49:c1:cd:fb: + 7d:e1:6f:6f:65:10:94:b7:9d:53:2a:50:90:f8:3f:a6: + 83:56:76:e6:91:0e:88:fc:9b:d7:29:57:1b:b1:18:bb: + 4e:34:19:e8:87:3a:21:9c:51:02:ca:d4:97:58:45:cf: + 22:3f:0b:f5:2a:58:2b:de:c6:d3:69:c9:61:80:80:71: + be:41:17:5d:40:95:fb:b1:b0:dc:6d:b2:be:b3:80:f6: + 8b:46:bb:ce:05:3d:75:5b:12:55:29:ea:db:85:f7:b3: + 00:9d:e7:69:e9:b5:78:cd:d5:2f:10:86:5b:03:30:c6 +Extensions + basicConstraints CRITICAL: + CA = false + keyUsage CRITICAL: + Digital signature + Key encipherment + extKeyUsage: + TLS Web Server Authentication`; + +// openssl genpkey -genparam -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out test-ec-param.pem +// openssl req -newkey ec:test-ec-param.pem -keyout test-ec.key -out test-ec.csr \ +// -subj "/C=CH/ST=Zurich/L=Zurich/O=Example RE/OU=IT Department/CN=example.com" \ +// -addext "subjectAltName = DNS:example.com,DNS:www.example.com" \ +// -addext "basicConstraints = critical,CA:FALSE" \ +// -addext "keyUsage = critical,digitalSignature,keyEncipherment" \ +// -addext "extendedKeyUsage = serverAuth" +const IN_EXAMPLE_COM_EC = `-----BEGIN CERTIFICATE REQUEST----- +MIIBmzCCAUECAQAwcjELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBlp1cmljaDEPMA0G +A1UEBwwGWnVyaWNoMRMwEQYDVQQKDApFeGFtcGxlIFJFMRYwFAYDVQQLDA1JVCBE +ZXBhcnRtZW50MRQwEgYDVQQDDAtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABAmpYXNh+L9E0Q3sLhrO+MF1XgKCfqJntrOyIkrGwoiQftHbJWTA +6duxQhU/3d9B+SN/ibeKY+xeiNBrs2eTYZ6gbTBrBgkqhkiG9w0BCQ4xXjBcMCcG +A1UdEQQgMB6CC2V4YW1wbGUuY29tgg93d3cuZXhhbXBsZS5jb20wDAYDVR0TAQH/ +BAIwADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYIKoZI +zj0EAwIDSAAwRQIgQkum/qaLzE3QZ3WD00uLpalUn113FObd7rM5Mr3HQwQCIQCr +7OjzYI9v7qIJp/E9N16XfJN87G2ZVIZ4FuPXVjokCQ== +-----END CERTIFICATE REQUEST-----`; + +const OUT_EXAMPLE_COM_EC = `Parse CSR - Cannot read public key. OID is not RSA.`; + +TestRegister.addTests([ + { + name: "Parse CSR: Example Certificate Signing Request (CSR) with RSA 1024", + input: IN_EXAMPLE_COM_RSA_1024, + expectedOutput: OUT_EXAMPLE_COM_RSA_1024, + recipeConfig: [ + { + "op": "Parse CSR", + "args": ["PEM", true] + } + ] + }, + { + name: "Parse CSR: Example Certificate Signing Request (CSR) with RSA 2048", + input: IN_EXAMPLE_COM_RSA_2048, + expectedOutput: OUT_EXAMPLE_COM_RSA_2048, + recipeConfig: [ + { + "op": "Parse CSR", + "args": ["PEM", true] + } + ] + }, + // RSA algorithm is the only one supported for CSR in node-forge as of 1.3.1 + { + name: "Parse CSR: Example Certificate Signing Request (CSR) with EC 256", + input: IN_EXAMPLE_COM_EC, + expectedError: true, + expectedOutput: OUT_EXAMPLE_COM_EC, + recipeConfig: [ + { + "op": "Parse CSR", + "args": ["PEM", true] + } + ] + } +]); From ab47b3557f564aca3a06460580bf628602142c65 Mon Sep 17 00:00:00 2001 From: zb3 Date: Mon, 1 Apr 2024 23:04:00 +0200 Subject: [PATCH 37/52] Fix CryptoJS argument passing in DeriveEVPKey CryptoJS treats strings as Utf8, so for binary strings, Latin1 needs to be used. --- src/core/operations/DeriveEVPKey.mjs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/operations/DeriveEVPKey.mjs b/src/core/operations/DeriveEVPKey.mjs index 5885f892..3d67aa51 100644 --- a/src/core/operations/DeriveEVPKey.mjs +++ b/src/core/operations/DeriveEVPKey.mjs @@ -62,11 +62,13 @@ class DeriveEVPKey extends Operation { * @returns {string} */ run(input, args) { - const passphrase = Utils.convertToByteString(args[0].string, args[0].option), + const passphrase = CryptoJS.enc.Latin1.parse( + Utils.convertToByteString(args[0].string, args[0].option)), keySize = args[1] / 32, iterations = args[2], hasher = args[3], - salt = Utils.convertToByteString(args[4].string, args[4].option), + salt = CryptoJS.enc.Latin1.parse( + Utils.convertToByteString(args[4].string, args[4].option)), key = CryptoJS.EvpKDF(passphrase, salt, { // lgtm [js/insufficient-password-hash] keySize: keySize, hasher: CryptoJS.algo[hasher], From 8d4ad6ae75a26f0270f6bd4297097c15410aa52b Mon Sep 17 00:00:00 2001 From: mshwed Date: Mon, 1 Apr 2024 22:22:43 -0400 Subject: [PATCH 38/52] Minor changes. Added test cases. --- src/core/operations/ExtractHashes.mjs | 4 +- tests/operations/index.mjs | 1 + tests/operations/tests/ExtractHashes.mjs | 77 ++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 tests/operations/tests/ExtractHashes.mjs diff --git a/src/core/operations/ExtractHashes.mjs b/src/core/operations/ExtractHashes.mjs index 3f15e53c..386aab0e 100644 --- a/src/core/operations/ExtractHashes.mjs +++ b/src/core/operations/ExtractHashes.mjs @@ -52,9 +52,7 @@ class ExtractHashes extends Operation { const results = []; let hashCount = 0; - const hashLength = args[0]; - const searchAllHashes = args[1]; - const showDisplayTotal = args[2]; + const [hashLength, searchAllHashes, showDisplayTotal] = args; // Convert character length to bit length let hashBitLengths = [(hashLength / 2) * 8]; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9f9be2b7..17298700 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -62,6 +62,7 @@ import "./tests/DefangIP.mjs"; import "./tests/ELFInfo.mjs"; import "./tests/Enigma.mjs"; import "./tests/ExtractEmailAddresses.mjs"; +import "./tests/ExtractHashes.mjs"; import "./tests/Float.mjs"; import "./tests/FileTree.mjs"; import "./tests/FletcherChecksum.mjs"; diff --git a/tests/operations/tests/ExtractHashes.mjs b/tests/operations/tests/ExtractHashes.mjs new file mode 100644 index 00000000..1dfb1ff2 --- /dev/null +++ b/tests/operations/tests/ExtractHashes.mjs @@ -0,0 +1,77 @@ +/** + * ExtractHashes tests. + * + * @author mshwed [m@ttshwed.com] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Extract MD5 hash", + input: "The quick brown fox jumps over the lazy dog\n\nMD5: 9e107d9d372bb6826bd81d3542a419d6", + expectedOutput: "9e107d9d372bb6826bd81d3542a419d6", + recipeConfig: [ + { + "op": "Extract Hashes", + "args": [32, false, false] + }, + ], + }, + { + name: "Extract SHA1 hash", + input: "The quick brown fox jumps over the lazy dog\n\nSHA1: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + expectedOutput: "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + recipeConfig: [ + { + "op": "Extract Hashes", + "args": [40, false, false] + }, + ], + }, + { + name: "Extract SHA256 hash", + input: "The quick brown fox jumps over the lazy dog\n\nSHA256: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + expectedOutput: "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + recipeConfig: [ + { + "op": "Extract Hashes", + "args": [64, false, false] + }, + ], + }, + { + name: "Extract SHA512 hash", + input: "The quick brown fox jumps over the lazy dog\n\nSHA512: 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", + expectedOutput: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", + recipeConfig: [ + { + "op": "Extract Hashes", + "args": [128, false, false] + }, + ], + }, + { + name: "Extract all hashes", + input: "The quick brown fox jumps over the lazy dog\n\nMD5: 9e107d9d372bb6826bd81d3542a419d6\nSHA1: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nSHA256: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + expectedOutput: "9e107d9d372bb6826bd81d3542a419d6\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + recipeConfig: [ + { + "op": "Extract Hashes", + "args": [0, true, false] + }, + ], + }, + { + name: "Extract hashes with total count", + input: "The quick brown fox jumps over the lazy dog\n\nMD5: 9e107d9d372bb6826bd81d3542a419d6\nSHA1: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nSHA256: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + expectedOutput: "Total Results: 3\n\n9e107d9d372bb6826bd81d3542a419d6\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + recipeConfig: [ + { + "op": "Extract Hashes", + "args": [0, true, true] + }, + ], + } +]); From 077b11e33bc9e1015147380309cd964f52bd657c Mon Sep 17 00:00:00 2001 From: mshwed Date: Mon, 1 Apr 2024 22:30:18 -0400 Subject: [PATCH 39/52] Fixed op name in test --- tests/operations/tests/ExtractHashes.mjs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/operations/tests/ExtractHashes.mjs b/tests/operations/tests/ExtractHashes.mjs index 1dfb1ff2..fe739418 100644 --- a/tests/operations/tests/ExtractHashes.mjs +++ b/tests/operations/tests/ExtractHashes.mjs @@ -14,7 +14,7 @@ TestRegister.addTests([ expectedOutput: "9e107d9d372bb6826bd81d3542a419d6", recipeConfig: [ { - "op": "Extract Hashes", + "op": "Extract hashes", "args": [32, false, false] }, ], @@ -25,7 +25,7 @@ TestRegister.addTests([ expectedOutput: "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", recipeConfig: [ { - "op": "Extract Hashes", + "op": "Extract hashes", "args": [40, false, false] }, ], @@ -36,7 +36,7 @@ TestRegister.addTests([ expectedOutput: "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", recipeConfig: [ { - "op": "Extract Hashes", + "op": "Extract hashes", "args": [64, false, false] }, ], @@ -47,7 +47,7 @@ TestRegister.addTests([ expectedOutput: "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", recipeConfig: [ { - "op": "Extract Hashes", + "op": "Extract hashes", "args": [128, false, false] }, ], @@ -58,7 +58,7 @@ TestRegister.addTests([ expectedOutput: "9e107d9d372bb6826bd81d3542a419d6\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", recipeConfig: [ { - "op": "Extract Hashes", + "op": "Extract hashes", "args": [0, true, false] }, ], @@ -69,7 +69,7 @@ TestRegister.addTests([ expectedOutput: "Total Results: 3\n\n9e107d9d372bb6826bd81d3542a419d6\n2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\nd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", recipeConfig: [ { - "op": "Extract Hashes", + "op": "Extract hashes", "args": [0, true, true] }, ], From 99efcb521d490ec971f64cceeac30340ae48f8cd Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Tue, 2 Apr 2024 18:09:48 +0100 Subject: [PATCH 40/52] Revert "Updated jsonwebtoken dependency to 9+" --- package-lock.json | 44 +++++++++------------------------ package.json | 2 +- src/core/operations/JWTSign.mjs | 7 +----- 3 files changed, 13 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 122a2990..fa76698e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "jsesc": "^3.0.2", "json5": "^2.2.3", "jsonpath-plus": "^8.0.0", - "jsonwebtoken": "^9.0.0", + "jsonwebtoken": "8.5.1", "jsqr": "^1.4.0", "jsrsasign": "^11.1.0", "kbpgp": "2.1.15", @@ -9712,9 +9712,9 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -9725,43 +9725,21 @@ "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.5.4" + "semver": "^5.6.0" }, "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "node": ">=4", + "npm": ">=1.4.28" } }, "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "semver": "bin/semver" } }, - "node_modules/jsonwebtoken/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/jsqr": { "version": "1.4.0", "license": "Apache-2.0" diff --git a/package.json b/package.json index 6e2965f0..64e6d5d9 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "jsesc": "^3.0.2", "json5": "^2.2.3", "jsonpath-plus": "^8.0.0", - "jsonwebtoken": "^9.0.0", + "jsonwebtoken": "8.5.1", "jsqr": "^1.4.0", "jsrsasign": "^11.1.0", "kbpgp": "2.1.15", diff --git a/src/core/operations/JWTSign.mjs b/src/core/operations/JWTSign.mjs index e4756c2b..af46908e 100644 --- a/src/core/operations/JWTSign.mjs +++ b/src/core/operations/JWTSign.mjs @@ -50,12 +50,7 @@ class JWTSign extends Operation { try { return jwt.sign(input, key, { - algorithm: algorithm === "None" ? "none" : algorithm, - - // To utilize jsonwebtoken 9+ library and maintain backwards compatibility for regression tests - // This could be turned into operation args in a future PR - allowInsecureKeySizes: true, - allowInvalidAsymmetricKeyTypes: true + algorithm: algorithm === "None" ? "none" : algorithm }); } catch (err) { throw new OperationError(`Error: Have you entered the key correctly? The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA. From fda77cf37a60b00782bc3976cef222c8ce252c7b Mon Sep 17 00:00:00 2001 From: Janne Kataja Date: Tue, 2 Apr 2024 21:30:59 +0200 Subject: [PATCH 41/52] add option to show Parse CSR only supports RSA --- src/core/operations/ParseCSR.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/operations/ParseCSR.mjs b/src/core/operations/ParseCSR.mjs index 15baa2c0..ad891902 100644 --- a/src/core/operations/ParseCSR.mjs +++ b/src/core/operations/ParseCSR.mjs @@ -31,6 +31,11 @@ class ParseCSR extends Operation { "type": "option", "value": ["PEM"] }, + { + "name": "Key type", + "type": "option", + "value": ["RSA"] + }, { "name": "Strict ASN.1 value lengths", "type": "boolean", From c7952715028a3382420d4d2b6c9314c9f416784e Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:27:48 +0000 Subject: [PATCH 42/52] Change output to 'html' --- src/core/operations/DateTimeDelta.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/DateTimeDelta.mjs b/src/core/operations/DateTimeDelta.mjs index c923374d..35090606 100644 --- a/src/core/operations/DateTimeDelta.mjs +++ b/src/core/operations/DateTimeDelta.mjs @@ -24,7 +24,7 @@ class DateTimeDelta extends Operation { this.description = "Calculates a new DateTime value given an input DateTime value and a time difference (delta) from the input DateTime value."; this.infoURL = ""; this.inputType = "string"; - this.outputType = "string"; + this.outputType = "html"; this.args = [ { "name": "Built in formats", From b5959c6f011259cc05c09f60d06ab9710c4ab5a2 Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:40:09 +0000 Subject: [PATCH 43/52] 10.15.0 --- CHANGELOG.md | 18 ++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b6497a8..dad28fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,14 @@ All major and minor version changes will be documented in this file. Details of ## Details +### [10.15.0] - 2024-04-02 +- Fix Ciphersaber2 key concatenation [@zb3] | [#1765] +- Fix DeriveEVPKey's array parsing [@zb3] | [#1767] +- Fix JWT operations [@a3957273] | [#1769] +- Added 'Parse Certificate Signing Request' operation [@jkataja] | [#1504] +- Added 'Extract Hash Values' operation [@MShwed] | [#512] +- Added 'DateTime Delta' operation [@tomgond] | [#1732] + ### [10.14.0] - 2024-03-31 - Added 'To Float' and 'From Float' operations [@tcode2k16] | [#1762] - Fix ChaCha raw export option [@joostrijneveld] | [#1606] @@ -410,6 +418,7 @@ All major and minor version changes will be documented in this file. Details of ## [4.0.0] - 2016-11-28 - Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306) +[10.14.0]: https://github.com/gchq/CyberChef/releases/tag/v10.14.0 [10.14.0]: https://github.com/gchq/CyberChef/releases/tag/v10.14.0 [10.13.0]: https://github.com/gchq/CyberChef/releases/tag/v10.13.0 [10.12.0]: https://github.com/gchq/CyberChef/releases/tag/v10.12.0 @@ -586,6 +595,9 @@ All major and minor version changes will be documented in this file. Details of [@breakersall]: https://github.com/breakersall [@evanreichard]: https://github.com/evanreichard [@devcydo]: https://github.com/devcydo +[@zb3]: https://github.com/zb3 +[@jkataja]: https://github.com/jkataja +[@tomgond]: https://github.com/tomgond [8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7 @@ -725,3 +737,9 @@ All major and minor version changes will be documented in this file. Details of [#1197]: https://github.com/gchq/CyberChef/issues/1197 [#933]: https://github.com/gchq/CyberChef/issues/933 [#1361]: https://github.com/gchq/CyberChef/issues/1361 +[#1765]: https://github.com/gchq/CyberChef/issues/1765 +[#1767]: https://github.com/gchq/CyberChef/issues/1767 +[#1769]: https://github.com/gchq/CyberChef/issues/1769 +[#1504]: https://github.com/gchq/CyberChef/issues/1504 +[#512]: https://github.com/gchq/CyberChef/issues/512 +[#1732]: https://github.com/gchq/CyberChef/issues/1732 diff --git a/package-lock.json b/package-lock.json index fa76698e..693e0d42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "10.14.0", + "version": "10.15.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "10.14.0", + "version": "10.15.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 64e6d5d9..ef61fbab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "10.14.0", + "version": "10.15.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 016825d4dea67a548d6150738c3b6330bfb269dd Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Tue, 2 Apr 2024 22:27:15 +0100 Subject: [PATCH 44/52] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad28fd1..ddff4460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -418,7 +418,7 @@ All major and minor version changes will be documented in this file. Details of ## [4.0.0] - 2016-11-28 - Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306) -[10.14.0]: https://github.com/gchq/CyberChef/releases/tag/v10.14.0 +[10.15.0]: https://github.com/gchq/CyberChef/releases/tag/v10.15.0 [10.14.0]: https://github.com/gchq/CyberChef/releases/tag/v10.14.0 [10.13.0]: https://github.com/gchq/CyberChef/releases/tag/v10.13.0 [10.12.0]: https://github.com/gchq/CyberChef/releases/tag/v10.12.0 From ab0493f53acd4c67f6622b48e6204e04dc302358 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 5 Apr 2024 15:56:31 +0100 Subject: [PATCH 45/52] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddff4460..ad12eda9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -740,6 +740,7 @@ All major and minor version changes will be documented in this file. Details of [#1765]: https://github.com/gchq/CyberChef/issues/1765 [#1767]: https://github.com/gchq/CyberChef/issues/1767 [#1769]: https://github.com/gchq/CyberChef/issues/1769 +[#1759]: https://github.com/gchq/CyberChef/issues/1759 [#1504]: https://github.com/gchq/CyberChef/issues/1504 [#512]: https://github.com/gchq/CyberChef/issues/512 [#1732]: https://github.com/gchq/CyberChef/issues/1732 From d3fb8bd6e9b3d3403acd6c9e6a57fee39ea66b80 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 5 Apr 2024 18:08:21 +0100 Subject: [PATCH 46/52] Fixed typos --- CHANGELOG.md | 2 +- src/core/Utils.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad12eda9..abceeda3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -725,7 +725,7 @@ All major and minor version changes will be documented in this file. Details of [#1667]: https://github.com/gchq/CyberChef/issues/1667 [#1555]: https://github.com/gchq/CyberChef/issues/1555 [#1694]: https://github.com/gchq/CyberChef/issues/1694 -[#1699]: https://github.com/gchq/CyberChef/issues/1694 +[#1699]: https://github.com/gchq/CyberChef/issues/1699 [#1757]: https://github.com/gchq/CyberChef/issues/1757 [#1752]: https://github.com/gchq/CyberChef/issues/1752 [#1753]: https://github.com/gchq/CyberChef/issues/1753 diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index 18b0e688..a9c381d7 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -893,7 +893,7 @@ class Utils { /** - * Converts a string to it's title case equivalent. + * Converts a string to its title case equivalent. * * @param {string} str * @returns string From 1b870e559e427464f4b25df5df7bc1dcaabfcc54 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 5 Apr 2024 18:09:07 +0100 Subject: [PATCH 47/52] Updated copyright declarations to a range up to the latest commit --- Gruntfile.js | 6 +++++- src/web/html/index.html | 12 ++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 32ba9007..b040d98d 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -86,10 +86,12 @@ module.exports = function (grunt) { // Project configuration - const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC", + const compileYear = grunt.template.today("UTC:yyyy"), + compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC", pkg = grunt.file.readJSON("package.json"), webpackConfig = require("./webpack.config.js"), BUILD_CONSTANTS = { + COMPILE_YEAR: JSON.stringify(compileYear), COMPILE_TIME: JSON.stringify(compileTime), COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""), PKG_VERSION: JSON.stringify(pkg.version), @@ -125,6 +127,7 @@ module.exports = function (grunt) { filename: "index.html", template: "./src/web/html/index.html", chunks: ["main"], + compileYear: compileYear, compileTime: compileTime, version: pkg.version, minify: { @@ -227,6 +230,7 @@ module.exports = function (grunt) { filename: "index.html", template: "./src/web/html/index.html", chunks: ["main"], + compileYear: compileYear, compileTime: compileTime, version: pkg.version, }) diff --git a/src/web/html/index.html b/src/web/html/index.html index 5c3c3263..02005796 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -1,10 +1,10 @@