Compare commits

..

19 Commits

Author SHA1 Message Date
n1474335
a85096ea11 5.3.4 2017-05-06 15:00:46 +01:00
n1474335
f67157f0ad Fixed erroring dependency 2017-05-06 15:00:28 +01:00
n1474335
17188b1e38 Merge branch 'tlwr-feature-async-ops-small' 2017-05-06 14:00:08 +01:00
n1474335
e9c3bebfff Fixed lint error 2017-05-06 13:59:33 +01:00
n1474335
03fc22d3da Merge conflicts 2017-05-06 13:47:26 +01:00
n1474335
5d52c49c31 5.3.3 2017-05-05 16:04:22 +00:00
n1474335
d53da4cfb5 Merge branch 'bug-x509-sig' 2017-05-05 16:03:40 +00:00
n1474335
76204f5f47 Fixed lint errors 2017-05-05 16:03:25 +00:00
n1474335
b68adbd9a8 Merge branch 'master' into bug-x509-sig 2017-05-05 16:02:12 +00:00
n1474335
b010fd88e8 Fix X.509 signature breakout bug 2017-05-05 15:42:24 +00:00
toby
274e1139fa Remove debounce from Utils 2017-05-03 10:43:30 -04:00
toby
6122e33f4f Removed debounced autobake & stop disabling input 2017-05-03 10:35:15 -04:00
toby
50784f2600 Debounce autobake in the web app.
Added debounce with guidance from the underscore.js implementation:
e944e0275a/underscore.js (L880)
2017-04-23 13:41:28 -04:00
toby
21c0fed833 Fix bug: baking error did not reset baking status 2017-04-23 13:14:59 -04:00
toby
a13e2468db Added UI loading indications to the HTML app 2017-04-21 20:04:12 -04:00
toby
3fb660d816 Add jsdoc-babel plugin
This is to stop jsdoc parsing errors.

More information in this thread:
https://github.com/jsdoc3/jsdoc/issues/555
2017-04-21 18:05:30 -04:00
toby
9f60dc3dd6 Change ecmaVersion to 8 to make eslint happy 2017-04-21 17:56:16 -04:00
toby
02f855ff09 Add more tests for flow control ops 2017-04-21 17:49:10 -04:00
toby
c39622ed1e Add support for async ops using async/await 2017-04-21 17:48:42 -04:00
12 changed files with 231 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
{
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": 8,
"ecmaFeatures": {
"impliedStrict": true
},

View File

@@ -2,7 +2,10 @@
"tags": {
"allowUnknownTags": true
},
"plugins": ["plugins/markdown"],
"plugins": [
"plugins/markdown",
"node_modules/jsdoc-babel"
],
"templates": {
"systemName": "CyberChef",
"footer": "",

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "5.3.2",
"version": "5.3.4",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",
@@ -51,6 +51,7 @@
"html-webpack-plugin": "^2.28.0",
"imports-loader": "^0.7.1",
"ink-docstrap": "^1.1.4",
"jsdoc-babel": "^0.3.0",
"less": "^2.7.2",
"less-loader": "^4.0.2",
"style-loader": "^0.15.0",
@@ -71,7 +72,7 @@
"google-code-prettify": "^1.0.5",
"jquery": "^3.1.1",
"jsbn": "^1.1.0",
"jsrsasign": "^7.1.0",
"jsrsasign": "7.1.3",
"lodash": "^4.17.4",
"moment": "^2.17.1",
"moment-timezone": "^0.5.11",

View File

@@ -34,7 +34,7 @@ const Chef = function() {
* @returns {number} response.duration - The number of ms it took to execute the recipe
* @returns {number} response.error - The error object thrown by a failed operation (false if no error)
*/
Chef.prototype.bake = function(inputText, recipeConfig, options, progress, step) {
Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, step) {
let startTime = new Date().getTime(),
recipe = new Recipe(recipeConfig),
containsFc = recipe.containsFlowControl(),
@@ -72,7 +72,7 @@ Chef.prototype.bake = function(inputText, recipeConfig, options, progress, step)
}
try {
progress = recipe.execute(this.dish, progress);
progress = await recipe.execute(this.dish, progress);
} catch (err) {
// Return the error in the result so that everything else gets correctly updated
// rather than throwing it here and losing state info.

View File

@@ -38,7 +38,7 @@ const FlowControl = {
* @param {Operation[]} state.opList - The list of operations in the recipe.
* @returns {Object} The updated state of the recipe.
*/
runFork: function(state) {
runFork: async function(state) {
let opList = state.opList,
inputType = opList[state.progress].inputType,
outputType = opList[state.progress].outputType,
@@ -74,7 +74,7 @@ const FlowControl = {
for (i = 0; i < inputs.length; i++) {
const dish = new Dish(inputs[i], inputType);
try {
progress = recipe.execute(dish, 0);
progress = await recipe.execute(dish, 0);
} catch (err) {
if (!ignoreErrors) {
throw err;

View File

@@ -145,7 +145,7 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
* @param {number} [startFrom=0] - The index of the Operation to start executing from
* @returns {number} - The final progress through the recipe
*/
Recipe.prototype.execute = function(dish, startFrom) {
Recipe.prototype.execute = async function(dish, startFrom) {
startFrom = startFrom || 0;
let op, input, output, numJumps = 0;
@@ -170,11 +170,11 @@ Recipe.prototype.execute = function(dish, startFrom) {
"numJumps" : numJumps
};
state = op.run(state);
state = await op.run(state);
i = state.progress;
numJumps = state.numJumps;
} else {
output = op.run(input, op.getIngValues());
output = await op.run(input, op.getIngValues());
dish.set(output, op.outputType);
}
} catch (err) {

View File

@@ -124,10 +124,17 @@ const PublicKey = {
}
// Signature fields
if (r.ASN1HEX.dump(certSig).indexOf("SEQUENCE") === 0) { // DSA or ECDSA
let breakoutSig = false;
try {
breakoutSig = r.ASN1HEX.dump(certSig).indexOf("SEQUENCE") === 0;
} catch (err) {
// Error processing signature, output without further breakout
}
if (breakoutSig) { // DSA or ECDSA
sigStr = " r: " + PublicKey._formatByteStr(r.ASN1HEX.getDecendantHexVByNthList(certSig, 0, [0]), 16, 18) + "\n" +
" s: " + PublicKey._formatByteStr(r.ASN1HEX.getDecendantHexVByNthList(certSig, 0, [1]), 16, 18) + "\n";
} else { // RSA
} else { // RSA or unknown
sigStr = " Signature: " + PublicKey._formatByteStr(certSig, 16, 18) + "\n";
}

View File

@@ -30,6 +30,7 @@ const App = function(categories, operations, defaultFavourites, defaultOptions)
this.chef = new Chef();
this.manager = new Manager(this);
this.baking = false;
this.autoBake_ = false;
this.progress = 0;
this.ingId = 0;
@@ -67,19 +68,49 @@ App.prototype.handleError = function(err) {
};
/**
* Updates the UI to show if baking is in process or not.
*
* @param {bakingStatus}
*/
App.prototype.setBakingStatus = function(bakingStatus) {
this.baking = bakingStatus;
let inputLoadingIcon = document.querySelector("#input .title .loading-icon"),
outputLoadingIcon = document.querySelector("#output .title .loading-icon"),
outputElement = document.querySelector("#output-text");
if (bakingStatus) {
inputLoadingIcon.style.display = "inline-block";
outputLoadingIcon.style.display = "inline-block";
outputElement.classList.add("disabled");
outputElement.disabled = true;
} else {
inputLoadingIcon.style.display = "none";
outputLoadingIcon.style.display = "none";
outputElement.classList.remove("disabled");
outputElement.disabled = false;
}
};
/**
* Calls the Chef to bake the current input using the current recipe.
*
* @param {boolean} [step] - Set to true if we should only execute one operation instead of the
* whole recipe.
*/
App.prototype.bake = function(step) {
App.prototype.bake = async function(step) {
let response;
if (this.baking) return;
this.setBakingStatus(true);
try {
response = this.chef.bake(
this.getInput(), // The user's input
this.getRecipeConfig(), // The configuration of the recipe
response = await this.chef.bake(
this.getInput(), // The user's input
this.getRecipeConfig(), // The configuration of the recipe
this.options, // Options set by the user
this.progress, // The current position in the recipe
step // Whether or not to take one step or execute the whole recipe
@@ -88,6 +119,8 @@ App.prototype.bake = function(step) {
this.handleError(err);
}
this.setBakingStatus(false);
if (!response) return;
if (response.error) {

View File

@@ -430,3 +430,36 @@ span.btn img {
border-top: none;
margin-top: 0;
}
@-moz-keyframes spinner {
from { -moz-transform: rotate(0deg); }
to { -moz-transform: rotate(359deg); }
}
@-webkit-keyframes spinner {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(359deg); }
}
@keyframes spinner {
from {transform:rotate(0deg);}
to {transform:rotate(359deg);}
}
.loading-icon::before {
content: "\21bb";
}
.loading-icon {
-webkit-animation-name: spinner;
-webkit-animation-duration: 1000ms;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-name: spinner;
-moz-animation-duration: 1000ms;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: linear;
-ms-animation-name: spinner;
-ms-animation-duration: 1000ms;
-ms-animation-iteration-count: infinite;
-ms-animation-timing-function: linear;
}

View File

@@ -100,6 +100,7 @@
<div id="input" class="split no-select">
<div class="title no-select">
<label for="input-text">Input</label>
<div class="loading-icon" style="display: none"></div>
<div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="clr-io"><img aria-hidden="true" src="<%- require('../static/images/recycle-16x16.png') %>" alt="Recycle Icon"/> Clear I/O</button>
<button type="button" class="btn btn-default btn-sm" id="reset-layout"><img aria-hidden="true" src="<%- require('../static/images/layout-16x16.png') %>" alt="Grid Icon"/> Reset layout</button>
@@ -116,6 +117,7 @@
<div id="output" class="split">
<div class="title no-select">
<label for="output-text">Output</label>
<div class="loading-icon" style="display: none"></div>
<div class="btn-group io-btn-group">
<button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
<button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>

View File

@@ -40,13 +40,13 @@ import Chef from "../src/core/Chef.js";
this.tests.map(function(test, i) {
let chef = new Chef();
return Promise.resolve(chef.bake(
return chef.bake(
test.input,
test.recipeConfig,
{},
0,
false
))
)
.then(function(result) {
let ret = {
test: test,

View File

@@ -66,6 +66,62 @@ TestRegister.addTests([
{"op":"To Base64", "args":["A-Za-z0-9+/="]}
]
},
{
name: "Jump: skips 0",
input: [
"should be changed",
].join("\n"),
expectedOutput: [
"should be changed was changed",
].join("\n"),
recipeConfig: [
{
op: "Jump",
args: [0, 10],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "should be changed"
},
"should be changed was changed",
true,
true,
true,
],
},
],
},
{
name: "Jump: skips 1",
input: [
"shouldnt be changed",
].join("\n"),
expectedOutput: [
"shouldnt be changed",
].join("\n"),
recipeConfig: [
{
op: "Jump",
args: [1, 10],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "shouldnt be changed"
},
"shouldnt be changed was changed",
true,
true,
true,
],
},
],
},
{
name: "Conditional Jump: Skips 0",
input: [
@@ -141,4 +197,81 @@ TestRegister.addTests([
}
]
},
{
name: "Conditional Jump: Skips 1",
input: [
"match",
"should not be changed",
"should be changed",
].join("\n"),
expectedOutput: [
"match",
"should not be changed",
"should be changed was changed"
].join("\n"),
recipeConfig: [
{
op: "Conditional Jump",
args: ["match", 1, 10],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "should not be changed"
},
"should not be changed was changed",
true,
true,
true,
],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "should be changed"
},
"should be changed was changed",
true,
true,
true,
],
},
],
},
{
name: "Conditional Jump: Skips negatively",
input: [
"match",
].join("\n"),
expectedOutput: [
"replaced",
].join("\n"),
recipeConfig: [
{
op: "Jump",
args: [1],
},
{
op: "Find / Replace",
args: [
{
"option": "Regex",
"string": "match"
},
"replaced",
true,
true,
true,
],
},
{
op: "Conditional Jump",
args: ["match", -2, 10],
},
],
},
]);