mirror of
https://github.com/gchq/CyberChef
synced 2025-12-27 21:53:53 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7197a434c2 | ||
|
|
5349115b94 | ||
|
|
4274e8f3a2 | ||
|
|
7610e159a3 | ||
|
|
9ec94434bb | ||
|
|
3f57711c39 | ||
|
|
dc46018757 | ||
|
|
1464e5d5e4 | ||
|
|
95f7ed0de4 | ||
|
|
6e7240026a | ||
|
|
8bae7bf809 | ||
|
|
b78bb2d3d6 | ||
|
|
f9a6402825 | ||
|
|
8ec5f3cb18 | ||
|
|
c330394ff2 | ||
|
|
36e66ad5b4 | ||
|
|
ed542582f9 | ||
|
|
2574a63975 | ||
|
|
b7a978505f | ||
|
|
1dbcd2ac84 | ||
|
|
a7cdb095d2 |
2985
package-lock.json
generated
2985
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
73
package.json
73
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.38.2",
|
||||
"version": "9.38.8",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -39,26 +39,27 @@
|
||||
"node >= 16"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.8",
|
||||
"@babel/eslint-parser": "^7.17.0",
|
||||
"@babel/plugin-syntax-import-assertions": "^7.16.7",
|
||||
"@babel/plugin-transform-runtime": "^7.17.0",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/runtime": "^7.17.8",
|
||||
"autoprefixer": "^10.4.4",
|
||||
"babel-loader": "^8.2.4",
|
||||
"@babel/core": "^7.18.2",
|
||||
"@babel/eslint-parser": "^7.18.2",
|
||||
"@babel/plugin-syntax-import-assertions": "^7.17.12",
|
||||
"@babel/plugin-transform-runtime": "^7.18.2",
|
||||
"@babel/preset-env": "^7.18.2",
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"babel-loader": "^8.2.5",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||
"chromedriver": "^101.0.0",
|
||||
"cli-progress": "^3.10.0",
|
||||
"cli-progress": "^3.11.1",
|
||||
"colors": "^1.4.0",
|
||||
"copy-webpack-plugin": "^10.2.4",
|
||||
"core-js": "^3.21.1",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"core-js": "^3.22.8",
|
||||
"css-loader": "6.7.1",
|
||||
"eslint": "^8.12.0",
|
||||
"grunt": "^1.4.1",
|
||||
"eslint": "^8.16.0",
|
||||
"grunt": "^1.5.3",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-concurrent": "^3.0.0",
|
||||
"grunt-contrib-clean": "~2.0.0",
|
||||
"grunt-contrib-clean": "~2.0.1",
|
||||
"grunt-contrib-connect": "^3.0.0",
|
||||
"grunt-contrib-copy": "~1.0.0",
|
||||
"grunt-contrib-watch": "^1.1.0",
|
||||
@@ -67,29 +68,28 @@
|
||||
"grunt-webpack": "^5.0.0",
|
||||
"grunt-zip": "^0.18.2",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"imports-loader": "^3.1.1",
|
||||
"imports-loader": "^4.0.0",
|
||||
"mini-css-extract-plugin": "2.6.0",
|
||||
"modify-source-webpack-plugin": "^3.0.0",
|
||||
"nightwatch": "^2.0.10",
|
||||
"postcss": "^8.4.12",
|
||||
"nightwatch": "^2.1.7",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-css-variables": "^0.18.0",
|
||||
"postcss-import": "^14.1.0",
|
||||
"postcss-loader": "^6.2.1",
|
||||
"prompt": "^1.2.2",
|
||||
"sass-loader": "^12.6.0",
|
||||
"postcss-loader": "^7.0.0",
|
||||
"prompt": "^1.3.0",
|
||||
"sass-loader": "^13.0.0",
|
||||
"sitemap": "^7.1.1",
|
||||
"terser": "^5.12.1",
|
||||
"webpack": "^5.70.0",
|
||||
"terser": "^5.14.0",
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
"webpack-dev-server": "4.7.4",
|
||||
"webpack-dev-server": "4.9.1",
|
||||
"webpack-node-externals": "^3.0.0",
|
||||
"worker-loader": "^3.0.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"arrive": "^2.4.1",
|
||||
"avsc": "^5.7.3",
|
||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||
"avsc": "^5.7.4",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"bignumber.js": "^9.0.2",
|
||||
"blakejs": "^1.2.1",
|
||||
@@ -97,7 +97,7 @@
|
||||
"bootstrap-colorpicker": "^3.4.0",
|
||||
"bootstrap-material-design": "^4.1.3",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"bson": "^4.6.2",
|
||||
"bson": "^4.6.4",
|
||||
"buffer": "^6.0.3",
|
||||
"cbor": "8.1.0",
|
||||
"chi-squared": "^1.1.0",
|
||||
@@ -106,9 +106,9 @@
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"ctph.js": "0.0.5",
|
||||
"d3": "7.3.0",
|
||||
"d3": "7.4.4",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
"diff": "^5.0.0",
|
||||
"diff": "^5.1.0",
|
||||
"es6-promisify": "^7.0.0",
|
||||
"escodegen": "^2.0.0",
|
||||
"esprima": "^4.0.1",
|
||||
@@ -116,37 +116,38 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"flat": "^5.0.2",
|
||||
"geodesy": "1.1.3",
|
||||
"highlight.js": "^11.5.0",
|
||||
"highlight.js": "^11.5.1",
|
||||
"jimp": "^0.16.1",
|
||||
"jquery": "3.6.0",
|
||||
"js-crc": "^0.2.0",
|
||||
"js-sha3": "^0.8.0",
|
||||
"jsesc": "^3.0.2",
|
||||
"json5": "^2.2.1",
|
||||
"jsonpath": "^1.1.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsqr": "^1.4.0",
|
||||
"jsrsasign": "^10.5.14",
|
||||
"jsrsasign": "^10.5.23",
|
||||
"kbpgp": "2.1.15",
|
||||
"libbzip2-wasm": "0.0.4",
|
||||
"libyara-wasm": "^1.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"loglevel": "^1.8.0",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"markdown-it": "^12.3.2",
|
||||
"moment": "^2.29.1",
|
||||
"markdown-it": "^13.0.1",
|
||||
"moment": "^2.29.3",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"ngeohash": "^0.6.3",
|
||||
"node-forge": "^1.3.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-md6": "^0.1.0",
|
||||
"node-sass": "^7.0.1",
|
||||
"nodom": "^2.4.0",
|
||||
"notepack.io": "^2.3.0",
|
||||
"notepack.io": "^3.0.1",
|
||||
"nwmatcher": "^1.4.4",
|
||||
"otp": "0.1.3",
|
||||
"path": "^0.12.7",
|
||||
"popper.js": "^1.16.1",
|
||||
"process": "^0.11.10",
|
||||
"protobufjs": "^6.11.2",
|
||||
"protobufjs": "^6.11.3",
|
||||
"qr-image": "^3.2.0",
|
||||
"scryptsy": "^2.1.0",
|
||||
"snackbarjs": "^1.1.0",
|
||||
|
||||
@@ -82,15 +82,46 @@ export function toBase64(data, alphabet="A-Za-z0-9+/=") {
|
||||
* // returns [72, 101, 108, 108, 111]
|
||||
* fromBase64("SGVsbG8=", null, "byteArray");
|
||||
*/
|
||||
export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
|
||||
export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true, strictMode=false) {
|
||||
if (!data) {
|
||||
return returnType === "string" ? "" : [];
|
||||
}
|
||||
|
||||
alphabet = alphabet || "A-Za-z0-9+/=";
|
||||
alphabet = Utils.expandAlphRange(alphabet).join("");
|
||||
|
||||
// Confirm alphabet is a valid length
|
||||
if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding
|
||||
throw new OperationError(`Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}`);
|
||||
throw new OperationError(`Error: Base64 alphabet should be 64 characters long, or 65 with a padding character. Found ${alphabet.length}: ${alphabet}`);
|
||||
}
|
||||
|
||||
// Remove non-alphabet characters
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
data = data.replace(re, "");
|
||||
}
|
||||
|
||||
if (strictMode) {
|
||||
// Check for incorrect lengths (even without padding)
|
||||
if (data.length % 4 === 1) {
|
||||
throw new OperationError(`Error: Invalid Base64 input length (${data.length}). Cannot be 4n+1, even without padding chars.`);
|
||||
}
|
||||
|
||||
if (alphabet.length === 65) { // Padding character included
|
||||
const pad = alphabet.charAt(64);
|
||||
const padPos = data.indexOf(pad);
|
||||
if (padPos >= 0) {
|
||||
// Check that the padding character is only used at the end and maximum of twice
|
||||
if (padPos < data.length - 2 || data.charAt(data.length - 1) !== pad) {
|
||||
throw new OperationError(`Error: Base64 padding character (${pad}) not used in the correct place.`);
|
||||
}
|
||||
|
||||
// Check that input is padded to the correct length
|
||||
if (data.length % 4 !== 0) {
|
||||
throw new OperationError("Error: Base64 not padded to a multiple of 4.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const output = [];
|
||||
@@ -98,31 +129,28 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r
|
||||
enc1, enc2, enc3, enc4,
|
||||
i = 0;
|
||||
|
||||
if (removeNonAlphChars) {
|
||||
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
||||
data = data.replace(re, "");
|
||||
}
|
||||
|
||||
while (i < data.length) {
|
||||
enc1 = alphabet.indexOf(data.charAt(i++));
|
||||
enc2 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
enc3 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
enc4 = alphabet.indexOf(data.charAt(i++) || "=");
|
||||
// Including `|| null` forces empty strings to null so that indexOf returns -1 instead of 0
|
||||
enc1 = alphabet.indexOf(data.charAt(i++) || null);
|
||||
enc2 = alphabet.indexOf(data.charAt(i++) || null);
|
||||
enc3 = alphabet.indexOf(data.charAt(i++) || null);
|
||||
enc4 = alphabet.indexOf(data.charAt(i++) || null);
|
||||
|
||||
enc2 = enc2 === -1 ? 64 : enc2;
|
||||
enc3 = enc3 === -1 ? 64 : enc3;
|
||||
enc4 = enc4 === -1 ? 64 : enc4;
|
||||
if (strictMode && (enc1 < 0 || enc2 < 0 || enc3 < 0 || enc4 < 0)) {
|
||||
throw new OperationError("Error: Base64 input contains non-alphabet char(s)");
|
||||
}
|
||||
|
||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
output.push(chr1);
|
||||
|
||||
if (enc3 !== 64) {
|
||||
if (chr1 >= 0 && chr1 < 256) {
|
||||
output.push(chr1);
|
||||
}
|
||||
if (chr2 >= 0 && chr2 < 256 && enc3 !== 64) {
|
||||
output.push(chr2);
|
||||
}
|
||||
if (enc4 !== 64) {
|
||||
if (chr3 >= 0 && chr3 < 256 && enc4 !== 64) {
|
||||
output.push(chr3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,31 +19,33 @@ import OperationError from "../errors/OperationError.mjs";
|
||||
* @returns {string}
|
||||
*
|
||||
* @example
|
||||
* // returns "00010000 00100000 00110000"
|
||||
* // returns "00001010 00010100 00011110"
|
||||
* toBinary([10,20,30]);
|
||||
*
|
||||
* // returns "00010000 00100000 00110000"
|
||||
* toBinary([10,20,30], ":");
|
||||
* // returns "00001010:00010100:00011110"
|
||||
* toBinary([10,20,30], "Colon");
|
||||
*
|
||||
* // returns "1010:10100:11110"
|
||||
* toBinary([10,20,30], "Colon", 0);
|
||||
*/
|
||||
export function toBinary(data, delim="Space", padding=8) {
|
||||
if (data === undefined || data === null)
|
||||
throw new OperationError("Unable to convert to binary: Empty input data enocuntered");
|
||||
|
||||
delim = Utils.charRep(delim);
|
||||
let output = "";
|
||||
|
||||
if (data.length) { // array
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output += data[i].toString(2).padStart(padding, "0") + delim;
|
||||
output += data[i].toString(2).padStart(padding, "0");
|
||||
if (i !== data.length - 1) output += delim;
|
||||
}
|
||||
} else if (typeof data === "number") { // Single value
|
||||
return data.toString(2).padStart(padding, "0");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (delim.length) {
|
||||
return output.slice(0, -delim.length);
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,10 +59,10 @@ export function toBinary(data, delim="Space", padding=8) {
|
||||
*
|
||||
* @example
|
||||
* // returns [10,20,30]
|
||||
* fromBinary("00010000 00100000 00110000");
|
||||
* fromBinary("00001010 00010100 00011110");
|
||||
*
|
||||
* // returns [10,20,30]
|
||||
* fromBinary("00010000:00100000:00110000", "Colon");
|
||||
* fromBinary("00001010:00010100:00011110", "Colon");
|
||||
*/
|
||||
export function fromBinary(data, delim="Space", byteLen=8) {
|
||||
if (byteLen < 1 || Math.round(byteLen) !== byteLen)
|
||||
|
||||
@@ -34,93 +34,98 @@ class FromBase64 extends Operation {
|
||||
name: "Remove non-alphabet chars",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "Strict mode",
|
||||
type: "boolean",
|
||||
value: false
|
||||
}
|
||||
];
|
||||
this.checks = [
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9+/=", true]
|
||||
args: ["A-Za-z0-9+/=", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*[A-Z\\d\\-_]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9-_", true]
|
||||
args: ["A-Za-z0-9-_", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9+\\-=", true]
|
||||
args: ["A-Za-z0-9+\\-=", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["./0-9A-Za-z=", true]
|
||||
args: ["./0-9A-Za-z=", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*[A-Z\\d_.]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9_.", true]
|
||||
args: ["A-Za-z0-9_.", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["A-Za-z0-9._-", true]
|
||||
args: ["A-Za-z0-9._-", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["0-9a-zA-Z+/=", true]
|
||||
args: ["0-9a-zA-Z+/=", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["0-9A-Za-z+/=", true]
|
||||
args: ["0-9A-Za-z+/=", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$",
|
||||
flags: "",
|
||||
args: [" -_", false]
|
||||
args: [" -_", false, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*[A-Z\\d+\\-]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["+\\-0-9A-Za-z", true]
|
||||
args: ["+\\-0-9A-Za-z", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}\\s*$",
|
||||
flags: "",
|
||||
args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", true]
|
||||
args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["N-ZA-Mn-za-m0-9+/=", true]
|
||||
args: ["N-ZA-Mn-za-m0-9+/=", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*[A-Z\\d./]{20,}\\s*$",
|
||||
flags: "i",
|
||||
args: ["./0-9A-Za-z", true]
|
||||
args: ["./0-9A-Za-z", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z=\\d\\+/]{4}){5,}(?:[A-Z=\\d\\+/]{2}CC|[A-Z=\\d\\+/]{3}C)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC", true]
|
||||
args: ["/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z=\\d\\+/]{4}){5,}(?:[A-Z=\\d\\+/]{2}55|[A-Z=\\d\\+/]{3}5)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5", true]
|
||||
args: ["3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z=\\d\\+/]{4}){5,}(?:[A-Z=\\d\\+/]{2}22|[A-Z=\\d\\+/]{3}2)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2", true]
|
||||
args: ["ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2", true, false]
|
||||
},
|
||||
{
|
||||
pattern: "^\\s*(?:[A-Z=\\d\\+/]{4}){5,}(?:[A-Z=\\d\\+/]{2}55|[A-Z=\\d\\+/]{3}5)?\\s*$",
|
||||
flags: "i",
|
||||
args: ["HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5", true]
|
||||
args: ["HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5", true, false]
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -131,9 +136,9 @@ class FromBase64 extends Operation {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [alphabet, removeNonAlphChars] = args;
|
||||
const [alphabet, removeNonAlphChars, strictMode] = args;
|
||||
|
||||
return fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
|
||||
return fromBase64(input, alphabet, "byteArray", removeNonAlphChars, strictMode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import vkbeautify from "vkbeautify";
|
||||
import JSON5 from "json5";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
|
||||
/**
|
||||
* JSON Beautify operation
|
||||
@@ -21,19 +23,25 @@ class JSONBeautify extends Operation {
|
||||
|
||||
this.name = "JSON Beautify";
|
||||
this.module = "Code";
|
||||
this.description = "Indents and prettifies JavaScript Object Notation (JSON) code.";
|
||||
this.description = "Indents and pretty prints JavaScript Object Notation (JSON) code.<br><br>Tags: json viewer, prettify, syntax highlighting";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.presentType = "html";
|
||||
this.args = [
|
||||
{
|
||||
"name": "Indent string",
|
||||
"type": "binaryShortString",
|
||||
"value": " "
|
||||
name: "Indent string",
|
||||
type: "binaryShortString",
|
||||
value: " "
|
||||
},
|
||||
{
|
||||
"name": "Sort Object Keys",
|
||||
"type": "boolean",
|
||||
"value": false
|
||||
name: "Sort Object Keys",
|
||||
type: "boolean",
|
||||
value: false
|
||||
},
|
||||
{
|
||||
name: "Formatted",
|
||||
type: "boolean",
|
||||
value: true
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -44,35 +52,193 @@ class JSONBeautify extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [indentStr, sortBool] = args;
|
||||
|
||||
if (!input) return "";
|
||||
if (sortBool) {
|
||||
input = JSON.stringify(JSONBeautify._sort(JSON.parse(input)));
|
||||
|
||||
const [indentStr, sortBool] = args;
|
||||
let json = null;
|
||||
|
||||
try {
|
||||
json = JSON5.parse(input);
|
||||
} catch (err) {
|
||||
throw new OperationError("Unable to parse input as JSON.\n" + err);
|
||||
}
|
||||
return vkbeautify.json(input, indentStr);
|
||||
|
||||
if (sortBool) json = sortKeys(json);
|
||||
|
||||
return JSON.stringify(json, null, indentStr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort JSON representation of an object
|
||||
* Adds various dynamic features to the JSON blob
|
||||
*
|
||||
* @author Phillip Nordwall [phillip.nordwall@gmail.com]
|
||||
* @private
|
||||
* @param {object} o
|
||||
* @returns {object}
|
||||
* @param {string} data
|
||||
* @param {Object[]} args
|
||||
* @returns {html}
|
||||
*/
|
||||
static _sort(o) {
|
||||
if (Array.isArray(o)) {
|
||||
return o.map(JSONBeautify._sort);
|
||||
} else if ("[object Object]" === Object.prototype.toString.call(o)) {
|
||||
return Object.keys(o).sort().reduce(function(a, k) {
|
||||
a[k] = JSONBeautify._sort(o[k]);
|
||||
return a;
|
||||
}, {});
|
||||
present(data, args) {
|
||||
const formatted = args[2];
|
||||
if (!formatted) return Utils.escapeHtml(data);
|
||||
|
||||
const json = JSON5.parse(data);
|
||||
const options = {
|
||||
withLinks: true,
|
||||
bigNumbers: true
|
||||
};
|
||||
let html = '<div class="json-document">';
|
||||
|
||||
if (isCollapsable(json)) {
|
||||
const isArr = json instanceof Array;
|
||||
html += '<details open class="json-details">' +
|
||||
`<summary class="json-summary ${isArr ? "json-arr" : "json-obj"}"></summary>` +
|
||||
json2html(json, options) +
|
||||
"</details>";
|
||||
} else {
|
||||
html += json2html(json, options);
|
||||
}
|
||||
return o;
|
||||
|
||||
html += "</div>";
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort keys in a JSON object
|
||||
*
|
||||
* @author Phillip Nordwall [phillip.nordwall@gmail.com]
|
||||
* @param {object} o
|
||||
* @returns {object}
|
||||
*/
|
||||
function sortKeys(o) {
|
||||
if (Array.isArray(o)) {
|
||||
return o.map(sortKeys);
|
||||
} else if ("[object Object]" === Object.prototype.toString.call(o)) {
|
||||
return Object.keys(o).sort().reduce(function(a, k) {
|
||||
a[k] = sortKeys(o[k]);
|
||||
return a;
|
||||
}, {});
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if arg is either an array with at least 1 element, or a dict with at least 1 key
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isCollapsable(arg) {
|
||||
return arg instanceof Object && Object.keys(arg).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string looks like a URL, based on protocol
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isUrl(string) {
|
||||
const protocols = ["http", "https", "ftp", "ftps"];
|
||||
for (let i = 0; i < protocols.length; i++) {
|
||||
if (string.startsWith(protocols[i] + "://")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a json object into html representation
|
||||
*
|
||||
* Adapted for CyberChef by @n1474335 from jQuery json-viewer
|
||||
* @author Alexandre Bodelot <alexandre.bodelot@gmail.com>
|
||||
* @link https://github.com/abodelot/jquery.json-viewer
|
||||
* @license MIT
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
function json2html(json, options) {
|
||||
let html = "";
|
||||
if (typeof json === "string") {
|
||||
// Escape tags and quotes
|
||||
json = Utils.escapeHtml(json);
|
||||
|
||||
if (options.withLinks && isUrl(json)) {
|
||||
html += `<a href="${json}" class="json-string" target="_blank">${json}</a>`;
|
||||
} else {
|
||||
// Escape double quotes in the rendered non-URL string.
|
||||
json = json.replace(/"/g, "\\"");
|
||||
html += `<span class="json-string">"${json}"</span>`;
|
||||
}
|
||||
} else if (typeof json === "number" || typeof json === "bigint") {
|
||||
html += `<span class="json-literal">${json}</span>`;
|
||||
} else if (typeof json === "boolean") {
|
||||
html += `<span class="json-literal">${json}</span>`;
|
||||
} else if (json === null) {
|
||||
html += '<span class="json-literal">null</span>';
|
||||
} else if (json instanceof Array) {
|
||||
if (json.length > 0) {
|
||||
html += '<span class="json-bracket">[</span><ol class="json-array">';
|
||||
for (let i = 0; i < json.length; i++) {
|
||||
html += "<li>";
|
||||
|
||||
// Add toggle button if item is collapsable
|
||||
if (isCollapsable(json[i])) {
|
||||
const isArr = json[i] instanceof Array;
|
||||
html += '<details open class="json-details">' +
|
||||
`<summary class="json-summary ${isArr ? "json-arr" : "json-obj"}"></summary>` +
|
||||
json2html(json[i], options) +
|
||||
"</details>";
|
||||
} else {
|
||||
html += json2html(json[i], options);
|
||||
}
|
||||
|
||||
// Add comma if item is not last
|
||||
if (i < json.length - 1) {
|
||||
html += '<span class="json-comma">,</span>';
|
||||
}
|
||||
html += "</li>";
|
||||
}
|
||||
html += '</ol><span class="json-bracket">]</span>';
|
||||
} else {
|
||||
html += '<span class="json-bracket">[]</span>';
|
||||
}
|
||||
} else if (typeof json === "object") {
|
||||
// Optional support different libraries for big numbers
|
||||
// json.isLosslessNumber: package lossless-json
|
||||
// json.toExponential(): packages bignumber.js, big.js, decimal.js, decimal.js-light, others?
|
||||
if (options.bigNumbers && (typeof json.toExponential === "function" || json.isLosslessNumber)) {
|
||||
html += `<span class="json-literal">${json.toString()}</span>`;
|
||||
} else {
|
||||
let keyCount = Object.keys(json).length;
|
||||
if (keyCount > 0) {
|
||||
html += '<span class="json-brace">{</span><ul class="json-dict">';
|
||||
for (const key in json) {
|
||||
if (Object.prototype.hasOwnProperty.call(json, key)) {
|
||||
const safeKey = Utils.escapeHtml(key);
|
||||
html += "<li>";
|
||||
|
||||
// Add toggle button if item is collapsable
|
||||
if (isCollapsable(json[key])) {
|
||||
const isArr = json[key] instanceof Array;
|
||||
html += '<details open class="json-details">' +
|
||||
`<summary class="json-summary ${isArr ? "json-arr" : "json-obj"}">${safeKey}<span class="json-colon">:</span> </summary>` +
|
||||
json2html(json[key], options) +
|
||||
"</details>";
|
||||
} else {
|
||||
html += safeKey + '<span class="json-colon">:</span> ' + json2html(json[key], options);
|
||||
}
|
||||
|
||||
// Add comma if item is not last
|
||||
if (--keyCount > 0) {
|
||||
html += '<span class="json-comma">,</span>';
|
||||
}
|
||||
html += "</li>";
|
||||
}
|
||||
}
|
||||
html += '</ul><span class="json-brace">}</span>';
|
||||
} else {
|
||||
html += '<span class="json-brace">{}</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
export default JSONBeautify;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @author cplussharp
|
||||
* @copyright Crown Copyright 2016
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import r from "jsrsasign";
|
||||
import { fromBase64 } from "../lib/Base64.mjs";
|
||||
import { toHexFast } from "../lib/Hex.mjs";
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* PEM to Hex operation
|
||||
@@ -19,12 +22,18 @@ class PEMToHex extends Operation {
|
||||
super();
|
||||
|
||||
this.name = "PEM to Hex";
|
||||
this.module = "PublicKey";
|
||||
this.module = "Default";
|
||||
this.description = "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/X.690#DER_encoding";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Privacy-Enhanced_Mail#Format";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [];
|
||||
this.checks = [
|
||||
{
|
||||
"pattern": "----BEGIN ([A-Z][A-Z ]+[A-Z])-----",
|
||||
"args": []
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,17 +42,25 @@ class PEMToHex extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (input.indexOf("-----BEGIN") < 0) {
|
||||
// Add header so that the KEYUTIL function works
|
||||
input = "-----BEGIN CERTIFICATE-----" + input;
|
||||
const output = [];
|
||||
let match;
|
||||
const regex = /-----BEGIN ([A-Z][A-Z ]+[A-Z])-----/g;
|
||||
while ((match = regex.exec(input)) !== null) {
|
||||
// find corresponding end tag
|
||||
const indexBase64 = match.index + match[0].length;
|
||||
const footer = `-----END ${match[1]}-----`;
|
||||
const indexFooter = input.indexOf(footer, indexBase64);
|
||||
if (indexFooter === -1) {
|
||||
throw new OperationError(`PEM footer '${footer}' not found`);
|
||||
}
|
||||
|
||||
// decode base64 content
|
||||
const base64 = input.substring(indexBase64, indexFooter);
|
||||
const bytes = fromBase64(base64, "A-Za-z0-9+/=", "byteArray", true);
|
||||
const hex = toHexFast(bytes);
|
||||
output.push(hex);
|
||||
}
|
||||
if (input.indexOf("-----END") < 0) {
|
||||
// Add footer so that the KEYUTIL function works
|
||||
input = input + "-----END CERTIFICATE-----";
|
||||
}
|
||||
const cert = new r.X509();
|
||||
cert.readCertPEM(input);
|
||||
return cert.hex;
|
||||
return output.join("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* To Upper case operation
|
||||
@@ -37,25 +38,30 @@ class ToUpperCase extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
if (!args || args.length === 0) {
|
||||
throw new OperationError("No capitalization scope was provided.");
|
||||
}
|
||||
|
||||
const scope = args[0];
|
||||
|
||||
switch (scope) {
|
||||
case "Word":
|
||||
return input.replace(/(\b\w)/gi, function(m) {
|
||||
return m.toUpperCase();
|
||||
});
|
||||
case "Sentence":
|
||||
return input.replace(/(?:\.|^)\s*(\b\w)/gi, function(m) {
|
||||
return m.toUpperCase();
|
||||
});
|
||||
case "Paragraph":
|
||||
return input.replace(/(?:\n|^)\s*(\b\w)/gi, function(m) {
|
||||
return m.toUpperCase();
|
||||
});
|
||||
case "All": /* falls through */
|
||||
default:
|
||||
return input.toUpperCase();
|
||||
if (scope === "All") {
|
||||
return input.toUpperCase();
|
||||
}
|
||||
|
||||
const scopeRegex = {
|
||||
"Word": /(\b\w)/gi,
|
||||
"Sentence": /(?:\.|^)\s*(\b\w)/gi,
|
||||
"Paragraph": /(?:\n|^)\s*(\b\w)/gi
|
||||
}[scope];
|
||||
|
||||
if (scopeRegex === undefined) {
|
||||
throw new OperationError("Unrecognized capitalization scope");
|
||||
}
|
||||
|
||||
// Use the regex to capitalize the input
|
||||
return input.replace(scopeRegex, function(m) {
|
||||
return m.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,3 +34,6 @@
|
||||
@import "./layout/_operations.css";
|
||||
@import "./layout/_recipe.css";
|
||||
@import "./layout/_structure.css";
|
||||
|
||||
/* Operations */
|
||||
@import "./operations/json.css";
|
||||
|
||||
78
src/web/stylesheets/operations/json.css
Normal file
78
src/web/stylesheets/operations/json.css
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* JSON styles
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2022
|
||||
* @license Apache-2.0
|
||||
*
|
||||
* Adapted for CyberChef by @n1474335 from jQuery json-viewer
|
||||
* @author Alexandre Bodelot <alexandre.bodelot@gmail.com>
|
||||
* @link https://github.com/abodelot/jquery.json-viewer
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/* Root element */
|
||||
.json-document {
|
||||
padding: .5em 1.5em;
|
||||
}
|
||||
|
||||
/* Syntax highlighting for JSON objects */
|
||||
ul.json-dict, ol.json-array {
|
||||
list-style-type: none;
|
||||
margin: 0 0 0 1px;
|
||||
border-left: 1px dotted #ccc;
|
||||
padding-left: 2em;
|
||||
}
|
||||
.json-string {
|
||||
color: green;
|
||||
}
|
||||
.json-literal {
|
||||
color: red;
|
||||
}
|
||||
.json-brace,
|
||||
.json-bracket,
|
||||
.json-colon,
|
||||
.json-comma {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
/* Collapse */
|
||||
.json-details {
|
||||
display: inline;
|
||||
}
|
||||
.json-details[open] {
|
||||
display: contents;
|
||||
}
|
||||
.json-summary {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
/* Display object and array brackets when closed */
|
||||
.json-summary.json-obj::after {
|
||||
color: gray;
|
||||
content: "{ ... }"
|
||||
}
|
||||
.json-summary.json-arr::after {
|
||||
color: gray;
|
||||
content: "[ ... ]"
|
||||
}
|
||||
.json-details[open] > .json-summary.json-obj::after,
|
||||
.json-details[open] > .json-summary.json-arr::after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Show arrows, even in inline mode */
|
||||
.json-summary::before {
|
||||
content: "\25BC";
|
||||
color: #c0c0c0;
|
||||
margin-left: -12px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.json-summary:hover::before {
|
||||
color: #aaa;
|
||||
}
|
||||
.json-details[open] > .json-summary::before {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
@@ -67,6 +67,7 @@ import "./tests/PGP.mjs";
|
||||
import "./tests/PHP.mjs";
|
||||
import "./tests/ParseIPRange.mjs";
|
||||
import "./tests/ParseQRCode.mjs";
|
||||
import "./tests/PEMtoHex.mjs";
|
||||
import "./tests/PowerSet.mjs";
|
||||
import "./tests/Regex.mjs";
|
||||
import "./tests/Register.mjs";
|
||||
|
||||
@@ -16,7 +16,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -27,7 +27,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -38,8 +38,12 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
{
|
||||
op: "HTML To Text",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -49,7 +53,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -60,7 +64,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -71,7 +75,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -82,7 +86,7 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: ["\t", false],
|
||||
args: ["\t", false, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -93,8 +97,12 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: [" ", false],
|
||||
args: [" ", false, false],
|
||||
},
|
||||
{
|
||||
op: "HTML To Text",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -104,8 +112,12 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: ["\t", false],
|
||||
args: ["\t", false, false],
|
||||
},
|
||||
{
|
||||
op: "HTML To Text",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -115,8 +127,12 @@ TestRegister.addTests([
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JSON Beautify",
|
||||
args: ["\t", true],
|
||||
args: ["\t", true, false],
|
||||
},
|
||||
{
|
||||
op: "HTML To Text",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -68,7 +68,7 @@ TestRegister.addTests([
|
||||
{
|
||||
name: "Magic Chain: Base64",
|
||||
input: "WkVkV2VtUkRRbnBrU0Vwd1ltMWpQUT09",
|
||||
expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Base64\('A-Za-z0-9\+\/=',true\)/,
|
||||
expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true,false\)\nFrom_Base64\('A-Za-z0-9\+\/=',true,false\)\nFrom_Base64\('A-Za-z0-9\+\/=',true,false\)/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Magic",
|
||||
@@ -79,7 +79,7 @@ TestRegister.addTests([
|
||||
{
|
||||
name: "Magic Chain: Hex -> Hexdump -> Base64",
|
||||
input: "MDAwMDAwMDAgIDM3IDM0IDIwIDM2IDM1IDIwIDM3IDMzIDIwIDM3IDM0IDIwIDMyIDMwIDIwIDM3ICB8NzQgNjUgNzMgNzQgMjAgN3wKMDAwMDAwMTAgIDMzIDIwIDM3IDM0IDIwIDM3IDMyIDIwIDM2IDM5IDIwIDM2IDY1IDIwIDM2IDM3ICB8MyA3NCA3MiA2OSA2ZSA2N3w=",
|
||||
expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true\)\nFrom_Hexdump\(\)\nFrom_Hex\('Space'\)/,
|
||||
expectedMatch: /From_Base64\('A-Za-z0-9\+\/=',true,false\)\nFrom_Hexdump\(\)\nFrom_Hex\('Space'\)/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Magic",
|
||||
|
||||
294
tests/operations/tests/PEMtoHex.mjs
Normal file
294
tests/operations/tests/PEMtoHex.mjs
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* Test PEMtoHex with different inputs
|
||||
*
|
||||
* @author cplussharp
|
||||
*
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
/** RSA 2048bit key pair as PKCS1 and PKCS8 and as certificate */
|
||||
const PEMS_RSA_PRIVATE_KEY_PKCS1 = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA5WykLKHiBAhmZh5WhocgpQQqZjdrApuRxRT21SJZx6Ce+Oz2
|
||||
V17/heozu5LEz63jCxW1NrBckzl/Ys8p9LeqYTu6x/LbKloTjfEWxlzXnzUSqn9J
|
||||
HIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDhe2KnMGVDDg6kfCLokDdLo256LeQ4
|
||||
CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE3I8sSAzgoLMBamQ5m3MbiULAYtxs
|
||||
kCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8vkzxLwe3t5Y4XgHL9TYQm1+BDnin
|
||||
upIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz+wIDAQABAoIBACQu3jWr0lmQeZXh
|
||||
cwQEi8F6xrUYSGhA4NyUUdmLcV1ql6fqt29QLDySk1Yh76hRZF17LvlRF0ig6NZM
|
||||
lfFihhyPrwWZ57bmPe9E9rKSMe+KD0eUi5NVEVk/BmJpzxwZSfRC6NTDz8Zjp7po
|
||||
FUwGkYlEJdocHlc5N/fcCZG1Jti/Z1AsZIjO6r6S0O7neC7icECBKHUyWa8/yE1N
|
||||
++TVyMV+z53Ad1PC+SHMGDlbqJAM3o4wAzD/FAIzyVo6GSnnC+bFdgMtIwtwgYTH
|
||||
rbr8M8j5fqAHTqNJeblqt/5KHEj2VVsIsHIuQ6lv4llESEqmH+N5KE4O33U7/Wmj
|
||||
y/+VGAECgYEA9ysROHXOx1ofh3tI/r2C2FUan6/AAe4dc+8E4jMGI5T4xeqYHTRV
|
||||
l1yS+ZKIxqclIoAmd6SJ7Nx2GdQ55MmokZdZRqsFN1flFOZw2kFH/I0zQZXdOjF+
|
||||
sf5Lu0FfcTw3VJhJ/YU3CVdlgdP4ekHbaJVFW5i/pTUf5vNs6AGBGxsCgYEA7Z9D
|
||||
0qnF6GhxA8lJfwnyuktYnwIQoXE6Xp26/NZD7t7HzxHDf43LQxmTk+mDP/yIQHwb
|
||||
xIx2NE/ncNxlUMl/g1PkJbKVkB8tdIZrLyiT4lebeqgT72Q07IsxRl/GHOr7CfN0
|
||||
61OBRCe44IlOtaNAZk4zWwuAwAYx+G8ifuOJ+KECgYBP5NvsJChyx+7pHDC8JwXk
|
||||
Z53zgBvQg+eBUgGCHHwfhEflsa75wbDo/EOF6JfNnrmiLUpB4i2zIpAKSU9tZMHY
|
||||
TdPNw/orqX2jA9n2sqNSP1ISIR8hcF5Dqq9QGBGByLUZ4yAHksf3fQiSrrHi0ubZ
|
||||
J2cD9Jv+Cu4E+Sp61AGngQKBgHmuTPTbq1TP5s+hi9laJsnvO3pxfEKv0MwSyWYf
|
||||
8rmnq3oGBq6S1buOpVvhAC0MDFm5NB76Lq2rHUFWGyu7g2ik1PfY823SCVzaWJjV
|
||||
lqUZZ6zv1QWJsvBOdvUqpjC4w8TcvsqjAFb+YFXa+ktZRekdsn607UFn6r7laizA
|
||||
KC8BAoGAZty7sIGMt1gDaoIjySgOox8x7AlY3QUyNQC5N8KW3MZ8KLC5UBtjhqLy
|
||||
wYOJr+/1R/7ibiHrKkIE/dmg5QN1iS5tZmFvyLwJ+nHQZObFrlcKtpr+1lekQY/m
|
||||
ly6YJFk3yj2nhYzt8eVXBX2lCoLG1gsrbpXvUfIGJ53L9m1mVAo=
|
||||
-----END RSA PRIVATE KEY-----`;
|
||||
|
||||
const PEMS_RSA_PRIVATE_KEY_PKCS8 = `-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDlbKQsoeIECGZm
|
||||
HlaGhyClBCpmN2sCm5HFFPbVIlnHoJ747PZXXv+F6jO7ksTPreMLFbU2sFyTOX9i
|
||||
zyn0t6phO7rH8tsqWhON8RbGXNefNRKqf0kcjGaYlDONen1fUP31OP41alEYQiII
|
||||
UTsl8OF7YqcwZUMODqR8IuiQN0ujbnot5DgISRWLBjp35q3jEOUgfC9lmYbhKaTn
|
||||
p4eG9ATcjyxIDOCgswFqZDmbcxuJQsBi3GyQKkJ+MXGsvpmJpqPsdmid4XjRHfQo
|
||||
Ij3KAXy+TPEvB7e3ljheAcv1NhCbX4EOeKe6kgH/NN47XKAEYDrqbrOmaSa4bt3w
|
||||
dch25zP7AgMBAAECggEAJC7eNavSWZB5leFzBASLwXrGtRhIaEDg3JRR2YtxXWqX
|
||||
p+q3b1AsPJKTViHvqFFkXXsu+VEXSKDo1kyV8WKGHI+vBZnntuY970T2spIx74oP
|
||||
R5SLk1URWT8GYmnPHBlJ9ELo1MPPxmOnumgVTAaRiUQl2hweVzk399wJkbUm2L9n
|
||||
UCxkiM7qvpLQ7ud4LuJwQIEodTJZrz/ITU375NXIxX7PncB3U8L5IcwYOVuokAze
|
||||
jjADMP8UAjPJWjoZKecL5sV2Ay0jC3CBhMetuvwzyPl+oAdOo0l5uWq3/kocSPZV
|
||||
Wwiwci5DqW/iWURISqYf43koTg7fdTv9aaPL/5UYAQKBgQD3KxE4dc7HWh+He0j+
|
||||
vYLYVRqfr8AB7h1z7wTiMwYjlPjF6pgdNFWXXJL5kojGpyUigCZ3pIns3HYZ1Dnk
|
||||
yaiRl1lGqwU3V+UU5nDaQUf8jTNBld06MX6x/ku7QV9xPDdUmEn9hTcJV2WB0/h6
|
||||
QdtolUVbmL+lNR/m82zoAYEbGwKBgQDtn0PSqcXoaHEDyUl/CfK6S1ifAhChcTpe
|
||||
nbr81kPu3sfPEcN/jctDGZOT6YM//IhAfBvEjHY0T+dw3GVQyX+DU+QlspWQHy10
|
||||
hmsvKJPiV5t6qBPvZDTsizFGX8Yc6vsJ83TrU4FEJ7jgiU61o0BmTjNbC4DABjH4
|
||||
byJ+44n4oQKBgE/k2+wkKHLH7ukcMLwnBeRnnfOAG9CD54FSAYIcfB+ER+WxrvnB
|
||||
sOj8Q4Xol82euaItSkHiLbMikApJT21kwdhN083D+iupfaMD2fayo1I/UhIhHyFw
|
||||
XkOqr1AYEYHItRnjIAeSx/d9CJKuseLS5tknZwP0m/4K7gT5KnrUAaeBAoGAea5M
|
||||
9NurVM/mz6GL2Vomye87enF8Qq/QzBLJZh/yuaeregYGrpLVu46lW+EALQwMWbk0
|
||||
HvourasdQVYbK7uDaKTU99jzbdIJXNpYmNWWpRlnrO/VBYmy8E529SqmMLjDxNy+
|
||||
yqMAVv5gVdr6S1lF6R2yfrTtQWfqvuVqLMAoLwECgYBm3LuwgYy3WANqgiPJKA6j
|
||||
HzHsCVjdBTI1ALk3wpbcxnwosLlQG2OGovLBg4mv7/VH/uJuIesqQgT92aDlA3WJ
|
||||
Lm1mYW/IvAn6cdBk5sWuVwq2mv7WV6RBj+aXLpgkWTfKPaeFjO3x5VcFfaUKgsbW
|
||||
Cytule9R8gYnncv2bWZUCg==
|
||||
-----END PRIVATE KEY-----`;
|
||||
|
||||
const PEMS_RSA_PUBLIC_KEY_PKCS1 = `-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBCgKCAQEA5WykLKHiBAhmZh5WhocgpQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/
|
||||
heozu5LEz63jCxW1NrBckzl/Ys8p9LeqYTu6x/LbKloTjfEWxlzXnzUSqn9JHIxm
|
||||
mJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDhe2KnMGVDDg6kfCLokDdLo256LeQ4CEkV
|
||||
iwY6d+at4xDlIHwvZZmG4Smk56eHhvQE3I8sSAzgoLMBamQ5m3MbiULAYtxskCpC
|
||||
fjFxrL6Ziaaj7HZoneF40R30KCI9ygF8vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB
|
||||
/zTeO1ygBGA66m6zpmkmuG7d8HXIducz+wIDAQAB
|
||||
-----END RSA PUBLIC KEY-----`;
|
||||
|
||||
const PEMS_RSA_PUBLIC_KEY_PKCS8 = `-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5WykLKHiBAhmZh5Whocg
|
||||
pQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/heozu5LEz63jCxW1NrBckzl/Ys8p9Leq
|
||||
YTu6x/LbKloTjfEWxlzXnzUSqn9JHIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDh
|
||||
e2KnMGVDDg6kfCLokDdLo256LeQ4CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE
|
||||
3I8sSAzgoLMBamQ5m3MbiULAYtxskCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8
|
||||
vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz
|
||||
+wIDAQAB
|
||||
-----END PUBLIC KEY-----`;
|
||||
|
||||
const PEMS_RSA_CERT = `-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIUROs52CB3BsvEVLOCtALalnJG8tEwDQYJKoZIhvcNAQEL
|
||||
BQAwHTEbMBkGA1UEAwwSUlNBIDIwNDggUHVibGljS2V5MB4XDTIxMDQxMzIxMDE0
|
||||
OVoXDTMxMDQxMTIxMDE0OVowHTEbMBkGA1UEAwwSUlNBIDIwNDggUHVibGljS2V5
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5WykLKHiBAhmZh5Whocg
|
||||
pQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/heozu5LEz63jCxW1NrBckzl/Ys8p9Leq
|
||||
YTu6x/LbKloTjfEWxlzXnzUSqn9JHIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDh
|
||||
e2KnMGVDDg6kfCLokDdLo256LeQ4CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE
|
||||
3I8sSAzgoLMBamQ5m3MbiULAYtxskCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8
|
||||
vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz
|
||||
+wIDAQABo1MwUTAdBgNVHQ4EFgQUcRhRB6H5JqlDHbymwqydW2/EAt8wHwYDVR0j
|
||||
BBgwFoAUcRhRB6H5JqlDHbymwqydW2/EAt8wDwYDVR0TAQH/BAUwAwEB/zANBgkq
|
||||
hkiG9w0BAQsFAAOCAQEALXBmDizTp/Uz4M2A4nCl0AVclrXEk+YjAKqZnvtj44Gs
|
||||
CUcpxtcXu64ppsSYCwawvzIm6B2Mdmib422aInH0e0oNrn8cRzC144Hjnzxguamj
|
||||
LyZXnH/0wN9SAjqCKt++urH9wbRMIl0v+g4CWjGyY+eYkMmd1UMQvdCCCv6RVm56
|
||||
7dBCijJIHg23JbgPJD72JCluXtTYWllv3duSwuWeYHo5EftU456pDcztkgn9XwFk
|
||||
PFGnHLmbjpSzjE7u29qCjwHl3CiUsjfUlYFl/mf27oDXPqaWqPYv3fWH3H3ymiZQ
|
||||
cqptUF4hDtPkaNkKWFmlljChN92o8g/jrv4DVDgJzQ==
|
||||
-----END CERTIFICATE-----`;
|
||||
|
||||
/** EC P-256 key pair and certificate */
|
||||
const PEMS_EC_P256_PRIVATE_KEY = `-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIIhdQxQIcMnCHD3X4WqNv+VgycWmFoEZpRl9X0+dT9uHoAoGCCqGSM49
|
||||
AwEHoUQDQgAEFLQcBbzDweo6af4k3k0gKWMNWOZVn8+9hH2rv4DKKYZ7E1z64LBt
|
||||
PnB1gMz++HDKySr2ozD3/46dIbQMXUZKpw==
|
||||
-----END EC PRIVATE KEY-----`;
|
||||
|
||||
const PEMS_EC_P256_PRIVATE_KEY_PKCS8 = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiF1DFAhwycIcPdfh
|
||||
ao2/5WDJxaYWgRmlGX1fT51P24ehRANCAAQUtBwFvMPB6jpp/iTeTSApYw1Y5lWf
|
||||
z72Efau/gMophnsTXPrgsG0+cHWAzP74cMrJKvajMPf/jp0htAxdRkqn
|
||||
-----END PRIVATE KEY-----`;
|
||||
|
||||
const PEMS_EC_P256_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFLQcBbzDweo6af4k3k0gKWMNWOZV
|
||||
n8+9hH2rv4DKKYZ7E1z64LBtPnB1gMz++HDKySr2ozD3/46dIbQMXUZKpw==
|
||||
-----END PUBLIC KEY-----`;
|
||||
|
||||
const PEMS_FOO = `-----BEGIN FOO-----
|
||||
Rk9P
|
||||
-----END FOO-----`;
|
||||
const PEMS_BAR = `-----BEGIN BAR-----
|
||||
QkFS
|
||||
-----END BAR-----`;
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "PEMtoHex: Nothing",
|
||||
input: "",
|
||||
expectedOutput: "",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: No footer",
|
||||
input: PEMS_RSA_PRIVATE_KEY_PKCS1.substring(0, 200),
|
||||
expectedOutput: "PEM footer '-----END RSA PRIVATE KEY-----' not found",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: Multiple PEMs",
|
||||
input: PEMS_FOO + "\n" + PEMS_BAR,
|
||||
expectedOutput: "FOOBAR",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["Auto"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: Single line PEM",
|
||||
input: PEMS_FOO.replace(/(\n|\r)/gm, ""),
|
||||
expectedOutput: "FOO",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: EC P-256 Private Key",
|
||||
input: PEMS_EC_P256_PRIVATE_KEY,
|
||||
expectedOutput: "30770201010420885d43140870c9c21c3dd7e16a8dbfe560c9c5a6168119a5197d5f4f9d4fdb87a00a06082a8648ce3d030107a1440342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: EC P-256 Private Key PKCS8",
|
||||
input: PEMS_EC_P256_PRIVATE_KEY_PKCS8,
|
||||
expectedOutput: "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420885d43140870c9c21c3dd7e16a8dbfe560c9c5a6168119a5197d5f4f9d4fdb87a1440342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: EC P-256 Public Key",
|
||||
input: PEMS_EC_P256_PUBLIC_KEY,
|
||||
expectedOutput: "3059301306072a8648ce3d020106082a8648ce3d0301070342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: RSA Private Key PKCS1",
|
||||
input: PEMS_RSA_PRIVATE_KEY_PKCS1,
|
||||
expectedOutput: "fb49bd96ffc5d1351a35d773921fac03",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "MD5",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: RSA Private Key PKCS8",
|
||||
input: PEMS_RSA_PRIVATE_KEY_PKCS8,
|
||||
expectedOutput: "23086d03633689fee64680c3c24409eb",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "MD5",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: RSA Public Key PKCS1",
|
||||
input: PEMS_RSA_PUBLIC_KEY_PKCS1,
|
||||
expectedOutput: "5fc3f1f6c5d5806760b12eaad0c0292c",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "MD5",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: RSA Public Key PKCS8",
|
||||
input: PEMS_RSA_PUBLIC_KEY_PKCS8,
|
||||
expectedOutput: "30fbe8e9495d591232affebdd6206ea6",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "MD5",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "PEMtoHex: Certificate",
|
||||
input: PEMS_RSA_CERT,
|
||||
expectedOutput: "6694d8ca4a0ceb84c3951d25dc05ec6e",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "PEM to Hex",
|
||||
"args": []
|
||||
},
|
||||
{
|
||||
"op": "MD5",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
Reference in New Issue
Block a user