mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 14:56:19 -04:00
Merge branch 'esmconversion' of https://github.com/artemisbot/CyberChef into esm
This commit is contained in:
commit
acb8a342a7
43 changed files with 1554 additions and 849 deletions
41
src/core/lib/Extract.mjs
Normal file
41
src/core/lib/Extract.mjs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* Identifier extraction functions
|
||||||
|
*
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs search operations across the input data using regular expressions.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @param {RegExp} searchRegex
|
||||||
|
* @param {RegExp} removeRegex - A regular expression defining results to remove from the
|
||||||
|
* final list
|
||||||
|
* @param {boolean} includeTotal - Whether or not to include the total number of results
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function search (input, searchRegex, removeRegex, includeTotal) {
|
||||||
|
let output = "",
|
||||||
|
total = 0,
|
||||||
|
match;
|
||||||
|
|
||||||
|
while ((match = searchRegex.exec(input))) {
|
||||||
|
// Moves pointer when an empty string is matched (prevents infinite loop)
|
||||||
|
if (match.index === searchRegex.lastIndex) {
|
||||||
|
searchRegex.lastIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeRegex && removeRegex.test(match[0]))
|
||||||
|
continue;
|
||||||
|
total++;
|
||||||
|
output += match[0] + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeTotal)
|
||||||
|
output = "Total found: " + total + "\n\n" + output;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
116
src/core/lib/PGP.mjs
Normal file
116
src/core/lib/PGP.mjs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
* PGP functions.
|
||||||
|
*
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
*
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import kbpgp from "kbpgp";
|
||||||
|
import promisifyDefault from "es6-promisify";
|
||||||
|
const promisify = promisifyDefault.promisify;
|
||||||
|
/**
|
||||||
|
* Progress callback
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const ASP = kbpgp.ASP({
|
||||||
|
"progress_hook": info => {
|
||||||
|
let msg = "";
|
||||||
|
|
||||||
|
switch (info.what) {
|
||||||
|
case "guess":
|
||||||
|
msg = "Guessing a prime";
|
||||||
|
break;
|
||||||
|
case "fermat":
|
||||||
|
msg = "Factoring prime using Fermat's factorization method";
|
||||||
|
break;
|
||||||
|
case "mr":
|
||||||
|
msg = "Performing Miller-Rabin primality test";
|
||||||
|
break;
|
||||||
|
case "passed_mr":
|
||||||
|
msg = "Passed Miller-Rabin primality test";
|
||||||
|
break;
|
||||||
|
case "failed_mr":
|
||||||
|
msg = "Failed Miller-Rabin primality test";
|
||||||
|
break;
|
||||||
|
case "found":
|
||||||
|
msg = "Prime found";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg = `Stage: ${info.what}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ENVIRONMENT_IS_WORKER())
|
||||||
|
self.sendStatusMessage(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get size of subkey
|
||||||
|
*
|
||||||
|
* @param {number} keySize
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
export function getSubkeySize(keySize) {
|
||||||
|
return {
|
||||||
|
1024: 1024,
|
||||||
|
2048: 1024,
|
||||||
|
4096: 2048,
|
||||||
|
256: 256,
|
||||||
|
384: 256,
|
||||||
|
}[keySize];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import private key and unlock if necessary
|
||||||
|
*
|
||||||
|
* @param {string} privateKey
|
||||||
|
* @param {string} [passphrase]
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export async function importPrivateKey(privateKey, passphrase) {
|
||||||
|
try {
|
||||||
|
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||||
|
armored: privateKey,
|
||||||
|
opts: {
|
||||||
|
"no_check_keys": true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (key.is_pgp_locked()) {
|
||||||
|
if (passphrase) {
|
||||||
|
await promisify(key.unlock_pgp.bind(key))({
|
||||||
|
passphrase
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw "Did not provide passphrase with locked private key.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
} catch (err) {
|
||||||
|
throw `Could not import private key: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import public key
|
||||||
|
*
|
||||||
|
* @param {string} publicKey
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export async function importPublicKey (publicKey) {
|
||||||
|
try {
|
||||||
|
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||||
|
armored: publicKey,
|
||||||
|
opts: {
|
||||||
|
"no_check_keys": true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return key;
|
||||||
|
} catch (err) {
|
||||||
|
throw `Could not import public key: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import forge from "node-forge/dist/forge.min.js";
|
import forge from "node-forge/dist/forge.min.js";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES Decrypt operation
|
* AES Decrypt operation
|
||||||
|
@ -65,6 +66,8 @@ class AESDecrypt extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if cannot decrypt input or invalid key length
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||||
|
@ -75,12 +78,12 @@ class AESDecrypt extends Operation {
|
||||||
gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
|
gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
|
||||||
|
|
||||||
if ([16, 24, 32].indexOf(key.length) < 0) {
|
if ([16, 24, 32].indexOf(key.length) < 0) {
|
||||||
return `Invalid key length: ${key.length} bytes
|
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||||
|
|
||||||
The following algorithms will be used based on the size of the key:
|
The following algorithms will be used based on the size of the key:
|
||||||
16 bytes = AES-128
|
16 bytes = AES-128
|
||||||
24 bytes = AES-192
|
24 bytes = AES-192
|
||||||
32 bytes = AES-256`;
|
32 bytes = AES-256`);
|
||||||
}
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
@ -96,7 +99,7 @@ The following algorithms will be used based on the size of the key:
|
||||||
if (result) {
|
if (result) {
|
||||||
return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
|
return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
|
||||||
} else {
|
} else {
|
||||||
return "Unable to decrypt input with these parameters.";
|
throw new OperationError("Unable to decrypt input with these parameters.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import forge from "node-forge/dist/forge.min.js";
|
import forge from "node-forge/dist/forge.min.js";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES Encrypt operation
|
* AES Encrypt operation
|
||||||
|
@ -59,6 +60,8 @@ class AESEncrypt extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid key length
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
const key = Utils.convertToByteArray(args[0].string, args[0].option),
|
||||||
|
@ -68,12 +71,12 @@ class AESEncrypt extends Operation {
|
||||||
outputType = args[4];
|
outputType = args[4];
|
||||||
|
|
||||||
if ([16, 24, 32].indexOf(key.length) < 0) {
|
if ([16, 24, 32].indexOf(key.length) < 0) {
|
||||||
return `Invalid key length: ${key.length} bytes
|
throw new OperationError(`Invalid key length: ${key.length} bytes
|
||||||
|
|
||||||
The following algorithms will be used based on the size of the key:
|
The following algorithms will be used based on the size of the key:
|
||||||
16 bytes = AES-128
|
16 bytes = AES-128
|
||||||
24 bytes = AES-192
|
24 bytes = AES-192
|
||||||
32 bytes = AES-256`;
|
32 bytes = AES-256`);
|
||||||
}
|
}
|
||||||
|
|
||||||
input = Utils.convertToByteString(input, inputType);
|
input = Utils.convertToByteString(input, inputType);
|
||||||
|
|
|
@ -42,6 +42,8 @@ class AffineCipherDecode extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if a or b values are invalid
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const alphabet = "abcdefghijklmnopqrstuvwxyz",
|
const alphabet = "abcdefghijklmnopqrstuvwxyz",
|
||||||
|
|
|
@ -37,6 +37,8 @@ class BifidCipherDecode extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid key
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
||||||
|
|
|
@ -37,6 +37,8 @@ class BifidCipherEncode extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if key is invalid
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
const keywordStr = args[0].toUpperCase().replace("J", "I"),
|
||||||
|
|
|
@ -41,7 +41,7 @@ class CartesianProduct extends Operation {
|
||||||
* Validate input length
|
* Validate input length
|
||||||
*
|
*
|
||||||
* @param {Object[]} sets
|
* @param {Object[]} sets
|
||||||
* @throws {Error} if fewer than 2 sets
|
* @throws {OperationError} if fewer than 2 sets
|
||||||
*/
|
*/
|
||||||
validateSampleNumbers(sets) {
|
validateSampleNumbers(sets) {
|
||||||
if (!sets || sets.length < 2) {
|
if (!sets || sets.length < 2) {
|
||||||
|
|
131
src/core/operations/DisassembleX86.mjs
Normal file
131
src/core/operations/DisassembleX86.mjs
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import * as disassemble from "../vendor/DisassembleX86-64";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disassemble x86 operation
|
||||||
|
*/
|
||||||
|
class DisassembleX86 extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassembleX86 constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Disassemble x86";
|
||||||
|
this.module = "Shellcode";
|
||||||
|
this.description = "Disassembly is the process of translating machine language into assembly language.<br><br>This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.<br><br>Input should be in hexadecimal.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Bit mode",
|
||||||
|
"type": "option",
|
||||||
|
"value": ["64", "32", "16"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Compatibility",
|
||||||
|
"type": "option",
|
||||||
|
"value": [
|
||||||
|
"Full x86 architecture",
|
||||||
|
"Knights Corner",
|
||||||
|
"Larrabee",
|
||||||
|
"Cyrix",
|
||||||
|
"Geode",
|
||||||
|
"Centaur",
|
||||||
|
"X86/486"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Code Segment (CS)",
|
||||||
|
"type": "number",
|
||||||
|
"value": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Offset (IP)",
|
||||||
|
"type": "number",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Show instruction hex",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Show instruction position",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid mode value
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const mode = args[0],
|
||||||
|
compatibility = args[1],
|
||||||
|
codeSegment = args[2],
|
||||||
|
offset = args[3],
|
||||||
|
showInstructionHex = args[4],
|
||||||
|
showInstructionPos = args[5];
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case "64":
|
||||||
|
disassemble.setBitMode(2);
|
||||||
|
break;
|
||||||
|
case "32":
|
||||||
|
disassemble.setBitMode(1);
|
||||||
|
break;
|
||||||
|
case "16":
|
||||||
|
disassemble.setBitMode(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new OperationError("Invalid mode value");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (compatibility) {
|
||||||
|
case "Full x86 architecture":
|
||||||
|
disassemble.CompatibilityMode(0);
|
||||||
|
break;
|
||||||
|
case "Knights Corner":
|
||||||
|
disassemble.CompatibilityMode(1);
|
||||||
|
break;
|
||||||
|
case "Larrabee":
|
||||||
|
disassemble.CompatibilityMode(2);
|
||||||
|
break;
|
||||||
|
case "Cyrix":
|
||||||
|
disassemble.CompatibilityMode(3);
|
||||||
|
break;
|
||||||
|
case "Geode":
|
||||||
|
disassemble.CompatibilityMode(4);
|
||||||
|
break;
|
||||||
|
case "Centaur":
|
||||||
|
disassemble.CompatibilityMode(5);
|
||||||
|
break;
|
||||||
|
case "X86/486":
|
||||||
|
disassemble.CompatibilityMode(6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
disassemble.SetBasePosition(codeSegment + ":" + offset);
|
||||||
|
disassemble.setShowInstructionHex(showInstructionHex);
|
||||||
|
disassemble.setShowInstructionPos(showInstructionPos);
|
||||||
|
disassemble.LoadBinCode(input.replace(/\s/g, ""));
|
||||||
|
return disassemble.LDisassemble();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DisassembleX86;
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop bytes operation
|
* Drop bytes operation
|
||||||
|
@ -45,6 +46,8 @@ class DropBytes extends Operation {
|
||||||
* @param {ArrayBuffer} input
|
* @param {ArrayBuffer} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {ArrayBuffer}
|
* @returns {ArrayBuffer}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid input
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const start = args[0],
|
const start = args[0],
|
||||||
|
@ -52,7 +55,7 @@ class DropBytes extends Operation {
|
||||||
applyToEachLine = args[2];
|
applyToEachLine = args[2];
|
||||||
|
|
||||||
if (start < 0 || length < 0)
|
if (start < 0 || length < 0)
|
||||||
throw "Error: Invalid value";
|
throw new OperationError("Error: Invalid value");
|
||||||
|
|
||||||
if (!applyToEachLine) {
|
if (!applyToEachLine) {
|
||||||
const left = input.slice(0, start),
|
const left = input.slice(0, start),
|
||||||
|
|
52
src/core/operations/ExtractDates.mjs
Normal file
52
src/core/operations/ExtractDates.mjs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract dates operation
|
||||||
|
*/
|
||||||
|
class ExtractDates extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractDates constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract dates";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts dates in the following formats<ul><li><code>yyyy-mm-dd</code></li><li><code>dd/mm/yyyy</code></li><li><code>mm/dd/yyyy</code></li></ul>Dividers can be any of /, -, . or space";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const displayTotal = args[0],
|
||||||
|
date1 = "(?:19|20)\\d\\d[- /.](?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])", // yyyy-mm-dd
|
||||||
|
date2 = "(?:0[1-9]|[12][0-9]|3[01])[- /.](?:0[1-9]|1[012])[- /.](?:19|20)\\d\\d", // dd/mm/yyyy
|
||||||
|
date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy
|
||||||
|
regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig");
|
||||||
|
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractDates;
|
49
src/core/operations/ExtractDomains.mjs
Normal file
49
src/core/operations/ExtractDomains.mjs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract domains operation
|
||||||
|
*/
|
||||||
|
class ExtractDomains extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractDomains constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract domains";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts domain names.<br>Note that this will not include paths. Use <strong>Extract URLs</strong> to find entire URLs.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": "Extract.DISPLAY_TOTAL"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const displayTotal = args[0],
|
||||||
|
regex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;
|
||||||
|
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractDomains;
|
49
src/core/operations/ExtractEmailAddresses.mjs
Normal file
49
src/core/operations/ExtractEmailAddresses.mjs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract email addresses operation
|
||||||
|
*/
|
||||||
|
class ExtractEmailAddresses extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractEmailAddresses constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract email addresses";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts all email addresses from the input.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const displayTotal = args[0],
|
||||||
|
regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig;
|
||||||
|
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractEmailAddresses;
|
79
src/core/operations/ExtractFilePaths.mjs
Normal file
79
src/core/operations/ExtractFilePaths.mjs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
/**
|
||||||
|
* Extract file paths operation
|
||||||
|
*/
|
||||||
|
class ExtractFilePaths extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractFilePaths constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract file paths";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts anything that looks like a Windows or UNIX file path.<br><br>Note that if UNIX is selected, there will likely be a lot of false positives.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Windows",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "UNIX",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const includeWinPath = args[0],
|
||||||
|
includeUnixPath = args[1],
|
||||||
|
displayTotal = args[2],
|
||||||
|
winDrive = "[A-Z]:\\\\",
|
||||||
|
winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}",
|
||||||
|
winExt = "[A-Z\\d]{1,6}",
|
||||||
|
winPath = winDrive + "(?:" + winName + "\\\\?)*" + winName +
|
||||||
|
"(?:\\." + winExt + ")?",
|
||||||
|
unixPath = "(?:/[A-Z\\d.][A-Z\\d\\-.]{0,61})+";
|
||||||
|
let filePaths = "";
|
||||||
|
|
||||||
|
if (includeWinPath && includeUnixPath) {
|
||||||
|
filePaths = winPath + "|" + unixPath;
|
||||||
|
} else if (includeWinPath) {
|
||||||
|
filePaths = winPath;
|
||||||
|
} else if (includeUnixPath) {
|
||||||
|
filePaths = unixPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filePaths) {
|
||||||
|
const regex = new RegExp(filePaths, "ig");
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractFilePaths;
|
94
src/core/operations/ExtractIPAddresses.mjs
Normal file
94
src/core/operations/ExtractIPAddresses.mjs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract IP addresses operation
|
||||||
|
*/
|
||||||
|
class ExtractIPAddresses extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractIPAddresses constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract IP addresses";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>710.65.0.456</code>, this will match <code>10.65.0.45</code> so always check the original input!";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "IPv4",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "IPv6",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Remove local IPv4 addresses",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const includeIpv4 = args[0],
|
||||||
|
includeIpv6 = args[1],
|
||||||
|
removeLocal = args[2],
|
||||||
|
displayTotal = args[3],
|
||||||
|
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
||||||
|
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})";
|
||||||
|
let ips = "";
|
||||||
|
|
||||||
|
if (includeIpv4 && includeIpv6) {
|
||||||
|
ips = ipv4 + "|" + ipv6;
|
||||||
|
} else if (includeIpv4) {
|
||||||
|
ips = ipv4;
|
||||||
|
} else if (includeIpv6) {
|
||||||
|
ips = ipv6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ips) {
|
||||||
|
const regex = new RegExp(ips, "ig");
|
||||||
|
|
||||||
|
if (removeLocal) {
|
||||||
|
const ten = "10\\..+",
|
||||||
|
oneninetwo = "192\\.168\\..+",
|
||||||
|
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
||||||
|
onetwoseven = "127\\..+",
|
||||||
|
removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo +
|
||||||
|
"|" + oneseventwo + "|" + onetwoseven + ")");
|
||||||
|
|
||||||
|
return search(input, regex, removeRegex, displayTotal);
|
||||||
|
} else {
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractIPAddresses;
|
49
src/core/operations/ExtractMACAddresses.mjs
Normal file
49
src/core/operations/ExtractMACAddresses.mjs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract MAC addresses operation
|
||||||
|
*/
|
||||||
|
class ExtractMACAddresses extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractMACAddresses constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract MAC addresses";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts all Media Access Control (MAC) addresses from the input.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const displayTotal = args[0],
|
||||||
|
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig;
|
||||||
|
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractMACAddresses;
|
55
src/core/operations/ExtractURLs.mjs
Normal file
55
src/core/operations/ExtractURLs.mjs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract URLs operation
|
||||||
|
*/
|
||||||
|
class ExtractURLs extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractURLs constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Extract URLs";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts Uniform Resource Locators (URLs) from the input. The protocol (http, ftp etc.) is required otherwise there will be far too many false positives.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const displayTotal = args[0],
|
||||||
|
protocol = "[A-Z]+://",
|
||||||
|
hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+",
|
||||||
|
port = ":\\d+";
|
||||||
|
let path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*";
|
||||||
|
|
||||||
|
path += "(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*";
|
||||||
|
const regex = new RegExp(protocol + hostname + "(?:" + port +
|
||||||
|
")?(?:" + path + ")?", "ig");
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExtractURLs;
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import {INPUT_DELIM_OPTIONS} from "../lib/Delim";
|
import {INPUT_DELIM_OPTIONS} from "../lib/Delim";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter operation
|
* Filter operation
|
||||||
|
@ -56,7 +57,7 @@ class Filter extends Operation {
|
||||||
try {
|
try {
|
||||||
regex = new RegExp(args[1]);
|
regex = new RegExp(args[1]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return "Invalid regex. Details: " + err.message;
|
throw new OperationError(`Invalid regex. Details: ${err.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const regexFilter = function(value) {
|
const regexFilter = function(value) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import {DELIM_OPTIONS} from "../lib/Delim";
|
import {DELIM_OPTIONS} from "../lib/Delim";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From Charcode operation
|
* From Charcode operation
|
||||||
|
@ -42,6 +43,8 @@ class FromCharcode extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if base out of range
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const delim = Utils.charRep(args[0] || "Space"),
|
const delim = Utils.charRep(args[0] || "Space"),
|
||||||
|
@ -50,7 +53,7 @@ class FromCharcode extends Operation {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if (base < 2 || base > 36) {
|
if (base < 2 || base > 36) {
|
||||||
throw "Error: Base argument must be between 2 and 36";
|
throw new OperationError("Error: Base argument must be between 2 and 36");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.length === 0) {
|
if (input.length === 0) {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import {UNITS} from "../lib/DateTime";
|
import {UNITS} from "../lib/DateTime";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From UNIX Timestamp operation
|
* From UNIX Timestamp operation
|
||||||
|
@ -37,6 +38,8 @@ class FromUNIXTimestamp extends Operation {
|
||||||
* @param {number} input
|
* @param {number} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid unit
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const units = args[0];
|
const units = args[0];
|
||||||
|
@ -57,7 +60,7 @@ class FromUNIXTimestamp extends Operation {
|
||||||
d = moment(input / 1000000);
|
d = moment(input / 1000000);
|
||||||
return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC";
|
return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC";
|
||||||
} else {
|
} else {
|
||||||
throw "Unrecognised unit";
|
throw new OperationError("Unrecognised unit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
115
src/core/operations/GeneratePGPKeyPair.mjs
Normal file
115
src/core/operations/GeneratePGPKeyPair.mjs
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import kbpgp from "kbpgp";
|
||||||
|
import { getSubkeySize, ASP } from "../lib/PGP";
|
||||||
|
import promisifyDefault from "es6-promisify";
|
||||||
|
const promisify = promisifyDefault.promisify;
|
||||||
|
/**
|
||||||
|
* Generate PGP Key Pair operation
|
||||||
|
*/
|
||||||
|
class GeneratePGPKeyPair extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GeneratePGPKeyPair constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Generate PGP Key Pair";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Key type",
|
||||||
|
"type": "option",
|
||||||
|
"value": ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Password (optional)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Name (optional)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Email (optional)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [keyType, keySize] = args[0].split("-"),
|
||||||
|
password = args[1],
|
||||||
|
name = args[2],
|
||||||
|
email = args[3];
|
||||||
|
let userIdentifier = "";
|
||||||
|
|
||||||
|
if (name) userIdentifier += name;
|
||||||
|
if (email) userIdentifier += ` <${email}>`;
|
||||||
|
|
||||||
|
let flags = kbpgp.const.openpgp.certify_keys;
|
||||||
|
flags |= kbpgp.const.openpgp.sign_data;
|
||||||
|
flags |= kbpgp.const.openpgp.auth;
|
||||||
|
flags |= kbpgp.const.openpgp.encrypt_comm;
|
||||||
|
flags |= kbpgp.const.openpgp.encrypt_storage;
|
||||||
|
|
||||||
|
const keyGenerationOptions = {
|
||||||
|
userid: userIdentifier,
|
||||||
|
ecc: keyType === "ecc",
|
||||||
|
primary: {
|
||||||
|
"nbits": keySize,
|
||||||
|
"flags": flags,
|
||||||
|
"expire_in": 0
|
||||||
|
},
|
||||||
|
subkeys: [{
|
||||||
|
"nbits": getSubkeySize(keySize),
|
||||||
|
"flags": kbpgp.const.openpgp.sign_data,
|
||||||
|
"expire_in": 86400 * 365 * 8
|
||||||
|
}, {
|
||||||
|
"nbits": getSubkeySize(keySize),
|
||||||
|
"flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage,
|
||||||
|
"expire_in": 86400 * 365 * 2
|
||||||
|
}],
|
||||||
|
asp: ASP
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const unsignedKey = await promisify(kbpgp.KeyManager.generate)(keyGenerationOptions);
|
||||||
|
await promisify(unsignedKey.sign.bind(unsignedKey))({});
|
||||||
|
|
||||||
|
const signedKey = unsignedKey,
|
||||||
|
privateKeyExportOptions = {};
|
||||||
|
|
||||||
|
if (password) privateKeyExportOptions.passphrase = password;
|
||||||
|
const privateKey = await promisify(signedKey.export_pgp_private.bind(signedKey))(privateKeyExportOptions);
|
||||||
|
const publicKey = await promisify(signedKey.export_pgp_public.bind(signedKey))({});
|
||||||
|
resolve(privateKey + "\n" + publicKey.trim());
|
||||||
|
} catch (err) {
|
||||||
|
reject(`Error whilst generating key pair: ${err}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GeneratePGPKeyPair;
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import {fromHex} from "../lib/Hex";
|
import {fromHex} from "../lib/Hex";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hamming Distance operation
|
* Hamming Distance operation
|
||||||
|
@ -55,11 +56,11 @@ class HammingDistance extends Operation {
|
||||||
samples = input.split(delim);
|
samples = input.split(delim);
|
||||||
|
|
||||||
if (samples.length !== 2) {
|
if (samples.length !== 2) {
|
||||||
return "Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.";
|
throw new OperationError("Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samples[0].length !== samples[1].length) {
|
if (samples[0].length !== samples[1].length) {
|
||||||
return "Error: Both inputs must be of the same length.";
|
throw new OperationError("Error: Both inputs must be of the same length.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inputType === "Hex") {
|
if (inputType === "Hex") {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offset checker operation
|
* Offset checker operation
|
||||||
|
@ -48,7 +49,7 @@ class OffsetChecker extends Operation {
|
||||||
chr;
|
chr;
|
||||||
|
|
||||||
if (!samples || samples.length < 2) {
|
if (!samples || samples.length < 2) {
|
||||||
return "Not enough samples, perhaps you need to modify the sample delimiter or add more data?";
|
throw new OperationError("Not enough samples, perhaps you need to modify the sample delimiter or add more data?");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise output strings
|
// Initialise output strings
|
||||||
|
|
79
src/core/operations/PGPDecrypt.mjs
Normal file
79
src/core/operations/PGPDecrypt.mjs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import kbpgp from "kbpgp";
|
||||||
|
import { ASP, importPrivateKey } from "../lib/PGP";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
import promisifyDefault from "es6-promisify";
|
||||||
|
const promisify = promisifyDefault.promisify;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Decrypt operation
|
||||||
|
*/
|
||||||
|
class PGPDecrypt extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPDecrypt constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Decrypt";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the ASCII-armoured PGP message you want to decrypt.\n<br><br>\nArguments: the ASCII-armoured PGP private key of the recipient, \n(and the private key password if necessary).\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Private key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key passphrase",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid private key
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const encryptedMessage = input,
|
||||||
|
privateKey = args[0],
|
||||||
|
passphrase = args[1],
|
||||||
|
keyring = new kbpgp.keyring.KeyRing();
|
||||||
|
let plaintextMessage;
|
||||||
|
|
||||||
|
if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
|
||||||
|
|
||||||
|
const key = await importPrivateKey(privateKey, passphrase);
|
||||||
|
keyring.add_key_manager(key);
|
||||||
|
|
||||||
|
try {
|
||||||
|
plaintextMessage = await promisify(kbpgp.unbox)({
|
||||||
|
armored: encryptedMessage,
|
||||||
|
keyfetch: keyring,
|
||||||
|
asp: ASP
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw new OperationError(`Couldn't decrypt message with provided private key: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return plaintextMessage.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPDecrypt;
|
113
src/core/operations/PGPDecryptAndVerify.mjs
Normal file
113
src/core/operations/PGPDecryptAndVerify.mjs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import kbpgp from "kbpgp";
|
||||||
|
import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
import promisifyDefault from "es6-promisify";
|
||||||
|
const promisify = promisifyDefault.promisify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Decrypt and Verify operation
|
||||||
|
*/
|
||||||
|
class PGPDecryptAndVerify extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPDecryptAndVerify constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Decrypt and Verify";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the ASCII-armoured encrypted PGP message you want to verify.\n<br><br>\nArguments: the ASCII-armoured PGP public key of the signer, \nthe ASCII-armoured private key of the recipient (and the private key password if necessary).\n<br><br>\nThis operation uses PGP to decrypt and verify an encrypted digital signature.\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Public key of signer",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key password",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const signedMessage = input,
|
||||||
|
publicKey = args[0],
|
||||||
|
privateKey = args[1],
|
||||||
|
passphrase = args[2],
|
||||||
|
keyring = new kbpgp.keyring.KeyRing();
|
||||||
|
let unboxedLiterals;
|
||||||
|
|
||||||
|
if (!publicKey) throw new OperationError("Enter the public key of the signer.");
|
||||||
|
if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
|
||||||
|
const privKey = await importPrivateKey(privateKey, passphrase);
|
||||||
|
const pubKey = await importPublicKey(publicKey);
|
||||||
|
keyring.add_key_manager(privKey);
|
||||||
|
keyring.add_key_manager(pubKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
unboxedLiterals = await promisify(kbpgp.unbox)({
|
||||||
|
armored: signedMessage,
|
||||||
|
keyfetch: keyring,
|
||||||
|
asp: ASP
|
||||||
|
});
|
||||||
|
const ds = unboxedLiterals[0].get_data_signer();
|
||||||
|
if (ds) {
|
||||||
|
const km = ds.get_key_manager();
|
||||||
|
if (km) {
|
||||||
|
const signer = km.get_userids_mark_primary()[0].components;
|
||||||
|
let text = "Signed by ";
|
||||||
|
if (signer.email || signer.username || signer.comment) {
|
||||||
|
if (signer.username) {
|
||||||
|
text += `${signer.username} `;
|
||||||
|
}
|
||||||
|
if (signer.comment) {
|
||||||
|
text += `${signer.comment} `;
|
||||||
|
}
|
||||||
|
if (signer.email) {
|
||||||
|
text += `<${signer.email}>`;
|
||||||
|
}
|
||||||
|
text += "\n";
|
||||||
|
}
|
||||||
|
text += [
|
||||||
|
`PGP fingerprint: ${km.get_pgp_fingerprint().toString("hex")}`,
|
||||||
|
`Signed on ${new Date(ds.sig.hashed_subpackets[0].time * 1000).toUTCString()}`,
|
||||||
|
"----------------------------------\n"
|
||||||
|
].join("\n");
|
||||||
|
text += unboxedLiterals.toString();
|
||||||
|
return text.trim();
|
||||||
|
} else {
|
||||||
|
throw new OperationError("Could not identify a key manager.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new OperationError("The data does not appear to be signed.");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
throw new OperationError(`Couldn't verify message: ${err}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPDecryptAndVerify;
|
77
src/core/operations/PGPEncrypt.mjs
Normal file
77
src/core/operations/PGPEncrypt.mjs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import kbpgp from "kbpgp";
|
||||||
|
import { ASP } from "../lib/PGP";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
import promisifyDefault from "es6-promisify";
|
||||||
|
const promisify = promisifyDefault.promisify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Encrypt operation
|
||||||
|
*/
|
||||||
|
class PGPEncrypt extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPEncrypt constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Encrypt";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the message you want to encrypt.\n<br><br>\nArguments: the ASCII-armoured PGP public key of the recipient.\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Public key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if failed private key import or failed encryption
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const plaintextMessage = input,
|
||||||
|
plainPubKey = args[0];
|
||||||
|
let key,
|
||||||
|
encryptedMessage;
|
||||||
|
|
||||||
|
if (!plainPubKey) throw new OperationError("Enter the public key of the recipient.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||||
|
armored: plainPubKey,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw new OperationError(`Could not import public key: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
encryptedMessage = await promisify(kbpgp.box)({
|
||||||
|
"msg": plaintextMessage,
|
||||||
|
"encrypt_for": key,
|
||||||
|
"asp": ASP
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw new OperationError(`Couldn't encrypt message with provided public key: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptedMessage.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPEncrypt;
|
84
src/core/operations/PGPEncryptAndSign.mjs
Normal file
84
src/core/operations/PGPEncryptAndSign.mjs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import kbpgp from "kbpgp";
|
||||||
|
import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
import promisifyDefault from "es6-promisify";
|
||||||
|
const promisify = promisifyDefault.promisify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Encrypt and Sign operation
|
||||||
|
*/
|
||||||
|
class PGPEncryptAndSign extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPEncryptAndSign constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Encrypt and Sign";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the cleartext you want to sign.\n<br><br>\nArguments: the ASCII-armoured private key of the signer (plus the private key password if necessary)\nand the ASCII-armoured PGP public key of the recipient.\n<br><br>\nThis operation uses PGP to produce an encrypted digital signature.\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Private key of signer",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key passphrase",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Public key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if failure to sign message
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const message = input,
|
||||||
|
privateKey = args[0],
|
||||||
|
passphrase = args[1],
|
||||||
|
publicKey = args[2];
|
||||||
|
let signedMessage;
|
||||||
|
|
||||||
|
if (!privateKey) throw new OperationError("Enter the private key of the signer.");
|
||||||
|
if (!publicKey) throw new OperationError("Enter the public key of the recipient.");
|
||||||
|
const privKey = await importPrivateKey(privateKey, passphrase);
|
||||||
|
const pubKey = await importPublicKey(publicKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
signedMessage = await promisify(kbpgp.box)({
|
||||||
|
"msg": message,
|
||||||
|
"encrypt_for": pubKey,
|
||||||
|
"sign_with": privKey,
|
||||||
|
"asp": ASP
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw new OperationError(`Couldn't sign message: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPEncryptAndSign;
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime";
|
import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse DateTime operation
|
* Parse DateTime operation
|
||||||
|
@ -59,7 +60,7 @@ class ParseDateTime extends Operation {
|
||||||
date = moment.tz(input, inputFormat, inputTimezone);
|
date = moment.tz(input, inputFormat, inputTimezone);
|
||||||
if (!date || date.format() === "Invalid date") throw Error;
|
if (!date || date.format() === "Invalid date") throw Error;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return "Invalid format.\n\n" + FORMAT_EXAMPLES;
|
throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
output += "Date: " + date.format("dddd Do MMMM YYYY") +
|
output += "Date: " + date.format("dddd Do MMMM YYYY") +
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse UNIX file permissions operation
|
* Parse UNIX file permissions operation
|
||||||
|
@ -169,7 +170,7 @@ class ParseUNIXFilePermissions extends Operation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.";
|
throw new OperationError("Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
output += "Textual representation: " + permsToStr(perms);
|
output += "Textual representation: " + permsToStr(perms);
|
||||||
|
|
69
src/core/operations/ParseURI.mjs
Normal file
69
src/core/operations/ParseURI.mjs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import url from "url";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse URI operation
|
||||||
|
*/
|
||||||
|
class ParseURI extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ParseURI constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Parse URI";
|
||||||
|
this.module = "URL";
|
||||||
|
this.description = "Pretty prints complicated Uniform Resource Identifier (URI) strings for ease of reading. Particularly useful for Uniform Resource Locators (URLs) with a lot of arguments.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const uri = url.parse(input, true);
|
||||||
|
|
||||||
|
let output = "";
|
||||||
|
|
||||||
|
if (uri.protocol) output += "Protocol:\t" + uri.protocol + "\n";
|
||||||
|
if (uri.auth) output += "Auth:\t\t" + uri.auth + "\n";
|
||||||
|
if (uri.hostname) output += "Hostname:\t" + uri.hostname + "\n";
|
||||||
|
if (uri.port) output += "Port:\t\t" + uri.port + "\n";
|
||||||
|
if (uri.pathname) output += "Path name:\t" + uri.pathname + "\n";
|
||||||
|
if (uri.query) {
|
||||||
|
const keys = Object.keys(uri.query);
|
||||||
|
let padding = 0;
|
||||||
|
|
||||||
|
keys.forEach(k => {
|
||||||
|
padding = (k.length > padding) ? k.length : padding;
|
||||||
|
});
|
||||||
|
|
||||||
|
output += "Arguments:\n";
|
||||||
|
for (const key in uri.query) {
|
||||||
|
output += "\t" + key.padEnd(padding, " ");
|
||||||
|
if (uri.query[key].length) {
|
||||||
|
output += " = " + uri.query[key] + "\n";
|
||||||
|
} else {
|
||||||
|
output += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n";
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ParseURI;
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
|
import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
|
||||||
import rawinflate from "zlibjs/bin/rawinflate.min";
|
import rawinflate from "zlibjs/bin/rawinflate.min";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
const Zlib = rawinflate.Zlib;
|
const Zlib = rawinflate.Zlib;
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ class RawInflate extends Operation {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
throw "Error: Unable to inflate data";
|
throw new OperationError("Error: Unable to inflate data");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This seems to be the easiest way...
|
// This seems to be the easiest way...
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import {fromBase64, toBase64} from "../lib/Base64";
|
import {fromBase64, toBase64} from "../lib/Base64";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show Base64 offsets operation
|
* Show Base64 offsets operation
|
||||||
|
@ -58,7 +59,7 @@ class ShowBase64Offsets extends Operation {
|
||||||
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
|
script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
|
||||||
|
|
||||||
if (input.length < 1) {
|
if (input.length < 1) {
|
||||||
return "Please enter a string.";
|
throw new OperationError("Please enter a string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Highlight offset 0
|
// Highlight offset 0
|
||||||
|
|
118
src/core/operations/Strings.mjs
Normal file
118
src/core/operations/Strings.mjs
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import XRegExp from "xregexp";
|
||||||
|
import { search } from "../lib/Extract";
|
||||||
|
/**
|
||||||
|
* Strings operation
|
||||||
|
*/
|
||||||
|
class Strings extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strings constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Strings";
|
||||||
|
this.module = "Regex";
|
||||||
|
this.description = "Extracts all strings from the input.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Encoding",
|
||||||
|
"type": "option",
|
||||||
|
"value": ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Minimum length",
|
||||||
|
"type": "number",
|
||||||
|
"value": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Match",
|
||||||
|
"type": "option",
|
||||||
|
"value": [
|
||||||
|
"[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)",
|
||||||
|
"[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Display total",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const encoding = args[0],
|
||||||
|
minLen = args[1],
|
||||||
|
matchType = args[2],
|
||||||
|
displayTotal = args[3],
|
||||||
|
alphanumeric = "A-Z\\d",
|
||||||
|
punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@",
|
||||||
|
printable = "\x20-\x7e",
|
||||||
|
uniAlphanumeric = "\\pL\\pN",
|
||||||
|
uniPunctuation = "\\pP\\pZ",
|
||||||
|
uniPrintable = "\\pL\\pM\\pZ\\pS\\pN\\pP";
|
||||||
|
|
||||||
|
let strings = "";
|
||||||
|
|
||||||
|
switch (matchType) {
|
||||||
|
case "Alphanumeric + punctuation (A)":
|
||||||
|
strings = `[${alphanumeric + punctuation}]`;
|
||||||
|
break;
|
||||||
|
case "All printable chars (A)":
|
||||||
|
case "Null-terminated strings (A)":
|
||||||
|
strings = `[${printable}]`;
|
||||||
|
break;
|
||||||
|
case "Alphanumeric + punctuation (U)":
|
||||||
|
strings = `[${uniAlphanumeric + uniPunctuation}]`;
|
||||||
|
break;
|
||||||
|
case "All printable chars (U)":
|
||||||
|
case "Null-terminated strings (U)":
|
||||||
|
strings = `[${uniPrintable}]`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UTF-16 support is hacked in by allowing null bytes on either side of the matched chars
|
||||||
|
switch (encoding) {
|
||||||
|
case "All":
|
||||||
|
strings = `(\x00?${strings}\x00?)`;
|
||||||
|
break;
|
||||||
|
case "16-bit littleendian":
|
||||||
|
strings = `(${strings}\x00)`;
|
||||||
|
break;
|
||||||
|
case "16-bit bigendian":
|
||||||
|
strings = `(\x00${strings})`;
|
||||||
|
break;
|
||||||
|
case "Single byte":
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strings = `${strings}{${minLen},}`;
|
||||||
|
|
||||||
|
if (matchType.includes("Null-terminated")) {
|
||||||
|
strings += "\x00";
|
||||||
|
}
|
||||||
|
|
||||||
|
const regex = new XRegExp(strings, "ig");
|
||||||
|
|
||||||
|
return search(input, regex, null, displayTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Strings;
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take bytes operation
|
* Take bytes operation
|
||||||
|
@ -45,6 +46,8 @@ class TakeBytes extends Operation {
|
||||||
* @param {ArrayBuffer} input
|
* @param {ArrayBuffer} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {ArrayBuffer}
|
* @returns {ArrayBuffer}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if invalid value
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const start = args[0],
|
const start = args[0],
|
||||||
|
@ -52,7 +55,7 @@ class TakeBytes extends Operation {
|
||||||
applyToEachLine = args[2];
|
applyToEachLine = args[2];
|
||||||
|
|
||||||
if (start < 0 || length < 0)
|
if (start < 0 || length < 0)
|
||||||
throw "Error: Invalid value";
|
throw new OperationError("Error: Invalid value");
|
||||||
|
|
||||||
if (!applyToEachLine)
|
if (!applyToEachLine)
|
||||||
return input.slice(start, start+length);
|
return input.slice(start, start+length);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import Utils from "../Utils";
|
import Utils from "../Utils";
|
||||||
import {DELIM_OPTIONS} from "../lib/Delim";
|
import {DELIM_OPTIONS} from "../lib/Delim";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To Charcode operation
|
* To Charcode operation
|
||||||
|
@ -42,6 +43,8 @@ class ToCharcode extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if base argument out of range
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const delim = Utils.charRep(args[0] || "Space"),
|
const delim = Utils.charRep(args[0] || "Space"),
|
||||||
|
@ -51,7 +54,7 @@ class ToCharcode extends Operation {
|
||||||
ordinal;
|
ordinal;
|
||||||
|
|
||||||
if (base < 2 || base > 36) {
|
if (base < 2 || base > 36) {
|
||||||
throw "Error: Base argument must be between 2 and 36";
|
throw new OperationError("Error: Base argument must be between 2 and 36");
|
||||||
}
|
}
|
||||||
|
|
||||||
const charcode = Utils.strToCharcode(input);
|
const charcode = Utils.strToCharcode(input);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import {UNITS} from "../lib/DateTime";
|
import {UNITS} from "../lib/DateTime";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To UNIX Timestamp operation
|
* To UNIX Timestamp operation
|
||||||
|
@ -47,6 +48,8 @@ class ToUNIXTimestamp extends Operation {
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
* @param {Object[]} args
|
* @param {Object[]} args
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
*
|
||||||
|
* @throws {OperationError} if unit unrecognised
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const [units, treatAsUTC, showDateTime] = args,
|
const [units, treatAsUTC, showDateTime] = args,
|
||||||
|
@ -63,7 +66,7 @@ class ToUNIXTimestamp extends Operation {
|
||||||
} else if (units === "Nanoseconds (ns)") {
|
} else if (units === "Nanoseconds (ns)") {
|
||||||
result = d.valueOf() * 1000000;
|
result = d.valueOf() * 1000000;
|
||||||
} else {
|
} else {
|
||||||
throw "Unrecognised unit";
|
throw new OperationError("Unrecognised unit");
|
||||||
}
|
}
|
||||||
|
|
||||||
return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString();
|
return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime";
|
import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime";
|
||||||
|
import OperationError from "../errors/OperationError";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate DateTime Format operation
|
* Translate DateTime Format operation
|
||||||
|
@ -67,7 +68,7 @@ class TranslateDateTimeFormat extends Operation {
|
||||||
date = moment.tz(input, inputFormat, inputTimezone);
|
date = moment.tz(input, inputFormat, inputTimezone);
|
||||||
if (!date || date.format() === "Invalid date") throw Error;
|
if (!date || date.format() === "Invalid date") throw Error;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return "Invalid format.\n\n" + FORMAT_EXAMPLES;
|
throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return date.tz(outputTimezone).format(outputFormat);
|
return date.tz(outputTimezone).format(outputFormat);
|
||||||
|
|
44
src/core/operations/URLDecode.mjs
Normal file
44
src/core/operations/URLDecode.mjs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL Decode operation
|
||||||
|
*/
|
||||||
|
class URLDecode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URLDecode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "URL Decode";
|
||||||
|
this.module = "URL";
|
||||||
|
this.description = "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const data = input.replace(/\+/g, "%20");
|
||||||
|
try {
|
||||||
|
return decodeURIComponent(data);
|
||||||
|
} catch (err) {
|
||||||
|
return unescape(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default URLDecode;
|
68
src/core/operations/URLEncode.mjs
Normal file
68
src/core/operations/URLEncode.mjs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2016
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL Encode operation
|
||||||
|
*/
|
||||||
|
class URLEncode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URLEncode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "URL Encode";
|
||||||
|
this.module = "URL";
|
||||||
|
this.description = "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.<br><br>e.g. <code>=</code> becomes <code>%3d</code>";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Encode all special chars",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const encodeAll = args[0];
|
||||||
|
return encodeAll ? this.encodeAllChars(input) : encodeURI(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode characters in URL outside of encodeURI() function spec
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
encodeAllChars (str) {
|
||||||
|
//TODO Do this programatically
|
||||||
|
return encodeURIComponent(str)
|
||||||
|
.replace(/!/g, "%21")
|
||||||
|
.replace(/#/g, "%23")
|
||||||
|
.replace(/'/g, "%27")
|
||||||
|
.replace(/\(/g, "%28")
|
||||||
|
.replace(/\)/g, "%29")
|
||||||
|
.replace(/\*/g, "%2A")
|
||||||
|
.replace(/-/g, "%2D")
|
||||||
|
.replace(/\./g, "%2E")
|
||||||
|
.replace(/_/g, "%5F")
|
||||||
|
.replace(/~/g, "%7E");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default URLEncode;
|
|
@ -1,333 +0,0 @@
|
||||||
import XRegExp from "xregexp";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Identifier extraction operations.
|
|
||||||
*
|
|
||||||
* @author n1474335 [n1474335@gmail.com]
|
|
||||||
* @copyright Crown Copyright 2016
|
|
||||||
* @license Apache-2.0
|
|
||||||
*
|
|
||||||
* @namespace
|
|
||||||
*/
|
|
||||||
const Extract = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs search operations across the input data using regular expressions.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {string} input
|
|
||||||
* @param {RegExp} searchRegex
|
|
||||||
* @param {RegExp} removeRegex - A regular expression defining results to remove from the
|
|
||||||
* final list
|
|
||||||
* @param {boolean} includeTotal - Whether or not to include the total number of results
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
_search: function(input, searchRegex, removeRegex, includeTotal) {
|
|
||||||
let output = "",
|
|
||||||
total = 0,
|
|
||||||
match;
|
|
||||||
|
|
||||||
while ((match = searchRegex.exec(input))) {
|
|
||||||
// Moves pointer when an empty string is matched (prevents infinite loop)
|
|
||||||
if (match.index === searchRegex.lastIndex) {
|
|
||||||
searchRegex.lastIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeRegex && removeRegex.test(match[0]))
|
|
||||||
continue;
|
|
||||||
total++;
|
|
||||||
output += match[0] + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeTotal)
|
|
||||||
output = "Total found: " + total + "\n\n" + output;
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
MIN_STRING_LEN: 4,
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
STRING_MATCH_TYPE: [
|
|
||||||
"[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)",
|
|
||||||
"[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)"
|
|
||||||
],
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
ENCODING_LIST: ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"],
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
DISPLAY_TOTAL: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strings operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runStrings: function(input, args) {
|
|
||||||
const encoding = args[0],
|
|
||||||
minLen = args[1],
|
|
||||||
matchType = args[2],
|
|
||||||
displayTotal = args[3],
|
|
||||||
alphanumeric = "A-Z\\d",
|
|
||||||
punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@",
|
|
||||||
printable = "\x20-\x7e",
|
|
||||||
uniAlphanumeric = "\\pL\\pN",
|
|
||||||
uniPunctuation = "\\pP\\pZ",
|
|
||||||
uniPrintable = "\\pL\\pM\\pZ\\pS\\pN\\pP";
|
|
||||||
|
|
||||||
let strings = "";
|
|
||||||
|
|
||||||
switch (matchType) {
|
|
||||||
case "Alphanumeric + punctuation (A)":
|
|
||||||
strings = `[${alphanumeric + punctuation}]`;
|
|
||||||
break;
|
|
||||||
case "All printable chars (A)":
|
|
||||||
case "Null-terminated strings (A)":
|
|
||||||
strings = `[${printable}]`;
|
|
||||||
break;
|
|
||||||
case "Alphanumeric + punctuation (U)":
|
|
||||||
strings = `[${uniAlphanumeric + uniPunctuation}]`;
|
|
||||||
break;
|
|
||||||
case "All printable chars (U)":
|
|
||||||
case "Null-terminated strings (U)":
|
|
||||||
strings = `[${uniPrintable}]`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UTF-16 support is hacked in by allowing null bytes on either side of the matched chars
|
|
||||||
switch (encoding) {
|
|
||||||
case "All":
|
|
||||||
strings = `(\x00?${strings}\x00?)`;
|
|
||||||
break;
|
|
||||||
case "16-bit littleendian":
|
|
||||||
strings = `(${strings}\x00)`;
|
|
||||||
break;
|
|
||||||
case "16-bit bigendian":
|
|
||||||
strings = `(\x00${strings})`;
|
|
||||||
break;
|
|
||||||
case "Single byte":
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
strings = `${strings}{${minLen},}`;
|
|
||||||
|
|
||||||
if (matchType.includes("Null-terminated")) {
|
|
||||||
strings += "\x00";
|
|
||||||
}
|
|
||||||
|
|
||||||
const regex = new XRegExp(strings, "ig");
|
|
||||||
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
INCLUDE_IPV4: true,
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
INCLUDE_IPV6: false,
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
REMOVE_LOCAL: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract IP addresses operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runIp: function(input, args) {
|
|
||||||
let includeIpv4 = args[0],
|
|
||||||
includeIpv6 = args[1],
|
|
||||||
removeLocal = args[2],
|
|
||||||
displayTotal = args[3],
|
|
||||||
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
|
||||||
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})",
|
|
||||||
ips = "";
|
|
||||||
|
|
||||||
if (includeIpv4 && includeIpv6) {
|
|
||||||
ips = ipv4 + "|" + ipv6;
|
|
||||||
} else if (includeIpv4) {
|
|
||||||
ips = ipv4;
|
|
||||||
} else if (includeIpv6) {
|
|
||||||
ips = ipv6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ips) {
|
|
||||||
const regex = new RegExp(ips, "ig");
|
|
||||||
|
|
||||||
if (removeLocal) {
|
|
||||||
let ten = "10\\..+",
|
|
||||||
oneninetwo = "192\\.168\\..+",
|
|
||||||
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
|
||||||
onetwoseven = "127\\..+",
|
|
||||||
removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo +
|
|
||||||
"|" + oneseventwo + "|" + onetwoseven + ")");
|
|
||||||
|
|
||||||
return Extract._search(input, regex, removeRegex, displayTotal);
|
|
||||||
} else {
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract email addresses operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runEmail: function(input, args) {
|
|
||||||
let displayTotal = args[0],
|
|
||||||
regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig;
|
|
||||||
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract MAC addresses operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runMac: function(input, args) {
|
|
||||||
let displayTotal = args[0],
|
|
||||||
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig;
|
|
||||||
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract URLs operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runUrls: function(input, args) {
|
|
||||||
let displayTotal = args[0],
|
|
||||||
protocol = "[A-Z]+://",
|
|
||||||
hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+",
|
|
||||||
port = ":\\d+",
|
|
||||||
path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*";
|
|
||||||
|
|
||||||
path += "(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*";
|
|
||||||
const regex = new RegExp(protocol + hostname + "(?:" + port +
|
|
||||||
")?(?:" + path + ")?", "ig");
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract domains operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runDomains: function(input, args) {
|
|
||||||
const displayTotal = args[0],
|
|
||||||
regex = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;
|
|
||||||
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
INCLUDE_WIN_PATH: true,
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
INCLUDE_UNIX_PATH: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract file paths operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runFilePaths: function(input, args) {
|
|
||||||
let includeWinPath = args[0],
|
|
||||||
includeUnixPath = args[1],
|
|
||||||
displayTotal = args[2],
|
|
||||||
winDrive = "[A-Z]:\\\\",
|
|
||||||
winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}",
|
|
||||||
winExt = "[A-Z\\d]{1,6}",
|
|
||||||
winPath = winDrive + "(?:" + winName + "\\\\?)*" + winName +
|
|
||||||
"(?:\\." + winExt + ")?",
|
|
||||||
unixPath = "(?:/[A-Z\\d.][A-Z\\d\\-.]{0,61})+",
|
|
||||||
filePaths = "";
|
|
||||||
|
|
||||||
if (includeWinPath && includeUnixPath) {
|
|
||||||
filePaths = winPath + "|" + unixPath;
|
|
||||||
} else if (includeWinPath) {
|
|
||||||
filePaths = winPath;
|
|
||||||
} else if (includeUnixPath) {
|
|
||||||
filePaths = unixPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filePaths) {
|
|
||||||
const regex = new RegExp(filePaths, "ig");
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract dates operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runDates: function(input, args) {
|
|
||||||
let displayTotal = args[0],
|
|
||||||
date1 = "(?:19|20)\\d\\d[- /.](?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])", // yyyy-mm-dd
|
|
||||||
date2 = "(?:0[1-9]|[12][0-9]|3[01])[- /.](?:0[1-9]|1[012])[- /.](?:19|20)\\d\\d", // dd/mm/yyyy
|
|
||||||
date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy
|
|
||||||
regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig");
|
|
||||||
|
|
||||||
return Extract._search(input, regex, null, displayTotal);
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Extract;
|
|
|
@ -1,364 +0,0 @@
|
||||||
import * as kbpgp from "kbpgp";
|
|
||||||
import {promisify} from "es6-promisify";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PGP operations.
|
|
||||||
*
|
|
||||||
* @author tlwr [toby@toby.codes]
|
|
||||||
* @author Matt C [matt@artemisbot.uk]
|
|
||||||
* @author n1474335 [n1474335@gmail.com]
|
|
||||||
* @copyright Crown Copyright 2017
|
|
||||||
* @license Apache-2.0
|
|
||||||
*
|
|
||||||
* @namespace
|
|
||||||
*/
|
|
||||||
const PGP = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
KEY_TYPES: ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"],
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get size of subkey
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {number} keySize
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
_getSubkeySize(keySize) {
|
|
||||||
return {
|
|
||||||
1024: 1024,
|
|
||||||
2048: 1024,
|
|
||||||
4096: 2048,
|
|
||||||
256: 256,
|
|
||||||
384: 256,
|
|
||||||
}[keySize];
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Progress callback
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_ASP: new kbpgp.ASP({
|
|
||||||
"progress_hook": info => {
|
|
||||||
let msg = "";
|
|
||||||
|
|
||||||
switch (info.what) {
|
|
||||||
case "guess":
|
|
||||||
msg = "Guessing a prime";
|
|
||||||
break;
|
|
||||||
case "fermat":
|
|
||||||
msg = "Factoring prime using Fermat's factorization method";
|
|
||||||
break;
|
|
||||||
case "mr":
|
|
||||||
msg = "Performing Miller-Rabin primality test";
|
|
||||||
break;
|
|
||||||
case "passed_mr":
|
|
||||||
msg = "Passed Miller-Rabin primality test";
|
|
||||||
break;
|
|
||||||
case "failed_mr":
|
|
||||||
msg = "Failed Miller-Rabin primality test";
|
|
||||||
break;
|
|
||||||
case "found":
|
|
||||||
msg = "Prime found";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
msg = `Stage: ${info.what}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ENVIRONMENT_IS_WORKER())
|
|
||||||
self.sendStatusMessage(msg);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import private key and unlock if necessary
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {string} privateKey
|
|
||||||
* @param {string} [passphrase]
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
async _importPrivateKey(privateKey, passphrase) {
|
|
||||||
try {
|
|
||||||
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
|
||||||
armored: privateKey,
|
|
||||||
opts: {
|
|
||||||
"no_check_keys": true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (key.is_pgp_locked()) {
|
|
||||||
if (passphrase) {
|
|
||||||
await promisify(key.unlock_pgp.bind(key))({
|
|
||||||
passphrase
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw "Did not provide passphrase with locked private key.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
} catch (err) {
|
|
||||||
throw `Could not import private key: ${err}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import public key
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {string} publicKey
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
async _importPublicKey (publicKey) {
|
|
||||||
try {
|
|
||||||
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
|
||||||
armored: publicKey,
|
|
||||||
opts: {
|
|
||||||
"no_check_keys": true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return key;
|
|
||||||
} catch (err) {
|
|
||||||
throw `Could not import public key: ${err}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate PGP Key Pair operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runGenerateKeyPair(input, args) {
|
|
||||||
let [keyType, keySize] = args[0].split("-"),
|
|
||||||
password = args[1],
|
|
||||||
name = args[2],
|
|
||||||
email = args[3],
|
|
||||||
userIdentifier = "";
|
|
||||||
|
|
||||||
if (name) userIdentifier += name;
|
|
||||||
if (email) userIdentifier += ` <${email}>`;
|
|
||||||
|
|
||||||
let flags = kbpgp.const.openpgp.certify_keys;
|
|
||||||
flags |= kbpgp.const.openpgp.sign_data;
|
|
||||||
flags |= kbpgp.const.openpgp.auth;
|
|
||||||
flags |= kbpgp.const.openpgp.encrypt_comm;
|
|
||||||
flags |= kbpgp.const.openpgp.encrypt_storage;
|
|
||||||
|
|
||||||
let keyGenerationOptions = {
|
|
||||||
userid: userIdentifier,
|
|
||||||
ecc: keyType === "ecc",
|
|
||||||
primary: {
|
|
||||||
"nbits": keySize,
|
|
||||||
"flags": flags,
|
|
||||||
"expire_in": 0
|
|
||||||
},
|
|
||||||
subkeys: [{
|
|
||||||
"nbits": PGP._getSubkeySize(keySize),
|
|
||||||
"flags": kbpgp.const.openpgp.sign_data,
|
|
||||||
"expire_in": 86400 * 365 * 8
|
|
||||||
}, {
|
|
||||||
"nbits": PGP._getSubkeySize(keySize),
|
|
||||||
"flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage,
|
|
||||||
"expire_in": 86400 * 365 * 2
|
|
||||||
}],
|
|
||||||
asp: PGP._ASP
|
|
||||||
};
|
|
||||||
|
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
try {
|
|
||||||
const unsignedKey = await promisify(kbpgp.KeyManager.generate)(keyGenerationOptions);
|
|
||||||
await promisify(unsignedKey.sign.bind(unsignedKey))({});
|
|
||||||
let signedKey = unsignedKey;
|
|
||||||
let privateKeyExportOptions = {};
|
|
||||||
if (password) privateKeyExportOptions.passphrase = password;
|
|
||||||
const privateKey = await promisify(signedKey.export_pgp_private.bind(signedKey))(privateKeyExportOptions);
|
|
||||||
const publicKey = await promisify(signedKey.export_pgp_public.bind(signedKey))({});
|
|
||||||
resolve(privateKey + "\n" + publicKey.trim());
|
|
||||||
} catch (err) {
|
|
||||||
reject(`Error whilst generating key pair: ${err}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PGP Encrypt operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
async runEncrypt(input, args) {
|
|
||||||
let plaintextMessage = input,
|
|
||||||
plainPubKey = args[0],
|
|
||||||
key,
|
|
||||||
encryptedMessage;
|
|
||||||
|
|
||||||
if (!plainPubKey) return "Enter the public key of the recipient.";
|
|
||||||
|
|
||||||
try {
|
|
||||||
key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
|
||||||
armored: plainPubKey,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
throw `Could not import public key: ${err}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
encryptedMessage = await promisify(kbpgp.box)({
|
|
||||||
"msg": plaintextMessage,
|
|
||||||
"encrypt_for": key,
|
|
||||||
"asp": PGP._ASP
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
throw `Couldn't encrypt message with provided public key: ${err}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return encryptedMessage.toString();
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PGP Decrypt operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
async runDecrypt(input, args) {
|
|
||||||
let encryptedMessage = input,
|
|
||||||
privateKey = args[0],
|
|
||||||
passphrase = args[1],
|
|
||||||
keyring = new kbpgp.keyring.KeyRing(),
|
|
||||||
plaintextMessage;
|
|
||||||
|
|
||||||
if (!privateKey) return "Enter the private key of the recipient.";
|
|
||||||
|
|
||||||
const key = await PGP._importPrivateKey(privateKey, passphrase);
|
|
||||||
keyring.add_key_manager(key);
|
|
||||||
|
|
||||||
try {
|
|
||||||
plaintextMessage = await promisify(kbpgp.unbox)({
|
|
||||||
armored: encryptedMessage,
|
|
||||||
keyfetch: keyring,
|
|
||||||
asp: PGP._ASP
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
throw `Couldn't decrypt message with provided private key: ${err}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return plaintextMessage.toString();
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PGP Sign Message operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
async runSign(input, args) {
|
|
||||||
let message = input,
|
|
||||||
privateKey = args[0],
|
|
||||||
passphrase = args[1],
|
|
||||||
publicKey = args[2],
|
|
||||||
signedMessage;
|
|
||||||
|
|
||||||
if (!privateKey) return "Enter the private key of the signer.";
|
|
||||||
if (!publicKey) return "Enter the public key of the recipient.";
|
|
||||||
const privKey = await PGP._importPrivateKey(privateKey, passphrase);
|
|
||||||
const pubKey = await PGP._importPublicKey(publicKey);
|
|
||||||
|
|
||||||
try {
|
|
||||||
signedMessage = await promisify(kbpgp.box)({
|
|
||||||
"msg": message,
|
|
||||||
"encrypt_for": pubKey,
|
|
||||||
"sign_with": privKey,
|
|
||||||
"asp": PGP._ASP
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
throw `Couldn't sign message: ${err}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return signedMessage;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PGP Verify Message operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
async runVerify(input, args) {
|
|
||||||
let signedMessage = input,
|
|
||||||
publicKey = args[0],
|
|
||||||
privateKey = args[1],
|
|
||||||
passphrase = args[2],
|
|
||||||
keyring = new kbpgp.keyring.KeyRing(),
|
|
||||||
unboxedLiterals;
|
|
||||||
|
|
||||||
if (!publicKey) return "Enter the public key of the signer.";
|
|
||||||
if (!privateKey) return "Enter the private key of the recipient.";
|
|
||||||
const privKey = await PGP._importPrivateKey(privateKey, passphrase);
|
|
||||||
const pubKey = await PGP._importPublicKey(publicKey);
|
|
||||||
keyring.add_key_manager(privKey);
|
|
||||||
keyring.add_key_manager(pubKey);
|
|
||||||
|
|
||||||
try {
|
|
||||||
unboxedLiterals = await promisify(kbpgp.unbox)({
|
|
||||||
armored: signedMessage,
|
|
||||||
keyfetch: keyring,
|
|
||||||
asp: PGP._ASP
|
|
||||||
});
|
|
||||||
const ds = unboxedLiterals[0].get_data_signer();
|
|
||||||
if (ds) {
|
|
||||||
const km = ds.get_key_manager();
|
|
||||||
if (km) {
|
|
||||||
const signer = km.get_userids_mark_primary()[0].components;
|
|
||||||
let text = "Signed by ";
|
|
||||||
if (signer.email || signer.username || signer.comment) {
|
|
||||||
if (signer.username) {
|
|
||||||
text += `${signer.username} `;
|
|
||||||
}
|
|
||||||
if (signer.comment) {
|
|
||||||
text += `${signer.comment} `;
|
|
||||||
}
|
|
||||||
if (signer.email) {
|
|
||||||
text += `<${signer.email}>`;
|
|
||||||
}
|
|
||||||
text += "\n";
|
|
||||||
}
|
|
||||||
text += [
|
|
||||||
`PGP fingerprint: ${km.get_pgp_fingerprint().toString("hex")}`,
|
|
||||||
`Signed on ${new Date(ds.sig.hashed_subpackets[0].time * 1000).toUTCString()}`,
|
|
||||||
"----------------------------------\n"
|
|
||||||
].join("\n");
|
|
||||||
text += unboxedLiterals.toString();
|
|
||||||
return text.trim();
|
|
||||||
} else {
|
|
||||||
return "Could not identify a key manager.";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "The data does not appear to be signed.";
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
return `Couldn't verify message: ${err}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PGP;
|
|
|
@ -1,118 +0,0 @@
|
||||||
/* globals unescape */
|
|
||||||
import url from "url";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL operations.
|
|
||||||
* Namespace is appended with an underscore to prevent overwriting the global URL object.
|
|
||||||
*
|
|
||||||
* @author n1474335 [n1474335@gmail.com]
|
|
||||||
* @copyright Crown Copyright 2016
|
|
||||||
* @license Apache-2.0
|
|
||||||
*
|
|
||||||
* @namespace
|
|
||||||
*/
|
|
||||||
const URL_ = {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
ENCODE_ALL: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL Encode operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runTo: function(input, args) {
|
|
||||||
const encodeAll = args[0];
|
|
||||||
return encodeAll ? URL_._encodeAllChars(input) : encodeURI(input);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL Decode operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runFrom: function(input, args) {
|
|
||||||
const data = input.replace(/\+/g, "%20");
|
|
||||||
try {
|
|
||||||
return decodeURIComponent(data);
|
|
||||||
} catch (err) {
|
|
||||||
return unescape(data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URI operation.
|
|
||||||
*
|
|
||||||
* @param {string} input
|
|
||||||
* @param {Object[]} args
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
runParse: function(input, args) {
|
|
||||||
const uri = url.parse(input, true);
|
|
||||||
|
|
||||||
let output = "";
|
|
||||||
|
|
||||||
if (uri.protocol) output += "Protocol:\t" + uri.protocol + "\n";
|
|
||||||
if (uri.auth) output += "Auth:\t\t" + uri.auth + "\n";
|
|
||||||
if (uri.hostname) output += "Hostname:\t" + uri.hostname + "\n";
|
|
||||||
if (uri.port) output += "Port:\t\t" + uri.port + "\n";
|
|
||||||
if (uri.pathname) output += "Path name:\t" + uri.pathname + "\n";
|
|
||||||
if (uri.query) {
|
|
||||||
let keys = Object.keys(uri.query),
|
|
||||||
padding = 0;
|
|
||||||
|
|
||||||
keys.forEach(k => {
|
|
||||||
padding = (k.length > padding) ? k.length : padding;
|
|
||||||
});
|
|
||||||
|
|
||||||
output += "Arguments:\n";
|
|
||||||
for (let key in uri.query) {
|
|
||||||
output += "\t" + key.padEnd(padding, " ");
|
|
||||||
if (uri.query[key].length) {
|
|
||||||
output += " = " + uri.query[key] + "\n";
|
|
||||||
} else {
|
|
||||||
output += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n";
|
|
||||||
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL encodes additional special characters beyond the standard set.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {string} str
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
_encodeAllChars: function(str) {
|
|
||||||
//TODO Do this programatically
|
|
||||||
return encodeURIComponent(str)
|
|
||||||
.replace(/!/g, "%21")
|
|
||||||
.replace(/#/g, "%23")
|
|
||||||
.replace(/'/g, "%27")
|
|
||||||
.replace(/\(/g, "%28")
|
|
||||||
.replace(/\)/g, "%29")
|
|
||||||
.replace(/\*/g, "%2A")
|
|
||||||
.replace(/-/g, "%2D")
|
|
||||||
.replace(/\./g, "%2E")
|
|
||||||
.replace(/_/g, "%5F")
|
|
||||||
.replace(/~/g, "%7E");
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export default URL_;
|
|
|
@ -3316,7 +3316,7 @@ If input "type" is set 5 it will adjust the mnemonic array to decode Centaur ins
|
||||||
If input "type" is set 6 it will adjust the mnemonic array to decode instruction for the X86/486 CPU which conflict with the vector unit instructions with UMOV.
|
If input "type" is set 6 it will adjust the mnemonic array to decode instruction for the X86/486 CPU which conflict with the vector unit instructions with UMOV.
|
||||||
-------------------------------------------------------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
function CompatibilityMode( type )
|
export function CompatibilityMode( type )
|
||||||
{
|
{
|
||||||
//Reset the changeable sections of the Mnemonics array, and operand encoding array.
|
//Reset the changeable sections of the Mnemonics array, and operand encoding array.
|
||||||
|
|
||||||
|
@ -3515,7 +3515,7 @@ The function "GetPosition()" Gives back the current base address in it's proper
|
||||||
If the hex input is invalid returns false.
|
If the hex input is invalid returns false.
|
||||||
-------------------------------------------------------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
function LoadBinCode( HexStr )
|
export function LoadBinCode( HexStr )
|
||||||
{
|
{
|
||||||
//Clear BinCode, and Reset Code Position in Bin Code array.
|
//Clear BinCode, and Reset Code Position in Bin Code array.
|
||||||
|
|
||||||
|
@ -3605,7 +3605,7 @@ segment, and offset address. Note that the Code Segment is used in 16 bit code.
|
||||||
if set 36, or higher. Effects instruction location in memory when decoding a program.
|
if set 36, or higher. Effects instruction location in memory when decoding a program.
|
||||||
-------------------------------------------------------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
function SetBasePosition( Address )
|
export function SetBasePosition( Address )
|
||||||
{
|
{
|
||||||
//Split the Segment:offset.
|
//Split the Segment:offset.
|
||||||
|
|
||||||
|
@ -5652,7 +5652,7 @@ function Reset()
|
||||||
do an linear disassemble.
|
do an linear disassemble.
|
||||||
-------------------------------------------------------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
function LDisassemble()
|
export function LDisassemble()
|
||||||
{
|
{
|
||||||
var Instruction = ""; //Stores the Decoded instruction.
|
var Instruction = ""; //Stores the Decoded instruction.
|
||||||
var Out = ""; //The Disassemble output
|
var Out = ""; //The Disassemble output
|
||||||
|
@ -5709,13 +5709,13 @@ function LDisassemble()
|
||||||
* The following code has been added to expose public methods for use in CyberChef
|
* The following code has been added to expose public methods for use in CyberChef
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default {
|
export function setBitMode (val) {
|
||||||
LoadBinCode: LoadBinCode,
|
BitMode = val;
|
||||||
LDisassemble: LDisassemble,
|
|
||||||
SetBasePosition: SetBasePosition,
|
|
||||||
CompatibilityMode: CompatibilityMode,
|
|
||||||
|
|
||||||
setBitMode: val => { BitMode = val; },
|
|
||||||
setShowInstructionHex: val => { ShowInstructionHex = val; },
|
|
||||||
setShowInstructionPos: val => { ShowInstructionPos = val; },
|
|
||||||
};
|
};
|
||||||
|
export function setShowInstructionHex (val) {
|
||||||
|
ShowInstructionHex = val;
|
||||||
|
};
|
||||||
|
export function setShowInstructionPos (val) {
|
||||||
|
ShowInstructionPos = val;
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue