2
0
mirror of https://github.com/gchq/CyberChef synced 2025-12-05 23:53:27 +00:00

Compare commits

...

98 Commits

Author SHA1 Message Date
n1474335
037300de79 8.10.0 2018-11-07 15:10:57 +00:00
n1474335
6990dcae89 Updated changelog 2018-11-07 15:10:25 +00:00
n1474335
6e81d6dfcd Merge branch 'klaxon1-feature/remove-letter-accents' 2018-11-07 15:08:09 +00:00
n1474335
cea30465d8 Changed 'Remove Letter Accents' to 'Remove Diacritics' 2018-11-07 15:07:54 +00:00
n1474335
b301d16cb2 Merge branch 'feature/remove-letter-accents' of https://github.com/klaxon1/CyberChef into klaxon1-feature/remove-letter-accents 2018-11-07 14:57:05 +00:00
n1474335
19c002fcdd 8.9.2 2018-11-07 14:40:13 +00:00
n1474335
ab3a73fe58 Merge branch 'qistoph-FromNegs' 2018-11-07 14:39:51 +00:00
n1474335
91fc2c28dc Added signed feature to 'To Decimal' 2018-11-07 14:39:33 +00:00
n1474335
ca47ba3c7c Merge branch 'FromNegs' of https://github.com/qistoph/CyberChef into qistoph-FromNegs 2018-11-07 14:23:39 +00:00
n1474335
e1b456c01c 8.9.1 2018-11-07 14:21:26 +00:00
n1474335
5eb7e00eac Merge branch 'qistoph-HmacToggleStr' 2018-11-07 14:21:18 +00:00
n1474335
8bcf68c8a1 Merge branch 'HmacToggleStr' of https://github.com/qistoph/CyberChef into qistoph-HmacToggleStr 2018-11-07 14:18:24 +00:00
n1474335
520eaedd9a 8.9.0 2018-11-07 13:23:26 +00:00
n1474335
4c5e664ce0 Merge branch 'arnydo-add_url_defang' 2018-11-07 13:23:17 +00:00
n1474335
53c500eb1b Added various options to the 'Defang URL' operation. 2018-11-07 13:23:05 +00:00
n1474335
253346a201 Merge branch 'add_url_defang' of https://github.com/arnydo/CyberChef into arnydo-add_url_defang 2018-11-07 12:29:58 +00:00
n1474335
c5d82a76ab 8.8.8 2018-11-07 12:29:32 +00:00
n1474335
18a9dfffc7 Updated dependencies. Removed shim from HMAC op and postinstall js-to-mjs step due to CryptoAPI fixes. 2018-11-07 12:29:23 +00:00
n1474335
38838e4dca 8.8.7 2018-11-06 18:52:31 +00:00
n1474335
5c151d727b Merge branch 'bwhitn-bugfixes' 2018-11-06 18:52:17 +00:00
n1474335
2d5b157c91 Merge branch 'bugfixes' of https://github.com/bwhitn/CyberChef into bwhitn-bugfixes 2018-11-06 18:51:40 +00:00
n1474335
10d3d27a33 8.8.6 2018-11-05 12:48:29 +00:00
n1474335
1614442bd7 Fixed theming issues 2018-11-05 12:48:22 +00:00
bwhitn
a3c5b1e107 Simplified while loop in FromBase58 to match ToBase58 2018-10-28 18:37:00 -04:00
Chris van Marle
3f0af9cdea Add tests for From Decimal 2018-10-22 17:51:26 +08:00
Brian Whitney
f4de4de8c1 Fixing the babel, scrypt, and base58 issues 2018-10-21 21:10:49 -04:00
arnydo
69033a7343 Add Defang URL 2018-10-16 15:03:29 -04:00
arnydo
5a22106731 Create DefangURL.mjs 2018-10-16 15:02:39 -04:00
d98762625
5155d0ed56 Merge branch 'qistoph-RegexTooltip' 2018-10-12 15:44:17 +01:00
Chris van Marle
9be674103f Tooltip regex matches #279
Tooltip shows offset and matched groups
2018-10-12 15:42:44 +01:00
Chris van Marle
b76aa16143 Fix Hash test 2018-10-12 13:54:40 +02:00
d98762625
8f7bb3a7c9 Merge pull request #371 from OllieGeek/master
CSS label / register-list Aesthetics
2018-10-12 12:12:48 +01:00
Chris van Marle
be2b466376 Use toggleString for Key in HMAC #263 2018-10-12 13:05:32 +02:00
n1474335
f957925aac 8.8.5 2018-10-12 10:51:01 +00:00
n1474335
1bf8d63d1a Merge branch 'Cynser-fix-wiki-urls' 2018-10-12 10:50:27 +00:00
n1474335
8875144307 Merge branch 'fix-wiki-urls' of https://github.com/Cynser/CyberChef into Cynser-fix-wiki-urls 2018-10-12 10:45:54 +00:00
n1474335
d5c01f387a 8.8.4 2018-10-12 10:43:01 +00:00
n1474335
32709cd60f Merge branch 'klaxon1-feature/improve-email-extract' 2018-10-12 10:42:21 +00:00
n1474335
aaf0a91975 Fixed populateOption overflows 2018-10-12 10:42:03 +00:00
n1474335
6cc6230b91 Merge branch 'feature/improve-email-extract' of https://github.com/klaxon1/CyberChef into klaxon1-feature/improve-email-extract 2018-10-12 10:34:00 +00:00
n1474335
dd630f20f8 8.8.3 2018-10-12 10:28:23 +00:00
n1474335
0c6efd95fa Modified bzip2 library export to use ES6 syntax. Fixes #382. 2018-10-12 10:28:15 +00:00
Chris van Marle
a276378887 Enable parsing of negative decimals #176 2018-10-12 10:08:24 +02:00
Cynser
98d861a639 Add check for Forensics Wiki URLs 2018-10-11 17:27:51 +01:00
Klaxon
3089c39369 add test 2018-10-11 22:26:44 +10:00
Klaxon
54793f2b78 update operation 2018-10-11 21:52:49 +10:00
Klaxon
f1ffe19ec8 Merge branch 'master' into feature/remove-letter-accents 2018-10-11 21:28:04 +10:00
Klaxon
e638fb69b5 fix comment 2018-10-11 20:52:12 +10:00
Klaxon
718a94b5e0 add tests for internationalized email addresses 2018-10-11 20:42:16 +10:00
Klaxon
3079059ce3 Update regex to support a wider variety of email addresses. 2018-10-11 18:25:05 +10:00
n1474335
d6c6981bc0 8.8.2 2018-10-10 15:49:11 +00:00
n1474335
8aeb7b60a7 Updated dependencies 2018-10-10 15:49:07 +00:00
n1474335
9197ac6510 8.8.1 2018-10-10 14:08:32 +00:00
n1474335
b67ad3073c Merge branch 'Cynser-csv-escape' 2018-10-10 14:08:20 +00:00
n1474335
4a4f37f888 Merge branch 'csv-escape' of https://github.com/Cynser/CyberChef into Cynser-csv-escape 2018-10-10 14:06:49 +00:00
n1474335
c55331f220 8.8.0 2018-10-10 13:59:37 +00:00
n1474335
757ec98554 Updated CHANGELOG 2018-10-10 13:59:28 +00:00
n1474335
14309f2069 Merge branch 'GCHQ77703-tlv' 2018-10-10 13:56:47 +00:00
n1474335
e6b89d571e Tidied up TLV operation and tests 2018-10-10 13:56:20 +00:00
Cynser
d957198fd6 Make the check for Wikipedia URLs slightly stricter 2018-10-07 22:52:08 +01:00
Cynser
903bd22999 Stop treating backslashes in CSV as escape character 2018-10-07 22:20:43 +01:00
Klaxon
04ee2fb3e4 add function to replace accent chars with latin chars 2018-10-03 13:26:01 +10:00
Klaxon
ac2466a304 create operation from npm run newop 2018-10-03 13:11:22 +10:00
Klaxon
ab4c9ef0d6 fix comment 2018-10-02 15:12:51 +10:00
Klaxon
a69063de9b add tests 2018-10-02 13:51:55 +10:00
Klaxon
62b76777c0 update regex to match more email address variations 2018-10-02 13:40:47 +10:00
OllieGeek
32a91bda0a CSS label / register-list Aesthetics
Occasionally depending on the page width and the operation used, the label.bmd-label-floating's wraps and covers the input - CSS to hide the wrap

On register-list, if the regex match is not a word and longer than the div, it'll over run - CSS of word-break: break-all
2018-09-24 22:56:38 +01:00
n1474335
a15af602e0 Merge branch 'tlv' of https://github.com/GCHQ77703/CyberChef into GCHQ77703-tlv 2018-08-31 15:12:54 +00:00
n1474335
ec9dfd2918 Updated NPM token 2018-08-31 14:08:18 +00:00
n1474335
016086ef4e 8.7.0 2018-08-31 14:00:29 +00:00
n1474335
2e5ea968ee Updated CHANGELOG 2018-08-31 14:00:24 +00:00
n1474335
5dde1c1c04 Merge branch 'GCHQ77703-jwt' 2018-08-31 13:58:33 +00:00
n1474335
be14d56eae Tidied up JWT operations 2018-08-31 13:58:06 +00:00
n1474335
100b097ace Merge branch 'jwt' of https://github.com/GCHQ77703/CyberChef into GCHQ77703-jwt 2018-08-31 12:20:37 +00:00
GCHQ 77703
3833c5f9fe Rename operation, add working tests, add info URL 2018-08-31 13:20:28 +01:00
n1474335
3470dd9f3b Merge branch 'GCHQ77703-alphabetical' 2018-08-31 11:41:43 +00:00
GCHQ 77703
c5e8649284 alphabetically sort tests 2018-08-29 22:48:47 +01:00
GCHQ 77703
a95f43aa4d Implement tests, fix options argument 2018-08-29 22:43:10 +01:00
n1474335
0420aa8edb Merge branch 'Sam-Dowling-patch-1' 2018-08-29 19:09:53 +00:00
n1474335
806b43dfec Merge branch 'patch-1' of https://github.com/Sam-Dowling/CyberChef into Sam-Dowling-patch-1 2018-08-29 19:09:19 +00:00
n1474335
98f4fe4c2b 8.6.2 2018-08-29 19:06:02 +00:00
n1474335
0d63b3cbae JSON output is now indented by default. Closes #350. 2018-08-29 19:05:58 +00:00
n1474335
7061c05f77 8.6.1 2018-08-29 18:58:01 +00:00
n1474335
9b9a182f9f Merge branch 'klaxon1-feature/improve-parse-ip-range' 2018-08-29 18:57:08 +00:00
n1474335
2d9e7fcc6d Added full stop to operation description 2018-08-29 18:56:50 +00:00
n1474335
56946a66aa Merge branch 'feature/improve-parse-ip-range' of https://github.com/klaxon1/CyberChef into klaxon1-feature/improve-parse-ip-range 2018-08-29 18:48:29 +00:00
n1474335
c9242e32fe Auto-generated configs and modules are now cleaned when starting a new dev or prod task 2018-08-29 18:21:46 +00:00
Sam Dowling
fd96bf345b Fixed typo
Fixed typo in operation description.
Wirlpool -> Whirlpool
2018-08-29 17:15:52 +01:00
Klaxon
2820660264 fix regex issues and ESlint errors and warnings
fix comment

fix ESlint errors and warnings

fix regex

add author
2018-08-28 23:07:53 +10:00
Klaxon
86145dbf67 add tests 2018-08-28 23:07:48 +10:00
Klaxon
135b17186e update description 2018-08-28 23:07:40 +10:00
Klaxon
ce494339ef add parse IPv6 list 2018-08-28 23:07:32 +10:00
Klaxon
dd5af7eb10 add parse IPv4 list 2018-08-28 23:07:04 +10:00
GCHQ 77703
3abe99078e Fix linting 2018-08-27 16:03:15 +01:00
GCHQ 77703
edbd540c68 Add Dysfunctional Test 2018-08-27 15:42:07 +01:00
GCHQ 77703
06d9302d96 Implement TLV / KLV 2018-08-27 14:57:24 +01:00
GCHQ 77703
032b4bed7f Add Length Value Decoder Operatoin 2018-08-27 01:17:06 +01:00
GCHQ 77703
8559f5c8ea Add JWT Verify, Decode and Sign 2018-08-26 23:16:13 +01:00
49 changed files with 3665 additions and 2031 deletions

View File

@@ -1,6 +1,6 @@
{
"presets": [
["env", {
["@babel/preset-env", {
"targets": {
"chrome": 40,
"firefox": 35,
@@ -8,7 +8,7 @@
"node": "6.5"
},
"modules": false,
"useBuiltIns": true
"useBuiltIns": "entry"
}]
],
"plugins": [

View File

@@ -36,7 +36,7 @@ deploy:
skip_cleanup: true
email: "n1474335@gmail.com"
api_key:
secure: "Z3FK6bm4RfQEIRXZ1lBNzQkVIoHpivThr9U+XBHmsBgIfdrK/XUnzs/slugo+NIz8nPiGmMx4gxyJonBCLHDGb1ysky2aEWTl26c0teaF4DeQEjWC1ZaGzv8MV1/GkUamnr1qouXjyUhyEAp33rd8ccN9Rq3QNYB/qLDcA9/FCme7JCW6sCd4zWO0LGEYMJEMc2FzAUkqhqsI05hegGhSDgKXRn5PmLARek4yHD+Hx7pstaTeQIy0WoGJjdzoB3iJIMmo/hWZGzZafktUOh223c5qzx4zMpDRNmMngBUw6R94nKd4KvplYRgB87Y3L/aiVU4CF+axwLmK8RPaC1wbJnlHf06zxHPdiFmsY/zKPpNel+nOnxzRrF5l2KMU4TU6gug3s9Jnzp9T5UMfhp0jW3YkxHGeuOPOeE1i0lTUWUGWrPHLQquAhLfkr2zxaU4ETk/y85hq9W4LAy0ENEDVXX2jP7FnI4Z1fdpmljpmVNJR+outPg6t+Coqgvil7v7XpMtDm8lKQanVYuxwmkb/ncOWFRWuM2j5zIEg3CHnFDcJ9bYrfKRg0b0tb/2BWD14pQnV76goVwzJQYVzdPc8TKIYJw2BZ1Nh9c0iruQVebe/6l1FX9fDCkz8VMmltni61/LxZrf8y0NT1YaU1raeNY2dH5UWvEa9p72FPMI6Eg="
secure: "UnDQL3Kh+GK2toL0TK3FObO0ujVssU3Eg4BBuYdjwLB81GhiGE5/DTh7THdZPOpbLo6wQeOwfZDuMeKC1OU+0Uf4NsdYFu1aq6xMO20qBQ4qUfgsyiK4Qgywj9gk0p1+OFZdGAZ/j1CNRAaF71XQIY6iV84c+SO4WoizXYrNT0Jh4sr2DA4/97G2xmJtPi0qOzYrJ09R56ZUozmqeik5G0pMRIuJRbpjS/7bZXV+N7WV0ombZc9RkUaetbabEVOLQ+Xx5YAIVq+VuEeMe9VBSnxY/FfCLmy1wJsjGzpLCyBI9nbrG4nw8Wgc2m8NfK9rcpIvBTGner9r2j60NVDkZ8kLZPrqXhq6AZMwa+oz6K5UQCqRo2RRQzSGwXxg67HY5Tcq+oNmjd+DqpPg4LZ3eGlluyP5XfG+hpSr9Ya4d8q8SrUWLxkoLHI6ZKMtoKFbTCSSQPiluW5hsZxjz3yDkkjsJw64M/EM8UyJrgaXqDklQu+7rBGKLfsK6os7RDiqjBWpQ7gwpo8HvY0O8yqEAabPz+QGkanpjcCOZCXFbSkzWxYy37RMAPu88iINVZVlZE4l+WJenCpZY95ueyy0mG9cyMSzVRPyX6A+/n4H6VMFPFjpGDLTD588ACEjY1lmHfS/eXwXJcgqPPD2gW0XdRdUheU/ssqlfCfGWQMTDXs="
on:
tags: true
branch: master

View File

@@ -1,6 +1,17 @@
# Changelog
All notable changes to CyberChef will be documented in this file.
### [8.10.0] - 2018-11-07
- 'Remove Diacritics' operation added [@klaxon1] | [#387]
### [8.9.0] - 2018-11-07
- 'Defang URL' operation added [@arnydo] | [#394]
### [8.8.0] - 2018-10-10
- 'Parse TLV' operation added [@GCHQ77703] | [#351]
### [8.7.0] - 2018-08-31
- 'JWT Sign', 'JWT Verify' and 'JWT Decode' operations added [@GCHQ77703] | [#348]
### [8.6.0] - 2018-08-29
- 'To Geohash' and 'From Geohash' operations added [@GCHQ77703] | [#344]
@@ -48,6 +59,8 @@ All notable changes to CyberChef will be documented in this file.
- Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
[8.8.0]: https://github.com/gchq/CyberChef/releases/tag/v8.8.0
[8.7.0]: https://github.com/gchq/CyberChef/releases/tag/v8.7.0
[8.6.0]: https://github.com/gchq/CyberChef/releases/tag/v8.6.0
[8.5.0]: https://github.com/gchq/CyberChef/releases/tag/v8.5.0
[8.4.0]: https://github.com/gchq/CyberChef/releases/tag/v8.4.0
@@ -69,6 +82,8 @@ All notable changes to CyberChef will be documented in this file.
[@JustAnotherMark]: https://github.com/JustAnotherMark
[@sevzero]: https://github.com/sevzero
[@PenguinGeorge]: https://github.com/PenguinGeorge
[@arnydo]: https://github.com/arnydo
[@klaxon1]: https://github.com/klaxon1
[#95]: https://github.com/gchq/CyberChef/pull/299
[#173]: https://github.com/gchq/CyberChef/pull/173
@@ -86,3 +101,7 @@ All notable changes to CyberChef will be documented in this file.
[#338]: https://github.com/gchq/CyberChef/pull/338
[#340]: https://github.com/gchq/CyberChef/pull/340
[#344]: https://github.com/gchq/CyberChef/pull/344
[#348]: https://github.com/gchq/CyberChef/pull/348
[#351]: https://github.com/gchq/CyberChef/pull/351
[#387]: https://github.com/gchq/CyberChef/pull/387
[#394]: https://github.com/gchq/CyberChef/pull/394

View File

@@ -22,7 +22,7 @@ module.exports = function (grunt) {
// Tasks
grunt.registerTask("dev",
"A persistent task which creates a development build whenever source files are modified.",
["clean:dev", "exec:generateConfig", "concurrent:dev"]);
["clean:dev", "clean:config", "exec:generateConfig", "concurrent:dev"]);
grunt.registerTask("node",
"Compiles CyberChef into a single NodeJS module.",
@@ -38,7 +38,7 @@ module.exports = function (grunt) {
grunt.registerTask("prod",
"Creates a production-ready build. Use the --msg flag to add a compile message.",
["eslint", "clean:prod", "exec:generateConfig", "webpack:web", "inline", "chmod"]);
["eslint", "clean:prod", "clean:config", "exec:generateConfig", "webpack:web", "inline", "chmod"]);
grunt.registerTask("default",
"Lints the code base",
@@ -280,7 +280,11 @@ module.exports = function (grunt) {
chunks: false,
modules: false,
entrypoints: false,
warningsFilter: [/source-map/, /dependency is an expression/],
warningsFilter: [
/source-map/,
/dependency is an expression/,
/export 'default'/
],
}
},
start: {
@@ -382,13 +386,13 @@ module.exports = function (grunt) {
"mkdir -p src/core/config/modules",
"echo 'export default {};\n' > src/core/config/modules/OpModules.mjs",
"echo '[]\n' > src/core/config/OperationConfig.json",
"node --experimental-modules src/core/config/scripts/generateOpsIndex.mjs",
"node --experimental-modules src/core/config/scripts/generateConfig.mjs",
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
"echo '--- Config scripts finished. ---\n'"
].join(";")
},
tests: {
command: "node --experimental-modules test/index.mjs"
command: "node --experimental-modules --no-warnings --no-deprecation test/index.mjs"
}
},
});

4131
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "8.6.0",
"version": "8.10.0",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@@ -30,45 +30,44 @@
"main": "build/node/CyberChef.js",
"bugs": "https://github.com/gchq/CyberChef/issues",
"devDependencies": {
"autoprefixer": "^9.1.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"@babel/core": "^7.1.5",
"@babel/preset-env": "^7.1.5",
"autoprefixer": "^9.3.1",
"babel-loader": "^8.0.4",
"bootstrap": "^4.1.3",
"colors": "^1.3.1",
"css-loader": "^1.0.0",
"eslint": "^5.3.0",
"colors": "^1.3.2",
"css-loader": "^1.0.1",
"eslint": "^5.8.0",
"exports-loader": "^0.7.0",
"extract-text-webpack-plugin": "^4.0.0-alpha0",
"file-loader": "^1.1.11",
"file-loader": "^2.0.0",
"grunt": "^1.0.3",
"grunt-accessibility": "~6.0.0",
"grunt-chmod": "~1.1.1",
"grunt-concurrent": "^2.3.1",
"grunt-contrib-clean": "~1.1.0",
"grunt-contrib-clean": "~2.0.0",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "^21.0.0",
"grunt-exec": "~3.0.0",
"grunt-jsdoc": "^2.2.1",
"grunt-webpack": "^3.1.2",
"grunt-jsdoc": "^2.3.0",
"grunt-webpack": "^3.1.3",
"html-webpack-plugin": "^3.2.0",
"imports-loader": "^0.8.0",
"ink-docstrap": "^1.3.2",
"js-to-mjs": "^0.2.0",
"jsdoc-babel": "^0.4.0",
"node-sass": "^4.9.2",
"postcss-css-variables": "^0.9.0",
"postcss-import": "^12.0.0",
"postcss-loader": "^2.1.6",
"jsdoc-babel": "^0.5.0",
"node-sass": "^4.10.0",
"postcss-css-variables": "^0.11.0",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"prompt": "^1.0.0",
"sass-loader": "^7.1.0",
"sitemap": "^1.13.0",
"style-loader": "^0.21.0",
"url-loader": "^1.0.1",
"sitemap": "^2.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"web-resource-inliner": "^4.2.1",
"webpack": "^4.16.4",
"webpack-dev-server": "^3.1.5",
"webpack": "^4.25.1",
"webpack-dev-server": "^3.1.10",
"webpack-node-externals": "^1.7.2",
"worker-loader": "^2.0.0"
},
@@ -77,37 +76,38 @@
"babel-plugin-transform-builtin-extend": "1.1.2",
"babel-polyfill": "^6.26.0",
"bcryptjs": "^2.4.3",
"bignumber.js": "^7.2.1",
"bignumber.js": "^8.0.1",
"bootstrap-colorpicker": "^2.5.3",
"bootstrap-material-design": "^4.1.1",
"bson": "^3.0.2",
"chi-squared": "^1.1.0",
"crypto-api": "^0.8.0",
"crypto-api": "^0.8.3",
"crypto-js": "^3.1.9-1",
"ctph.js": "0.0.5",
"diff": "^3.5.0",
"es6-promisify": "^6.0.0",
"es6-promisify": "^6.0.1",
"escodegen": "^1.11.0",
"esmangle": "^1.0.1",
"esprima": "^4.0.1",
"exif-parser": "^0.1.12",
"file-saver": "^1.3.8",
"highlight.js": "^9.12.0",
"file-saver": "^2.0.0-rc.4",
"highlight.js": "^9.13.1",
"jquery": "^3.3.1",
"js-crc": "^0.2.0",
"js-sha3": "^0.7.0",
"js-sha3": "^0.8.0",
"jsbn": "^1.1.0",
"jsesc": "^2.5.1",
"jsonpath": "^1.0.0",
"jsonwebtoken": "^8.3.0",
"jsrsasign": "8.0.12",
"kbpgp": "^2.0.77",
"lodash": "^4.17.10",
"kbpgp": "^2.0.82",
"lodash": "^4.17.11",
"loglevel": "^1.6.1",
"loglevel-message-prefix": "^3.0.0",
"moment": "^2.22.2",
"moment-timezone": "^0.5.21",
"moment-timezone": "^0.5.23",
"ngeohash": "^0.6.0",
"node-forge": "^0.7.5",
"node-forge": "^0.7.6",
"node-md6": "^0.1.0",
"notepack.io": "^2.1.3",
"nwmatcher": "^1.4.4",
@@ -116,9 +116,9 @@
"scryptsy": "^2.0.0",
"snackbarjs": "^1.1.0",
"sortablejs": "^1.7.0",
"split.js": "^1.3.5",
"split.js": "^1.5.9",
"ssdeep.js": "0.0.2",
"ua-parser-js": "^0.7.18",
"ua-parser-js": "^0.7.19",
"utf8": "^3.0.0",
"vkbeautify": "^0.99.3",
"xmldom": "^0.1.27",
@@ -132,7 +132,6 @@
"test": "grunt test",
"docs": "grunt docs",
"lint": "grunt lint",
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs",
"postinstall": "[ -f node_modules/crypto-api/src/crypto-api.mjs ] || npx j2m node_modules/crypto-api/src/crypto-api.js"
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs"
}
}

View File

@@ -169,7 +169,7 @@ class Dish {
this.value = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toFixed()) : [];
break;
case Dish.JSON:
this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value)) : [];
this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value, null, 4)) : [];
break;
case Dish.FILE:
this.value = await Utils.readFile(this.value);

View File

@@ -555,8 +555,6 @@ class Utils {
if (renderNext) {
cell += b;
renderNext = false;
} else if (b === "\\") {
renderNext = true;
} else if (b === "\"" && !inString) {
inString = true;
} else if (b === "\"" && inString) {

View File

@@ -53,7 +53,8 @@
"To MessagePack",
"From MessagePack",
"To Braille",
"From Braille"
"From Braille",
"Parse TLV"
]
},
{
@@ -89,6 +90,9 @@
"Derive EVP key",
"Bcrypt",
"Scrypt",
"JWT Sign",
"JWT Verify",
"JWT Decode",
"Pseudo-Random Number Generator"
]
},
@@ -155,7 +159,8 @@
"Change IP format",
"Group IP addresses",
"Encode NetBIOS Name",
"Decode NetBIOS Name"
"Decode NetBIOS Name",
"Defang URL"
]
},
{
@@ -163,6 +168,7 @@
"ops": [
"Encode text",
"Decode text",
"Remove Diacritics",
"Unescape Unicode Characters"
]
},

View File

@@ -39,3 +39,21 @@ export function search (input, searchRegex, removeRegex, includeTotal) {
return output;
}
/**
* URL regular expression
*/
const protocol = "[A-Z]+://",
hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+",
port = ":\\d+",
path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*" +
"(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*";
export const URL_REGEX = new RegExp(protocol + hostname + "(?:" + port + ")?(?:" + path + ")?", "ig");
/**
* Domain name regular expression
*/
export const DOMAIN_REGEX = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;

View File

@@ -3,6 +3,7 @@
*
* @author picapi
* @author n1474335 [n1474335@gmail.com]
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
@@ -109,8 +110,8 @@ export function ipv6CidrRange(cidr, includeNetworkInfo) {
* @returns {string}
*/
export function ipv4HyphenatedRange(range, includeNetworkInfo, enumerateAddresses, allowLargeList) {
const ip1 = strToIpv4(range[1]),
ip2 = strToIpv4(range[2]);
const ip1 = strToIpv4(range[0].split("-")[0].trim()),
ip2 = strToIpv4(range[0].split("-")[1].trim());
let output = "";
@@ -162,8 +163,8 @@ Total addresses in range: ${(((ip2 - ip1) >>> 0) + 1)}
* @returns {string}
*/
export function ipv6HyphenatedRange(range, includeNetworkInfo) {
const ip1 = strToIpv6(range[1]),
ip2 = strToIpv6(range[14]),
const ip1 = strToIpv6(range[0].split("-")[0].trim()),
ip2 = strToIpv6(range[0].split("-")[1].trim()),
total = new Array(128).fill();
let output = "",
@@ -188,6 +189,93 @@ export function ipv6HyphenatedRange(range, includeNetworkInfo) {
return output;
}
/**
* Parses a list of IPv4 addresses separated by a new line (\n) and displays information
* about it.
*
* @param {RegExp} list
* @param {boolean} includeNetworkInfo
* @param {boolean} enumerateAddresses
* @param {boolean} allowLargeList
* @returns {string}
*/
export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList) {
let ipv4List = match[0].split("\n");
ipv4List = ipv4List.filter(Boolean);
const ipv4CidrList = ipv4List.filter(function(a) {
return a.includes("/");
});
for (let i = 0; i < ipv4CidrList.length; i++) {
const network = strToIpv4(ipv4CidrList[i].split("/")[0]);
const cidrRange = parseInt(ipv4CidrList[i].split("/")[1], 10);
if (cidrRange < 0 || cidrRange > 31) {
return "IPv4 CIDR must be less than 32";
}
const mask = ~(0xFFFFFFFF >>> cidrRange),
cidrIp1 = network & mask,
cidrIp2 = cidrIp1 | ~mask;
ipv4List.splice(ipv4List.indexOf(ipv4CidrList[i]), 1);
ipv4List.push(ipv4ToStr(cidrIp1), ipv4ToStr(cidrIp2));
}
ipv4List = ipv4List.sort(ipv4Compare);
const ip1 = ipv4List[0];
const ip2 = ipv4List[ipv4List.length - 1];
const range = [ip1 + " - " + ip2];
return ipv4HyphenatedRange(range, includeNetworkInfo, enumerateAddresses, allowLargeList);
}
/**
* Parses a list of IPv6 addresses separated by a new line (\n) and displays information
* about it.
*
* @param {RegExp} list
* @param {boolean} includeNetworkInfo
* @returns {string}
*/
export function ipv6ListedRange(match, includeNetworkInfo) {
let ipv6List = match[0].split("\n");
ipv6List = ipv6List.filter(function(str) {
return str.trim();
});
for (let i =0; i < ipv6List.length; i++){
ipv6List[i] = ipv6List[i].trim();
}
const ipv6CidrList = ipv6List.filter(function(a) {
return a.includes("/");
});
for (let i = 0; i < ipv6CidrList.length; i++) {
const network = strToIpv6(ipv6CidrList[i].split("/")[0]);
const cidrRange = parseInt(ipv6CidrList[i].split("/")[1], 10);
if (cidrRange < 0 || cidrRange > 127) {
return "IPv6 CIDR must be less than 128";
}
const cidrIp1 = new Array(8),
cidrIp2 = new Array(8);
const mask = genIpv6Mask(cidrRange);
for (let j = 0; j < 8; j++) {
cidrIp1[j] = network[j] & mask[j];
cidrIp2[j] = cidrIp1[j] | (~mask[j] & 0x0000FFFF);
}
ipv6List.splice(ipv6List.indexOf(ipv6CidrList[i]), 1);
ipv6List.push(ipv6ToStr(cidrIp1), ipv6ToStr(cidrIp2));
}
ipv6List = ipv6List.sort(ipv6Compare);
const ip1 = ipv6List[0];
const ip2 = ipv6List[ipv6List.length - 1];
const range = [ip1 + " - " + ip2];
return ipv6HyphenatedRange(range, includeNetworkInfo);
}
/**
* Converts an IPv4 address from string format to numerical format.
*
@@ -391,6 +479,37 @@ export function genIpv6Mask(cidr) {
return mask;
}
/**
* Comparison operation for sorting of IPv4 addresses.
*
* @param {string} a
* @param {string} b
* @returns {number}
*/
export function ipv4Compare(a, b) {
return strToIpv4(a) - strToIpv4(b);
}
/**
* Comparison operation for sorting of IPv6 addresses.
*
* @param {string} a
* @param {string} b
* @returns {number}
*/
export function ipv6Compare(a, b) {
const a_ = strToIpv6(a),
b_ = strToIpv6(b);
for (let i = 0; i < a_.length; i++){
if (a_[i] !== b_[i]){
return a_[i] - b_[i];
}
}
return 0;
}
const _LARGE_RANGE_ERROR = "The specified range contains more than 65,536 addresses. Running this query could crash your browser. If you want to run it, select the \"Allow large queries\" option. You are advised to turn off \"Auto Bake\" whilst editing large ranges.";
/**

View File

@@ -0,0 +1,78 @@
/**
* Parser for Type-length-value data.
*
* @author gchq77703 []
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
const defaults = {
location: 0,
bytesInLength: 1,
basicEncodingRules: false
};
/**
* TLVParser library
*/
export default class TLVParser {
/**
* TLVParser constructor
*
* @param {byteArray} input
* @param {Object} options
*/
constructor(input, options) {
this.input = input;
Object.assign(this, defaults, options);
}
/**
* @returns {number}
*/
getLength() {
if (this.basicEncodingRules) {
const bit = this.input[this.location];
if (bit & 0x80) {
this.bytesInLength = bit & ~0x80;
} else {
this.location++;
return bit & ~0x80;
}
}
let length = 0;
for (let i = 0; i < this.bytesInLength; i++) {
length += this.input[this.location] * Math.pow(Math.pow(2, 8), i);
this.location++;
}
return length;
}
/**
* @param {number} length
* @returns {number[]}
*/
getValue(length) {
const value = [];
for (let i = 0; i < length; i++) {
if (this.location > this.input.length) return value;
value.push(this.input[this.location]);
this.location++;
}
return value;
}
/**
* @returns {boolean}
*/
atEnd() {
return this.input.length <= this.location;
}
}

View File

@@ -5,7 +5,7 @@
*/
import Operation from "../Operation";
import bzip2 from "../vendor/bzip2.js";
import bzip2 from "../vendor/bzip2";
import OperationError from "../errors/OperationError";
/**

View File

@@ -0,0 +1,102 @@
/**
* @author arnydo [arnydo@protonmail.com]
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import {URL_REGEX, DOMAIN_REGEX} from "../lib/Extract";
/**
* DefangURL operation
*/
class DefangURL extends Operation {
/**
* DefangURL constructor
*/
constructor() {
super();
this.name = "Defang URL";
this.module = "Default";
this.description = "Takes a Universal Resource Locator (URL) and 'Defangs' it; meaning the URL becomes invalid, neutralising the risk of accidentally clicking on a malicious link.<br><br>This is often used when dealing with malicious links or IOCs.<br><br>Works well when combined with the 'Extract URLs' operation.";
this.infoURL = "https://isc.sans.edu/forums/diary/Defang+all+the+things/22744/";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "Escape dots",
type: "boolean",
value: true
},
{
name: "Escape http",
type: "boolean",
value: true
},
{
name: "Escape ://",
type: "boolean",
value: true
},
{
name: "Process",
type: "option",
value: ["Valid domains and full URLs", "Only full URLs", "Everything"]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [dots, http, slashes, process] = args;
switch (process) {
case "Valid domains and full URLs":
input = input.replace(URL_REGEX, x => {
return defangURL(x, dots, http, slashes);
});
input = input.replace(DOMAIN_REGEX, x => {
return defangURL(x, dots, http, slashes);
});
break;
case "Only full URLs":
input = input.replace(URL_REGEX, x => {
return defangURL(x, dots, http, slashes);
});
break;
case "Everything":
input = defangURL(input, dots, http, slashes);
break;
}
return input;
}
}
/**
* Defangs a given URL
*
* @param {string} url
* @param {boolean} dots
* @param {boolean} http
* @param {boolean} slashes
* @returns {string}
*/
function defangURL(url, dots, http, slashes) {
if (dots) url = url.replace(/\./g, "[.]");
if (http) url = url.replace(/http/gi, "hxxp");
if (slashes) url = url.replace(/:\/\//g, "[://]");
return url;
}
export default DefangURL;

View File

@@ -5,7 +5,7 @@
*/
import Operation from "../Operation";
import { search } from "../lib/Extract";
import { search, DOMAIN_REGEX } from "../lib/Extract";
/**
* Extract domains operation
@@ -38,10 +38,8 @@ class ExtractDomains extends Operation {
* @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);
const displayTotal = args[0];
return search(input, DOMAIN_REGEX, null, displayTotal);
}
}

View File

@@ -39,8 +39,8 @@ class ExtractEmailAddresses extends Operation {
*/
run(input, args) {
const displayTotal = args[0],
regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig;
// email regex from: https://www.regextester.com/98066
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ig;
return search(input, regex, null, displayTotal);
}

View File

@@ -5,7 +5,7 @@
*/
import Operation from "../Operation";
import { search } from "../lib/Extract";
import { search, URL_REGEX } from "../lib/Extract";
/**
* Extract URLs operation
@@ -38,16 +38,8 @@ class ExtractURLs extends Operation {
* @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);
const displayTotal = args[0];
return search(input, URL_REGEX, null, displayTotal);
}
}

View File

@@ -71,6 +71,11 @@ class FromBase58 extends Operation {
if (input.length === 0) return [];
let zeroPrefix = 0;
for (let i = 0; i < input.length && input[i] === alphabet[0]; i++) {
zeroPrefix++;
}
[].forEach.call(input, function(c, charIndex) {
const index = alphabet.indexOf(c);
@@ -98,6 +103,10 @@ class FromBase58 extends Operation {
}
});
while (zeroPrefix--) {
result.push(0);
}
return result.reverse();
}

View File

@@ -29,38 +29,43 @@ class FromDecimal extends Operation {
"name": "Delimiter",
"type": "option",
"value": DELIM_OPTIONS
},
{
"name": "Support signed values",
"type": "boolean",
"value": false
}
];
this.patterns = [
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Space"]
args: ["Space", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Comma"]
args: ["Comma", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Semi-colon"]
args: ["Semi-colon", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Colon"]
args: ["Colon", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["Line feed"]
args: ["Line feed", false]
},
{
match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$",
flags: "",
args: ["CRLF"]
args: ["CRLF", false]
},
];
}
@@ -71,7 +76,11 @@ class FromDecimal extends Operation {
* @returns {byteArray}
*/
run(input, args) {
return fromDecimal(input, args[0]);
let data = fromDecimal(input, args[0]);
if (args[1]) { // Convert negatives
data = data.map(v => v < 0 ? 0xFF + v + 1 : v);
}
return data;
}
}

View File

@@ -28,8 +28,9 @@ class HMAC extends Operation {
this.args = [
{
"name": "Key",
"type": "binaryString",
"value": ""
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "Decimal", "Base64", "UTF8", "Latin1"]
},
{
"name": "Hashing function",
@@ -66,18 +67,11 @@ class HMAC extends Operation {
* @returns {string}
*/
run(input, args) {
const key = args[0],
const key = Utils.convertToByteString(args[0].string || "", args[0].option),
hashFunc = args[1].toLowerCase(),
msg = Utils.arrayBufferToStr(input, false),
hasher = CryptoApi.getHasher(hashFunc);
// Horrible shim to fix constructor bug. Reported in nf404/crypto-api#8
hasher.reset = () => {
hasher.state = {};
const tmp = new hasher.constructor();
hasher.state = tmp.state;
};
const mac = CryptoApi.getHmac(CryptoApi.encoder.fromUtf(key), hasher);
mac.update(msg);
return CryptoApi.encoder.toHex(mac.finalize());

View File

@@ -0,0 +1,51 @@
/**
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import jwt from "jsonwebtoken";
import OperationError from "../errors/OperationError";
/**
* JWT Decode operation
*/
class JWTDecode extends Operation {
/**
* JWTDecode constructor
*/
constructor() {
super();
this.name = "JWT Decode";
this.module = "Crypto";
this.description = "Decodes a JSON Web Token <b>without</b> checking whether the provided secret / private key is valid. Use 'JWT Verify' to check if the signature is valid as well.";
this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token";
this.inputType = "string";
this.outputType = "JSON";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {JSON}
*/
run(input, args) {
try {
const decoded = jwt.decode(input, {
json: true,
complete: true
});
return decoded.payload;
} catch (err) {
throw new OperationError(err);
}
}
}
export default JWTDecode;

View File

@@ -0,0 +1,74 @@
/**
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import jwt from "jsonwebtoken";
import OperationError from "../errors/OperationError";
/**
* JWT Sign operation
*/
class JWTSign extends Operation {
/**
* JWTSign constructor
*/
constructor() {
super();
this.name = "JWT Sign";
this.module = "Crypto";
this.description = "Signs a JSON object as a JSON Web Token using a provided secret / private key.<br><br>The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.";
this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token";
this.inputType = "JSON";
this.outputType = "string";
this.args = [
{
name: "Private/Secret Key",
type: "text",
value: "secret"
},
{
name: "Signing algorithm",
type: "option",
value: [
"HS256",
"HS384",
"HS512",
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512",
"None"
]
}
];
}
/**
* @param {JSON} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [key, algorithm] = args;
try {
return jwt.sign(input, key, {
algorithm: algorithm === "None" ? "none" : algorithm
});
} catch (err) {
throw new OperationError(`Error: Have you entered the key correctly? The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.
${err}`);
}
}
}
export default JWTSign;

View File

@@ -0,0 +1,65 @@
/**
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import jwt from "jsonwebtoken";
import OperationError from "../errors/OperationError";
/**
* JWT Verify operation
*/
class JWTVerify extends Operation {
/**
* JWTVerify constructor
*/
constructor() {
super();
this.name = "JWT Verify";
this.module = "Crypto";
this.description = "Verifies that a JSON Web Token is valid and has been signed with the provided secret / private key.<br><br>The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.";
this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token";
this.inputType = "string";
this.outputType = "JSON";
this.args = [
{
name: "Private/Secret Key",
type: "text",
value: "secret"
},
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [key] = args;
try {
const verified = jwt.verify(input, key, { algorithms: [
"HS256",
"HS384",
"HS512",
"none"
]});
if (verified.hasOwnProperty("name") && verified.name === "JsonWebTokenError") {
throw new OperationError(verified.message);
}
return verified;
} catch (err) {
throw new OperationError(err);
}
}
}
export default JWTVerify;

View File

@@ -1,12 +1,13 @@
/**
* @author n1474335 [n1474335@gmail.com]
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation";
import OperationError from "../errors/OperationError";
import {ipv4CidrRange, ipv4HyphenatedRange, ipv6CidrRange, ipv6HyphenatedRange} from "../lib/IP";
import {ipv4CidrRange, ipv4HyphenatedRange, ipv4ListedRange, ipv6CidrRange, ipv6HyphenatedRange, ipv6ListedRange} from "../lib/IP";
/**
* Parse IP range operation
@@ -21,7 +22,7 @@ class ParseIPRange extends Operation {
this.name = "Parse IP range";
this.module = "JSBN";
this.description = "Given a CIDR range (e.g. <code>10.0.0.0/24</code>) or a hyphenated range (e.g. <code>10.0.0.0 - 10.0.1.0</code>), this operation provides network information and enumerates all IP addresses in the range.<br><br>IPv6 is supported but will not be enumerated.";
this.description = "Given a CIDR range (e.g. <code>10.0.0.0/24</code>), hyphenated range (e.g. <code>10.0.0.0 - 10.0.1.0</code>), or a list of IPs and/or CIDR ranges (separated by a new line), this operation provides network information and enumerates all IP addresses in the range.<br><br>IPv6 is supported but will not be enumerated.";
this.infoURL = "https://wikipedia.org/wiki/Subnetwork";
this.inputType = "string";
this.outputType = "string";
@@ -59,18 +60,24 @@ class ParseIPRange extends Operation {
// Check what type of input we are looking at
const ipv4CidrRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\/(\d\d?)\s*$/,
ipv4RangeRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*-\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/,
ipv4ListRegex = /^\s*(((?:\d{1,3}\.){3}\d{1,3})(\/(\d\d?))?(\n|$)(\n*))+\s*$/,
ipv6CidrRegex = /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\/(\d\d?\d?)\s*$/i,
ipv6RangeRegex = /^\s*(((?=.*::)(?!.*::[^-]+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*-\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\17)::|:\b|(?![\dA-F])))|(?!\16\17)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i;
ipv6RangeRegex = /^\s*(((?=.*::)(?!.*::[^-]+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*-\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\17)::|:\b|(?![\dA-F])))|(?!\16\17)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i,
ipv6ListRegex = /^\s*((((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))(\/(\d\d?\d?))?(\n|$)(\n*))+\s*$/i;
let match;
if ((match = ipv4CidrRegex.exec(input))) {
return ipv4CidrRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList);
} else if ((match = ipv4RangeRegex.exec(input))) {
return ipv4HyphenatedRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList);
} else if ((match = ipv4ListRegex.exec(input))) {
return ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList);
} else if ((match = ipv6CidrRegex.exec(input))) {
return ipv6CidrRange(match, includeNetworkInfo);
} else if ((match = ipv6RangeRegex.exec(input))) {
return ipv6HyphenatedRange(match, includeNetworkInfo);
} else if ((match = ipv6ListRegex.exec(input))) {
return ipv6ListedRange(match, includeNetworkInfo);
} else {
throw new OperationError("Invalid input.\n\nEnter either a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0). IPv6 also supported.");
}

View File

@@ -0,0 +1,76 @@
/**
* @author gchq77703 []
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
import TLVParser from "../lib/TLVParser";
import OperationError from "../errors/OperationError";
/**
* Parse TLV operation
*/
class ParseTLV extends Operation {
/**
* ParseTLV constructor
*/
constructor() {
super();
this.name = "Parse TLV";
this.module = "Default";
this.description = "Converts a Type-Length-Value (TLV) encoded string into a JSON object. Can optionally include a <code>Key</code> / <code>Type</code> entry. <br><br>Tags: Key-Length-Value, KLV, Length-Value, LV";
this.infoURL = "https://wikipedia.org/wiki/Type-length-value";
this.inputType = "byteArray";
this.outputType = "JSON";
this.args = [
{
name: "Type/Key size",
type: "number",
value: 1
},
{
name: "Length size",
type: "number",
value: 1
},
{
name: "Use BER",
type: "boolean",
value: false
}
];
}
/**
* @param {byteArray} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [bytesInKey, bytesInLength, basicEncodingRules] = args;
if (bytesInKey <= 0 && bytesInLength <= 0)
throw new OperationError("Type or Length size must be greater than 0");
const tlv = new TLVParser(input, { bytesInLength, basicEncodingRules });
const data = [];
while (!tlv.atEnd()) {
const key = bytesInKey ? tlv.getValue(bytesInKey) : undefined;
const length = tlv.getLength();
const value = tlv.getValue(length);
data.push({ key, length, value });
}
return data;
}
}
export default ParseTLV;

View File

@@ -227,6 +227,7 @@ function regexList (input, regex, displayTotal, matches, captureGroups) {
*/
function regexHighlight (input, regex, displayTotal) {
let output = "",
title = "",
m,
hl = 1,
i = 0,
@@ -241,8 +242,16 @@ function regexHighlight (input, regex, displayTotal) {
// Add up to match
output += Utils.escapeHtml(input.slice(i, m.index));
title = `Offset: ${m.index}\n`;
if (m.length > 1) {
title += "Groups:\n";
for (let n = 1; n < m.length; ++n) {
title += `\t${n}: ${m[n]}\n`;
}
}
// Add match with highlighting
output += "<span class='hl"+hl+"'>" + Utils.escapeHtml(m[0]) + "</span>";
output += "<span class='hl"+hl+"' title='"+title+"'>" + Utils.escapeHtml(m[0]) + "</span>";
// Switch highlight
hl = hl === 1 ? 2 : 1;

View File

@@ -0,0 +1,41 @@
/**
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import Operation from "../Operation";
/**
* Remove Diacritics operation
*/
class RemoveDiacritics extends Operation {
/**
* RemoveDiacritics constructor
*/
constructor() {
super();
this.name = "Remove Diacritics";
this.module = "Default";
this.description = "Replaces accented characters with their latin character equivalent.";
this.infoURL = "https://wikipedia.org/wiki/Diacritic";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
// reference: https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript/37511463
return input.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
}
}
export default RemoveDiacritics;

View File

@@ -62,7 +62,7 @@ class Scrypt extends Operation {
* @returns {string}
*/
run(input, args) {
const salt = Utils.convertToByteString(args[0].string || "", args[0].option),
const salt = Buffer.from(Utils.convertToByteArray(args[0].string || "", args[0].option)),
iterations = args[1],
memFactor = args[2],
parallelFactor = args[3],

View File

@@ -53,6 +53,11 @@ class ToBase58 extends Operation {
if (input.length === 0) return "";
let zeroPrefix = 0;
for (let i = 0; i < input.length && input[i] === 0; i++) {
zeroPrefix++;
}
input.forEach(function(b) {
let carry = (result[0] << 8) + b;
result[0] = carry % 58;
@@ -74,7 +79,7 @@ class ToBase58 extends Operation {
return alphabet[b];
}).reverse().join("");
while (result.length < input.length) {
while (zeroPrefix--) {
result = alphabet[0] + result;
}

View File

@@ -30,6 +30,11 @@ class ToDecimal extends Operation {
"name": "Delimiter",
"type": "option",
"value": DELIM_OPTIONS
},
{
"name": "Support signed values",
"type": "boolean",
"value": false
}
];
}
@@ -40,7 +45,11 @@ class ToDecimal extends Operation {
* @returns {string}
*/
run(input, args) {
const delim = Utils.charRep(args[0]);
const delim = Utils.charRep(args[0]),
signed = args[1];
if (signed) {
input = input.map(v => v > 0x7F ? v - 0xFF - 1 : v);
}
return input.join(delim);
}

View File

@@ -20,7 +20,7 @@ class Whirlpool extends Operation {
this.name = "Whirlpool";
this.module = "Hashing";
this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>";
this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Whirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>";
this.infoURL = "https://wikipedia.org/wiki/Whirlpool_(cryptography)";
this.inputType = "ArrayBuffer";
this.outputType = "string";

View File

@@ -262,4 +262,4 @@ bzip2.decompress = function(bits, size, len){
return output;
}
module.exports = bzip2;
export default bzip2;

View File

@@ -67,6 +67,7 @@ class BackgroundWorkerWaiter {
log.debug("Background ChefWorker loaded");
break;
case "optionUpdate":
case "statusMessage":
// Ignore these messages
break;
default:

View File

@@ -154,7 +154,7 @@ class HTMLIngredient {
} else if ((m = this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i))) {
html += "</optgroup>";
} else {
html += `<option populate-value="${this.value[i].value}">${this.value[i].name}</option>`;
html += `<option populate-value='${this.value[i].value}'>${this.value[i].name}</option>`;
}
}
html += `</select>

View File

@@ -131,14 +131,16 @@ class HTMLOperation {
*/
function titleFromWikiLink(url) {
const splitURL = url.split("/");
if (splitURL.indexOf("wiki") < 0) {
if (splitURL.indexOf("wikipedia.org") < 0 && splitURL.indexOf("forensicswiki.org") < 0) {
// Not a wiki link, return full URL
return `<a href='${url}' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a>`;
}
const wikiName = splitURL.indexOf("forensicswiki.org") < 0 ? "Wikipedia" : "Forensics Wiki";
const pageTitle = decodeURIComponent(splitURL[splitURL.length - 1])
.replace(/_/g, " ");
return `<a href='${url}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on Wikipedia`;
return `<a href='${url}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on ${wikiName}`;
}
export default HTMLOperation;

View File

@@ -116,6 +116,13 @@ div.toggle-string {
left: 12px;
}
.operation label.bmd-label-floating {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: calc(100% - 13px);
}
.operation .bmd-form-group .bmd-help {
margin-top: -17px;
}
@@ -172,6 +179,7 @@ div.toggle-string {
background-color: var(--fc-operation-border-colour);
font-family: var(--fixed-width-font-family);
padding: 10px;
word-break: break-all;
}
.op-icon {

View File

@@ -24,48 +24,57 @@ global.ENVIRONMENT_IS_WEB = function() {
};
import TestRegister from "./TestRegister";
import "./tests/operations/BCD";
import "./tests/operations/BSON";
import "./tests/operations/Base58";
import "./tests/operations/Base64";
import "./tests/operations/BCD";
import "./tests/operations/BitwiseOp";
import "./tests/operations/BSON";
import "./tests/operations/ByteRepr";
import "./tests/operations/CartesianProduct";
import "./tests/operations/CharEnc";
import "./tests/operations/Ciphers";
import "./tests/operations/Checksum";
import "./tests/operations/Ciphers";
import "./tests/operations/Code";
import "./tests/operations/Comment";
import "./tests/operations/Compress";
import "./tests/operations/ConditionalJump";
import "./tests/operations/Crypt";
import "./tests/operations/DateTime";
import "./tests/operations/ExtractEmailAddresses";
import "./tests/operations/Fork";
import "./tests/operations/Jump";
import "./tests/operations/ConditionalJump";
import "./tests/operations/Register";
import "./tests/operations/Comment";
import "./tests/operations/FromDecimal";
import "./tests/operations/FromGeohash";
import "./tests/operations/Hash";
import "./tests/operations/HaversineDistance";
import "./tests/operations/Hexdump";
import "./tests/operations/Image";
import "./tests/operations/MorseCode";
import "./tests/operations/Jump";
import "./tests/operations/JWTDecode";
import "./tests/operations/JWTSign";
import "./tests/operations/JWTVerify";
import "./tests/operations/MS";
import "./tests/operations/PGP";
import "./tests/operations/PHP";
import "./tests/operations/Magic";
import "./tests/operations/MorseCode";
import "./tests/operations/NetBIOS";
import "./tests/operations/OTP";
import "./tests/operations/PGP";
import "./tests/operations/PHP";
import "./tests/operations/ParseIPRange";
import "./tests/operations/PowerSet";
import "./tests/operations/Regex";
import "./tests/operations/Register";
import "./tests/operations/RemoveDiacritics";
import "./tests/operations/Rotate";
import "./tests/operations/StrUtils";
import "./tests/operations/SeqUtils";
import "./tests/operations/SetDifference";
import "./tests/operations/SetIntersection";
import "./tests/operations/SetUnion";
import "./tests/operations/StrUtils";
import "./tests/operations/SymmetricDifference";
import "./tests/operations/ToGeohash.mjs";
import "./tests/operations/TranslateDateTimeFormat";
import "./tests/operations/Magic";
import "./tests/operations/ToGeohash.mjs";
import "./tests/operations/FromGeohash.mjs";
import "./tests/operations/ParseTLV";
let allTestsPassing = true;
const testStatusCounts = {
@@ -144,4 +153,3 @@ TestRegister.runTests()
process.exit(allTestsPassing ? 0 : 1);
});

View File

@@ -53,6 +53,28 @@ TestRegister.addTests([
},
],
},
{
name: "To Base58 with null prefix and suffix",
input: "\0\0\0Hello\0\0\0",
expectedOutput: "111D7LMXYjHjTu",
recipeConfig: [
{
op: "To Base58",
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"],
},
],
},
{
name: "From Base58 with null prefix and suffix",
input: "111D7LMXYjHjTu",
expectedOutput: "\0\0\0Hello\0\0\0",
recipeConfig: [
{
op: "From Base58",
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"],
},
],
},
{
name: "From Base58 (Bitcoin): 'StV1DL6CwTryKyV'",
input: "StV1DL6CwTryKyV",

View File

@@ -380,7 +380,7 @@ TestRegister.addTests([
{
name: "From MessagePack: valid msgpack",
input: "81 a5 73 74 6f 72 65 83 a4 62 6f 6f 6b 94 84 a8 63 61 74 65 67 6f 72 79 a9 72 65 66 65 72 65 6e 63 65 a6 61 75 74 68 6f 72 aa 4e 69 67 65 6c 20 52 65 65 73 a5 74 69 74 6c 65 b6 53 61 79 69 6e 67 73 20 6f 66 20 74 68 65 20 43 65 6e 74 75 72 79 a5 70 72 69 63 65 cb 40 21 e6 66 66 66 66 66 84 a8 63 61 74 65 67 6f 72 79 a7 66 69 63 74 69 6f 6e a6 61 75 74 68 6f 72 ac 45 76 65 6c 79 6e 20 57 61 75 67 68 a5 74 69 74 6c 65 af 53 77 6f 72 64 20 6f 66 20 48 6f 6e 6f 75 72 a5 70 72 69 63 65 cb 40 29 fa e1 47 ae 14 7b 85 a8 63 61 74 65 67 6f 72 79 a7 66 69 63 74 69 6f 6e a6 61 75 74 68 6f 72 af 48 65 72 6d 61 6e 20 4d 65 6c 76 69 6c 6c 65 a5 74 69 74 6c 65 a9 4d 6f 62 79 20 44 69 63 6b a4 69 73 62 6e ad 30 2d 35 35 33 2d 32 31 33 31 31 2d 33 a5 70 72 69 63 65 cb 40 21 fa e1 47 ae 14 7b 85 a8 63 61 74 65 67 6f 72 79 a7 66 69 63 74 69 6f 6e a6 61 75 74 68 6f 72 b0 4a 2e 20 52 2e 20 52 2e 20 54 6f 6c 6b 69 65 6e a5 74 69 74 6c 65 b5 54 68 65 20 4c 6f 72 64 20 6f 66 20 74 68 65 20 52 69 6e 67 73 a4 69 73 62 6e ad 30 2d 33 39 35 2d 31 39 33 39 35 2d 38 a5 70 72 69 63 65 cb 40 36 fd 70 a3 d7 0a 3d a7 62 69 63 79 63 6c 65 82 a5 63 6f 6c 6f 72 a3 72 65 64 a5 70 72 69 63 65 cb 40 33 f3 33 33 33 33 33 a9 6e 65 77 73 70 61 70 65 72 92 83 a6 66 6f 72 6d 61 74 aa 62 72 6f 61 64 73 68 65 65 74 a5 74 69 74 6c 65 af 46 69 6e 61 6e 63 69 61 6c 20 54 69 6d 65 73 a5 70 72 69 63 65 cb 40 06 00 00 00 00 00 00 83 a6 66 6f 72 6d 61 74 a7 74 61 62 6c 6f 69 64 a5 74 69 74 6c 65 ac 54 68 65 20 47 75 61 72 64 69 61 6e a5 70 72 69 63 65 02",
expectedOutput: JSON.stringify(JSON_TEST_DATA),
expectedOutput: JSON.stringify(JSON_TEST_DATA, null, 4),
recipeConfig: [
{
"op": "From Hex",

View File

@@ -0,0 +1,55 @@
/**
* extract email address tests.
*
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "Extract email address",
input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n",
recipeConfig: [
{
"op": "Extract email addresses",
"args": [false]
},
],
},
{
name: "Extract email address - Display total",
input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n",
recipeConfig: [
{
"op": "Extract email addresses",
"args": [true]
},
],
},
{
name: "Extract email address (Internationalized)",
input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n",
recipeConfig: [
{
"op": "Extract email addresses",
"args": [false]
},
],
},
{
name: "Extract email address - Display total (Internationalized)",
input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n",
recipeConfig: [
{
"op": "Extract email addresses",
"args": [true]
},
],
},
]);

View File

@@ -0,0 +1,33 @@
/**
* From Decimal tests
*
* @author qistoph
* @copyright Crown Copyright 2018
* @licence Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "From Decimal",
input: "83 97 109 112 108 101 32 84 101 120 116",
expectedOutput: "Sample Text",
recipeConfig: [
{
op: "From Decimal",
args: ["Space", false]
},
],
},
{
name: "From Decimal with negatives",
input: "-130,-140,-152,-151,115,33,0,-1",
expectedOutput: "~this!\u0000\u00ff",
recipeConfig: [
{
op: "From Decimal",
args: ["Comma", true]
},
],
},
]);

View File

@@ -411,7 +411,7 @@ TestRegister.addTests([
recipeConfig: [
{
"op": "HMAC",
"args": ["test", "SHA256"]
"args": [{"option": "Latin1", "string": "test"}, "SHA256"]
}
]
},

View File

@@ -0,0 +1,51 @@
/**
* JWT Decode tests
*
* @author gchq77703 []
*
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
const outputObject = JSON.stringify({
String: "SomeString",
Number: 42,
iat: 1
}, null, 4);
TestRegister.addTests([
{
name: "JWT Decode: HS",
input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk",
expectedOutput: outputObject,
recipeConfig: [
{
op: "JWT Decode",
args: [],
}
],
},
{
name: "JWT Decode: RS",
input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y",
expectedOutput: outputObject,
recipeConfig: [
{
op: "JWT Decode",
args: [],
}
],
},
{
name: "JWT Decode: ES",
input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA",
expectedOutput: outputObject,
recipeConfig: [
{
op: "JWT Decode",
args: [],
}
],
}
]);

View File

@@ -0,0 +1,163 @@
/**
* JWT Sign tests
*
* @author gchq77703 []
*
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
const inputObject = JSON.stringify({
String: "SomeString",
Number: 42,
iat: 1
}, null, 4);
const hsKey = "secret_cat";
const rsKey = `-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS
3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp
uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE
2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0
GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K
Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY
6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5
fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
-----END RSA PRIVATE KEY-----`;
const esKey = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
-----END PRIVATE KEY-----`;
TestRegister.addTests([
{
name: "JWT Sign: HS256",
input: inputObject,
expectedOutput: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk",
recipeConfig: [
{
op: "JWT Sign",
args: [hsKey, "HS256"],
}
],
},
{
name: "JWT Sign: HS384",
input: inputObject,
expectedOutput: "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ._bPK-Y3mIACConbJqkGFMQ_L3vbxgKXy9gSxtL9hA5XTganozTSXxD0vX0N1yT5s",
recipeConfig: [
{
op: "JWT Sign",
args: [hsKey, "HS384"],
}
],
},
{
name: "JWT Sign: HS512",
input: inputObject,
expectedOutput: "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.vZIJU4XYMFt3FLE1V_RZOxEetmV4RvxtPZQGzJthK_d47pjwlEb6pQE23YxHFmOj8H5RLEdqqLPw4jNsOyHRzA",
recipeConfig: [
{
op: "JWT Sign",
args: [hsKey, "HS512"],
}
],
},
{
name: "JWT Sign: ES256",
input: inputObject,
expectedOutput: inputObject,
recipeConfig: [
{
op: "JWT Sign",
args: [esKey, "ES256"],
},
{
op: "JWT Decode",
args: []
}
],
},
{
name: "JWT Sign: ES384",
input: inputObject,
expectedOutput: inputObject,
recipeConfig: [
{
op: "JWT Sign",
args: [esKey, "ES384"],
},
{
op: "JWT Decode",
args: []
}
],
},
{
name: "JWT Sign: ES512",
input: inputObject,
expectedOutput: inputObject,
recipeConfig: [
{
op: "JWT Sign",
args: [esKey, "ES512"],
},
{
op: "JWT Decode",
args: []
}
],
},
{
name: "JWT Sign: RS256",
input: inputObject,
expectedOutput: inputObject,
recipeConfig: [
{
op: "JWT Sign",
args: [rsKey, "RS256"],
},
{
op: "JWT Decode",
args: []
}
],
},
{
name: "JWT Sign: RS384",
input: inputObject,
expectedOutput: inputObject,
recipeConfig: [
{
op: "JWT Sign",
args: [rsKey, "RS384"],
},
{
op: "JWT Decode",
args: []
}
],
},
{
name: "JWT Sign: RS512",
input: inputObject,
expectedOutput: inputObject,
recipeConfig: [
{
op: "JWT Sign",
args: [esKey, "RS512"],
},
{
op: "JWT Decode",
args: []
}
],
}
]);

View File

@@ -0,0 +1,75 @@
/**
* JWT Verify tests
*
* @author gchq77703 []
*
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
const outputObject = JSON.stringify({
String: "SomeString",
Number: 42,
iat: 1
}, null, 4);
const invalidAlgorithm = "JsonWebTokenError: invalid algorithm";
const hsKey = "secret_cat";
const rsKey = `-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS
3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp
uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE
2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0
GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K
Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY
6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5
fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
-----END RSA PRIVATE KEY-----`;
const esKey = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
-----END PRIVATE KEY-----`;
TestRegister.addTests([
{
name: "JWT Verify: HS",
input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk",
expectedOutput: outputObject,
recipeConfig: [
{
op: "JWT Verify",
args: [hsKey],
}
],
},
{
name: "JWT Verify: RS",
input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y",
expectedOutput: invalidAlgorithm,
recipeConfig: [
{
op: "JWT Verify",
args: [rsKey],
}
],
},
{
name: "JWT Verify: ES",
input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA",
expectedOutput: invalidAlgorithm,
recipeConfig: [
{
op: "JWT Verify",
args: [esKey],
}
],
}
]);

View File

@@ -0,0 +1,132 @@
/**
* Parse IP Range tests.
*
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "Parse IPv4 CIDR",
input: "10.0.0.0/30",
expectedOutput: "Network: 10.0.0.0\nCIDR: 30\nMask: 255.255.255.252\nRange: 10.0.0.0 - 10.0.0.3\nTotal addresses in range: 4\n\n10.0.0.0\n10.0.0.1\n10.0.0.2\n10.0.0.3",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "Parse IPv4 hyphenated",
input: "10.0.0.0 - 10.0.0.3",
expectedOutput: "Minimum subnet required to hold this range:\n\tNetwork: 10.0.0.0\n\tCIDR: 30\n\tMask: 255.255.255.252\n\tSubnet range: 10.0.0.0 - 10.0.0.3\n\tTotal addresses in subnet: 4\n\nRange: 10.0.0.0 - 10.0.0.3\nTotal addresses in range: 4\n\n10.0.0.0\n10.0.0.1\n10.0.0.2\n10.0.0.3",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "Parse IPv4 list",
input: "10.0.0.8\n10.0.0.5/30\n10.0.0.1\n10.0.0.3",
expectedOutput: "Minimum subnet required to hold this range:\n\tNetwork: 10.0.0.0\n\tCIDR: 28\n\tMask: 255.255.255.240\n\tSubnet range: 10.0.0.0 - 10.0.0.15\n\tTotal addresses in subnet: 16\n\nRange: 10.0.0.1 - 10.0.0.8\nTotal addresses in range: 8\n\n10.0.0.1\n10.0.0.2\n10.0.0.3\n10.0.0.4\n10.0.0.5\n10.0.0.6\n10.0.0.7\n10.0.0.8",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "Parse IPv6 CIDR - full",
input: "2404:6800:4001:0000:0000:0000:0000:0000/48",
expectedOutput: "Network: 2404:6800:4001:0000:0000:0000:0000:0000\nShorthand: 2404:6800:4001::\nCIDR: 48\nMask: ffff:ffff:ffff:0000:0000:0000:0000:0000\nRange: 2404:6800:4001:0000:0000:0000:0000:0000 - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff\nTotal addresses in range: 1.2089258196146292e+24\n\n",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "Parse IPv6 CIDR - collapsed",
input: "2404:6800:4001::/48",
expectedOutput: "Network: 2404:6800:4001:0000:0000:0000:0000:0000\nShorthand: 2404:6800:4001::\nCIDR: 48\nMask: ffff:ffff:ffff:0000:0000:0000:0000:0000\nRange: 2404:6800:4001:0000:0000:0000:0000:0000 - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff\nTotal addresses in range: 1.2089258196146292e+24\n\n",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "Parse IPv6 hyphenated",
input: "2404:6800:4001:: - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff",
expectedOutput: "Range: 2404:6800:4001:0000:0000:0000:0000:0000 - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff\nShorthand range: 2404:6800:4001:: - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff\nTotal addresses in range: 1.2089258196146292e+24\n\n",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "Parse IPv6 list",
input: "2404:6800:4001:ffff:ffff:ffff:ffff:ffff\n2404:6800:4001::ffff\n2404:6800:4001:ffff:ffff::1111\n2404:6800:4001::/64",
expectedOutput: "Range: 2404:6800:4001:0000:0000:0000:0000:0000 - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff\nShorthand range: 2404:6800:4001:: - 2404:6800:4001:ffff:ffff:ffff:ffff:ffff\nTotal addresses in range: 1.2089258196146292e+24\n\n",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "IPv4 subnet out of range error",
input: "10.1.1.1/34",
expectedOutput: "IPv4 CIDR must be less than 32",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "invalid IPv4 address error",
input: "444.1.1.1/30",
expectedOutput: "Block out of range.",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "IPv6 subnet out of range error",
input: "2404:6800:4001::/129",
expectedOutput: "IPv6 CIDR must be less than 128",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
{
name: "invalid IPv6 address error",
input: "2404:6800:4001:/12",
expectedOutput: "Invalid input.\n\nEnter either a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0). IPv6 also supported.",
recipeConfig: [
{
"op": "Parse IP range",
"args": [true, true, false]
},
],
},
]);

View File

@@ -0,0 +1,56 @@
/**
* Parse TLV tests.
*
* @author gchq77703 []
* @copyright Crown Copyright 2018
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "Parse TLV: LengthValue",
input: "\x05\x48\x6f\x75\x73\x65\x04\x72\x6f\x6f\x6d\x04\x64\x6f\x6f\x72",
expectedOutput: JSON.stringify([{"length": 5, "value": [72, 111, 117, 115, 101]}, {"length": 4, "value": [114, 111, 111, 109]}, {"length": 4, "value": [100, 111, 111, 114]}], null, 4),
recipeConfig: [
{
"op": "Parse TLV",
"args": [0, 1, false]
}
]
},
{
name: "Parse TLV: LengthValue with BER",
input: "\x05\x48\x6f\x75\x73\x65\x04\x72\x6f\x6f\x6d\x04\x64\x6f\x6f\x72",
expectedOutput: JSON.stringify([{"length": 5, "value": [72, 111, 117, 115, 101]}, {"length": 4, "value": [114, 111, 111, 109]}, {"length": 4, "value": [100, 111, 111, 114]}], null, 4),
recipeConfig: [
{
"op": "Parse TLV",
"args": [0, 4, true] // length value is patently wrong, should be ignored by BER.
}
]
},
{
name: "Parse TLV: KeyLengthValue",
input: "\x04\x05\x48\x6f\x75\x73\x65\x05\x04\x72\x6f\x6f\x6d\x42\x04\x64\x6f\x6f\x72",
expectedOutput: JSON.stringify([{"key": [4], "length": 5, "value": [72, 111, 117, 115, 101]}, {"key": [5], "length": 4, "value": [114, 111, 111, 109]}, {"key": [66], "length": 4, "value": [100, 111, 111, 114]}], null, 4),
recipeConfig: [
{
"op": "Parse TLV",
"args": [1, 1, false]
}
]
},
{
name: "Parse TLV: KeyLengthValue with BER",
input: "\x04\x05\x48\x6f\x75\x73\x65\x05\x04\x72\x6f\x6f\x6d\x42\x04\x64\x6f\x6f\x72",
expectedOutput: JSON.stringify([{"key": [4], "length": 5, "value": [72, 111, 117, 115, 101]}, {"key": [5], "length": 4, "value": [114, 111, 111, 109]}, {"key": [66], "length": 4, "value": [100, 111, 111, 114]}], null, 4),
recipeConfig: [
{
"op": "Parse TLV",
"args": [1, 4, true] // length value is patently wrong, should be ignored by BER.
}
]
}
]);

View File

@@ -0,0 +1,23 @@
/**
* Remove Diacritics tests.
*
* @author Klaxon [klaxon@veyr.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import TestRegister from "../../TestRegister";
TestRegister.addTests([
{
name: "Remove Diacritics",
input: "\xe0, \xe8, \xec, \xf2, \xf9 \xc0, \xc8, \xcc, \xd2, \xd9\n\xe1, \xe9, \xed, \xf3, \xfa, \xfd \xc1, \xc9, \xcd, \xd3, \xda, \xdd\n\xe2, \xea, \xee, \xf4, \xfb \xc2, \xca, \xce, \xd4, \xdb\n\xe3, \xf1, \xf5 \xc3, \xd1, \xd5\n\xe4, \xeb, \xef, \xf6, \xfc, \xff \xc4, \xcb, \xcf, \xd6, \xdc, \u0178\n\xe5, \xc5",
expectedOutput: "a, e, i, o, u A, E, I, O, U\na, e, i, o, u, y A, E, I, O, U, Y\na, e, i, o, u A, E, I, O, U\na, n, o A, N, O\na, e, i, o, u, y A, E, I, O, U, Y\na, A",
recipeConfig: [
{
"op": "Remove Diacritics",
"args": []
},
],
},
]);

View File

@@ -30,6 +30,9 @@ const banner = `/**
* limitations under the License.
*/`;
const vendorCSS = new ExtractTextPlugin("vendor.css");
const projectCSS = new ExtractTextPlugin("styles.css");
module.exports = {
plugins: [
new webpack.ProvidePlugin({
@@ -42,7 +45,8 @@ module.exports = {
raw: true,
entryOnly: true
}),
new ExtractTextPlugin("styles.css")
vendorCSS,
projectCSS
],
resolve: {
alias: {
@@ -67,7 +71,7 @@ module.exports = {
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: projectCSS.extract({
use: [
{ loader: "css-loader" },
{ loader: "postcss-loader" },
@@ -76,7 +80,7 @@ module.exports = {
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
use: vendorCSS.extract({
use: [
{ loader: "css-loader" },
{ loader: "sass-loader" }
@@ -113,7 +117,11 @@ module.exports = {
chunks: false,
modules: false,
entrypoints: false,
warningsFilter: [/source-map/, /dependency is an expression/],
warningsFilter: [
/source-map/,
/dependency is an expression/,
/export 'default'/
],
},
node: {
fs: "empty"