cyberchef 11.0.0 → 11.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +144 -0
- package/Dockerfile +2 -2
- package/Gruntfile.js +10 -5
- package/README.md +3 -1
- package/SECURITY.md +8 -18
- package/package.json +35 -34
- package/src/core/config/Categories.json +6 -0
- package/src/core/config/OperationConfig.json +140 -16
- package/src/core/config/modules/Default.mjs +8 -0
- package/src/core/config/modules/PGP.mjs +2 -0
- package/src/core/config/scripts/generateOpsIndex.mjs +63 -0
- package/src/core/config/scripts/newOperation.mjs +31 -4
- package/src/core/operations/AESDecrypt.mjs +61 -16
- package/src/core/operations/AESEncrypt.mjs +26 -11
- package/src/core/operations/BLAKE3.mjs +13 -7
- package/src/core/operations/BSONDeserialise.mjs +2 -2
- package/src/core/operations/BSONSerialise.mjs +3 -2
- package/src/core/operations/Bcrypt.mjs +1 -1
- package/src/core/operations/BcryptCompare.mjs +1 -1
- package/src/core/operations/DecodeText.mjs +4 -0
- package/src/core/operations/EncodeText.mjs +4 -0
- package/src/core/operations/EscapeSmartCharacters.mjs +129 -0
- package/src/core/operations/GenerateLoremIpsum.mjs +34 -3
- package/src/core/operations/GeneratePGPKeyPair.mjs +8 -7
- package/src/core/operations/PGPSign.mjs +83 -0
- package/src/core/operations/ParseEthernetFrame.mjs +1 -1
- package/src/core/operations/ParseIPv4Header.mjs +1 -1
- package/src/core/operations/ParseObjectIDTimestamp.mjs +2 -2
- package/src/core/operations/ParseUserAgent.mjs +1 -1
- package/src/core/operations/ROR13.mjs +83 -0
- package/src/core/operations/RemoveANSIEscapeCodes.mjs +41 -0
- package/src/core/operations/SeriesChart.mjs +16 -0
- package/src/core/operations/Wrap.mjs +47 -0
- package/src/core/operations/index.mjs +10 -0
- package/src/node/index.mjs +25 -0
- package/src/web/App.mjs +19 -1
- package/src/web/HTMLIngredient.mjs +1 -0
- package/src/web/html/index.html +3 -3
- package/src/web/static/sitemap.mjs +3 -3
- package/src/web/waiters/RecipeWaiter.mjs +9 -1
- package/tests/browser/02_ops.js +7 -7
- package/tests/browser/03_recipe_load.js +48 -0
- package/tests/browser/browserUtils.js +6 -3
- package/tests/node/index.mjs +1 -0
- package/tests/node/tests/PGP.mjs +69 -0
- package/tests/node/tests/operations.mjs +41 -2
- package/tests/operations/index.mjs +71 -66
- package/tests/operations/tests/BLAKE3.mjs +18 -0
- package/tests/operations/tests/CharEnc.mjs +26 -0
- package/tests/operations/tests/Charts.mjs +11 -0
- package/tests/operations/tests/Crypt.mjs +288 -62
- package/tests/operations/tests/EscapeSmartCharacters.mjs +132 -0
- package/tests/operations/tests/FlaskSession.mjs +11 -8
- package/tests/operations/tests/GenerateLoremIpsum.mjs +80 -0
- package/tests/operations/tests/IPv6Transition.mjs +4 -4
- package/tests/operations/tests/PGP.mjs +178 -154
- package/tests/operations/tests/ParseEthernetFrame.mjs +11 -0
- package/tests/operations/tests/ParseIPv4Header.mjs +23 -0
- package/tests/operations/tests/ParseX509CRL.mjs +16 -16
- package/tests/operations/tests/ROR13.mjs +45 -0
- package/tests/operations/tests/Register.mjs +3 -1
- package/tests/operations/tests/RemoveANSIEscapeCodes.mjs +62 -0
- package/tests/operations/tests/Wrap.mjs +44 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author 0xff1ce [github.com/0xff1ce]
|
|
3
|
+
* @copyright Crown Copyright 2024
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Wrap operation
|
|
11
|
+
*/
|
|
12
|
+
class Wrap extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Wrap constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "Wrap";
|
|
21
|
+
this.module = "Default";
|
|
22
|
+
this.description = "Wraps the input text at a specified number of characters per line.";
|
|
23
|
+
this.inputType = "string";
|
|
24
|
+
this.outputType = "string";
|
|
25
|
+
this.args = [
|
|
26
|
+
{
|
|
27
|
+
"name": "Line Width",
|
|
28
|
+
"type": "number",
|
|
29
|
+
"value": 64,
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} input
|
|
36
|
+
* @param {Object[]} args
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
run(input, args) {
|
|
40
|
+
if (!input) return ""; // Handle empty input
|
|
41
|
+
const lineWidth = args[0];
|
|
42
|
+
const regex = new RegExp(`.{1,${lineWidth}}`, "g");
|
|
43
|
+
return input.match(regex).join("\n");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default Wrap;
|
|
@@ -114,6 +114,7 @@ import EncodeNetBIOSName from "./EncodeNetBIOSName.mjs";
|
|
|
114
114
|
import EncodeText from "./EncodeText.mjs";
|
|
115
115
|
import Enigma from "./Enigma.mjs";
|
|
116
116
|
import Entropy from "./Entropy.mjs";
|
|
117
|
+
import EscapeSmartCharacters from "./EscapeSmartCharacters.mjs";
|
|
117
118
|
import EscapeString from "./EscapeString.mjs";
|
|
118
119
|
import EscapeUnicodeCharacters from "./EscapeUnicodeCharacters.mjs";
|
|
119
120
|
import ExpandAlphabetRange from "./ExpandAlphabetRange.mjs";
|
|
@@ -283,6 +284,7 @@ import PGPDecrypt from "./PGPDecrypt.mjs";
|
|
|
283
284
|
import PGPDecryptAndVerify from "./PGPDecryptAndVerify.mjs";
|
|
284
285
|
import PGPEncrypt from "./PGPEncrypt.mjs";
|
|
285
286
|
import PGPEncryptAndSign from "./PGPEncryptAndSign.mjs";
|
|
287
|
+
import PGPSign from "./PGPSign.mjs";
|
|
286
288
|
import PGPVerify from "./PGPVerify.mjs";
|
|
287
289
|
import PHPDeserialize from "./PHPDeserialize.mjs";
|
|
288
290
|
import PHPSerialize from "./PHPSerialize.mjs";
|
|
@@ -325,6 +327,7 @@ import RC4Drop from "./RC4Drop.mjs";
|
|
|
325
327
|
import RC6Decrypt from "./RC6Decrypt.mjs";
|
|
326
328
|
import RC6Encrypt from "./RC6Encrypt.mjs";
|
|
327
329
|
import RIPEMD from "./RIPEMD.mjs";
|
|
330
|
+
import ROR13 from "./ROR13.mjs";
|
|
328
331
|
import ROT13 from "./ROT13.mjs";
|
|
329
332
|
import ROT13BruteForce from "./ROT13BruteForce.mjs";
|
|
330
333
|
import ROT47 from "./ROT47.mjs";
|
|
@@ -342,6 +345,7 @@ import RawDeflate from "./RawDeflate.mjs";
|
|
|
342
345
|
import RawInflate from "./RawInflate.mjs";
|
|
343
346
|
import Register from "./Register.mjs";
|
|
344
347
|
import RegularExpression from "./RegularExpression.mjs";
|
|
348
|
+
import RemoveANSIEscapeCodes from "./RemoveANSIEscapeCodes.mjs";
|
|
345
349
|
import RemoveDiacritics from "./RemoveDiacritics.mjs";
|
|
346
350
|
import RemoveEXIF from "./RemoveEXIF.mjs";
|
|
347
351
|
import RemoveLineNumbers from "./RemoveLineNumbers.mjs";
|
|
@@ -466,6 +470,7 @@ import VigenèreDecode from "./VigenèreDecode.mjs";
|
|
|
466
470
|
import VigenèreEncode from "./VigenèreEncode.mjs";
|
|
467
471
|
import Whirlpool from "./Whirlpool.mjs";
|
|
468
472
|
import WindowsFiletimeToUNIXTimestamp from "./WindowsFiletimeToUNIXTimestamp.mjs";
|
|
473
|
+
import Wrap from "./Wrap.mjs";
|
|
469
474
|
import XKCDRandomNumber from "./XKCDRandomNumber.mjs";
|
|
470
475
|
import XMLBeautify from "./XMLBeautify.mjs";
|
|
471
476
|
import XMLMinify from "./XMLMinify.mjs";
|
|
@@ -592,6 +597,7 @@ export {
|
|
|
592
597
|
EncodeText,
|
|
593
598
|
Enigma,
|
|
594
599
|
Entropy,
|
|
600
|
+
EscapeSmartCharacters,
|
|
595
601
|
EscapeString,
|
|
596
602
|
EscapeUnicodeCharacters,
|
|
597
603
|
ExpandAlphabetRange,
|
|
@@ -761,6 +767,7 @@ export {
|
|
|
761
767
|
PGPDecryptAndVerify,
|
|
762
768
|
PGPEncrypt,
|
|
763
769
|
PGPEncryptAndSign,
|
|
770
|
+
PGPSign,
|
|
764
771
|
PGPVerify,
|
|
765
772
|
PHPDeserialize,
|
|
766
773
|
PHPSerialize,
|
|
@@ -803,6 +810,7 @@ export {
|
|
|
803
810
|
RC6Decrypt,
|
|
804
811
|
RC6Encrypt,
|
|
805
812
|
RIPEMD,
|
|
813
|
+
ROR13,
|
|
806
814
|
ROT13,
|
|
807
815
|
ROT13BruteForce,
|
|
808
816
|
ROT47,
|
|
@@ -820,6 +828,7 @@ export {
|
|
|
820
828
|
RawInflate,
|
|
821
829
|
Register,
|
|
822
830
|
RegularExpression,
|
|
831
|
+
RemoveANSIEscapeCodes,
|
|
823
832
|
RemoveDiacritics,
|
|
824
833
|
RemoveEXIF,
|
|
825
834
|
RemoveLineNumbers,
|
|
@@ -944,6 +953,7 @@ export {
|
|
|
944
953
|
VigenèreEncode,
|
|
945
954
|
Whirlpool,
|
|
946
955
|
WindowsFiletimeToUNIXTimestamp,
|
|
956
|
+
Wrap,
|
|
947
957
|
XKCDRandomNumber,
|
|
948
958
|
XMLBeautify,
|
|
949
959
|
XMLMinify,
|
package/src/node/index.mjs
CHANGED
|
@@ -122,6 +122,7 @@ import {
|
|
|
122
122
|
EncodeText as core_EncodeText,
|
|
123
123
|
Enigma as core_Enigma,
|
|
124
124
|
Entropy as core_Entropy,
|
|
125
|
+
EscapeSmartCharacters as core_EscapeSmartCharacters,
|
|
125
126
|
EscapeString as core_EscapeString,
|
|
126
127
|
EscapeUnicodeCharacters as core_EscapeUnicodeCharacters,
|
|
127
128
|
ExpandAlphabetRange as core_ExpandAlphabetRange,
|
|
@@ -284,6 +285,7 @@ import {
|
|
|
284
285
|
PGPDecryptAndVerify as core_PGPDecryptAndVerify,
|
|
285
286
|
PGPEncrypt as core_PGPEncrypt,
|
|
286
287
|
PGPEncryptAndSign as core_PGPEncryptAndSign,
|
|
288
|
+
PGPSign as core_PGPSign,
|
|
287
289
|
PGPVerify as core_PGPVerify,
|
|
288
290
|
PHPDeserialize as core_PHPDeserialize,
|
|
289
291
|
PHPSerialize as core_PHPSerialize,
|
|
@@ -326,6 +328,7 @@ import {
|
|
|
326
328
|
RC6Decrypt as core_RC6Decrypt,
|
|
327
329
|
RC6Encrypt as core_RC6Encrypt,
|
|
328
330
|
RIPEMD as core_RIPEMD,
|
|
331
|
+
ROR13 as core_ROR13,
|
|
329
332
|
ROT13 as core_ROT13,
|
|
330
333
|
ROT13BruteForce as core_ROT13BruteForce,
|
|
331
334
|
ROT47 as core_ROT47,
|
|
@@ -343,6 +346,7 @@ import {
|
|
|
343
346
|
RawInflate as core_RawInflate,
|
|
344
347
|
Register as core_Register,
|
|
345
348
|
RegularExpression as core_RegularExpression,
|
|
349
|
+
RemoveANSIEscapeCodes as core_RemoveANSIEscapeCodes,
|
|
346
350
|
RemoveDiacritics as core_RemoveDiacritics,
|
|
347
351
|
RemoveEXIF as core_RemoveEXIF,
|
|
348
352
|
RemoveLineNumbers as core_RemoveLineNumbers,
|
|
@@ -466,6 +470,7 @@ import {
|
|
|
466
470
|
VigenèreEncode as core_VigenèreEncode,
|
|
467
471
|
Whirlpool as core_Whirlpool,
|
|
468
472
|
WindowsFiletimeToUNIXTimestamp as core_WindowsFiletimeToUNIXTimestamp,
|
|
473
|
+
Wrap as core_Wrap,
|
|
469
474
|
XKCDRandomNumber as core_XKCDRandomNumber,
|
|
470
475
|
XMLBeautify as core_XMLBeautify,
|
|
471
476
|
XMLMinify as core_XMLMinify,
|
|
@@ -600,6 +605,7 @@ function generateChef() {
|
|
|
600
605
|
"encodeText": _wrap(core_EncodeText),
|
|
601
606
|
"enigma": _wrap(core_Enigma),
|
|
602
607
|
"entropy": _wrap(core_Entropy),
|
|
608
|
+
"escapeSmartCharacters": _wrap(core_EscapeSmartCharacters),
|
|
603
609
|
"escapeString": _wrap(core_EscapeString),
|
|
604
610
|
"escapeUnicodeCharacters": _wrap(core_EscapeUnicodeCharacters),
|
|
605
611
|
"expandAlphabetRange": _wrap(core_ExpandAlphabetRange),
|
|
@@ -762,6 +768,7 @@ function generateChef() {
|
|
|
762
768
|
"PGPDecryptAndVerify": _wrap(core_PGPDecryptAndVerify),
|
|
763
769
|
"PGPEncrypt": _wrap(core_PGPEncrypt),
|
|
764
770
|
"PGPEncryptAndSign": _wrap(core_PGPEncryptAndSign),
|
|
771
|
+
"PGPSign": _wrap(core_PGPSign),
|
|
765
772
|
"PGPVerify": _wrap(core_PGPVerify),
|
|
766
773
|
"PHPDeserialize": _wrap(core_PHPDeserialize),
|
|
767
774
|
"PHPSerialize": _wrap(core_PHPSerialize),
|
|
@@ -804,6 +811,7 @@ function generateChef() {
|
|
|
804
811
|
"RC6Decrypt": _wrap(core_RC6Decrypt),
|
|
805
812
|
"RC6Encrypt": _wrap(core_RC6Encrypt),
|
|
806
813
|
"RIPEMD": _wrap(core_RIPEMD),
|
|
814
|
+
"ROR13": _wrap(core_ROR13),
|
|
807
815
|
"ROT13": _wrap(core_ROT13),
|
|
808
816
|
"ROT13BruteForce": _wrap(core_ROT13BruteForce),
|
|
809
817
|
"ROT47": _wrap(core_ROT47),
|
|
@@ -821,6 +829,7 @@ function generateChef() {
|
|
|
821
829
|
"rawInflate": _wrap(core_RawInflate),
|
|
822
830
|
"register": _wrap(core_Register),
|
|
823
831
|
"regularExpression": _wrap(core_RegularExpression),
|
|
832
|
+
"removeANSIEscapeCodes": _wrap(core_RemoveANSIEscapeCodes),
|
|
824
833
|
"removeDiacritics": _wrap(core_RemoveDiacritics),
|
|
825
834
|
"removeEXIF": _wrap(core_RemoveEXIF),
|
|
826
835
|
"removeLineNumbers": _wrap(core_RemoveLineNumbers),
|
|
@@ -944,6 +953,7 @@ function generateChef() {
|
|
|
944
953
|
"vigenèreEncode": _wrap(core_VigenèreEncode),
|
|
945
954
|
"whirlpool": _wrap(core_Whirlpool),
|
|
946
955
|
"windowsFiletimeToUNIXTimestamp": _wrap(core_WindowsFiletimeToUNIXTimestamp),
|
|
956
|
+
"wrap": _wrap(core_Wrap),
|
|
947
957
|
"XKCDRandomNumber": _wrap(core_XKCDRandomNumber),
|
|
948
958
|
"XMLBeautify": _wrap(core_XMLBeautify),
|
|
949
959
|
"XMLMinify": _wrap(core_XMLMinify),
|
|
@@ -1088,6 +1098,7 @@ const encodeNetBIOSName = chef.encodeNetBIOSName;
|
|
|
1088
1098
|
const encodeText = chef.encodeText;
|
|
1089
1099
|
const enigma = chef.enigma;
|
|
1090
1100
|
const entropy = chef.entropy;
|
|
1101
|
+
const escapeSmartCharacters = chef.escapeSmartCharacters;
|
|
1091
1102
|
const escapeString = chef.escapeString;
|
|
1092
1103
|
const escapeUnicodeCharacters = chef.escapeUnicodeCharacters;
|
|
1093
1104
|
const expandAlphabetRange = chef.expandAlphabetRange;
|
|
@@ -1257,6 +1268,7 @@ const PGPDecrypt = chef.PGPDecrypt;
|
|
|
1257
1268
|
const PGPDecryptAndVerify = chef.PGPDecryptAndVerify;
|
|
1258
1269
|
const PGPEncrypt = chef.PGPEncrypt;
|
|
1259
1270
|
const PGPEncryptAndSign = chef.PGPEncryptAndSign;
|
|
1271
|
+
const PGPSign = chef.PGPSign;
|
|
1260
1272
|
const PGPVerify = chef.PGPVerify;
|
|
1261
1273
|
const PHPDeserialize = chef.PHPDeserialize;
|
|
1262
1274
|
const PHPSerialize = chef.PHPSerialize;
|
|
@@ -1299,6 +1311,7 @@ const RC4Drop = chef.RC4Drop;
|
|
|
1299
1311
|
const RC6Decrypt = chef.RC6Decrypt;
|
|
1300
1312
|
const RC6Encrypt = chef.RC6Encrypt;
|
|
1301
1313
|
const RIPEMD = chef.RIPEMD;
|
|
1314
|
+
const ROR13 = chef.ROR13;
|
|
1302
1315
|
const ROT13 = chef.ROT13;
|
|
1303
1316
|
const ROT13BruteForce = chef.ROT13BruteForce;
|
|
1304
1317
|
const ROT47 = chef.ROT47;
|
|
@@ -1316,6 +1329,7 @@ const rawDeflate = chef.rawDeflate;
|
|
|
1316
1329
|
const rawInflate = chef.rawInflate;
|
|
1317
1330
|
const register = chef.register;
|
|
1318
1331
|
const regularExpression = chef.regularExpression;
|
|
1332
|
+
const removeANSIEscapeCodes = chef.removeANSIEscapeCodes;
|
|
1319
1333
|
const removeDiacritics = chef.removeDiacritics;
|
|
1320
1334
|
const removeEXIF = chef.removeEXIF;
|
|
1321
1335
|
const removeLineNumbers = chef.removeLineNumbers;
|
|
@@ -1440,6 +1454,7 @@ const vigenèreDecode = chef.vigenèreDecode;
|
|
|
1440
1454
|
const vigenèreEncode = chef.vigenèreEncode;
|
|
1441
1455
|
const whirlpool = chef.whirlpool;
|
|
1442
1456
|
const windowsFiletimeToUNIXTimestamp = chef.windowsFiletimeToUNIXTimestamp;
|
|
1457
|
+
const wrap = chef.wrap;
|
|
1443
1458
|
const XKCDRandomNumber = chef.XKCDRandomNumber;
|
|
1444
1459
|
const XMLBeautify = chef.XMLBeautify;
|
|
1445
1460
|
const XMLMinify = chef.XMLMinify;
|
|
@@ -1568,6 +1583,7 @@ const operations = [
|
|
|
1568
1583
|
encodeText,
|
|
1569
1584
|
enigma,
|
|
1570
1585
|
entropy,
|
|
1586
|
+
escapeSmartCharacters,
|
|
1571
1587
|
escapeString,
|
|
1572
1588
|
escapeUnicodeCharacters,
|
|
1573
1589
|
expandAlphabetRange,
|
|
@@ -1737,6 +1753,7 @@ const operations = [
|
|
|
1737
1753
|
PGPDecryptAndVerify,
|
|
1738
1754
|
PGPEncrypt,
|
|
1739
1755
|
PGPEncryptAndSign,
|
|
1756
|
+
PGPSign,
|
|
1740
1757
|
PGPVerify,
|
|
1741
1758
|
PHPDeserialize,
|
|
1742
1759
|
PHPSerialize,
|
|
@@ -1779,6 +1796,7 @@ const operations = [
|
|
|
1779
1796
|
RC6Decrypt,
|
|
1780
1797
|
RC6Encrypt,
|
|
1781
1798
|
RIPEMD,
|
|
1799
|
+
ROR13,
|
|
1782
1800
|
ROT13,
|
|
1783
1801
|
ROT13BruteForce,
|
|
1784
1802
|
ROT47,
|
|
@@ -1796,6 +1814,7 @@ const operations = [
|
|
|
1796
1814
|
rawInflate,
|
|
1797
1815
|
register,
|
|
1798
1816
|
regularExpression,
|
|
1817
|
+
removeANSIEscapeCodes,
|
|
1799
1818
|
removeDiacritics,
|
|
1800
1819
|
removeEXIF,
|
|
1801
1820
|
removeLineNumbers,
|
|
@@ -1920,6 +1939,7 @@ const operations = [
|
|
|
1920
1939
|
vigenèreEncode,
|
|
1921
1940
|
whirlpool,
|
|
1922
1941
|
windowsFiletimeToUNIXTimestamp,
|
|
1942
|
+
wrap,
|
|
1923
1943
|
XKCDRandomNumber,
|
|
1924
1944
|
XMLBeautify,
|
|
1925
1945
|
XMLMinify,
|
|
@@ -2052,6 +2072,7 @@ export {
|
|
|
2052
2072
|
encodeText,
|
|
2053
2073
|
enigma,
|
|
2054
2074
|
entropy,
|
|
2075
|
+
escapeSmartCharacters,
|
|
2055
2076
|
escapeString,
|
|
2056
2077
|
escapeUnicodeCharacters,
|
|
2057
2078
|
expandAlphabetRange,
|
|
@@ -2221,6 +2242,7 @@ export {
|
|
|
2221
2242
|
PGPDecryptAndVerify,
|
|
2222
2243
|
PGPEncrypt,
|
|
2223
2244
|
PGPEncryptAndSign,
|
|
2245
|
+
PGPSign,
|
|
2224
2246
|
PGPVerify,
|
|
2225
2247
|
PHPDeserialize,
|
|
2226
2248
|
PHPSerialize,
|
|
@@ -2263,6 +2285,7 @@ export {
|
|
|
2263
2285
|
RC6Decrypt,
|
|
2264
2286
|
RC6Encrypt,
|
|
2265
2287
|
RIPEMD,
|
|
2288
|
+
ROR13,
|
|
2266
2289
|
ROT13,
|
|
2267
2290
|
ROT13BruteForce,
|
|
2268
2291
|
ROT47,
|
|
@@ -2280,6 +2303,7 @@ export {
|
|
|
2280
2303
|
rawInflate,
|
|
2281
2304
|
register,
|
|
2282
2305
|
regularExpression,
|
|
2306
|
+
removeANSIEscapeCodes,
|
|
2283
2307
|
removeDiacritics,
|
|
2284
2308
|
removeEXIF,
|
|
2285
2309
|
removeLineNumbers,
|
|
@@ -2404,6 +2428,7 @@ export {
|
|
|
2404
2428
|
vigenèreEncode,
|
|
2405
2429
|
whirlpool,
|
|
2406
2430
|
windowsFiletimeToUNIXTimestamp,
|
|
2431
|
+
wrap,
|
|
2407
2432
|
XKCDRandomNumber,
|
|
2408
2433
|
XMLBeautify,
|
|
2409
2434
|
XMLMinify,
|
package/src/web/App.mjs
CHANGED
|
@@ -42,6 +42,14 @@ class App {
|
|
|
42
42
|
this.progress = 0;
|
|
43
43
|
this.ingId = 0;
|
|
44
44
|
|
|
45
|
+
// stateChangeId increments on every statechange dispatch; bakeStateId records
|
|
46
|
+
// the stateChangeId captured when the most recent bake started. autoBake uses
|
|
47
|
+
// these to decide whether the output is genuinely stale, so a debounced
|
|
48
|
+
// autoBake firing shortly after a manual bake doesn't clobber the bake's
|
|
49
|
+
// hideStaleIndicator with a redundant showStaleIndicator.
|
|
50
|
+
this.stateChangeId = 0;
|
|
51
|
+
this.bakeStateId = -1;
|
|
52
|
+
|
|
45
53
|
this.appLoaded = false;
|
|
46
54
|
this.workerLoaded = false;
|
|
47
55
|
this.waitersLoaded = false;
|
|
@@ -136,6 +144,9 @@ class App {
|
|
|
136
144
|
bake(step=false) {
|
|
137
145
|
if (this.baking) return;
|
|
138
146
|
|
|
147
|
+
// Record which state version this bake is covering.
|
|
148
|
+
this.bakeStateId = this.stateChangeId;
|
|
149
|
+
|
|
139
150
|
// Reset attemptHighlight flag
|
|
140
151
|
this.options.attemptHighlight = true;
|
|
141
152
|
|
|
@@ -166,7 +177,10 @@ class App {
|
|
|
166
177
|
nums: [this.manager.tabs.getActiveTab("input")],
|
|
167
178
|
step: false
|
|
168
179
|
});
|
|
169
|
-
} else {
|
|
180
|
+
} else if (this.bakeStateId < this.stateChangeId) {
|
|
181
|
+
// Only show stale-indicator if the most recent bake didn't cover the
|
|
182
|
+
// current state. Without this guard, a debounced autoBake firing after
|
|
183
|
+
// a manual bake completed would re-show the indicator on fresh output.
|
|
170
184
|
this.manager.controls.showStaleIndicator();
|
|
171
185
|
}
|
|
172
186
|
}
|
|
@@ -768,6 +782,10 @@ class App {
|
|
|
768
782
|
* @param {event} e
|
|
769
783
|
*/
|
|
770
784
|
stateChange(e) {
|
|
785
|
+
// Bump the state-change counter synchronously so a manual bake invoked between
|
|
786
|
+
// here and the debounced autoBake firing can record it via bakeStateId.
|
|
787
|
+
this.stateChangeId++;
|
|
788
|
+
|
|
771
789
|
debounce(function() {
|
|
772
790
|
this.progress = 0;
|
|
773
791
|
this.autoBake();
|
|
@@ -166,6 +166,7 @@ class HTMLIngredient {
|
|
|
166
166
|
id="${this.id}"
|
|
167
167
|
tabindex="${this.tabIndex}"
|
|
168
168
|
arg-name="${this.name}"
|
|
169
|
+
data-target="${this.target}"
|
|
169
170
|
${this.disabled ? "disabled" : ""}>`;
|
|
170
171
|
for (i = 0; i < this.value.length; i++) {
|
|
171
172
|
if ((m = this.value[i].name.match(/\[([a-z0-9 -()^]+)\]/i))) {
|
package/src/web/html/index.html
CHANGED
|
@@ -868,15 +868,15 @@
|
|
|
868
868
|
Be aware that the standalone version will never update itself, meaning it will not receive bug fixes or new features until you re-download newer versions manually.
|
|
869
869
|
</p>
|
|
870
870
|
|
|
871
|
-
<h6>CyberChef
|
|
871
|
+
<h6>CyberChef <%= htmlWebpackPlugin.options.version %></h6>
|
|
872
872
|
<ul>
|
|
873
873
|
<li>Build time: <%= htmlWebpackPlugin.options.compileTime %></li>
|
|
874
|
-
<li>The changelog for this version can be viewed <a href="https://github.com/gchq/CyberChef/blob/v<%= htmlWebpackPlugin.options.
|
|
874
|
+
<li>The changelog for this version can be viewed <a href="https://github.com/gchq/CyberChef/blob/v<%= htmlWebpackPlugin.options.latestReleaseVersion %>/CHANGELOG.md">here</a></li>
|
|
875
875
|
<li>© Crown Copyright 2016-<%= htmlWebpackPlugin.options.compileYear %></li>
|
|
876
876
|
<li>Released under the Apache Licence, Version 2.0</li>
|
|
877
877
|
<li>SHA256 hash: DOWNLOAD_HASH_PLACEHOLDER</li>
|
|
878
878
|
</ul>
|
|
879
|
-
<a href="
|
|
879
|
+
<a href="<%= htmlWebpackPlugin.options.downloadZipFilename %>" download class="btn btn-outline-primary">Download ZIP file</a>
|
|
880
880
|
</div>
|
|
881
881
|
<div class="modal-footer">
|
|
882
882
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Ok</button>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { SitemapStream, streamToPromise } from "sitemap";
|
|
2
2
|
import OperationConfig from "../../core/config/OperationConfig.json" with { type: "json" };
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -11,7 +11,7 @@ import OperationConfig from "../../core/config/OperationConfig.json" with { type
|
|
|
11
11
|
|
|
12
12
|
const baseUrl = "https://gchq.github.io/CyberChef/";
|
|
13
13
|
|
|
14
|
-
const smStream = new
|
|
14
|
+
const smStream = new SitemapStream({});
|
|
15
15
|
|
|
16
16
|
smStream.write({
|
|
17
17
|
url: baseUrl,
|
|
@@ -28,6 +28,6 @@ for (const op in OperationConfig) {
|
|
|
28
28
|
}
|
|
29
29
|
smStream.end();
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
streamToPromise(smStream).then(
|
|
32
32
|
(buffer) => console.log(buffer.toString()), // eslint-disable-line no-console
|
|
33
33
|
);
|
|
@@ -487,11 +487,19 @@ class RecipeWaiter {
|
|
|
487
487
|
* @param {HTMLElement} op
|
|
488
488
|
*/
|
|
489
489
|
triggerArgEvents(op) {
|
|
490
|
-
// Trigger
|
|
490
|
+
// Trigger argSelector events and populateOption events only where the target is empty.
|
|
491
|
+
// When loading a saved recipe, arguments are populated before this method is called, so
|
|
492
|
+
// re-triggering populateOption events would overwrite saved custom values with defaults.
|
|
493
|
+
const args = op.querySelectorAll(".arg");
|
|
491
494
|
const triggerableOptions = op.querySelectorAll(".populate-option, .arg-selector");
|
|
492
495
|
const evt = new Event("change", {bubbles: true});
|
|
496
|
+
|
|
493
497
|
if (triggerableOptions.length) {
|
|
494
498
|
for (const el of triggerableOptions) {
|
|
499
|
+
if (el.classList.contains("populate-option")) {
|
|
500
|
+
const target = args[el.getAttribute("data-target")];
|
|
501
|
+
if (target && target.value !== "") continue;
|
|
502
|
+
}
|
|
495
503
|
el.dispatchEvent(evt);
|
|
496
504
|
}
|
|
497
505
|
}
|
package/tests/browser/02_ops.js
CHANGED
|
@@ -30,8 +30,8 @@ module.exports = {
|
|
|
30
30
|
testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput");
|
|
31
31
|
testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20");
|
|
32
32
|
testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]);
|
|
33
|
-
testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]);
|
|
34
|
-
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]);
|
|
33
|
+
testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, 16, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }, { "option": "Hex", "string": "" }, "Off"]);
|
|
34
|
+
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex", "Off"]);
|
|
35
35
|
testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]);
|
|
36
36
|
testOp(browser, "Add line numbers", "test input", "1 test input");
|
|
37
37
|
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "50cdf8ea483c55564a091650c2bccb4586f919b721e5fe9d6a61660505b4346d6ebdb2ef0cf075a7728cd84cb26ea3e477b5bd86a94a49a27d79423994afb60a", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto"], []]);
|
|
@@ -64,7 +64,7 @@ module.exports = {
|
|
|
64
64
|
testOp(browser, "BSON serialise", '{"a":"test"}', "\u0011\u0000\u0000\u0000\u0002a\u0000\u0005\u0000\u0000\u0000test\u0000\u0000");
|
|
65
65
|
// testOp(browser, "Bacon Cipher Decode", "test input", "test_output");
|
|
66
66
|
// testOp(browser, "Bacon Cipher Encode", "test input", "test_output");
|
|
67
|
-
testOp(browser, "Bcrypt", "test input", /^\$
|
|
67
|
+
testOp(browser, "Bcrypt", "test input", /^\$2b\$06\$.{53}$/, [6]);
|
|
68
68
|
testOp(browser, "Bcrypt compare", "test input", "Match: test input", ["$2a$05$FCfBSVX7OeRkK.9kQVFCiOYu9XtwtIbePqUiroD1lkASW9q5QClzG"]);
|
|
69
69
|
testOp(browser, "Bcrypt parse", "$2a$05$kXWtAIGB/R8VEzInoM5ocOTBtyc0m2YTIwFiBU/0XoW032f9QrkWW", /Rounds: 5/);
|
|
70
70
|
testOp(browser, "Bifid Cipher Decode", "qblb tfovy", "test input", ["pass"]);
|
|
@@ -80,8 +80,8 @@ module.exports = {
|
|
|
80
80
|
testOpHtml(browser, "Bombe", "XTSYN WAEUG EZALY NRQIM AMLZX MFUOD AWXLY LZCUZ QOQBQ JLCPK NDDRW F", "table tr:last-child td:first-child", "ECG", ["3-rotor", "LEYJVCNIXWPBQMDRTAKZGFUHOS", "BDFHJLCPRTXVZNYEIWGAKMUSQO<W", "AJDKSIRUXBLHWTMCQGZNPYFVOE<F", "ESOVPZJAYQUIRHXLNFTGKDCMWB<K", "AY BR CU DH EQ FS GL IP JX KN MO TZ VW", "HELLO CYBER CHEFU SER", 0, true]);
|
|
81
81
|
testOp(browser, ["Bzip2 Compress", "To Hex"], "test input", "42 5a 68 39 31 41 59 26 53 59 cf 96 82 1d 00 00 03 91 80 40 00 02 21 4e 00 20 00 21 90 c2 10 c0 88 33 92 8e df 17 72 45 38 50 90 cf 96 82 1d");
|
|
82
82
|
testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]);
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
testOp(browser, ["From Hex", "CBOR Decode"], "f9 3e 00", "1.5");
|
|
84
|
+
testOp(browser, ["CBOR Encode", "To Hex"], "1.5", "f9 3e 00");
|
|
85
85
|
testOp(browser, "CRC Checksum", "test input", "77c7", ["CRC-16"]);
|
|
86
86
|
testOp(browser, "CRC Checksum", "test input", "29822bc8", ["CRC-32"]);
|
|
87
87
|
testOp(browser, "CRC Checksum", "test input", "9d", ["CRC-8"]);
|
|
@@ -278,11 +278,11 @@ module.exports = {
|
|
|
278
278
|
testOpHtml(browser, "Parse UDP", "04 89 00 35 00 2c 01 01", "tr:last-child td:last-child", "0x0101");
|
|
279
279
|
// testOp(browser, "Parse UNIX file permissions", "test input", "test_output");
|
|
280
280
|
// testOp(browser, "Parse URI", "test input", "test_output");
|
|
281
|
-
|
|
281
|
+
testOp(browser, "Parse User Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 ", /Architecture: amd64/);
|
|
282
282
|
// testOp(browser, "Parse X.509 certificate", "test input", "test_output");
|
|
283
283
|
testOpFile(browser, "Play Media", "files/mp3example.mp3", "audio", "");
|
|
284
284
|
// testOp(browser, "Power Set", "test input", "test_output");
|
|
285
|
-
|
|
285
|
+
testOp(browser, ["From Hex", "Protobuf Decode"], "0d1c0000001203596f751a024d65202b2a0a0a066162633132331200", /"1": "abc123"/, [[], ["", false, false]]);
|
|
286
286
|
// testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output");
|
|
287
287
|
// testOp(browser, "RC2 Decrypt", "test input", "test_output");
|
|
288
288
|
// testOp(browser, "RC2 Encrypt", "test input", "test_output");
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for recipe loading behaviour.
|
|
3
|
+
*
|
|
4
|
+
* @author C85297 [95289555+C85297@users.noreply.github.com]
|
|
5
|
+
* @copyright Crown Copyright
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const utils = require("./browserUtils.js");
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
before: browser => {
|
|
13
|
+
browser
|
|
14
|
+
.resizeWindow(1280, 800)
|
|
15
|
+
.url(browser.launchUrl)
|
|
16
|
+
.useCss()
|
|
17
|
+
.waitForElementNotPresent("#preloader", 10000);
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
"Recipe load preserves populated arguments": browser => {
|
|
21
|
+
const inputFormat = "HH:mm:ss a MMM DD, YYYY ";
|
|
22
|
+
const input = "10:20:30 pm Sep 26, 2019 ";
|
|
23
|
+
|
|
24
|
+
utils.loadRecipe(
|
|
25
|
+
browser,
|
|
26
|
+
"Translate DateTime Format",
|
|
27
|
+
input,
|
|
28
|
+
[
|
|
29
|
+
"Standard date and time",
|
|
30
|
+
inputFormat,
|
|
31
|
+
"UTC",
|
|
32
|
+
"DD/MM/YYYY HH:mm:ss",
|
|
33
|
+
"UTC"
|
|
34
|
+
]
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
browser.execute(() => {
|
|
38
|
+
return Array.from(document.querySelectorAll("#rec-list li.operation .arg"))
|
|
39
|
+
.map(arg => arg.value);
|
|
40
|
+
}, [], function({value}) {
|
|
41
|
+
browser.expect(value[1]).to.equal(inputFormat);
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
after: browser => {
|
|
46
|
+
browser.end();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -51,14 +51,17 @@ function setInput(browser, input, type=true) {
|
|
|
51
51
|
*/
|
|
52
52
|
function bake(browser) {
|
|
53
53
|
browser
|
|
54
|
+
// Let any pending debounced inputChange/stateChange (~20ms each) fire so the
|
|
55
|
+
// worker has the latest input buffer before we ask it to bake.
|
|
56
|
+
.pause(50)
|
|
54
57
|
// Ensure we're not currently busy
|
|
55
|
-
.waitForElementNotVisible("#output-loader",
|
|
58
|
+
.waitForElementNotVisible("#output-loader", 10000)
|
|
56
59
|
.expect.element("#bake span").text.to.equal("BAKE!");
|
|
57
60
|
|
|
58
61
|
browser
|
|
59
62
|
.click("#bake")
|
|
60
|
-
.waitForElementNotVisible("#stale-indicator",
|
|
61
|
-
.waitForElementNotVisible("#output-loader",
|
|
63
|
+
.waitForElementNotVisible("#stale-indicator", 10000)
|
|
64
|
+
.waitForElementNotVisible("#output-loader", 10000);
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
/** @function
|
package/tests/node/index.mjs
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PGP node tests.
|
|
3
|
+
*
|
|
4
|
+
* @author C85297 [95289555+C85297@users.noreply.github.com]
|
|
5
|
+
* @copyright Crown Copyright 2026
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import assert from "assert";
|
|
10
|
+
import kbpgp from "kbpgp";
|
|
11
|
+
import * as es6promisify from "es6-promisify";
|
|
12
|
+
|
|
13
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
14
|
+
import it from "../assertionHandler.mjs";
|
|
15
|
+
import GeneratePGPKeyPair from "../../../src/core/operations/GeneratePGPKeyPair.mjs";
|
|
16
|
+
|
|
17
|
+
const promisify = es6promisify.default ? es6promisify.default.promisify : es6promisify.promisify;
|
|
18
|
+
|
|
19
|
+
const PUBLIC_KEY_BLOCK = /-----BEGIN PGP PUBLIC KEY BLOCK-----[\s\S]*-----END PGP PUBLIC KEY BLOCK-----/;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Generate a PGP key pair and import the generated public key.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} keyType
|
|
25
|
+
* @returns {Promise<Object>}
|
|
26
|
+
*/
|
|
27
|
+
async function generateAndImportPublicKey(keyType) {
|
|
28
|
+
const operation = new GeneratePGPKeyPair();
|
|
29
|
+
const generatedKeyPair = await operation.run("", [
|
|
30
|
+
keyType,
|
|
31
|
+
"",
|
|
32
|
+
"User",
|
|
33
|
+
"akb@notreal.gchq.gov.uk"
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const publicKey = generatedKeyPair.match(PUBLIC_KEY_BLOCK);
|
|
37
|
+
|
|
38
|
+
assert(publicKey, "Generated key pair should contain an ASCII-armoured public key");
|
|
39
|
+
|
|
40
|
+
return promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
|
41
|
+
armored: publicKey[0],
|
|
42
|
+
opts: {
|
|
43
|
+
"no_check_keys": true
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
TestRegister.addApiTests([
|
|
49
|
+
it("Generate PGP Key Pair: ECC keys should include ECDSA signing and ECDH encryption subkeys", async () => {
|
|
50
|
+
const publicKey = await generateAndImportPublicKey("ECC-256");
|
|
51
|
+
const subkeyAlgorithms = publicKey.subkeys.map(subkey => subkey.key.type);
|
|
52
|
+
|
|
53
|
+
assert.strictEqual(
|
|
54
|
+
publicKey.primary.key.type,
|
|
55
|
+
kbpgp.const.openpgp.public_key_algorithms.ECDSA,
|
|
56
|
+
"Generated ECC PGP primary key should use ECDSA"
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
assert(
|
|
60
|
+
subkeyAlgorithms.includes(kbpgp.const.openpgp.public_key_algorithms.ECDSA),
|
|
61
|
+
"Generated ECC PGP key should include an ECDSA signing subkey"
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
assert(
|
|
65
|
+
subkeyAlgorithms.includes(kbpgp.const.openpgp.public_key_algorithms.ECDH),
|
|
66
|
+
"Generated ECC PGP key should include an ECDH encryption subkey"
|
|
67
|
+
);
|
|
68
|
+
})
|
|
69
|
+
]);
|