mirror of
https://github.com/gchq/CyberChef
synced 2026-01-05 01:53:36 +00:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e080c5d72e | ||
|
|
9cc177a9ad | ||
|
|
60b5fe0e76 | ||
|
|
9273f97d88 | ||
|
|
98a6baf55a | ||
|
|
b5677387f5 | ||
|
|
cd3eaa4762 | ||
|
|
9733bf65de | ||
|
|
bc433f0234 | ||
|
|
ad7283ee6f | ||
|
|
5b941358a9 | ||
|
|
f19e898c57 | ||
|
|
590ffa184d | ||
|
|
46de51512f | ||
|
|
a13f2f26e4 | ||
|
|
c9c26f6f9f | ||
|
|
787c29e42b | ||
|
|
1c0b83d833 | ||
|
|
5c767d09b0 | ||
|
|
75dba51f56 | ||
|
|
78a1827af8 | ||
|
|
9e3733b33b | ||
|
|
4ef65589e8 | ||
|
|
cf9e670309 | ||
|
|
b09f98fbb4 | ||
|
|
e43e010163 | ||
|
|
2a5cee0bd3 | ||
|
|
c962bb79f5 | ||
|
|
2e23a33dfc | ||
|
|
bca296ee37 | ||
|
|
2dbd647868 | ||
|
|
2991e7d1fe | ||
|
|
f6f12fc193 | ||
|
|
1fac8c1cea | ||
|
|
590462e2e4 | ||
|
|
291c55befd | ||
|
|
f630c499d5 | ||
|
|
cfc29ef821 | ||
|
|
83c6775038 | ||
|
|
ae1b12c120 | ||
|
|
c423de545f | ||
|
|
84011371b7 | ||
|
|
f831ec6b7e | ||
|
|
05bfa9158d | ||
|
|
649016bc85 | ||
|
|
7492b874cf | ||
|
|
9ea21af61f | ||
|
|
dd18e52993 | ||
|
|
7712ee7f35 | ||
|
|
c01ce90e06 | ||
|
|
d68c8cb845 |
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"parser": "babel-eslint",
|
"parser": "@babel/eslint-parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 9,
|
"ecmaVersion": 9,
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
|
|||||||
1
.github/workflows/codeql.yml
vendored
1
.github/workflows/codeql.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
name: "CodeQL Analysis"
|
name: "CodeQL Analysis"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|||||||
5
.github/workflows/master.yml
vendored
5
.github/workflows/master.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
name: "Master Build, Test & Deploy"
|
name: "Master Build, Test & Deploy"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
@@ -14,7 +15,7 @@ jobs:
|
|||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: '10.x'
|
node-version: '17.x'
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
@@ -27,7 +28,7 @@ jobs:
|
|||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: |
|
run: |
|
||||||
npm test
|
npm test
|
||||||
npx grunt testnodeconsumer
|
npm run testnodeconsumer
|
||||||
|
|
||||||
- name: Production Build
|
- name: Production Build
|
||||||
if: success()
|
if: success()
|
||||||
|
|||||||
5
.github/workflows/pull_requests.yml
vendored
5
.github/workflows/pull_requests.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
name: "Pull Requests"
|
name: "Pull Requests"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [synchronize, opened, reopened]
|
types: [synchronize, opened, reopened]
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ jobs:
|
|||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: '10.x'
|
node-version: '17.x'
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
@@ -26,7 +27,7 @@ jobs:
|
|||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: |
|
run: |
|
||||||
npm test
|
npm test
|
||||||
npx grunt testnodeconsumer
|
npm run testnodeconsumer
|
||||||
|
|
||||||
- name: Production Build
|
- name: Production Build
|
||||||
if: success()
|
if: success()
|
||||||
|
|||||||
5
.github/workflows/releases.yml
vendored
5
.github/workflows/releases.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
name: "Releases"
|
name: "Releases"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- 'v*'
|
||||||
@@ -14,7 +15,7 @@ jobs:
|
|||||||
- name: Set node version
|
- name: Set node version
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: '10.x'
|
node-version: '17.x'
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
@@ -27,7 +28,7 @@ jobs:
|
|||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
run: |
|
run: |
|
||||||
npm test
|
npm test
|
||||||
npx grunt testnodeconsumer
|
npm run testnodeconsumer
|
||||||
|
|
||||||
- name: Production Build
|
- name: Production Build
|
||||||
if: success()
|
if: success()
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,4 +11,4 @@ src/node/config/OperationConfig.json
|
|||||||
src/node/index.mjs
|
src/node/index.mjs
|
||||||
**/*.DS_Store
|
**/*.DS_Store
|
||||||
tests/browser/output/*
|
tests/browser/output/*
|
||||||
|
.node-version
|
||||||
|
|||||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -13,6 +13,16 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
|
### [9.34.0] - 2022-03-28
|
||||||
|
- 'Get All Casings' operation added [@n1073645] | [#1065]
|
||||||
|
|
||||||
|
### [9.33.0] - 2022-03-25
|
||||||
|
- Updated to support Node 17 [@n1474335] [@john19696] [@t-8ch] | [[#1326] [#1313] [#1244]
|
||||||
|
- Improved CJS and ESM module support [@d98762625] | [#1037]
|
||||||
|
|
||||||
|
### [9.32.0] - 2021-08-18
|
||||||
|
- 'Protobuf Encode' operation added and decode operation modified to allow decoding with full and partial schemas [@n1474335] | [dd18e52]
|
||||||
|
|
||||||
### [9.31.0] - 2021-08-10
|
### [9.31.0] - 2021-08-10
|
||||||
- 'HASSH Client Fingerprint' and 'HASSH Server Fingerprint' operations added [@n1474335] | [e9ca4dc]
|
- 'HASSH Client Fingerprint' and 'HASSH Server Fingerprint' operations added [@n1474335] | [e9ca4dc]
|
||||||
|
|
||||||
@@ -268,6 +278,9 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[9.34.0]: https://github.com/gchq/CyberChef/releases/tag/v9.34.0
|
||||||
|
[9.33.0]: https://github.com/gchq/CyberChef/releases/tag/v9.33.0
|
||||||
|
[9.32.0]: https://github.com/gchq/CyberChef/releases/tag/v9.32.0
|
||||||
[9.31.0]: https://github.com/gchq/CyberChef/releases/tag/v9.31.0
|
[9.31.0]: https://github.com/gchq/CyberChef/releases/tag/v9.31.0
|
||||||
[9.30.0]: https://github.com/gchq/CyberChef/releases/tag/v9.30.0
|
[9.30.0]: https://github.com/gchq/CyberChef/releases/tag/v9.30.0
|
||||||
[9.29.0]: https://github.com/gchq/CyberChef/releases/tag/v9.29.0
|
[9.29.0]: https://github.com/gchq/CyberChef/releases/tag/v9.29.0
|
||||||
@@ -380,11 +393,14 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[@dmfj]: https://github.com/dmfj
|
[@dmfj]: https://github.com/dmfj
|
||||||
[@mattnotmitt]: https://github.com/mattnotmitt
|
[@mattnotmitt]: https://github.com/mattnotmitt
|
||||||
[@Danh4]: https://github.com/Danh4
|
[@Danh4]: https://github.com/Danh4
|
||||||
|
[@john19696]: https://github.com/john19696
|
||||||
|
[@t-8ch]: https://github.com/t-8ch
|
||||||
|
|
||||||
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
||||||
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
||||||
[289a417]: https://github.com/gchq/CyberChef/commit/289a417dfb5923de5e1694354ec42a08d9395bfe
|
[289a417]: https://github.com/gchq/CyberChef/commit/289a417dfb5923de5e1694354ec42a08d9395bfe
|
||||||
[e9ca4dc]: https://github.com/gchq/CyberChef/commit/e9ca4dc9caf98f33fd986431cd400c88082a42b8
|
[e9ca4dc]: https://github.com/gchq/CyberChef/commit/e9ca4dc9caf98f33fd986431cd400c88082a42b8
|
||||||
|
[dd18e52]: https://github.com/gchq/CyberChef/commit/dd18e529939078b89867297b181a584e8b2cc7da
|
||||||
|
|
||||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||||
@@ -461,6 +477,11 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[#999]: https://github.com/gchq/CyberChef/pull/999
|
[#999]: https://github.com/gchq/CyberChef/pull/999
|
||||||
[#1006]: https://github.com/gchq/CyberChef/pull/1006
|
[#1006]: https://github.com/gchq/CyberChef/pull/1006
|
||||||
[#1022]: https://github.com/gchq/CyberChef/pull/1022
|
[#1022]: https://github.com/gchq/CyberChef/pull/1022
|
||||||
|
[#1037]: https://github.com/gchq/CyberChef/pull/1037
|
||||||
[#1045]: https://github.com/gchq/CyberChef/pull/1045
|
[#1045]: https://github.com/gchq/CyberChef/pull/1045
|
||||||
[#1049]: https://github.com/gchq/CyberChef/pull/1049
|
[#1049]: https://github.com/gchq/CyberChef/pull/1049
|
||||||
[#1083]: https://github.com/gchq/CyberChef/pull/1083
|
[#1065]: https://github.com/gchq/CyberChef/pull/1065
|
||||||
|
[#1083]: https://github.com/gchq/CyberChef/pull/1083
|
||||||
|
[#1244]: https://github.com/gchq/CyberChef/pull/1244
|
||||||
|
[#1313]: https://github.com/gchq/CyberChef/pull/1313
|
||||||
|
[#1326]: https://github.com/gchq/CyberChef/pull/1326
|
||||||
97
Gruntfile.js
97
Gruntfile.js
@@ -6,6 +6,8 @@ const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPl
|
|||||||
const glob = require("glob");
|
const glob = require("glob");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
|
const nodeFlags = "--experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings --no-deprecation";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grunt configuration for building the app in various formats.
|
* Grunt configuration for building the app in various formats.
|
||||||
*
|
*
|
||||||
@@ -48,7 +50,7 @@ module.exports = function (grunt) {
|
|||||||
|
|
||||||
grunt.registerTask("testnodeconsumer",
|
grunt.registerTask("testnodeconsumer",
|
||||||
"A task which checks whether consuming CJS and ESM apps work with the CyberChef build",
|
"A task which checks whether consuming CJS and ESM apps work with the CyberChef build",
|
||||||
["exec:setupNodeConsumers", "exec:testCJSNodeConsumer", "exec:testESMNodeConsumer", "exec:testESMDeepImportNodeConsumer", "exec:teardownNodeConsumers"]);
|
["exec:setupNodeConsumers", "exec:testCJSNodeConsumer", "exec:testESMNodeConsumer", "exec:teardownNodeConsumers"]);
|
||||||
|
|
||||||
grunt.registerTask("default",
|
grunt.registerTask("default",
|
||||||
"Lints the code base",
|
"Lints the code base",
|
||||||
@@ -187,9 +189,6 @@ module.exports = function (grunt) {
|
|||||||
standalone: ["build/prod/CyberChef*.html"]
|
standalone: ["build/prod/CyberChef*.html"]
|
||||||
},
|
},
|
||||||
eslint: {
|
eslint: {
|
||||||
options: {
|
|
||||||
configFile: "./.eslintrc.json"
|
|
||||||
},
|
|
||||||
configs: ["*.{js,mjs}"],
|
configs: ["*.{js,mjs}"],
|
||||||
core: ["src/core/**/*.{js,mjs}", "!src/core/vendor/**/*", "!src/core/operations/legacy/**/*"],
|
core: ["src/core/**/*.{js,mjs}", "!src/core/vendor/**/*", "!src/core/operations/legacy/**/*"],
|
||||||
web: ["src/web/**/*.{js,mjs}", "!src/web/static/**/*"],
|
web: ["src/web/**/*.{js,mjs}", "!src/web/static/**/*"],
|
||||||
@@ -201,50 +200,35 @@ module.exports = function (grunt) {
|
|||||||
web: webpackProdConf(),
|
web: webpackProdConf(),
|
||||||
},
|
},
|
||||||
"webpack-dev-server": {
|
"webpack-dev-server": {
|
||||||
options: {
|
options: webpackConfig,
|
||||||
webpack: webpackConfig,
|
|
||||||
host: "0.0.0.0",
|
|
||||||
port: grunt.option("port") || 8080,
|
|
||||||
disableHostCheck: true,
|
|
||||||
overlay: true,
|
|
||||||
inline: false,
|
|
||||||
clientLogLevel: "error",
|
|
||||||
stats: {
|
|
||||||
children: false,
|
|
||||||
chunks: false,
|
|
||||||
modules: false,
|
|
||||||
entrypoints: false,
|
|
||||||
warningsFilter: [
|
|
||||||
/source-map/,
|
|
||||||
/dependency is an expression/,
|
|
||||||
/export 'default'/,
|
|
||||||
/Can't resolve 'sodium'/
|
|
||||||
],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: {
|
start: {
|
||||||
webpack: {
|
mode: "development",
|
||||||
mode: "development",
|
target: "web",
|
||||||
target: "web",
|
entry: Object.assign({
|
||||||
entry: Object.assign({
|
main: "./src/web/index.js"
|
||||||
main: "./src/web/index.js"
|
}, moduleEntryPoints),
|
||||||
}, moduleEntryPoints),
|
resolve: {
|
||||||
resolve: {
|
alias: {
|
||||||
alias: {
|
"./config/modules/OpModules.mjs": "./config/modules/Default.mjs"
|
||||||
"./config/modules/OpModules.mjs": "./config/modules/Default.mjs"
|
}
|
||||||
}
|
},
|
||||||
},
|
devServer: {
|
||||||
plugins: [
|
port: grunt.option("port") || 8080,
|
||||||
new webpack.DefinePlugin(BUILD_CONSTANTS),
|
client: {
|
||||||
new HtmlWebpackPlugin({
|
logging: "error",
|
||||||
filename: "index.html",
|
overlay: true
|
||||||
template: "./src/web/html/index.html",
|
}
|
||||||
chunks: ["main"],
|
},
|
||||||
compileTime: compileTime,
|
plugins: [
|
||||||
version: pkg.version,
|
new webpack.DefinePlugin(BUILD_CONSTANTS),
|
||||||
})
|
new HtmlWebpackPlugin({
|
||||||
]
|
filename: "index.html",
|
||||||
}
|
template: "./src/web/html/index.html",
|
||||||
|
chunks: ["main"],
|
||||||
|
compileTime: compileTime,
|
||||||
|
version: pkg.version,
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
zip: {
|
zip: {
|
||||||
@@ -349,15 +333,15 @@ module.exports = function (grunt) {
|
|||||||
command: "git gc --prune=now --aggressive"
|
command: "git gc --prune=now --aggressive"
|
||||||
},
|
},
|
||||||
sitemap: {
|
sitemap: {
|
||||||
command: "node --experimental-modules --no-warnings --no-deprecation src/web/static/sitemap.mjs > build/prod/sitemap.xml",
|
command: `node ${nodeFlags} src/web/static/sitemap.mjs > build/prod/sitemap.xml`,
|
||||||
sync: true
|
sync: true
|
||||||
},
|
},
|
||||||
generateConfig: {
|
generateConfig: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
"echo '\n--- Regenerating config files. ---'",
|
"echo '\n--- Regenerating config files. ---'",
|
||||||
"echo [] > src/core/config/OperationConfig.json",
|
"echo [] > src/core/config/OperationConfig.json",
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
|
`node ${nodeFlags} src/core/config/scripts/generateOpsIndex.mjs`,
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
|
`node ${nodeFlags} src/core/config/scripts/generateConfig.mjs`,
|
||||||
"echo '--- Config scripts finished. ---\n'"
|
"echo '--- Config scripts finished. ---\n'"
|
||||||
]),
|
]),
|
||||||
sync: true
|
sync: true
|
||||||
@@ -365,7 +349,7 @@ module.exports = function (grunt) {
|
|||||||
generateNodeIndex: {
|
generateNodeIndex: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
"echo '\n--- Regenerating node index ---'",
|
"echo '\n--- Regenerating node index ---'",
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
|
`node ${nodeFlags} src/node/config/scripts/generateNodeIndex.mjs`,
|
||||||
"echo '--- Node index generated. ---\n'"
|
"echo '--- Node index generated. ---\n'"
|
||||||
]),
|
]),
|
||||||
sync: true
|
sync: true
|
||||||
@@ -393,21 +377,14 @@ module.exports = function (grunt) {
|
|||||||
testCJSNodeConsumer: {
|
testCJSNodeConsumer: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"node --no-warnings cjs-consumer.js",
|
`node ${nodeFlags} cjs-consumer.js`,
|
||||||
]),
|
]),
|
||||||
stdout: false,
|
stdout: false,
|
||||||
},
|
},
|
||||||
testESMNodeConsumer: {
|
testESMNodeConsumer: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"node --no-warnings --experimental-modules esm-consumer.mjs",
|
`node ${nodeFlags} esm-consumer.mjs`,
|
||||||
]),
|
|
||||||
stdout: false,
|
|
||||||
},
|
|
||||||
testESMDeepImportNodeConsumer: {
|
|
||||||
command: chainCommands([
|
|
||||||
`cd ${nodeConsumerTestPath}`,
|
|
||||||
"node --no-warnings --experimental-modules esm-deep-import-consumer.mjs",
|
|
||||||
]),
|
]),
|
||||||
stdout: false,
|
stdout: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
[](https://github.com/gchq/CyberChef/actions?query=workflow%3A%22Master+Build%2C+Test+%26+Deploy%22)
|
[](https://github.com/gchq/CyberChef/actions?query=workflow%3A%22Master+Build%2C+Test+%26+Deploy%22)
|
||||||
[](https://lgtm.com/projects/g/gchq/CyberChef/context:javascript)
|
[](https://lgtm.com/projects/g/gchq/CyberChef/context:javascript)
|
||||||
[](https://david-dm.org/gchq/CyberChef)
|
|
||||||
[](https://www.npmjs.com/package/cyberchef)
|
[](https://www.npmjs.com/package/cyberchef)
|
||||||
[](https://github.com/gchq/CyberChef/blob/master/LICENSE)
|
[](https://github.com/gchq/CyberChef/blob/master/LICENSE)
|
||||||
[](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
@@ -10,7 +9,7 @@
|
|||||||
|
|
||||||
#### *The Cyber Swiss Army Knife*
|
#### *The Cyber Swiss Army Knife*
|
||||||
|
|
||||||
CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include simple encoding like XOR or Base64, more complex encryption like AES, DES and Blowfish, creating binary and hexdumps, compression and decompression of data, calculating hashes and checksums, IPv6 and X.509 parsing, changing character encodings, and much more.
|
CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include simple encoding like XOR and Base64, more complex encryption like AES, DES and Blowfish, creating binary and hexdumps, compression and decompression of data, calculating hashes and checksums, IPv6 and X.509 parsing, changing character encodings, and much more.
|
||||||
|
|
||||||
The tool is designed to enable both technical and non-technical analysts to manipulate data in complex ways without having to deal with complex tools or algorithms. It was conceived, designed, built and incrementally improved by an analyst in their 10% innovation time over several years.
|
The tool is designed to enable both technical and non-technical analysts to manipulate data in complex ways without having to deal with complex tools or algorithms. It was conceived, designed, built and incrementally improved by an analyst in their 10% innovation time over several years.
|
||||||
|
|
||||||
@@ -106,7 +105,7 @@ An installation walkthrough, how-to guides for adding new operations and themes,
|
|||||||
|
|
||||||
## Licencing
|
## Licencing
|
||||||
|
|
||||||
CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/licenses/LICENSE-2.0) and is covered by [Crown Copyright](https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/copyright-and-re-use/crown-copyright/).
|
CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/licenses/LICENSE-2.0) and is covered by [Crown Copyright](https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/).
|
||||||
|
|
||||||
|
|
||||||
[1]: https://gchq.github.io/CyberChef
|
[1]: https://gchq.github.io/CyberChef
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ module.exports = function(api) {
|
|||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"dynamic-import-node",
|
"dynamic-import-node",
|
||||||
|
"@babel/plugin-syntax-import-assertions",
|
||||||
[
|
[
|
||||||
"babel-plugin-transform-builtin-extend", {
|
"babel-plugin-transform-builtin-extend", {
|
||||||
"globals": ["Error"]
|
"globals": ["Error"]
|
||||||
|
|||||||
28613
package-lock.json
generated
28613
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
141
package.json
141
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cyberchef",
|
"name": "cyberchef",
|
||||||
"version": "9.31.0",
|
"version": "9.34.2",
|
||||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||||
"author": "n1474335 <n1474335@gmail.com>",
|
"author": "n1474335 <n1474335@gmail.com>",
|
||||||
"homepage": "https://gchq.github.io/CyberChef",
|
"homepage": "https://gchq.github.io/CyberChef",
|
||||||
@@ -27,118 +27,117 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/gchq/CyberChef/"
|
"url": "https://github.com/gchq/CyberChef/"
|
||||||
},
|
},
|
||||||
"main": "src/node/cjs.js",
|
"main": "src/node/wrapper.js",
|
||||||
"module": "src/node/index.mjs",
|
"exports": {
|
||||||
|
"import": "./src/node/index.mjs",
|
||||||
|
"require": "./src/node/wrapper.js"
|
||||||
|
},
|
||||||
"bugs": "https://github.com/gchq/CyberChef/issues",
|
"bugs": "https://github.com/gchq/CyberChef/issues",
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"Chrome >= 50",
|
"Chrome >= 50",
|
||||||
"Firefox >= 38",
|
"Firefox >= 38",
|
||||||
"node >= 10"
|
"node >= 16"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@babel/core": "^7.17.8",
|
||||||
"@babel/plugin-transform-runtime": "^7.12.15",
|
"@babel/eslint-parser": "^7.17.0",
|
||||||
"@babel/preset-env": "^7.12.16",
|
"@babel/plugin-syntax-import-assertions": "^7.16.7",
|
||||||
"autoprefixer": "^10.2.4",
|
"@babel/plugin-transform-runtime": "^7.17.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"@babel/preset-env": "^7.16.11",
|
||||||
"babel-loader": "^8.2.2",
|
"@babel/runtime": "^7.17.8",
|
||||||
|
"autoprefixer": "^10.4.4",
|
||||||
|
"babel-loader": "^8.2.4",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||||
"chromedriver": "^92.0.0",
|
"chromedriver": "^99.0.0",
|
||||||
"cli-progress": "^3.9.0",
|
"cli-progress": "^3.10.0",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"copy-webpack-plugin": "^7.0.0",
|
"copy-webpack-plugin": "^10.2.4",
|
||||||
"css-loader": "^5.0.2",
|
"core-js": "^3.21.1",
|
||||||
"eslint": "^7.20.0",
|
"css-loader": "6.7.1",
|
||||||
"exports-loader": "^2.0.0",
|
"eslint": "^8.12.0",
|
||||||
"file-loader": "^6.2.0",
|
"grunt": "^1.4.1",
|
||||||
"grunt": "^1.3.0",
|
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-concurrent": "^3.0.0",
|
"grunt-concurrent": "^3.0.0",
|
||||||
"grunt-contrib-clean": "~2.0.0",
|
"grunt-contrib-clean": "~2.0.0",
|
||||||
"grunt-contrib-connect": "^3.0.0",
|
"grunt-contrib-connect": "^3.0.0",
|
||||||
"grunt-contrib-copy": "~1.0.0",
|
"grunt-contrib-copy": "~1.0.0",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"grunt-eslint": "^23.0.0",
|
"grunt-eslint": "^24.0.0",
|
||||||
"grunt-exec": "~3.0.0",
|
"grunt-exec": "~3.0.0",
|
||||||
"grunt-webpack": "^4.0.2",
|
"grunt-webpack": "^5.0.0",
|
||||||
"grunt-zip": "^0.18.2",
|
"grunt-zip": "^0.18.2",
|
||||||
"html-webpack-plugin": "^5.1.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
"imports-loader": "^2.0.0",
|
"imports-loader": "^3.1.1",
|
||||||
"mini-css-extract-plugin": "^1.3.7",
|
"mini-css-extract-plugin": "2.6.0",
|
||||||
"nightwatch": "^1.7.7",
|
"nightwatch": "^2.0.10",
|
||||||
"node-sass": "^5.0.0",
|
"postcss": "^8.4.12",
|
||||||
"postcss": "^8.2.6",
|
"postcss-css-variables": "^0.18.0",
|
||||||
"postcss-css-variables": "^0.17.0",
|
"postcss-import": "^14.1.0",
|
||||||
"postcss-import": "^14.0.0",
|
"postcss-loader": "^6.2.1",
|
||||||
"postcss-loader": "^5.0.0",
|
"prompt": "^1.2.2",
|
||||||
"prompt": "^1.1.0",
|
"sass-loader": "^12.6.0",
|
||||||
"sass-loader": "^11.0.1",
|
"sitemap": "^7.1.1",
|
||||||
"sitemap": "^6.3.6",
|
"terser": "^5.12.1",
|
||||||
"style-loader": "^2.0.0",
|
"webpack": "^5.70.0",
|
||||||
"svg-url-loader": "^7.1.1",
|
"webpack-bundle-analyzer": "^4.5.0",
|
||||||
"url-loader": "^4.1.1",
|
"webpack-dev-server": "4.7.4",
|
||||||
"webpack": "^5.22.0",
|
|
||||||
"webpack-bundle-analyzer": "^4.4.0",
|
|
||||||
"webpack-dev-server": "^3.11.2",
|
|
||||||
"webpack-node-externals": "^3.0.0",
|
"webpack-node-externals": "^3.0.0",
|
||||||
"worker-loader": "^3.0.8"
|
"worker-loader": "^3.0.8"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.12.1",
|
"@babel/polyfill": "^7.12.1",
|
||||||
"@babel/runtime": "^7.12.13",
|
|
||||||
"arrive": "^2.4.1",
|
"arrive": "^2.4.1",
|
||||||
"avsc": "^5.5.3",
|
"avsc": "^5.7.3",
|
||||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"bignumber.js": "^9.0.1",
|
"bignumber.js": "^9.0.2",
|
||||||
"blakejs": "^1.1.0",
|
"blakejs": "^1.2.1",
|
||||||
"bootstrap": "4.6.0",
|
"bootstrap": "4.6.1",
|
||||||
"bootstrap-colorpicker": "^3.2.0",
|
"bootstrap-colorpicker": "^3.4.0",
|
||||||
"bootstrap-material-design": "^4.1.3",
|
"bootstrap-material-design": "^4.1.3",
|
||||||
"browserify-zlib": "^0.2.0",
|
"browserify-zlib": "^0.2.0",
|
||||||
"bson": "^4.2.2",
|
"bson": "^4.6.2",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"cbor": "^5.0.1",
|
"cbor": "8.1.0",
|
||||||
"chi-squared": "^1.1.0",
|
"chi-squared": "^1.1.0",
|
||||||
"codepage": "^1.14.0",
|
"codepage": "^1.15.0",
|
||||||
"core-js": "^3.8.3",
|
|
||||||
"crypto-api": "^0.8.5",
|
"crypto-api": "^0.8.5",
|
||||||
"crypto-browserify": "^3.12.0",
|
"crypto-browserify": "^3.12.0",
|
||||||
"crypto-js": "^4.0.0",
|
"crypto-js": "^4.1.1",
|
||||||
"ctph.js": "0.0.5",
|
"ctph.js": "0.0.5",
|
||||||
"d3": "^6.5.0",
|
"d3": "7.3.0",
|
||||||
"d3-hexbin": "^0.2.2",
|
"d3-hexbin": "^0.2.2",
|
||||||
"diff": "^5.0.0",
|
"diff": "^5.0.0",
|
||||||
"es6-promisify": "^6.1.1",
|
"es6-promisify": "^7.0.0",
|
||||||
"escodegen": "^2.0.0",
|
"escodegen": "^2.0.0",
|
||||||
"esm": "^3.2.25",
|
|
||||||
"esprima": "^4.0.1",
|
"esprima": "^4.0.1",
|
||||||
"exif-parser": "^0.1.12",
|
"exif-parser": "^0.1.12",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"flat": "^5.0.2",
|
"flat": "^5.0.2",
|
||||||
"geodesy": "1.1.3",
|
"geodesy": "1.1.3",
|
||||||
"highlight.js": "^10.6.0",
|
"highlight.js": "^11.5.0",
|
||||||
"jimp": "^0.16.1",
|
"jimp": "^0.16.1",
|
||||||
"jquery": "3.5.1",
|
"jquery": "3.6.0",
|
||||||
"js-crc": "^0.2.0",
|
"js-crc": "^0.2.0",
|
||||||
"js-sha3": "^0.8.0",
|
"js-sha3": "^0.8.0",
|
||||||
"jsesc": "^3.0.2",
|
"jsesc": "^3.0.2",
|
||||||
"jsonpath": "^1.1.1",
|
"jsonpath": "^1.1.1",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"jsqr": "^1.3.1",
|
"jsqr": "^1.4.0",
|
||||||
"jsrsasign": "^10.3.0",
|
"jsrsasign": "^10.5.14",
|
||||||
"kbpgp": "2.1.15",
|
"kbpgp": "2.1.15",
|
||||||
"libbzip2-wasm": "0.0.4",
|
"libbzip2-wasm": "0.0.4",
|
||||||
"libyara-wasm": "^1.1.0",
|
"libyara-wasm": "^1.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"loglevel": "^1.7.1",
|
"loglevel": "^1.8.0",
|
||||||
"loglevel-message-prefix": "^3.0.0",
|
"loglevel-message-prefix": "^3.0.0",
|
||||||
"markdown-it": "^12.0.4",
|
"markdown-it": "^12.3.2",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"moment-timezone": "^0.5.33",
|
"moment-timezone": "^0.5.34",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
"node-forge": "^0.10.0",
|
"node-forge": "^1.3.0",
|
||||||
"node-md6": "^0.1.0",
|
"node-md6": "^0.1.0",
|
||||||
|
"node-sass": "^7.0.1",
|
||||||
"nodom": "^2.4.0",
|
"nodom": "^2.4.0",
|
||||||
"notepack.io": "^2.3.0",
|
"notepack.io": "^2.3.0",
|
||||||
"nwmatcher": "^1.4.4",
|
"nwmatcher": "^1.4.4",
|
||||||
@@ -146,35 +145,35 @@
|
|||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"popper.js": "^1.16.1",
|
"popper.js": "^1.16.1",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
|
"protobufjs": "^6.11.2",
|
||||||
"qr-image": "^3.2.0",
|
"qr-image": "^3.2.0",
|
||||||
"scryptsy": "^2.1.0",
|
"scryptsy": "^2.1.0",
|
||||||
"snackbarjs": "^1.1.0",
|
"snackbarjs": "^1.1.0",
|
||||||
"sortablejs": "^1.13.0",
|
"sortablejs": "^1.15.0",
|
||||||
"split.js": "^1.6.2",
|
"split.js": "^1.6.5",
|
||||||
"ssdeep.js": "0.0.2",
|
"ssdeep.js": "0.0.3",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"terser": "^5.6.0",
|
"tesseract.js": "2.1.5",
|
||||||
"tesseract.js": "2.1.1",
|
"ua-parser-js": "^1.0.2",
|
||||||
"ua-parser-js": "^0.7.24",
|
|
||||||
"unorm": "^1.6.0",
|
"unorm": "^1.6.0",
|
||||||
"utf8": "^3.0.0",
|
"utf8": "^3.0.0",
|
||||||
"vkbeautify": "^0.99.3",
|
"vkbeautify": "^0.99.3",
|
||||||
"xmldom": "^0.6.0",
|
"xmldom": "^0.6.0",
|
||||||
"xpath": "0.0.32",
|
"xpath": "0.0.32",
|
||||||
"xregexp": "^5.0.1",
|
"xregexp": "^5.1.0",
|
||||||
"zlibjs": "^0.3.1"
|
"zlibjs": "^0.3.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npx grunt dev",
|
"start": "npx grunt dev",
|
||||||
"build": "npx grunt prod",
|
"build": "npx grunt prod",
|
||||||
"repl": "node src/node/repl.js",
|
"repl": "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings src/node/repl.mjs",
|
||||||
"test": "npx grunt configTests && node --experimental-modules --no-warnings --no-deprecation tests/node/index.mjs && node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs",
|
"test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation tests/operations/index.mjs",
|
||||||
"test-node-consumer": "npx grunt testnodeconsumer",
|
"testnodeconsumer": "npx grunt testnodeconsumer",
|
||||||
"testui": "npx grunt testui",
|
"testui": "npx grunt testui",
|
||||||
"testuidev": "npx nightwatch --env=dev",
|
"testuidev": "npx nightwatch --env=dev",
|
||||||
"lint": "npx grunt lint",
|
"lint": "npx grunt lint",
|
||||||
"postinstall": "npx grunt exec:fixCryptoApiImports",
|
"postinstall": "npx grunt exec:fixCryptoApiImports",
|
||||||
"newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs",
|
"newop": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newOperation.mjs",
|
||||||
"getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'",
|
"getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'",
|
||||||
"setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048"
|
"setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Chef from "./Chef.mjs";
|
import Chef from "./Chef.mjs";
|
||||||
import OperationConfig from "./config/OperationConfig.json";
|
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
|
||||||
import OpModules from "./config/modules/OpModules.mjs";
|
import OpModules from "./config/modules/OpModules.mjs";
|
||||||
|
|
||||||
// Add ">" to the start of all log messages in the Chef Worker
|
// Add ">" to the start of all log messages in the Chef Worker
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import OperationConfig from "./config/OperationConfig.json";
|
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
|
||||||
import OperationError from "./errors/OperationError.mjs";
|
import OperationError from "./errors/OperationError.mjs";
|
||||||
import Operation from "./Operation.mjs";
|
import Operation from "./Operation.mjs";
|
||||||
import DishError from "./errors/DishError.mjs";
|
import DishError from "./errors/DishError.mjs";
|
||||||
|
|||||||
@@ -723,7 +723,8 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (removeScriptAndStyle) {
|
if (removeScriptAndStyle) {
|
||||||
htmlStr = recursiveRemove(/<(script|style)[^>]*>.*?<\/(script|style)>/gi, htmlStr);
|
htmlStr = recursiveRemove(/<script[^>]*>.*?<\/script>/gi, htmlStr);
|
||||||
|
htmlStr = recursiveRemove(/<style[^>]*>.*?<\/style>/gi, htmlStr);
|
||||||
}
|
}
|
||||||
return htmlStr.replace(/<[^>]+>/g, "");
|
return htmlStr.replace(/<[^>]+>/g, "");
|
||||||
}
|
}
|
||||||
|
|||||||
2
src/core/config/Categories.json
Executable file → Normal file
2
src/core/config/Categories.json
Executable file → Normal file
@@ -191,6 +191,7 @@
|
|||||||
"URL Encode",
|
"URL Encode",
|
||||||
"URL Decode",
|
"URL Decode",
|
||||||
"Protobuf Decode",
|
"Protobuf Decode",
|
||||||
|
"Protobuf Encode",
|
||||||
"VarInt Encode",
|
"VarInt Encode",
|
||||||
"VarInt Decode",
|
"VarInt Decode",
|
||||||
"JA3 Fingerprint",
|
"JA3 Fingerprint",
|
||||||
@@ -229,6 +230,7 @@
|
|||||||
"From Case Insensitive Regex",
|
"From Case Insensitive Regex",
|
||||||
"Add line numbers",
|
"Add line numbers",
|
||||||
"Remove line numbers",
|
"Remove line numbers",
|
||||||
|
"Get All Casings",
|
||||||
"To Table",
|
"To Table",
|
||||||
"Reverse",
|
"Reverse",
|
||||||
"Sort",
|
"Sort",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import OperationError from "./OperationError.mjs";
|
import OperationError from "./OperationError.mjs";
|
||||||
import DishError from "./DishError.mjs";
|
import DishError from "./DishError.mjs";
|
||||||
import ExcludedOperationError from "./ExcludedOperationError";
|
import ExcludedOperationError from "./ExcludedOperationError.mjs";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
OperationError,
|
OperationError,
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ export function bitOp (input, key, func, nullPreserving, scheme) {
|
|||||||
!(nullPreserving && (o === 0 || o === k))) {
|
!(nullPreserving && (o === 0 || o === k))) {
|
||||||
switch (scheme) {
|
switch (scheme) {
|
||||||
case "Input differential":
|
case "Input differential":
|
||||||
key[i % key.length] = x;
|
key[i % key.length] = o;
|
||||||
break;
|
break;
|
||||||
case "Output differential":
|
case "Output differential":
|
||||||
key[i % key.length] = o;
|
key[i % key.length] = x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import OperationConfig from "../config/OperationConfig.json";
|
import OperationConfig from "../config/OperationConfig.json" assert {type: "json"};
|
||||||
import Utils, { isWorkerEnvironment } from "../Utils.mjs";
|
import Utils, { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import Recipe from "../Recipe.mjs";
|
import Recipe from "../Recipe.mjs";
|
||||||
import Dish from "../Dish.mjs";
|
import Dish from "../Dish.mjs";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
|
import protobuf from "protobufjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protobuf lib. Contains functions to decode protobuf serialised
|
* Protobuf lib. Contains functions to decode protobuf serialised
|
||||||
@@ -32,9 +33,10 @@ class Protobuf {
|
|||||||
this.MSB = 0x80;
|
this.MSB = 0x80;
|
||||||
this.VALUE = 0x7f;
|
this.VALUE = 0x7f;
|
||||||
|
|
||||||
// Declare offset and length
|
// Declare offset, length, and field type object
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
this.LENGTH = data.length;
|
this.LENGTH = data.length;
|
||||||
|
this.fieldTypes = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public Functions
|
// Public Functions
|
||||||
@@ -76,15 +78,281 @@ class Protobuf {
|
|||||||
return pb._varInt();
|
return pb._varInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode input JSON according to the given schema
|
||||||
|
*
|
||||||
|
* @param {Object} input
|
||||||
|
* @param {Object []} args
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
static encode(input, args) {
|
||||||
|
this.updateProtoRoot(args[0]);
|
||||||
|
if (!this.mainMessageName) {
|
||||||
|
throw new Error("Schema Error: Schema not defined");
|
||||||
|
}
|
||||||
|
const message = this.parsedProto.root.nested[this.mainMessageName];
|
||||||
|
|
||||||
|
// Convert input into instance of message, and verify instance
|
||||||
|
input = message.fromObject(input);
|
||||||
|
const error = message.verify(input);
|
||||||
|
if (error) {
|
||||||
|
throw new Error("Input Error: " + error);
|
||||||
|
}
|
||||||
|
// Encode input
|
||||||
|
const output = message.encode(input).finish();
|
||||||
|
return new Uint8Array(output).buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse Protobuf data
|
* Parse Protobuf data
|
||||||
*
|
*
|
||||||
* @param {byteArray} input
|
* @param {byteArray} input
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
static decode(input) {
|
static decode(input, args) {
|
||||||
|
this.updateProtoRoot(args[0]);
|
||||||
|
this.showUnknownFields = args[1];
|
||||||
|
this.showTypes = args[2];
|
||||||
|
return this.mergeDecodes(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the parsedProto, throw parsing errors
|
||||||
|
*
|
||||||
|
* @param {string} protoText
|
||||||
|
*/
|
||||||
|
static updateProtoRoot(protoText) {
|
||||||
|
try {
|
||||||
|
this.parsedProto = protobuf.parse(protoText);
|
||||||
|
if (this.parsedProto.package) {
|
||||||
|
this.parsedProto.root = this.parsedProto.root.nested[this.parsedProto.package];
|
||||||
|
}
|
||||||
|
this.updateMainMessageName();
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error("Schema " + error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set mainMessageName to the first instance of a message defined in the schema that is not a submessage
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static updateMainMessageName() {
|
||||||
|
const messageNames = [];
|
||||||
|
const fieldTypes = [];
|
||||||
|
this.parsedProto.root.nestedArray.forEach(block => {
|
||||||
|
if (block instanceof protobuf.Type) {
|
||||||
|
messageNames.push(block.name);
|
||||||
|
this.parsedProto.root.nested[block.name].fieldsArray.forEach(field => {
|
||||||
|
fieldTypes.push(field.type);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (messageNames.length === 0) {
|
||||||
|
this.mainMessageName = null;
|
||||||
|
} else {
|
||||||
|
// for (const name of messageNames) {
|
||||||
|
// if (!fieldTypes.includes(name)) {
|
||||||
|
// this.mainMessageName = name;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
this.mainMessageName = messageNames[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode input using Protobufjs package and raw methods, compare, and merge results
|
||||||
|
*
|
||||||
|
* @param {byteArray} input
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
static mergeDecodes(input) {
|
||||||
const pb = new Protobuf(input);
|
const pb = new Protobuf(input);
|
||||||
return pb._parse();
|
let rawDecode = pb._parse();
|
||||||
|
let message;
|
||||||
|
|
||||||
|
if (this.showTypes) {
|
||||||
|
rawDecode = this.showRawTypes(rawDecode, pb.fieldTypes);
|
||||||
|
this.parsedProto.root = this.appendTypesToFieldNames(this.parsedProto.root);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = this.parsedProto.root.nested[this.mainMessageName];
|
||||||
|
const packageDecode = message.toObject(message.decode(input), {
|
||||||
|
bytes: String,
|
||||||
|
longs: Number,
|
||||||
|
enums: String,
|
||||||
|
defualts: true
|
||||||
|
});
|
||||||
|
const output = {};
|
||||||
|
|
||||||
|
if (this.showUnknownFields) {
|
||||||
|
output[message.name] = packageDecode;
|
||||||
|
output["Unknown Fields"] = this.compareFields(rawDecode, message);
|
||||||
|
return output;
|
||||||
|
} else {
|
||||||
|
return packageDecode;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
if (message) {
|
||||||
|
throw new Error("Input " + error);
|
||||||
|
} else {
|
||||||
|
return rawDecode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace fieldnames with fieldname and type
|
||||||
|
*
|
||||||
|
* @param {Object} schemaRoot
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
static appendTypesToFieldNames(schemaRoot) {
|
||||||
|
for (const block of schemaRoot.nestedArray) {
|
||||||
|
if (block instanceof protobuf.Type) {
|
||||||
|
for (const [fieldName, fieldData] of Object.entries(block.fields)) {
|
||||||
|
schemaRoot.nested[block.name].remove(block.fields[fieldName]);
|
||||||
|
schemaRoot.nested[block.name].add(new protobuf.Field(`${fieldName} (${fieldData.type})`, fieldData.id, fieldData.type, fieldData.rule));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return schemaRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add field type to field name for fields in the raw decoded output
|
||||||
|
*
|
||||||
|
* @param {Object} rawDecode
|
||||||
|
* @param {Object} fieldTypes
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
static showRawTypes(rawDecode, fieldTypes) {
|
||||||
|
for (const [fieldNum, value] of Object.entries(rawDecode)) {
|
||||||
|
const fieldType = fieldTypes[fieldNum];
|
||||||
|
let outputFieldValue;
|
||||||
|
let outputFieldType;
|
||||||
|
|
||||||
|
// Submessages
|
||||||
|
if (isNaN(fieldType)) {
|
||||||
|
outputFieldType = 2;
|
||||||
|
|
||||||
|
// Repeated submessages
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
const fieldInstances = [];
|
||||||
|
for (const instance of Object.keys(value)) {
|
||||||
|
if (typeof(value[instance]) !== "string") {
|
||||||
|
fieldInstances.push(this.showRawTypes(value[instance], fieldType));
|
||||||
|
} else {
|
||||||
|
fieldInstances.push(value[instance]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outputFieldValue = fieldInstances;
|
||||||
|
|
||||||
|
// Single submessage
|
||||||
|
} else {
|
||||||
|
outputFieldValue = this.showRawTypes(value, fieldType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-submessage field
|
||||||
|
} else {
|
||||||
|
outputFieldType = fieldType;
|
||||||
|
outputFieldValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Substitute fieldNum with field number and type
|
||||||
|
rawDecode[`field #${fieldNum}: ${this.getTypeInfo(outputFieldType)}`] = outputFieldValue;
|
||||||
|
delete rawDecode[fieldNum];
|
||||||
|
}
|
||||||
|
return rawDecode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare raw decode to package decode and return discrepancies
|
||||||
|
*
|
||||||
|
* @param rawDecodedMessage
|
||||||
|
* @param schemaMessage
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
static compareFields(rawDecodedMessage, schemaMessage) {
|
||||||
|
// Define message data using raw decode output and schema
|
||||||
|
const schemaFieldProperties = {};
|
||||||
|
const schemaFieldNames = Object.keys(schemaMessage.fields);
|
||||||
|
schemaFieldNames.forEach(field => schemaFieldProperties[schemaMessage.fields[field].id] = field);
|
||||||
|
|
||||||
|
// Loop over each field present in the raw decode output
|
||||||
|
for (const fieldName in rawDecodedMessage) {
|
||||||
|
let fieldId;
|
||||||
|
if (isNaN(fieldName)) {
|
||||||
|
fieldId = fieldName.match(/^field #(\d+)/)[1];
|
||||||
|
} else {
|
||||||
|
fieldId = fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this field is defined in the schema
|
||||||
|
if (fieldId in schemaFieldProperties) {
|
||||||
|
const schemaFieldName = schemaFieldProperties[fieldId];
|
||||||
|
|
||||||
|
// Extract the current field data from the raw decode and schema
|
||||||
|
const rawFieldData = rawDecodedMessage[fieldName];
|
||||||
|
const schemaField = schemaMessage.fields[schemaFieldName];
|
||||||
|
|
||||||
|
// Check for repeated fields
|
||||||
|
if (Array.isArray(rawFieldData) && !schemaField.repeated) {
|
||||||
|
rawDecodedMessage[`(${schemaMessage.name}) ${schemaFieldName} is a repeated field`] = rawFieldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for submessage fields
|
||||||
|
if (schemaField.resolvedType instanceof protobuf.Type) {
|
||||||
|
const subMessageType = schemaMessage.fields[schemaFieldName].type;
|
||||||
|
const schemaSubMessage = this.parsedProto.root.nested[subMessageType];
|
||||||
|
const rawSubMessages = rawDecodedMessage[fieldName];
|
||||||
|
let rawDecodedSubMessage = {};
|
||||||
|
|
||||||
|
// Squash multiple submessage instances into one submessage
|
||||||
|
if (Array.isArray(rawSubMessages)) {
|
||||||
|
rawSubMessages.forEach(subMessageInstance => {
|
||||||
|
const instanceFields = Object.entries(subMessageInstance);
|
||||||
|
instanceFields.forEach(subField => {
|
||||||
|
rawDecodedSubMessage[subField[0]] = subField[1];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
rawDecodedSubMessage = rawSubMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Treat submessage as own message and compare its fields
|
||||||
|
rawDecodedSubMessage = Protobuf.compareFields(rawDecodedSubMessage, schemaSubMessage);
|
||||||
|
if (Object.entries(rawDecodedSubMessage).length !== 0) {
|
||||||
|
rawDecodedMessage[`${schemaFieldName} (${subMessageType}) has missing fields`] = rawDecodedSubMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete rawDecodedMessage[fieldName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rawDecodedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns wiretype information for input wiretype number
|
||||||
|
*
|
||||||
|
* @param {number} wireType
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static getTypeInfo(wireType) {
|
||||||
|
switch (wireType) {
|
||||||
|
case 0:
|
||||||
|
return "VarInt (e.g. int32, bool)";
|
||||||
|
case 1:
|
||||||
|
return "64-Bit (e.g. fixed64, double)";
|
||||||
|
case 2:
|
||||||
|
return "L-delim (e.g. string, message)";
|
||||||
|
case 5:
|
||||||
|
return "32-Bit (e.g. fixed32, float)";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private Class Functions
|
// Private Class Functions
|
||||||
@@ -143,6 +411,11 @@ class Protobuf {
|
|||||||
const header = this._fieldHeader();
|
const header = this._fieldHeader();
|
||||||
const type = header.type;
|
const type = header.type;
|
||||||
const key = header.key;
|
const key = header.key;
|
||||||
|
|
||||||
|
if (typeof(this.fieldTypes[key]) !== "object") {
|
||||||
|
this.fieldTypes[key] = type;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// varint
|
// varint
|
||||||
case 0:
|
case 0:
|
||||||
@@ -152,7 +425,7 @@ class Protobuf {
|
|||||||
return { "key": key, "value": this._uint64() };
|
return { "key": key, "value": this._uint64() };
|
||||||
// length delimited
|
// length delimited
|
||||||
case 2:
|
case 2:
|
||||||
return { "key": key, "value": this._lenDelim() };
|
return { "key": key, "value": this._lenDelim(key) };
|
||||||
// fixed 32
|
// fixed 32
|
||||||
case 5:
|
case 5:
|
||||||
return { "key": key, "value": this._uint32() };
|
return { "key": key, "value": this._uint32() };
|
||||||
@@ -237,10 +510,10 @@ class Protobuf {
|
|||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
_uint64() {
|
_uint64() {
|
||||||
// Read off a Uint64
|
// Read off a Uint64 with little-endian
|
||||||
let num = this.data[this.offset++] * 0x1000000 + (this.data[this.offset++] << 16) + (this.data[this.offset++] << 8) + this.data[this.offset++];
|
const lowerHalf = this.data[this.offset++] + (this.data[this.offset++] * 0x100) + (this.data[this.offset++] * 0x10000) + this.data[this.offset++] * 0x1000000;
|
||||||
num = num * 0x100000000 + this.data[this.offset++] * 0x1000000 + (this.data[this.offset++] << 16) + (this.data[this.offset++] << 8) + this.data[this.offset++];
|
const upperHalf = this.data[this.offset++] + (this.data[this.offset++] * 0x100) + (this.data[this.offset++] * 0x10000) + this.data[this.offset++] * 0x1000000;
|
||||||
return num;
|
return upperHalf * 0x100000000 + lowerHalf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,7 +522,7 @@ class Protobuf {
|
|||||||
* @private
|
* @private
|
||||||
* @returns {Object|string}
|
* @returns {Object|string}
|
||||||
*/
|
*/
|
||||||
_lenDelim() {
|
_lenDelim(fieldNum) {
|
||||||
// Read off the field length
|
// Read off the field length
|
||||||
const length = this._varInt();
|
const length = this._varInt();
|
||||||
const fieldBytes = this.data.slice(this.offset, this.offset + length);
|
const fieldBytes = this.data.slice(this.offset, this.offset + length);
|
||||||
@@ -258,6 +531,10 @@ class Protobuf {
|
|||||||
// Attempt to parse as a new Protobuf Object
|
// Attempt to parse as a new Protobuf Object
|
||||||
const pbObject = new Protobuf(fieldBytes);
|
const pbObject = new Protobuf(fieldBytes);
|
||||||
field = pbObject._parse();
|
field = pbObject._parse();
|
||||||
|
|
||||||
|
// Set field types object
|
||||||
|
this.fieldTypes[fieldNum] = {...this.fieldTypes[fieldNum], ...pbObject.fieldTypes};
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Otherwise treat as bytes
|
// Otherwise treat as bytes
|
||||||
field = Utils.byteArrayToChars(fieldBytes);
|
field = Utils.byteArrayToChars(fieldBytes);
|
||||||
@@ -276,7 +553,7 @@ class Protobuf {
|
|||||||
_uint32() {
|
_uint32() {
|
||||||
// Use a dataview to read off the integer
|
// Use a dataview to read off the integer
|
||||||
const dataview = new DataView(new Uint8Array(this.data.slice(this.offset, this.offset + 4)).buffer);
|
const dataview = new DataView(new Uint8Array(this.data.slice(this.offset, this.offset + 4)).buffer);
|
||||||
const value = dataview.getUint32(0);
|
const value = dataview.getUint32(0, true);
|
||||||
this.offset += 4;
|
this.offset += 4;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class DeriveEVPKey extends Operation {
|
|||||||
iterations = args[2],
|
iterations = args[2],
|
||||||
hasher = args[3],
|
hasher = args[3],
|
||||||
salt = Utils.convertToByteString(args[4].string, args[4].option),
|
salt = Utils.convertToByteString(args[4].string, args[4].option),
|
||||||
key = CryptoJS.EvpKDF(passphrase, salt, {
|
key = CryptoJS.EvpKDF(passphrase, salt, { // lgtm [js/insufficient-password-hash]
|
||||||
keySize: keySize,
|
keySize: keySize,
|
||||||
hasher: CryptoJS.algo[hasher],
|
hasher: CryptoJS.algo[hasher],
|
||||||
iterations: iterations,
|
iterations: iterations,
|
||||||
|
|||||||
53
src/core/operations/GetAllCasings.mjs
Normal file
53
src/core/operations/GetAllCasings.mjs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @author n1073645 [n1073645@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2020
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permutate String operation
|
||||||
|
*/
|
||||||
|
class GetAllCasings extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetAllCasings constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Get All Casings";
|
||||||
|
this.module = "Default";
|
||||||
|
this.description = "Outputs all possible casing variations of a string.";
|
||||||
|
this.infoURL = "";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const length = input.length;
|
||||||
|
const max = 1 << length;
|
||||||
|
input = input.toLowerCase();
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
for (let i = 0; i < max; i++) {
|
||||||
|
const temp = input.split("");
|
||||||
|
for (let j = 0; j < length; j++) {
|
||||||
|
if (((i >> j) & 1) === 1) {
|
||||||
|
temp[j] = temp[j].toUpperCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result += temp.join("") + "\n";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GetAllCasings;
|
||||||
@@ -20,12 +20,30 @@ class ProtobufDecode extends Operation {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.name = "Protobuf Decode";
|
this.name = "Protobuf Decode";
|
||||||
this.module = "Default";
|
this.module = "Protobuf";
|
||||||
this.description = "Decodes any Protobuf encoded data to a JSON representation of the data using the field number as the field key.";
|
this.description = "Decodes any Protobuf encoded data to a JSON representation of the data using the field number as the field key.<br><br>If a .proto schema is defined, the encoded data will be decoded with reference to the schema. Only one message instance will be decoded. <br><br><u>Show Unknown Fields</u><br>When a schema is used, this option shows fields that are present in the input data but not defined in the schema.<br><br><u>Show Types</u><br>Show the type of a field next to its name. For undefined fields, the wiretype and example types are shown instead.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Protocol_Buffers";
|
this.infoURL = "https://wikipedia.org/wiki/Protocol_Buffers";
|
||||||
this.inputType = "ArrayBuffer";
|
this.inputType = "ArrayBuffer";
|
||||||
this.outputType = "JSON";
|
this.outputType = "JSON";
|
||||||
this.args = [];
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Schema (.proto text)",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
rows: 8,
|
||||||
|
hint: "Drag and drop is enabled on this ingredient"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Show Unknown Fields",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Show Types",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +54,7 @@ class ProtobufDecode extends Operation {
|
|||||||
run(input, args) {
|
run(input, args) {
|
||||||
input = new Uint8Array(input);
|
input = new Uint8Array(input);
|
||||||
try {
|
try {
|
||||||
return Protobuf.decode(input);
|
return Protobuf.decode(input, args);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new OperationError(err);
|
throw new OperationError(err);
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/core/operations/ProtobufEncode.mjs
Normal file
54
src/core/operations/ProtobufEncode.mjs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* @author GCHQ Contributor [3]
|
||||||
|
* @copyright Crown Copyright 2021
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
import Protobuf from "../lib/Protobuf.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protobuf Encode operation
|
||||||
|
*/
|
||||||
|
class ProtobufEncode extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProtobufEncode constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Protobuf Encode";
|
||||||
|
this.module = "Protobuf";
|
||||||
|
this.description = "Encodes a valid JSON object into a protobuf byte array using the input .proto schema.";
|
||||||
|
this.infoURL = "https://developers.google.com/protocol-buffers/docs/encoding";
|
||||||
|
this.inputType = "JSON";
|
||||||
|
this.outputType = "ArrayBuffer";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Schema (.proto text)",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
rows: 8,
|
||||||
|
hint: "Drag and drop is enabled on this ingredient"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {ArrayBuffer}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
try {
|
||||||
|
return Protobuf.encode(input, args);
|
||||||
|
} catch (error) {
|
||||||
|
throw new OperationError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProtobufEncode;
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import NodeDish from "./NodeDish.mjs";
|
import NodeDish from "./NodeDish.mjs";
|
||||||
import NodeRecipe from "./NodeRecipe.mjs";
|
import NodeRecipe from "./NodeRecipe.mjs";
|
||||||
import OperationConfig from "../core/config/OperationConfig.json";
|
import OperationConfig from "../core/config/OperationConfig.json" assert {type: "json"};
|
||||||
import { sanitise, removeSubheadingsFromArray, sentenceToCamelCase } from "./apiUtils.mjs";
|
import { sanitise, removeSubheadingsFromArray, sentenceToCamelCase } from "./apiUtils.mjs";
|
||||||
import ExcludedOperationError from "../core/errors/ExcludedOperationError.mjs";
|
import ExcludedOperationError from "../core/errors/ExcludedOperationError.mjs";
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Export the main ESM module as CommonJS
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author d98762656 [d98762625@gmail.com]
|
|
||||||
* @copyright Crown Copyright 2019
|
|
||||||
* @license Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint no-global-assign: ["off"] */
|
|
||||||
require = require("esm")(module);
|
|
||||||
module.exports = require("./index.mjs");
|
|
||||||
module.exports.File = require("./File.mjs");
|
|
||||||
@@ -41,7 +41,7 @@ let code = `/**
|
|||||||
import NodeDish from "./NodeDish.mjs";
|
import NodeDish from "./NodeDish.mjs";
|
||||||
import { _wrap, help, bake, _explainExcludedFunction } from "./api.mjs";
|
import { _wrap, help, bake, _explainExcludedFunction } from "./api.mjs";
|
||||||
import File from "./File.mjs";
|
import File from "./File.mjs";
|
||||||
import { OperationError, DishError, ExcludedOperationError } from "../core/errors/index";
|
import { OperationError, DishError, ExcludedOperationError } from "../core/errors/index.mjs";
|
||||||
import {
|
import {
|
||||||
// import as core_ to avoid name clashes after wrap.
|
// import as core_ to avoid name clashes after wrap.
|
||||||
`;
|
`;
|
||||||
@@ -52,7 +52,7 @@ includedOperations.forEach((op) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
code +=`
|
code +=`
|
||||||
} from "../core/operations/index";
|
} from "../core/operations/index.mjs";
|
||||||
|
|
||||||
global.File = File;
|
global.File = File;
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const chef = require("./cjs.js");
|
import chef from "./index.mjs";
|
||||||
const repl = require("repl");
|
import repl from "repl";
|
||||||
|
|
||||||
|
|
||||||
/* eslint no-console: ["off"] */
|
/* eslint no-console: ["off"] */
|
||||||
11
src/node/wrapper.js
Normal file
11
src/node/wrapper.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Export the main ESM module as CommonJS
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author d98762656 [d98762625@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = (async () => await import("./index.mjs"))();
|
||||||
|
module.exports.File = (async () => await import("./File.mjs"))();
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
|
<meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
|
||||||
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
|
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
|
||||||
|
|
||||||
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico').default %>" />
|
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button type="button" class="mx-2 btn btn-lg btn-success btn-raised btn-block" id="bake">
|
<button type="button" class="mx-2 btn btn-lg btn-success btn-raised btn-block" id="bake">
|
||||||
<img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png').default %>" alt="Chef Icon"/>
|
<img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png') %>" alt="Chef Icon"/>
|
||||||
<span>Bake!</span>
|
<span>Bake!</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
<div class="file-overlay" id="file-overlay"></div>
|
<div class="file-overlay" id="file-overlay"></div>
|
||||||
<div style="position: relative; height: 100%;">
|
<div style="position: relative; height: 100%;">
|
||||||
<div class="io-card card">
|
<div class="io-card card">
|
||||||
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png').default %>" alt="File icon" id="input-file-thumbnail"/>
|
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png') %>" alt="File icon" id="input-file-thumbnail"/>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<button type="button" class="close" id="input-file-close">×</button>
|
<button type="button" class="close" id="input-file-close">×</button>
|
||||||
Name: <span id="input-file-name"></span><br>
|
Name: <span id="input-file-name"></span><br>
|
||||||
@@ -346,12 +346,12 @@
|
|||||||
<div id="output-highlighter" class="no-select"></div>
|
<div id="output-highlighter" class="no-select"></div>
|
||||||
<div id="output-html"></div>
|
<div id="output-html"></div>
|
||||||
<textarea id="output-text" readonly="readonly" spellcheck="false"></textarea>
|
<textarea id="output-text" readonly="readonly" spellcheck="false"></textarea>
|
||||||
<img id="show-file-overlay" aria-hidden="true" src="<%- require('../static/images/file-32x32.png').default %>" alt="Show file overlay" title="Show file overlay"/>
|
<img id="show-file-overlay" aria-hidden="true" src="<%- require('../static/images/file-32x32.png') %>" alt="Show file overlay" title="Show file overlay"/>
|
||||||
<div id="output-file">
|
<div id="output-file">
|
||||||
<div class="file-overlay"></div>
|
<div class="file-overlay"></div>
|
||||||
<div style="position: relative; height: 100%;">
|
<div style="position: relative; height: 100%;">
|
||||||
<div class="io-card card">
|
<div class="io-card card">
|
||||||
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png').default %>" alt="File icon"/>
|
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png') %>" alt="File icon"/>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
Size: <span id="output-file-size"></span><br>
|
Size: <span id="output-file-size"></span><br>
|
||||||
<button id="output-file-download" type="button" class="btn btn-primary btn-outline">Download</button>
|
<button id="output-file-download" type="button" class="btn btn-primary btn-outline">Download</button>
|
||||||
@@ -626,7 +626,7 @@
|
|||||||
<h5 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h5>
|
<h5 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png').default %>" alt="CyberChef Logo"/>
|
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" alt="CyberChef Logo"/>
|
||||||
<p class="subtext">
|
<p class="subtext">
|
||||||
Version <%= htmlWebpackPlugin.options.version %><br>
|
Version <%= htmlWebpackPlugin.options.version %><br>
|
||||||
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
|
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
|
||||||
@@ -749,7 +749,7 @@
|
|||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
</div>
|
</div>
|
||||||
<a href="https://github.com/gchq/CyberChef">
|
<a href="https://github.com/gchq/CyberChef">
|
||||||
<img aria-hidden="true" style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png').default %>" alt="Fork me on GitHub">
|
<img aria-hidden="true" style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png') %>" alt="Fork me on GitHub">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import * as CanvasComponents from "../core/lib/CanvasComponents.mjs";
|
|||||||
|
|
||||||
// CyberChef
|
// CyberChef
|
||||||
import App from "./App.mjs";
|
import App from "./App.mjs";
|
||||||
import Categories from "../core/config/Categories.json";
|
import Categories from "../core/config/Categories.json" assert {type: "json"};
|
||||||
import OperationConfig from "../core/config/OperationConfig.json";
|
import OperationConfig from "../core/config/OperationConfig.json" assert {type: "json"};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import sm from "sitemap";
|
import sm from "sitemap";
|
||||||
import OperationConfig from "../../core/config/OperationConfig.json";
|
import OperationConfig from "../../core/config/OperationConfig.json" assert {type: "json"};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -303,7 +303,7 @@
|
|||||||
|
|
||||||
#stale-indicator {
|
#stale-indicator {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visibile;
|
visibility: visible;
|
||||||
transition: margin 0s, opacity 0.3s;
|
transition: margin 0s, opacity 0.3s;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
@@ -316,7 +316,7 @@
|
|||||||
|
|
||||||
#magic {
|
#magic {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visibile;
|
visibility: visible;
|
||||||
transition: margin 0s 0.3s, opacity 0.3s 0.3s, visibility 0.3s 0.3s;
|
transition: margin 0s 0.3s, opacity 0.3s 0.3s, visibility 0.3s 0.3s;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ module.exports = {
|
|||||||
.moveToElement(toHex, 10, 10)
|
.moveToElement(toHex, 10, 10)
|
||||||
.useCss()
|
.useCss()
|
||||||
.waitForElementVisible(".popover-body", 1000)
|
.waitForElementVisible(".popover-body", 1000)
|
||||||
.doubleClick();
|
.doubleClick("xpath", toHex);
|
||||||
|
|
||||||
// Confirm that it has been added to the recipe
|
// Confirm that it has been added to the recipe
|
||||||
browser
|
browser
|
||||||
@@ -90,7 +90,7 @@ module.exports = {
|
|||||||
browser
|
browser
|
||||||
.useCss()
|
.useCss()
|
||||||
.waitForElementNotVisible("#stale-indicator", 1000)
|
.waitForElementNotVisible("#stale-indicator", 1000)
|
||||||
.expect.element("#output-text").to.have.value.that.equals("44 6f 6e 27 74 20 50 61 6e 69 63 2e");
|
.expect.element("#output-text").to.have.property("value").that.equals("44 6f 6e 27 74 20 50 61 6e 69 63 2e");
|
||||||
|
|
||||||
// Clear recipe
|
// Clear recipe
|
||||||
browser
|
browser
|
||||||
@@ -202,11 +202,11 @@ module.exports = {
|
|||||||
browser
|
browser
|
||||||
.getLocationInView(genUUID)
|
.getLocationInView(genUUID)
|
||||||
.moveToElement(genUUID, 10, 10)
|
.moveToElement(genUUID, 10, 10)
|
||||||
.doubleClick()
|
.doubleClick("xpath", genUUID)
|
||||||
.useCss()
|
.useCss()
|
||||||
.waitForElementVisible(".operation .op-title", 1000)
|
.waitForElementVisible(".operation .op-title", 1000)
|
||||||
.waitForElementNotVisible("#stale-indicator", 1000)
|
.waitForElementNotVisible("#stale-indicator", 1000)
|
||||||
.expect.element("#output-text").to.have.value.which.matches(/[\da-f-]{36}/);
|
.expect.element("#output-text").to.have.property("value").which.matches(/[\da-f-]{36}/);
|
||||||
|
|
||||||
browser.click("#clr-recipe");
|
browser.click("#clr-recipe");
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -393,13 +393,13 @@ function testOp(browser, opName, input, output, args=[]) {
|
|||||||
.click("#clr-recipe")
|
.click("#clr-recipe")
|
||||||
.click("#clr-io")
|
.click("#clr-io")
|
||||||
.waitForElementNotPresent("#rec-list li.operation")
|
.waitForElementNotPresent("#rec-list li.operation")
|
||||||
.expect.element("#input-text").to.have.value.that.equals("");
|
.expect.element("#input-text").to.have.property("value").that.equals("");
|
||||||
|
|
||||||
browser
|
browser
|
||||||
.urlHash("recipe=" + recipeConfig)
|
.urlHash("recipe=" + recipeConfig)
|
||||||
.setValue("#input-text", input)
|
.setValue("#input-text", input)
|
||||||
.waitForElementPresent("#rec-list li.operation")
|
.waitForElementPresent("#rec-list li.operation")
|
||||||
.expect.element("#input-text").to.have.value.that.equals(input);
|
.expect.element("#input-text").to.have.property("value").that.equals(input);
|
||||||
|
|
||||||
browser
|
browser
|
||||||
.waitForElementVisible("#stale-indicator", 5000)
|
.waitForElementVisible("#stale-indicator", 5000)
|
||||||
@@ -410,8 +410,8 @@ function testOp(browser, opName, input, output, args=[]) {
|
|||||||
.waitForElementNotVisible("#output-loader", 5000);
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
if (typeof output === "string") {
|
if (typeof output === "string") {
|
||||||
browser.expect.element("#output-text").to.have.value.that.equals(output);
|
browser.expect.element("#output-text").to.have.property("value").that.equals(output);
|
||||||
} else if (output instanceof RegExp) {
|
} else if (output instanceof RegExp) {
|
||||||
browser.expect.element("#output-text").to.have.value.that.matches(output);
|
browser.expect.element("#output-text").to.have.property("value").that.matches(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,24 +6,27 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const chef = require("cyberchef");
|
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
|
|
||||||
const d = chef.bake("Testing, 1 2 3", [
|
require("cyberchef").then(chef => {
|
||||||
chef.toHex,
|
|
||||||
chef.reverse,
|
|
||||||
{
|
|
||||||
op: chef.unique,
|
|
||||||
args: {
|
|
||||||
delimiter: "Space",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
op: chef.multiply,
|
|
||||||
args: {
|
|
||||||
delimiter: "Space",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert.equal(d.value, "630957449041920");
|
const d = chef.bake("Testing, 1 2 3", [
|
||||||
|
chef.toHex,
|
||||||
|
chef.reverse,
|
||||||
|
{
|
||||||
|
op: chef.unique,
|
||||||
|
args: {
|
||||||
|
delimiter: "Space",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: chef.multiply,
|
||||||
|
args: {
|
||||||
|
delimiter: "Space",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.equal(d.value, "630957449041920");
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,8 +7,28 @@
|
|||||||
*/
|
*/
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import chef from "cyberchef";
|
import chef from "cyberchef";
|
||||||
|
import { bake, toHex, reverse, unique, multiply } from "cyberchef";
|
||||||
|
|
||||||
const d = chef.bake("Testing, 1 2 3", [
|
const a = bake("Testing, 1 2 3", [
|
||||||
|
toHex,
|
||||||
|
reverse,
|
||||||
|
{
|
||||||
|
op: unique,
|
||||||
|
args: {
|
||||||
|
delimiter: "Space",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: multiply,
|
||||||
|
args: {
|
||||||
|
delimiter: "Space",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.equal(a.value, "630957449041920");
|
||||||
|
|
||||||
|
const b = chef.bake("Testing, 1 2 3", [
|
||||||
chef.toHex,
|
chef.toHex,
|
||||||
chef.reverse,
|
chef.reverse,
|
||||||
{
|
{
|
||||||
@@ -25,4 +45,4 @@ const d = chef.bake("Testing, 1 2 3", [
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.equal(d.value, "630957449041920");
|
assert.equal(b.value, "630957449041920");
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* Tests to ensure that a consuming app can use named imports from deep import patch
|
|
||||||
*
|
|
||||||
* @author d98762625 [d98762625@gmail.com]
|
|
||||||
* @copyright Crown Copyright 2019
|
|
||||||
* @license Apache-2.0
|
|
||||||
*/
|
|
||||||
import assert from "assert";
|
|
||||||
import { bake, toHex, reverse, unique, multiply } from "cyberchef/src/node/index.mjs";
|
|
||||||
|
|
||||||
const d = bake("Testing, 1 2 3", [
|
|
||||||
toHex,
|
|
||||||
reverse,
|
|
||||||
{
|
|
||||||
op: unique,
|
|
||||||
args: {
|
|
||||||
delimiter: "Space",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
op: multiply,
|
|
||||||
args: {
|
|
||||||
delimiter: "Space",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert.equal(d.value, "630957449041920");
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import TestRegister from "../../lib/TestRegister.mjs";
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
import Categories from "../../../src/core/config/Categories.json";
|
import Categories from "../../../src/core/config/Categories.json" assert {type: "json"};
|
||||||
import OperationConfig from "../../../src/core/config/OperationConfig.json";
|
import OperationConfig from "../../../src/core/config/OperationConfig.json" assert {type: "json"};
|
||||||
import it from "../assertionHandler.mjs";
|
import it from "../assertionHandler.mjs";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
CSSMinify,
|
CSSMinify,
|
||||||
toBase64,
|
toBase64,
|
||||||
toHex
|
toHex
|
||||||
} from "../../../src/node/index";
|
} from "../../../src/node/index.mjs";
|
||||||
import chef from "../../../src/node/index.mjs";
|
import chef from "../../../src/node/index.mjs";
|
||||||
import TestRegister from "../../lib/TestRegister.mjs";
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
import File from "../../../src/node/File.mjs";
|
import File from "../../../src/node/File.mjs";
|
||||||
@@ -685,8 +685,8 @@ Arguments:
|
|||||||
it("Parse user agent", () => {
|
it("Parse user agent", () => {
|
||||||
const result = chef.parseUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 ");
|
const result = chef.parseUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 ");
|
||||||
const expected = `Browser
|
const expected = `Browser
|
||||||
Name: Mozilla
|
Name: Firefox
|
||||||
Version: 5.0
|
Version: 47.0
|
||||||
Device
|
Device
|
||||||
Model: unknown
|
Model: unknown
|
||||||
Type: unknown
|
Type: unknown
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ import "./tests/CBORDecode.mjs";
|
|||||||
import "./tests/JA3Fingerprint.mjs";
|
import "./tests/JA3Fingerprint.mjs";
|
||||||
import "./tests/JA3SFingerprint.mjs";
|
import "./tests/JA3SFingerprint.mjs";
|
||||||
import "./tests/HASSH.mjs";
|
import "./tests/HASSH.mjs";
|
||||||
|
import "./tests/GetAllCasings.mjs";
|
||||||
|
|
||||||
// Cannot test operations that use the File type yet
|
// Cannot test operations that use the File type yet
|
||||||
// import "./tests/SplitColourChannels.mjs";
|
// import "./tests/SplitColourChannels.mjs";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TestRegister from "../../lib/TestRegister";
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
TestRegister.addTests([
|
TestRegister.addTests([
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
* @copyright Karsten Silkenbäumer 2019
|
* @copyright Karsten Silkenbäumer 2019
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
import TestRegister from "../../lib/TestRegister";
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
import { BACON_ALPHABETS, BACON_TRANSLATIONS } from "../../../src/core/lib/Bacon";
|
import { BACON_ALPHABETS, BACON_TRANSLATIONS } from "../../../src/core/lib/Bacon.mjs";
|
||||||
|
|
||||||
const alphabets = Object.keys(BACON_ALPHABETS);
|
const alphabets = Object.keys(BACON_ALPHABETS);
|
||||||
const translations = BACON_TRANSLATIONS;
|
const translations = BACON_TRANSLATIONS;
|
||||||
|
|||||||
44
tests/operations/tests/GetAllCasings.mjs
Normal file
44
tests/operations/tests/GetAllCasings.mjs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* GetAllCasings tests.
|
||||||
|
*
|
||||||
|
* @author n1073645 [n1073645@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2020
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "All casings of test",
|
||||||
|
input: "test",
|
||||||
|
expectedOutput: "test\nTest\ntEst\nTEst\nteSt\nTeSt\ntESt\nTESt\ntesT\nTesT\ntEsT\nTEsT\nteST\nTeST\ntEST\nTEST\n",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Get All Casings",
|
||||||
|
"args": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "All casings of t",
|
||||||
|
input: "t",
|
||||||
|
expectedOutput: "t\nT\n",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Get All Casings",
|
||||||
|
"args": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "All casings of null",
|
||||||
|
input: "",
|
||||||
|
expectedOutput: "\n",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Get All Casings",
|
||||||
|
"args": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
@@ -10,10 +10,10 @@ import TestRegister from "../../lib/TestRegister.mjs";
|
|||||||
|
|
||||||
TestRegister.addTests([
|
TestRegister.addTests([
|
||||||
{
|
{
|
||||||
name: "Protobuf Decode",
|
name: "Protobuf Decode: no schema",
|
||||||
input: "0d1c0000001203596f751a024d65202b2a0a0a066162633132331200",
|
input: "0d1c0000001203596f751a024d65202b2a0a0a066162633132331200",
|
||||||
expectedOutput: JSON.stringify({
|
expectedOutput: JSON.stringify({
|
||||||
"1": 469762048,
|
"1": 28,
|
||||||
"2": "You",
|
"2": "You",
|
||||||
"3": "Me",
|
"3": "Me",
|
||||||
"4": 43,
|
"4": 43,
|
||||||
@@ -29,7 +29,277 @@ TestRegister.addTests([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"op": "Protobuf Decode",
|
"op": "Protobuf Decode",
|
||||||
"args": []
|
"args": ["", false, false]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Protobuf Decode: partial schema, no unknown fields",
|
||||||
|
input: "0d1c0000001203596f751a024d65202b2a0a0a066162633132331200",
|
||||||
|
expectedOutput: JSON.stringify({
|
||||||
|
"Apple": [
|
||||||
|
28
|
||||||
|
],
|
||||||
|
"Banana": "You",
|
||||||
|
"Carrot": [
|
||||||
|
"Me"
|
||||||
|
]
|
||||||
|
}, null, 4),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From Hex",
|
||||||
|
"args": ["Auto"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Protobuf Decode",
|
||||||
|
"args": [
|
||||||
|
`message Test {
|
||||||
|
repeated fixed32 Apple = 1;
|
||||||
|
optional string Banana = 2;
|
||||||
|
repeated string Carrot = 3;
|
||||||
|
}`,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Protobuf Decode: partial schema, show unknown fields",
|
||||||
|
input: "0d1c0000001203596f751a024d65202b2a0a0a066162633132331200",
|
||||||
|
expectedOutput: JSON.stringify({
|
||||||
|
"Test": {
|
||||||
|
"Apple": [
|
||||||
|
28
|
||||||
|
],
|
||||||
|
"Banana": "You",
|
||||||
|
"Carrot": [
|
||||||
|
"Me"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Unknown Fields": {
|
||||||
|
"4": 43,
|
||||||
|
"5": {
|
||||||
|
"1": "abc123",
|
||||||
|
"2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, null, 4),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From Hex",
|
||||||
|
"args": ["Auto"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Protobuf Decode",
|
||||||
|
"args": [
|
||||||
|
`message Test {
|
||||||
|
repeated fixed32 Apple = 1;
|
||||||
|
optional string Banana = 2;
|
||||||
|
repeated string Carrot = 3;
|
||||||
|
}`,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Protobuf Decode: full schema, no unknown fields",
|
||||||
|
input: "0d1c0000001203596f751a024d65202b2a0a0a06616263313233120031ff00000000000000",
|
||||||
|
expectedOutput: JSON.stringify({
|
||||||
|
"Apple": [
|
||||||
|
28
|
||||||
|
],
|
||||||
|
"Banana": "You",
|
||||||
|
"Carrot": [
|
||||||
|
"Me"
|
||||||
|
],
|
||||||
|
"Date": 43,
|
||||||
|
"Elderberry": {
|
||||||
|
"Fig": "abc123",
|
||||||
|
"Grape": {}
|
||||||
|
},
|
||||||
|
"Huckleberry": 255
|
||||||
|
}, null, 4),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From Hex",
|
||||||
|
"args": ["Auto"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Protobuf Decode",
|
||||||
|
"args": [
|
||||||
|
`message Test {
|
||||||
|
repeated fixed32 Apple = 1;
|
||||||
|
optional string Banana = 2;
|
||||||
|
repeated string Carrot = 3;
|
||||||
|
optional int32 Date = 4;
|
||||||
|
optional subTest Elderberry = 5;
|
||||||
|
optional fixed64 Huckleberry = 6;
|
||||||
|
}
|
||||||
|
message subTest {
|
||||||
|
optional string Fig = 1;
|
||||||
|
optional subSubTest Grape = 2;
|
||||||
|
}
|
||||||
|
message subSubTest {}`,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Protobuf Decode: partial schema, show unknown fields, show types",
|
||||||
|
input: "0d1c0000001203596f751a024d65202b2a0a0a06616263313233120031ba32a96cc10200003801",
|
||||||
|
expectedOutput: JSON.stringify({
|
||||||
|
"Test": {
|
||||||
|
"Banana (string)": "You",
|
||||||
|
"Carrot (string)": [
|
||||||
|
"Me"
|
||||||
|
],
|
||||||
|
"Date (int32)": 43,
|
||||||
|
"Imbe (Options)": "Option1"
|
||||||
|
},
|
||||||
|
"Unknown Fields": {
|
||||||
|
"field #1: 32-Bit (e.g. fixed32, float)": 28,
|
||||||
|
"field #5: L-delim (e.g. string, message)": {
|
||||||
|
"field #1: L-delim (e.g. string, message)": "abc123",
|
||||||
|
"field #2: L-delim (e.g. string, message)": {}
|
||||||
|
},
|
||||||
|
"field #6: 64-Bit (e.g. fixed64, double)": 3029774971578
|
||||||
|
}
|
||||||
|
}, null, 4),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "From Hex",
|
||||||
|
"args": ["Auto"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "Protobuf Decode",
|
||||||
|
"args": [
|
||||||
|
`message Test {
|
||||||
|
optional string Banana = 2;
|
||||||
|
repeated string Carrot = 3;
|
||||||
|
optional int32 Date = 4;
|
||||||
|
optional Options Imbe = 7;
|
||||||
|
}
|
||||||
|
message subTest {
|
||||||
|
optional string Fig = 1;
|
||||||
|
optional subSubTest Grape = 2;
|
||||||
|
}
|
||||||
|
message subSubTest {}
|
||||||
|
enum Options {
|
||||||
|
Option0 = 0;
|
||||||
|
Option1 = 1;
|
||||||
|
Option2 = 2;
|
||||||
|
}`,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Protobuf Encode",
|
||||||
|
input: JSON.stringify({
|
||||||
|
"Apple": [
|
||||||
|
28
|
||||||
|
],
|
||||||
|
"Banana": "You",
|
||||||
|
"Carrot": [
|
||||||
|
"Me"
|
||||||
|
],
|
||||||
|
"Date": 43,
|
||||||
|
"Elderberry": {
|
||||||
|
"Fig": "abc123",
|
||||||
|
"Grape": {}
|
||||||
|
},
|
||||||
|
"Huckleberry": [3029774971578],
|
||||||
|
"Imbe": 1
|
||||||
|
}, null, 4),
|
||||||
|
expectedOutput: "0d1c0000001203596f751a024d65202b2a0a0a06616263313233120031ba32a96cc10200003801",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Protobuf Encode",
|
||||||
|
"args": [
|
||||||
|
`message Test {
|
||||||
|
repeated fixed32 Apple = 1;
|
||||||
|
optional string Banana = 2;
|
||||||
|
repeated string Carrot = 3;
|
||||||
|
optional int32 Date = 4;
|
||||||
|
optional subTest Elderberry = 5;
|
||||||
|
repeated fixed64 Huckleberry = 6;
|
||||||
|
optional Options Imbe = 7;
|
||||||
|
}
|
||||||
|
message subTest {
|
||||||
|
optional string Fig = 1;
|
||||||
|
optional subSubTest Grape = 2;
|
||||||
|
}
|
||||||
|
message subSubTest {}
|
||||||
|
enum Options {
|
||||||
|
Option0 = 0;
|
||||||
|
Option1 = 1;
|
||||||
|
Option2 = 2;
|
||||||
|
}`
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "To Hex",
|
||||||
|
"args": [
|
||||||
|
"None",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Protobuf Encode: incomplete schema",
|
||||||
|
input: JSON.stringify({
|
||||||
|
"Apple": [
|
||||||
|
28
|
||||||
|
],
|
||||||
|
"Banana": "You",
|
||||||
|
"Carrot": [
|
||||||
|
"Me"
|
||||||
|
],
|
||||||
|
"Date": 43,
|
||||||
|
"Elderberry": {
|
||||||
|
"Fig": "abc123",
|
||||||
|
"Grape": {}
|
||||||
|
},
|
||||||
|
"Huckleberry": [3029774971578],
|
||||||
|
"Imbe": 1
|
||||||
|
}, null, 4),
|
||||||
|
expectedOutput: "1203596f75202b2a0a0a06616263313233120031ba32a96cc1020000",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "Protobuf Encode",
|
||||||
|
"args": [
|
||||||
|
`message Test {
|
||||||
|
optional string Banana = 2;
|
||||||
|
optional int32 Date = 4;
|
||||||
|
optional subTest Elderberry = 5;
|
||||||
|
repeated fixed64 Huckleberry = 6;
|
||||||
|
}
|
||||||
|
message subTest {
|
||||||
|
optional string Fig = 1;
|
||||||
|
optional subSubTest Grape = 2;
|
||||||
|
}
|
||||||
|
message subSubTest {}
|
||||||
|
enum Options {
|
||||||
|
Option0 = 0;
|
||||||
|
Option1 = 1;
|
||||||
|
Option2 = 2;
|
||||||
|
}`
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"op": "To Hex",
|
||||||
|
"args": [
|
||||||
|
"None",
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ const banner = `/**
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
output: {
|
output: {
|
||||||
publicPath: "",
|
publicPath: "",
|
||||||
globalObject: "this"
|
globalObject: "this",
|
||||||
|
assetModuleFilename: "assets/[hash][ext][query]"
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.ProvidePlugin({
|
new webpack.ProvidePlugin({
|
||||||
@@ -122,7 +123,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /prime.worker.min.js$/,
|
test: /prime.worker.min.js$/,
|
||||||
use: "raw-loader"
|
type: "asset/source"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /bootstrap-material-design/,
|
test: /bootstrap-material-design/,
|
||||||
@@ -165,53 +166,33 @@ module.exports = {
|
|||||||
"sass-loader",
|
"sass-loader",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* The limit for these files has been increased to 60,000 (60KB)
|
|
||||||
* to ensure the material icons font is inlined.
|
|
||||||
*
|
|
||||||
* See: https://github.com/gchq/CyberChef/issues/612
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
test: /\.(ico|eot|ttf|woff|woff2)$/,
|
test: /\.(ico|eot|ttf|woff|woff2)$/,
|
||||||
loader: "url-loader",
|
type: "asset/resource",
|
||||||
options: {
|
|
||||||
limit: 60000,
|
|
||||||
name: "[hash].[ext]",
|
|
||||||
outputPath: "assets"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.svg$/,
|
test: /\.svg$/,
|
||||||
loader: "svg-url-loader",
|
type: "asset/inline",
|
||||||
options: {
|
|
||||||
encoding: "base64"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{ // Store font .fnt and .png files in a separate fonts folder
|
{ // Store font .fnt and .png files in a separate fonts folder
|
||||||
test: /(\.fnt$|bmfonts\/.+\.png$)/,
|
test: /(\.fnt$|bmfonts\/.+\.png$)/,
|
||||||
loader: "file-loader",
|
type: "asset/resource",
|
||||||
options: {
|
generator: {
|
||||||
name: "[name].[ext]",
|
filename: "assets/fonts/[name][ext]"
|
||||||
outputPath: "assets/fonts"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ // First party images are saved as files to be cached
|
{ // First party images are saved as files to be cached
|
||||||
test: /\.(png|jpg|gif)$/,
|
test: /\.(png|jpg|gif)$/,
|
||||||
exclude: /(node_modules|bmfonts)/,
|
exclude: /(node_modules|bmfonts)/,
|
||||||
loader: "file-loader",
|
type: "asset/resource",
|
||||||
options: {
|
generator: {
|
||||||
name: "images/[name].[ext]"
|
filename: "images/[name][ext]"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ // Third party images are inlined
|
{ // Third party images are inlined
|
||||||
test: /\.(png|jpg|gif)$/,
|
test: /\.(png|jpg|gif)$/,
|
||||||
exclude: /web\/static/,
|
exclude: /web\/static/,
|
||||||
loader: "url-loader",
|
type: "asset/inline",
|
||||||
options: {
|
|
||||||
limit: 10000,
|
|
||||||
name: "[hash].[ext]",
|
|
||||||
outputPath: "assets"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -219,14 +200,15 @@ module.exports = {
|
|||||||
children: false,
|
children: false,
|
||||||
chunks: false,
|
chunks: false,
|
||||||
modules: false,
|
modules: false,
|
||||||
entrypoints: false,
|
entrypoints: false
|
||||||
warningsFilter: [
|
|
||||||
/source-map/,
|
|
||||||
/dependency is an expression/,
|
|
||||||
/export 'default'/,
|
|
||||||
/Can't resolve 'sodium'/
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
ignoreWarnings: [
|
||||||
|
/source-map/,
|
||||||
|
/source map/,
|
||||||
|
/dependency is an expression/,
|
||||||
|
/export 'default'/,
|
||||||
|
/Can't resolve 'sodium'/
|
||||||
|
],
|
||||||
performance: {
|
performance: {
|
||||||
hints: false
|
hints: false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user