Merge 4d8d28b7aa4a7843e12f9c0e3e879de95c47951e into 2eada231feceb4474b418fb18de41722a6d47c20
This commit is contained in:
commit
06a11f8f63
@ -69,6 +69,7 @@
|
|||||||
"jsrsasign": "^7.1.0",
|
"jsrsasign": "^7.1.0",
|
||||||
"moment": "^2.17.1",
|
"moment": "^2.17.1",
|
||||||
"moment-timezone": "^0.5.11",
|
"moment-timezone": "^0.5.11",
|
||||||
|
"openpgp": "^2.5.4",
|
||||||
"sladex-blowfish": "^0.8.1",
|
"sladex-blowfish": "^0.8.1",
|
||||||
"sortablejs": "^1.5.1",
|
"sortablejs": "^1.5.1",
|
||||||
"split.js": "^1.2.0",
|
"split.js": "^1.2.0",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 6,
|
"ecmaVersion": 8,
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
"impliedStrict": true
|
"impliedStrict": true
|
||||||
},
|
},
|
||||||
|
|||||||
@ -145,10 +145,10 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
|
|||||||
* @param {number} [currentStep=0] - The index of the Operation to start executing from
|
* @param {number} [currentStep=0] - The index of the Operation to start executing from
|
||||||
* @returns {number} - The final progress through the recipe
|
* @returns {number} - The final progress through the recipe
|
||||||
*/
|
*/
|
||||||
Recipe.prototype.execute = function(dish, currentStep, state) {
|
Recipe.prototype.execute = async function(dish, currentStep, state) {
|
||||||
var recipe = this;
|
var recipe = this;
|
||||||
|
|
||||||
var formatErrMsg = function(err, step, op) {
|
let formatErrMsg = function(err, step, op) {
|
||||||
var e = typeof err == "string" ? { message: err } : err;
|
var e = typeof err == "string" ? { message: err } : err;
|
||||||
|
|
||||||
e.progress = step;
|
e.progress = step;
|
||||||
@ -163,90 +163,40 @@ Recipe.prototype.execute = function(dish, currentStep, state) {
|
|||||||
return e;
|
return e;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Operations can be asynchronous so we have to return a Promise to a future value.
|
currentStep = currentStep || 0;
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
// Helper function to clean up recursing to the next recipe step.
|
|
||||||
// It is a closure to avoid having to pass in resolve and reject.
|
|
||||||
var execRecipe = function(recipe, dish, step, state) {
|
|
||||||
return recipe.execute(dish, step, state)
|
|
||||||
.then(function(progress) {
|
|
||||||
resolve(progress);
|
|
||||||
})
|
|
||||||
.catch(function(err) {
|
|
||||||
// Pass back the error to the previous caller.
|
|
||||||
// We don't want to handle the error here as the current
|
|
||||||
// operation did not cause the error, and so it should
|
|
||||||
// not appear in the error message.
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
currentStep = currentStep || 0;
|
if (currentStep >= recipe.opList.length) {
|
||||||
|
return currentStep;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentStep >= recipe.opList.length) {
|
let op = recipe.opList[currentStep],
|
||||||
resolve(currentStep);
|
input = dish.get(op.inputType);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = recipe.opList[currentStep],
|
|
||||||
input = dish.get(op.inputType);
|
|
||||||
|
|
||||||
|
try {
|
||||||
if (op.isDisabled()) {
|
if (op.isDisabled()) {
|
||||||
// Skip to next operation
|
// Skip to next operation
|
||||||
var nextStep = currentStep + 1;
|
return recipe.execute(dish, currentStep + 1, state);
|
||||||
execRecipe(recipe, dish, nextStep, state);
|
|
||||||
} else if (op.isBreakpoint()) {
|
} else if (op.isBreakpoint()) {
|
||||||
// We are at a breakpoint, we shouldn't recurse to the next op.
|
// We are at a breakpoint, we shouldn't recurse to the next op.
|
||||||
resolve(currentStep);
|
return currentStep;
|
||||||
} else {
|
} else if (op.isFlowControl()) {
|
||||||
var operationResult;
|
state = {
|
||||||
|
progress: currentStep,
|
||||||
// We must try/catch here because op.run can either return
|
dish: dish,
|
||||||
// A) a value
|
opList: recipe.opList,
|
||||||
// B) a promise
|
numJumps: (state && state.numJumps) || 0,
|
||||||
// Promise.resolve -> .catch will handle errors from promises
|
};
|
||||||
// try/catch will handle errors from values
|
state = await op.run(state);
|
||||||
try {
|
let progress = await recipe.execute(state.dish, state.progress + 1);
|
||||||
if (op.isFlowControl()) {
|
return progress;
|
||||||
state = {
|
} else {
|
||||||
progress: currentStep,
|
let output = await op.run(input, op.getIngValues());
|
||||||
dish: dish,
|
dish.set(output, op.outputType);
|
||||||
opList: recipe.opList,
|
return recipe.execute(dish, currentStep + 1, state);
|
||||||
numJumps: (state && state.numJumps) || 0,
|
|
||||||
};
|
|
||||||
operationResult = op.run(state);
|
|
||||||
} else {
|
|
||||||
operationResult = op.run(input, op.getIngValues());
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
reject(formatErrMsg(err, currentStep, op));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op.isFlowControl()) {
|
|
||||||
Promise.resolve(operationResult)
|
|
||||||
.then(function(state) {
|
|
||||||
return recipe.execute(state.dish, state.progress + 1);
|
|
||||||
})
|
|
||||||
.then(function(progress) {
|
|
||||||
resolve(progress);
|
|
||||||
})
|
|
||||||
.catch(function(err) {
|
|
||||||
reject(formatErrMsg(err, currentStep, op));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Promise.resolve(operationResult)
|
|
||||||
.then(function(output) {
|
|
||||||
dish.set(output, op.outputType);
|
|
||||||
var nextStep = currentStep + 1;
|
|
||||||
execRecipe(recipe, dish, nextStep, state);
|
|
||||||
})
|
|
||||||
.catch(function(err) {
|
|
||||||
reject(formatErrMsg(err, currentStep, op));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
} catch (err) {
|
||||||
|
throw formatErrMsg(err, currentStep, op);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -92,6 +92,18 @@ const Categories = [
|
|||||||
"Substitute",
|
"Substitute",
|
||||||
"Derive PBKDF2 key",
|
"Derive PBKDF2 key",
|
||||||
"Derive EVP key",
|
"Derive EVP key",
|
||||||
|
"PGP Encrypt",
|
||||||
|
"PGP Decrypt",
|
||||||
|
"PGP Sign",
|
||||||
|
"PGP Verify",
|
||||||
|
"Sign PGP Detached",
|
||||||
|
"Verify PGP Detached",
|
||||||
|
"Sign PGP Cleartext",
|
||||||
|
"Verify PGP Cleartext",
|
||||||
|
"Generate PGP Key Pair",
|
||||||
|
"Detach PGP Cleartext",
|
||||||
|
"Add PGP ASCII Armour",
|
||||||
|
"Remove PGP ASCII Armour",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -103,6 +115,18 @@ const Categories = [
|
|||||||
"Hex to PEM",
|
"Hex to PEM",
|
||||||
"Hex to Object Identifier",
|
"Hex to Object Identifier",
|
||||||
"Object Identifier to Hex",
|
"Object Identifier to Hex",
|
||||||
|
"PGP Encrypt",
|
||||||
|
"PGP Decrypt",
|
||||||
|
"PGP Sign",
|
||||||
|
"PGP Verify",
|
||||||
|
"Sign PGP Detached",
|
||||||
|
"Verify PGP Detached",
|
||||||
|
"Sign PGP Cleartext",
|
||||||
|
"Verify PGP Cleartext",
|
||||||
|
"Detach PGP Cleartext",
|
||||||
|
"Generate PGP Key Pair",
|
||||||
|
"Add PGP ASCII Armour",
|
||||||
|
"Remove PGP ASCII Armour",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import MorseCode from "../operations/MorseCode.js";
|
|||||||
import NetBIOS from "../operations/NetBIOS.js";
|
import NetBIOS from "../operations/NetBIOS.js";
|
||||||
import Numberwang from "../operations/Numberwang.js";
|
import Numberwang from "../operations/Numberwang.js";
|
||||||
import OS from "../operations/OS.js";
|
import OS from "../operations/OS.js";
|
||||||
|
import PGP from "../operations/PGP.js";
|
||||||
import PublicKey from "../operations/PublicKey.js";
|
import PublicKey from "../operations/PublicKey.js";
|
||||||
import Punycode from "../operations/Punycode.js";
|
import Punycode from "../operations/Punycode.js";
|
||||||
import QuotedPrintable from "../operations/QuotedPrintable.js";
|
import QuotedPrintable from "../operations/QuotedPrintable.js";
|
||||||
@ -3181,6 +3182,353 @@ const OperationConfig = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"PGP Encrypt": {
|
||||||
|
description: [
|
||||||
|
"Input: the message you want to encrypt.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP public key of the recipient.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runEncrypt,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Public key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PGP Decrypt": {
|
||||||
|
description: [
|
||||||
|
"Input: the ASCII-armoured PGP message you want to decrypt.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP private key of the recipient, ",
|
||||||
|
"(and the private key password if necessary).",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.<br><br>See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runDecrypt,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Private key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key password",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PGP Sign": {
|
||||||
|
description: [
|
||||||
|
"Input: the cleartext you want to sign.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP public key of the recipient, ",
|
||||||
|
"the ASCII-armoured private key of the signer (and the private key password if necessary).",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation uses PGP to produce an encrypted digital signature.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runSign,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Public key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key password",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"PGP Verify": {
|
||||||
|
description: [
|
||||||
|
"Input: the ASCII-armoured encrypted PGP message you want to verify.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP public key of the signer, ",
|
||||||
|
"the ASCII-armoured private key of the recipient (and the private key password if necessary).",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation uses PGP to decrypt and verify an encrypted digital signature.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runVerify,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Public key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key password",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Sign PGP Detached": {
|
||||||
|
description: [
|
||||||
|
"Input: the cleartext you want to sign.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP private key of the signer, ",
|
||||||
|
" (and the private key password if necessary).",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation uses PGP to produce a cleartext message and its digital signature. ",
|
||||||
|
"It outputs 3 files as HTML: ",
|
||||||
|
"the cleartext message (msg), ",
|
||||||
|
"the ASCII-armoured signature (msg.asc), and ",
|
||||||
|
"the raw bytes of the signature (msg.sig).",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runSignDetached,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "HTML",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Private key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key password",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Verify PGP Detached": {
|
||||||
|
description: [
|
||||||
|
"Input: the cleartext of the message you want to verify.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP public key of the sender, ",
|
||||||
|
"the ASCII-armoured signature of the message.",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation uses PGP to verify a detached cleartext PGP signature.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runVerifyDetached,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Public key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Signature",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Sign PGP Cleartext": {
|
||||||
|
description: [
|
||||||
|
"Input: the cleartext of the message you want to sign.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP private key of the signer, ",
|
||||||
|
"(and the private key password if necessary).",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation uses PGP to produce a digital signature.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runSignCleartext,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Private key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Private key password",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Verify PGP Cleartext": {
|
||||||
|
description: [
|
||||||
|
"Input: the ASCII-armoured cleartext signature you want to verify.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the ASCII-armoured PGP public key of the sender.",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation uses PGP to verify a cleartext digital signature.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runVerifyCleartext,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Public key",
|
||||||
|
type: "text",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Generate PGP Key Pair": {
|
||||||
|
description: [
|
||||||
|
"Input is ignored.",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation generates a PGP key pair.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runGenKeyPair,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Password",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Key size",
|
||||||
|
type: "option",
|
||||||
|
value: ["1024", "2048", "4096"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Name",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Email",
|
||||||
|
type: "string",
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Detach PGP Cleartext": {
|
||||||
|
description: [
|
||||||
|
"Input: the ASCII-armoured cleartext signature you want to verify.",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation will detach the cleartext message from the signature.",
|
||||||
|
"It outputs 3 files as HTML: ",
|
||||||
|
"the cleartext message (msg), ",
|
||||||
|
"the ASCII-armoured signature (msg.asc), and ",
|
||||||
|
"the raw bytes of the signature (msg.sig).",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runDetachClearsig,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "HTML",
|
||||||
|
args: [
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"Add PGP ASCII Armour": {
|
||||||
|
description: [
|
||||||
|
"Input: the raw PGP bytes of the message or key that you want to add ASCII-armour to.",
|
||||||
|
"<br><br>",
|
||||||
|
"Arguments: the kind of the raw bytes: message / public key / private key.",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation will output the ASCII-armoured input.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runAddArmour,
|
||||||
|
inputType: "byteArray",
|
||||||
|
outputType: "string",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Armour type",
|
||||||
|
type: "option",
|
||||||
|
value: PGP.ARMOUR_TYPES,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"Remove PGP ASCII Armour": {
|
||||||
|
description: [
|
||||||
|
"Input: the ASCII-armoured PGP message or key that you want to remove the ASCII-armour from.",
|
||||||
|
"<br><br>",
|
||||||
|
"This operation will output the raw bytes of the PGP packets.",
|
||||||
|
"<br><br>",
|
||||||
|
"Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
|
||||||
|
"<br><br>",
|
||||||
|
"This function relies on OpenPGP.js for the implementation of PGP.",
|
||||||
|
"<br><br>",
|
||||||
|
"See more at https://openpgpjs.org/",
|
||||||
|
].join("\n"),
|
||||||
|
run: PGP.runRemoveArmour,
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "byteArray",
|
||||||
|
args: [
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default OperationConfig;
|
export default OperationConfig;
|
||||||
|
|||||||
596
src/core/operations/PGP.js
Executable file
596
src/core/operations/PGP.js
Executable file
@ -0,0 +1,596 @@
|
|||||||
|
import * as openpgp from "openpgp";
|
||||||
|
import Utils from "../Utils.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP operations.
|
||||||
|
*
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*
|
||||||
|
* @namespace
|
||||||
|
*/
|
||||||
|
|
||||||
|
const PGP = {
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
ARMOUR_TYPES: [
|
||||||
|
"Message",
|
||||||
|
"Public key",
|
||||||
|
"Private key",
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
ARMOUR_TYPE_MAPPING: {
|
||||||
|
"Message": 3,
|
||||||
|
"Public key": 4,
|
||||||
|
"Private key": 5,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypts the input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - plaintext to encrypt
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runEncrypt: function (plaintext, args) {
|
||||||
|
let publicKey = args[0],
|
||||||
|
publicKeys;
|
||||||
|
|
||||||
|
try {
|
||||||
|
publicKeys = openpgp.key.readArmored(publicKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Cannot read public key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
data: plaintext,
|
||||||
|
publicKeys: publicKeys,
|
||||||
|
};
|
||||||
|
|
||||||
|
return openpgp.encrypt(options)
|
||||||
|
.then(ciphertext => ciphertext.data)
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not encrypt text: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypts the input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - ciphertext to decrypt
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runDecrypt: function (input, args) {
|
||||||
|
let privateKey = args[0],
|
||||||
|
password = args[1],
|
||||||
|
message;
|
||||||
|
|
||||||
|
try {
|
||||||
|
privateKey = openpgp.key.readArmored(privateKey).keys[0];
|
||||||
|
} catch (err) {
|
||||||
|
throw "Cannot read private key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = openpgp.message.readArmored(input);
|
||||||
|
} catch (err) {
|
||||||
|
throw "Cannot read message: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
message: message,
|
||||||
|
privateKey: privateKey,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
privateKey.decrypt(password);
|
||||||
|
}
|
||||||
|
if (privateKey.primaryKey.encrypted !== null) {
|
||||||
|
throw "Could not decrypt private key.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return openpgp.decrypt(options)
|
||||||
|
.then(plaintext => plaintext.data)
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not decrypt message: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signs the input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - data to be signed
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runSign: function (input, args) {
|
||||||
|
let publicKey = args[0],
|
||||||
|
privateKey = args[1],
|
||||||
|
password = args[2],
|
||||||
|
publicKeys,
|
||||||
|
privateKeys;
|
||||||
|
|
||||||
|
try {
|
||||||
|
publicKeys = openpgp.key.readArmored(publicKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read public key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
privateKeys = openpgp.key.readArmored(privateKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read private key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
privateKeys[0].decrypt(password);
|
||||||
|
}
|
||||||
|
if (privateKeys[0].primaryKey.encrypted !== null) {
|
||||||
|
throw "Could not decrypt private key.";
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
data: input,
|
||||||
|
publicKeys: publicKeys,
|
||||||
|
privateKeys: privateKeys,
|
||||||
|
};
|
||||||
|
|
||||||
|
return openpgp.encrypt(options)
|
||||||
|
.then(signedData => signedData.data)
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not sign input: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies the signed input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - signed input to verify
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string} - the original message, and a summary of the verification process
|
||||||
|
*/
|
||||||
|
runVerify: function (input, args) {
|
||||||
|
let publicKey = args[0],
|
||||||
|
privateKey = args[1],
|
||||||
|
password = args[2],
|
||||||
|
publicKeys,
|
||||||
|
privateKeys,
|
||||||
|
message;
|
||||||
|
|
||||||
|
try {
|
||||||
|
publicKeys = openpgp.key.readArmored(publicKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read public key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
privateKeys = openpgp.key.readArmored(privateKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read private key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
privateKeys[0].decrypt(password);
|
||||||
|
}
|
||||||
|
if (privateKeys[0].primaryKey.encrypted !== null) {
|
||||||
|
throw "Could not decrypt private key.";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = openpgp.message.readArmored(input);
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read encrypted message: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let packetContainingAlgorithms = message.packets.filterByTag(
|
||||||
|
openpgp.enums.packet.publicKeyEncryptedSessionKey
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
let verification = {
|
||||||
|
verified: false,
|
||||||
|
pkAlgorithm: packetContainingAlgorithms.publicKeyAlgorithm,
|
||||||
|
sessionAlgorithm: packetContainingAlgorithms.sessionKeyAlgorithm,
|
||||||
|
author: publicKeys[0].users[0].userId.userid,
|
||||||
|
recipient: privateKeys[0].users[0].userId.userid,
|
||||||
|
keyID: "",
|
||||||
|
message: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
return openpgp.decrypt({
|
||||||
|
message: message,
|
||||||
|
publicKeys: publicKeys,
|
||||||
|
privateKey: privateKeys[0],
|
||||||
|
})
|
||||||
|
.then(decrypted => {
|
||||||
|
if (decrypted.signatures) {
|
||||||
|
// valid is either true or null, casting required.
|
||||||
|
verification.verified = !!decrypted.signatures[0].valid;
|
||||||
|
verification.keyID = decrypted.signatures[0].keyid.toHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"Verified: " + verification.verified,
|
||||||
|
"Key ID: " + verification.keyID,
|
||||||
|
"Encrypted for: " + verification.recipient,
|
||||||
|
"Signed by: " + verification.author,
|
||||||
|
"Signed with: " +
|
||||||
|
verification.pkAlgorithm +
|
||||||
|
"/" +
|
||||||
|
verification.sessionAlgorithm,
|
||||||
|
"\n",
|
||||||
|
decrypted.data,
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not decrypt and verify message: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signs the input using PGP and outputs the plaintext, the raw PGP signature, and the ASCII armoured signature files.
|
||||||
|
*
|
||||||
|
* @param {string} input - data to be signed
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {HTML} - HTML file display of message, armoured signature, and bytes signature
|
||||||
|
*/
|
||||||
|
runSignDetached: function (input, args) {
|
||||||
|
let privateKey = args[0],
|
||||||
|
password = args[1],
|
||||||
|
privateKeys;
|
||||||
|
|
||||||
|
try {
|
||||||
|
privateKeys = openpgp.key.readArmored(privateKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read private key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
privateKeys[0].decrypt(password);
|
||||||
|
}
|
||||||
|
if (privateKeys[0].primaryKey.encrypted !== null) {
|
||||||
|
throw "Could not decrypt private key.";
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytes = openpgp.util.str2Uint8Array(input);
|
||||||
|
let message = openpgp.message.fromBinary(bytes);
|
||||||
|
|
||||||
|
let signedMessage = message.sign(privateKeys);
|
||||||
|
let signature = signedMessage.packets.filterByTag(openpgp.enums.packet.signature);
|
||||||
|
let rawSignatureBytes = signature.write();
|
||||||
|
|
||||||
|
let armouredMessage = openpgp.armor.encode(
|
||||||
|
openpgp.enums.armor.message,
|
||||||
|
rawSignatureBytes
|
||||||
|
);
|
||||||
|
armouredMessage = armouredMessage.replace(
|
||||||
|
"-----BEGIN PGP MESSAGE-----\r\n",
|
||||||
|
"-----BEGIN PGP SIGNATURE-----\r\n"
|
||||||
|
);
|
||||||
|
armouredMessage = armouredMessage.replace(
|
||||||
|
"-----END PGP MESSAGE-----\r\n",
|
||||||
|
"-----END PGP SIGNATURE-----\r\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
let files = [{
|
||||||
|
fileName: "msg",
|
||||||
|
size: input.length,
|
||||||
|
contents: input,
|
||||||
|
bytes: bytes,
|
||||||
|
}, {
|
||||||
|
fileName: "msg.asc",
|
||||||
|
size: armouredMessage.length,
|
||||||
|
contents: armouredMessage,
|
||||||
|
bytes: openpgp.util.str2Uint8Array(armouredMessage),
|
||||||
|
}, {
|
||||||
|
fileName: "msg.sig",
|
||||||
|
size: rawSignatureBytes.length,
|
||||||
|
contents: openpgp.util.Uint8Array2str(rawSignatureBytes),
|
||||||
|
bytes: rawSignatureBytes,
|
||||||
|
}];
|
||||||
|
|
||||||
|
return Utils.displayFilesAsHTML(files);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies the detached signature and input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - signed input to verify
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string} - the original message, and a summary of the verification process
|
||||||
|
*/
|
||||||
|
runVerifyDetached: function (input, args) {
|
||||||
|
let publicKey = args[0],
|
||||||
|
armouredSignature = args[1],
|
||||||
|
publicKeys,
|
||||||
|
message;
|
||||||
|
|
||||||
|
try {
|
||||||
|
publicKeys = openpgp.key.readArmored(publicKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read public key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = openpgp.message.readSignedContent(
|
||||||
|
input,
|
||||||
|
armouredSignature
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read armoured signature or message: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let packetContainingSignature = message.packets.filterByTag(
|
||||||
|
openpgp.enums.packet.signature
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
let verification = {
|
||||||
|
verified: false,
|
||||||
|
pkAlgorithm: publicKeys[0].primaryKey.algorithm,
|
||||||
|
author: publicKeys[0].users[0].userId.userid,
|
||||||
|
date: packetContainingSignature.created,
|
||||||
|
keyID: "",
|
||||||
|
message: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.resolve(message.verify(publicKeys))
|
||||||
|
.then(function(signatures) {
|
||||||
|
if (signatures && signatures.length) {
|
||||||
|
verification.verified = !!signatures[0].valid;
|
||||||
|
verification.keyID = signatures[0].keyid.toHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"Verified: " + verification.verified,
|
||||||
|
"Key ID: " + verification.keyID,
|
||||||
|
"Signed on: " + verification.date,
|
||||||
|
"Signed by: " + verification.author,
|
||||||
|
"Signed with: " + verification.pkAlgorithm,
|
||||||
|
"\n",
|
||||||
|
input,
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not verify message: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clearsigns the input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - data to be signed
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
runSignCleartext: function (input, args) {
|
||||||
|
let privateKey = args[0],
|
||||||
|
password = args[1],
|
||||||
|
privateKeys;
|
||||||
|
|
||||||
|
try {
|
||||||
|
privateKeys = openpgp.key.readArmored(privateKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read private key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
privateKeys[0].decrypt(password);
|
||||||
|
}
|
||||||
|
if (privateKeys[0].primaryKey.encrypted !== null) {
|
||||||
|
throw "Could not decrypt private key.";
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
data: input,
|
||||||
|
privateKeys: privateKeys,
|
||||||
|
};
|
||||||
|
|
||||||
|
return openpgp.sign(options)
|
||||||
|
.then(signedData => signedData.data)
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not clearsign input: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies the clearsigned input using PGP.
|
||||||
|
*
|
||||||
|
* @param {string} input - signed input to verify
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string} - the original message, and a summary of the verification process
|
||||||
|
*/
|
||||||
|
runVerifyCleartext: function (input, args) {
|
||||||
|
let publicKey = args[0],
|
||||||
|
publicKeys,
|
||||||
|
message;
|
||||||
|
|
||||||
|
try {
|
||||||
|
publicKeys = openpgp.key.readArmored(publicKey).keys;
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read public key: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = openpgp.cleartext.readArmored(input);
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read input message: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let packetContainingSignature = message.packets.filterByTag(
|
||||||
|
openpgp.enums.packet.signature
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
let verification = {
|
||||||
|
verified: false,
|
||||||
|
pkAlgorithm: publicKeys[0].primaryKey.algorithm,
|
||||||
|
author: publicKeys[0].users[0].userId.userid,
|
||||||
|
date: packetContainingSignature.created,
|
||||||
|
keyID: "",
|
||||||
|
message: message.text,
|
||||||
|
};
|
||||||
|
|
||||||
|
return openpgp.verify({
|
||||||
|
message: message,
|
||||||
|
publicKeys: publicKeys,
|
||||||
|
})
|
||||||
|
.then(verifiedData => {
|
||||||
|
if (verifiedData.signatures) {
|
||||||
|
// valid is either true or null, casting required.
|
||||||
|
verification.verified = !!verifiedData.signatures[0].valid;
|
||||||
|
verification.keyID = verifiedData.signatures[0].keyid.toHex();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"Verified: " + verification.verified,
|
||||||
|
"Key ID: " + verification.keyID,
|
||||||
|
"Signed on: " + verification.date,
|
||||||
|
"Signed by: " + verification.author,
|
||||||
|
"Signed with: " + verification.pkAlgorithm,
|
||||||
|
"\n",
|
||||||
|
verification.message,
|
||||||
|
].join("\n");
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not verify message: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a PGP key pair.
|
||||||
|
*
|
||||||
|
* @param {string} input is ignored
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string} - armoured public key and private key separated by whitespace.
|
||||||
|
*/
|
||||||
|
runGenKeyPair: function (input, args) {
|
||||||
|
let password = args[0],
|
||||||
|
keySize = parseInt(args[1], 10),
|
||||||
|
name = args[2],
|
||||||
|
email = args[3];
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
numBits: keySize,
|
||||||
|
userIds: [{name: name, email: email}],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
options.passphrase = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
return openpgp.generateKey(options)
|
||||||
|
.then(key => {
|
||||||
|
return [
|
||||||
|
key.publicKeyArmored,
|
||||||
|
key.privateKeyArmored,
|
||||||
|
].join(""); // Preceding and trailing newlines are already generated.
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
throw "Could not generate key pair: " + err;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns a PGP clearsigned message into a detached signature.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {HTML} - HTML file display of message, armoured signature, and bytes signature
|
||||||
|
*/
|
||||||
|
runDetachClearsig: function (input, args) {
|
||||||
|
let message;
|
||||||
|
|
||||||
|
try {
|
||||||
|
message = openpgp.cleartext.readArmored(input);
|
||||||
|
} catch (err) {
|
||||||
|
throw "Could not read input message: " + err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleartext = message.getText();
|
||||||
|
let clearbytes = openpgp.util.str2Uint8Array(cleartext);
|
||||||
|
|
||||||
|
let signature = message.packets.filterByTag(openpgp.enums.packet.signature);
|
||||||
|
let rawSignatureBytes = signature.write();
|
||||||
|
|
||||||
|
let armouredMessage = openpgp.armor.encode(
|
||||||
|
openpgp.enums.armor.message,
|
||||||
|
rawSignatureBytes
|
||||||
|
);
|
||||||
|
armouredMessage = armouredMessage.replace(
|
||||||
|
"-----BEGIN PGP MESSAGE-----\r\n",
|
||||||
|
"-----BEGIN PGP SIGNATURE-----\r\n"
|
||||||
|
);
|
||||||
|
armouredMessage = armouredMessage.replace(
|
||||||
|
"-----END PGP MESSAGE-----\r\n",
|
||||||
|
"-----END PGP SIGNATURE-----\r\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
let files = [{
|
||||||
|
fileName: "msg",
|
||||||
|
size: cleartext.length,
|
||||||
|
contents: cleartext,
|
||||||
|
bytes: clearbytes,
|
||||||
|
}, {
|
||||||
|
fileName: "msg.asc",
|
||||||
|
size: armouredMessage.length,
|
||||||
|
contents: armouredMessage,
|
||||||
|
bytes: openpgp.util.str2Uint8Array(armouredMessage),
|
||||||
|
}, {
|
||||||
|
fileName: "msg.sig",
|
||||||
|
size: rawSignatureBytes.length,
|
||||||
|
contents: openpgp.util.Uint8Array2str(rawSignatureBytes),
|
||||||
|
bytes: rawSignatureBytes,
|
||||||
|
}];
|
||||||
|
|
||||||
|
return Utils.displayFilesAsHTML(files);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns raw PGP bytes into an ASCII armoured string.
|
||||||
|
*
|
||||||
|
* @param {byteArray} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string} - armoured public key and private key separated by whitespace.
|
||||||
|
*/
|
||||||
|
runAddArmour: function (input, args) {
|
||||||
|
let armourType = PGP.ARMOUR_TYPE_MAPPING[args[0]];
|
||||||
|
return openpgp.armor.encode(armourType, input);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns an ASCII armoured string into raw PGP bytes.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {byteArray}
|
||||||
|
*/
|
||||||
|
runRemoveArmour: function (input, args) {
|
||||||
|
let decoded = openpgp.armor.decode(input);
|
||||||
|
let uint8bytes = decoded.data;
|
||||||
|
let bytes = Array.prototype.slice.call(uint8bytes);
|
||||||
|
return bytes;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PGP;
|
||||||
@ -112,41 +112,45 @@ App.prototype.bake = function(step) {
|
|||||||
app.setBakingStatus(true);
|
app.setBakingStatus(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.chef.bake(
|
// This timeout is so the UI has time to update the baking status
|
||||||
app.getInput(), // The user's input
|
// before any blocking operations delay it until after the operation.
|
||||||
app.getRecipeConfig(), // The configuration of the recipe
|
setTimeout(function() {
|
||||||
app.options, // Options set by the user
|
app.chef.bake(
|
||||||
app.progress, // The current position in the recipe
|
app.getInput(), // The user's input
|
||||||
step // Whether or not to take one step or execute the whole recipe
|
app.getRecipeConfig(), // The configuration of the recipe
|
||||||
)
|
app.options, // Options set by the user
|
||||||
.then(function(response) {
|
app.progress, // The current position in the recipe
|
||||||
app.setBakingStatus(false);
|
step // Whether or not to take one step or execute the whole recipe
|
||||||
|
)
|
||||||
|
.then(function(response) {
|
||||||
|
app.setBakingStatus(false);
|
||||||
|
|
||||||
if (!response) return;
|
if (!response) return;
|
||||||
if (response.error) app.handleError(response.error);
|
if (response.error) app.handleError(response.error);
|
||||||
|
|
||||||
app.options = response.options;
|
app.options = response.options;
|
||||||
|
|
||||||
if (response.type === "html") {
|
if (response.type === "html") {
|
||||||
app.dishStr = Utils.stripHtmlTags(response.result, true);
|
app.dishStr = Utils.stripHtmlTags(response.result, true);
|
||||||
} else {
|
} else {
|
||||||
app.dishStr = response.result;
|
app.dishStr = response.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
app.progress = response.progress;
|
app.progress = response.progress;
|
||||||
app.manager.recipe.updateBreakpointIndicator(response.progress);
|
app.manager.recipe.updateBreakpointIndicator(response.progress);
|
||||||
app.manager.output.set(response.result, response.type, response.duration);
|
app.manager.output.set(response.result, response.type, response.duration);
|
||||||
|
|
||||||
// If baking took too long, disable auto-bake
|
// If baking took too long, disable auto-bake
|
||||||
if (response.duration > app.options.autoBakeThreshold && app.autoBake_) {
|
if (response.duration > app.options.autoBakeThreshold && app.autoBake_) {
|
||||||
app.manager.controls.setAutoBake(false);
|
app.manager.controls.setAutoBake(false);
|
||||||
app.alert("Baking took longer than " + app.options.autoBakeThreshold +
|
app.alert("Baking took longer than " + app.options.autoBakeThreshold +
|
||||||
"ms, Auto Bake has been disabled.", "warning", 5000);
|
"ms, Auto Bake has been disabled.", "warning", 5000);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
console.error("Chef's promise was rejected, this should never occur");
|
console.error("Chef's promise was rejected, this should never occur");
|
||||||
});
|
});
|
||||||
|
}, 10);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
app.setBakingStatus(false);
|
app.setBakingStatus(false);
|
||||||
app.handleError(err);
|
app.handleError(err);
|
||||||
|
|||||||
@ -54,6 +54,11 @@ import Chef from "../src/core/Chef.js";
|
|||||||
output: null,
|
output: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Remove whitespace helper
|
||||||
|
var noWS = function(string) {
|
||||||
|
return string.replace(/\s/g, "");
|
||||||
|
};
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
if (test.expectedError) {
|
if (test.expectedError) {
|
||||||
ret.status = "passing";
|
ret.status = "passing";
|
||||||
@ -67,6 +72,9 @@ import Chef from "../src/core/Chef.js";
|
|||||||
ret.output = "Expected an error but did not receive one.";
|
ret.output = "Expected an error but did not receive one.";
|
||||||
} else if (result.result === test.expectedOutput) {
|
} else if (result.result === test.expectedOutput) {
|
||||||
ret.status = "passing";
|
ret.status = "passing";
|
||||||
|
} else if (test.ignoreWhitespace &&
|
||||||
|
noWS(result.result) === noWS(test.expectedOutput)) {
|
||||||
|
ret.status = "passing";
|
||||||
} else {
|
} else {
|
||||||
ret.status = "failing";
|
ret.status = "failing";
|
||||||
ret.output = [
|
ret.output = [
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import "./tests/operations/Base58.js";
|
|||||||
import "./tests/operations/Compress.js";
|
import "./tests/operations/Compress.js";
|
||||||
import "./tests/operations/FlowControl.js";
|
import "./tests/operations/FlowControl.js";
|
||||||
import "./tests/operations/MorseCode.js";
|
import "./tests/operations/MorseCode.js";
|
||||||
|
import "./tests/operations/PGP.js";
|
||||||
import "./tests/operations/StrUtils.js";
|
import "./tests/operations/StrUtils.js";
|
||||||
|
|
||||||
var allTestsPassing = true,
|
var allTestsPassing = true,
|
||||||
|
|||||||
457
test/tests/operations/PGP.js
Normal file
457
test/tests/operations/PGP.js
Normal file
@ -0,0 +1,457 @@
|
|||||||
|
/**
|
||||||
|
* PGP tests.
|
||||||
|
*
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
*
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
import TestRegister from "../../TestRegister.js";
|
||||||
|
|
||||||
|
const CYBERCHEF_GENERATED_KEY_PAIRS = [
|
||||||
|
{
|
||||||
|
name: "CyberChef 1",
|
||||||
|
size: 1024,
|
||||||
|
pub: [
|
||||||
|
"-----BEGIN PGP PUBLIC KEY BLOCK-----",
|
||||||
|
"Version: OpenPGP.js v2.3.6",
|
||||||
|
"Comment: http://openpgpjs.org",
|
||||||
|
"",
|
||||||
|
"xo0EWMQszAEEAMY6F0o6jL6TrVVXDkqJwNVJRR6tQKr+LIt7plEJoaTRVDfL",
|
||||||
|
"1jetdhPg+YiE7xZI8ygf6fhsrot4ccUN1QdtwedAz6GH0xjFzpL1i4/7/f3U",
|
||||||
|
"ItJ0p1MO4Amy8Tei/AtXXMTy/YwE77V1AMcv7OYFw9va5S0PD87XoKK6rx7z",
|
||||||
|
"GFMTABEBAAHNAjw+wrUEEAEIACkFAljELMwGCwkHCAMCCRAar/puuym6vQQV",
|
||||||
|
"CAIKAxYCAQIZAQIbAwIeAQAA8/QEAKDVde34L3rvFECzUOFPA5w4w4gbwkg+",
|
||||||
|
"YwPa084WvMTdo/wBEiEhj+7P+/5eN/U96yuHD48+Cmm5AHBaaf+K1b2LbNe7",
|
||||||
|
"3PP5rV1rMcooUGeIhq7SFw0BdPZTLoCNbkBKFCpvrS/F4SuUQF7g+fVyOyve",
|
||||||
|
"zVWew+E41ZC3vsDd63Y3zo0EWMQszAEEANYNy0yka1+c3Oe2U1GqoAHXv05p",
|
||||||
|
"VnlHAZ+28JGs8Thq5ns0K8bxI+Fn9CFpPO7Vofrr40V3vweoJVK2Eiq2gN/X",
|
||||||
|
"QdxPHckcpYbFKTAZIXt2MAZfb027JxWZid5lyYSCwvY+BK7x5X4jdY5KfbKu",
|
||||||
|
"7WDivOkq8MhomSiX+QYDV8qrABEBAAHCnwQYAQgAEwUCWMQszAkQGq/6brsp",
|
||||||
|
"ur0CGwwAAIjWA/9WhpbfM+oA08m5XwXgCkuRfTymIkexzn17dZOngTzaGcbK",
|
||||||
|
"vpS3QN164XNu229JNKTrsdgn5zeeq3AqhQ63hTMbePajvUYSssHPqKB8qQlp",
|
||||||
|
"OUY/rcFEUXMirIkKBGByYBmlz56Ai855wJoSOrZJA6yfnGepyV5ChcG/cEmB",
|
||||||
|
"dH/6bA==",
|
||||||
|
"=4nW6",
|
||||||
|
"-----END PGP PUBLIC KEY BLOCK-----",
|
||||||
|
].join("\n"),
|
||||||
|
sec: [
|
||||||
|
"-----BEGIN PGP PRIVATE KEY BLOCK-----",
|
||||||
|
"Version: OpenPGP.js v2.3.6",
|
||||||
|
"Comment: http://openpgpjs.org",
|
||||||
|
"",
|
||||||
|
"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",
|
||||||
|
"=8R+g",
|
||||||
|
"-----END PGP PRIVATE KEY BLOCK-----",
|
||||||
|
].join("\n"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const PGP_TEST_KEY_PAIRS = [
|
||||||
|
{
|
||||||
|
keyID: "a9510d8fd7e352f5",
|
||||||
|
name: "CyberChef nopw 1024 <toby@toby.codes>",
|
||||||
|
size: 1024,
|
||||||
|
pub: [
|
||||||
|
"-----BEGIN PGP PUBLIC KEY BLOCK-----",
|
||||||
|
"",
|
||||||
|
"mI0EWL7mbwEEANVcA5s+pXliwZBZXvfjy69JlPkX8dWRTZLuqZPz5XKGb9E1RKxQ",
|
||||||
|
"jELZ9bBIv/t0HDoiwh1XJok3SRMPzLPHK9lLXaa/l7716CkRddTvkd3cjFA3yAEL",
|
||||||
|
"X97+4nPVIajYUPDy6ovCrRru2bXyW2cjHKErlI0GJ37Hbbpj/GXSQL6HABEBAAG0",
|
||||||
|
"JUN5YmVyQ2hlZiBub3B3IDEwMjQgPHRvYnlAdG9ieS5jb2Rlcz6ItwQTAQgAIQUC",
|
||||||
|
"WL7mbwIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRCpUQ2P1+NS9ZhxA/49",
|
||||||
|
"sXqWYoi34HMtHfVejPpPSXrFxY+ZjgM1cMVe5m4cumBeZVVYaEH9/3xDlrhfrlMi",
|
||||||
|
"xCRGNqfIRwavIbNWyBshrjVnZ1PR/hvp2P3tV0ciV51lJi6ApO46fsmsWZw84cOA",
|
||||||
|
"ejQ1giBjuLuu4du52+MVbcko2yEJ2tOS2WMPnYO7RbiNBFi+5m8BBAClMs6KZuXd",
|
||||||
|
"2mhmz3vGcczlA0vv2k7lZjdT7LmbYLt/ir7Hdqg7z7l84wO1qPNQc6pRkLVd1rMX",
|
||||||
|
"8fh+RtLUVAuvATpRJCAdaeslcxaH7o0p5DbjrRmiDmnaLDl/S0xMhI137XaKdUS7",
|
||||||
|
"ZRuGFZVfqXeFerpbjrlUlhzAcHua8aAmHQARAQABiJ8EGAEIAAkFAli+5m8CGwwA",
|
||||||
|
"CgkQqVENj9fjUvUA6AP/b9jZvaQ7w6mdlCvCrFpfp3vBZN1E0vLIMdRKRMmNR8D7",
|
||||||
|
"pmZ4RcmMJxjVTLkB6Uc90+9Tbb2ysykQaTTw3YdpmyoGmy3qgH3opd/IdZzEAJyL",
|
||||||
|
"oBC+u8G7nATB58m4xmBYL1G5hn8nCBbNAiz1rrbXmWmVExQCVAXp7T50vPBdyFY=",
|
||||||
|
"=xCxV",
|
||||||
|
"-----END PGP PUBLIC KEY BLOCK-----",
|
||||||
|
].join("\n"),
|
||||||
|
sec: [
|
||||||
|
"-----BEGIN PGP PRIVATE KEY BLOCK-----",
|
||||||
|
"",
|
||||||
|
"lQHYBFi+5m8BBADVXAObPqV5YsGQWV7348uvSZT5F/HVkU2S7qmT8+Vyhm/RNUSs",
|
||||||
|
"UIxC2fWwSL/7dBw6IsIdVyaJN0kTD8yzxyvZS12mv5e+9egpEXXU75Hd3IxQN8gB",
|
||||||
|
"C1/e/uJz1SGo2FDw8uqLwq0a7tm18ltnIxyhK5SNBid+x226Y/xl0kC+hwARAQAB",
|
||||||
|
"AAP7BLFYuDDhPrQDIgsdyzzsuIDPbj6G9z9+hsN/sLrZlEFbBt67c95+Sbzm6h1O",
|
||||||
|
"SdgcoZiPgJig0L3OyR1kO5ypBG4jhSgbaTKRHjP4KsOWoPuXmL1p8XLzZHOGp3hS",
|
||||||
|
"/recAxhqdbbO7uim+nbaPdmby9v0XrMAkFkBTU+D+ZlmC3ECAODTUZ7i+vRD6R3x",
|
||||||
|
"NzN2uhomWy94I7SkugTjcTw6BrzvdffFKtW7Yp6MbPdCpRIhuKy/QhG1LCUGwJKQ",
|
||||||
|
"vvNe5z8CAPLxrsx6jiFHpzAtUBYNBY5M3t805OYRFbs3mJ3LgsUP0wVOnODqo5TA",
|
||||||
|
"anevkFoakvcKJ8d0OlbO0/ewm4wd3rkB+wRQrllfYFfLqGzUlZDP15NKoHFk8T/w",
|
||||||
|
"LWg6nDm8pxXlhptaA8V4rVK1HrrPU56GBbzXftqL6iDpbYh9ZPR/U/qoXLQlQ3li",
|
||||||
|
"ZXJDaGVmIG5vcHcgMTAyNCA8dG9ieUB0b2J5LmNvZGVzPoi3BBMBCAAhBQJYvuZv",
|
||||||
|
"AhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEKlRDY/X41L1mHED/j2xepZi",
|
||||||
|
"iLfgcy0d9V6M+k9JesXFj5mOAzVwxV7mbhy6YF5lVVhoQf3/fEOWuF+uUyLEJEY2",
|
||||||
|
"p8hHBq8hs1bIGyGuNWdnU9H+G+nY/e1XRyJXnWUmLoCk7jp+yaxZnDzhw4B6NDWC",
|
||||||
|
"IGO4u67h27nb4xVtySjbIQna05LZYw+dg7tFnQHYBFi+5m8BBAClMs6KZuXd2mhm",
|
||||||
|
"z3vGcczlA0vv2k7lZjdT7LmbYLt/ir7Hdqg7z7l84wO1qPNQc6pRkLVd1rMX8fh+",
|
||||||
|
"RtLUVAuvATpRJCAdaeslcxaH7o0p5DbjrRmiDmnaLDl/S0xMhI137XaKdUS7ZRuG",
|
||||||
|
"FZVfqXeFerpbjrlUlhzAcHua8aAmHQARAQABAAP8C0IAnaGbME4WMkzDyHIbPqTF",
|
||||||
|
"s9qX6NMumbthVLY4C4jhgnH9egH9x9sn9rpvm7/Iz2vXUvCdiNgLu/3zQoFYawsn",
|
||||||
|
"zpTQREm6CyITOLxyc5TrckodSlx6eoCezvnTzI/PvXrUSSqEP9c9hvcLuKm+aeZz",
|
||||||
|
"fclhPfDOL/EQx337aeECAMU0UXXb95hQqSdRMcsGkpoAlAIEM664/S9eBvXrJYWw",
|
||||||
|
"1Pfgms7Axi/tZ4ebkc3urRW/YKAt423Ixmdd5rOwIDECANZzoOU8LxreLcLQOoA9",
|
||||||
|
"SWswRWUeyQTvH4yskT2iIXen22CO1pp7ruy07vSxHE+yyR3t2ZHKPJU864J39d4k",
|
||||||
|
"da0CAJS838KMD8h+Zv1C/jhKkYjpnDRuE+Lj7qVNHCJqsFSzpJAbJ09VpwSGbUso",
|
||||||
|
"Ptc/oyXgzb91+sLKfsIwGa7ZysarEIifBBgBCAAJBQJYvuZvAhsMAAoJEKlRDY/X",
|
||||||
|
"41L1AOgD/2/Y2b2kO8OpnZQrwqxaX6d7wWTdRNLyyDHUSkTJjUfA+6ZmeEXJjCcY",
|
||||||
|
"1Uy5AelHPdPvU229srMpEGk08N2HaZsqBpst6oB96KXfyHWcxACci6AQvrvBu5wE",
|
||||||
|
"wefJuMZgWC9RuYZ/JwgWzQIs9a6215lplRMUAlQF6e0+dLzwXchW",
|
||||||
|
"=S56e",
|
||||||
|
"-----END PGP PRIVATE KEY BLOCK-----",
|
||||||
|
].join("\n"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keyID: "02da58ca894c4cc7",
|
||||||
|
name: "CyberChef pw 1024 <toby@toby.codes>",
|
||||||
|
size: 1024,
|
||||||
|
password: "2NSRJYTzgsTVJfih",
|
||||||
|
pub: [
|
||||||
|
"-----BEGIN PGP PUBLIC KEY BLOCK-----",
|
||||||
|
"",
|
||||||
|
"mI0EWL7mswEEAMcw0PSzmNfh4MkGwejsyreXb34FqEjYMc1GmswvC5uuLp0KzbC6",
|
||||||
|
"HecV1GyyPQ7kKshWVLloShN3KtgSZF7DJ8/Hioiv4Q5HJYPY4AYwqECi+/C4W1FA",
|
||||||
|
"tJEbItdEIxw0IgHOX64X5kMptVV9J5bGc7DqkqUHgapXJI+yLZel0s83ABEBAAG0",
|
||||||
|
"I0N5YmVyQ2hlZiBwdyAxMDI0IDx0b2J5QHRvYnkuY29kZXM+iLcEEwEIACEFAli+",
|
||||||
|
"5rMCGwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQAtpYyolMTMeOGwP+NvLU",
|
||||||
|
"GHhHaIFwI+VMB655CiD6QuRWnurcrXq7qZYl3flyBehhZdtgGBx9vynffElEFEFz",
|
||||||
|
"cbqzv8unkDTRdPqTA0gM2wOaC/L6Kuy4ErjQD7A4i5rC/IG0ja+3DQeKLShGGtaD",
|
||||||
|
"bG0H0mJl7gzlqR3/fxgLxi/JaCtqapjtZDF/GTC4jQRYvuazAQQA5oNC4NeWKBKU",
|
||||||
|
"m9H/QZyxKRWGaaQRKLrmSGVkQgJlzo3pnNjJMFUaMcQaJve+PZGay7y9sCOFpumf",
|
||||||
|
"6v1ERY+qw4ZOyCRnRqHJOxdLrbTPSmOwIUYkYFkNzARGpdy/FqWCByXDXea5qsb1",
|
||||||
|
"DJRT9WUte3Bbx1YvzsqrZMqsExgwgdcAEQEAAYifBBgBCAAJBQJYvuazAhsMAAoJ",
|
||||||
|
"EALaWMqJTEzH7woEAKIKQS8bEf8iHaVf7aGEWWOShN10gb+xpWD4V5r8H6hlNpIk",
|
||||||
|
"xwQEbj8glTJBEJoD5xO1tdrHmOJ7BVO1d7otdgXpjBAOxn0ngW4MAB8BO+Qa5U/t",
|
||||||
|
"M+6yuL8REwE5YUnvIyhgvhiHsBhlLeMNXtwCrF94WyDzyb+hwVwwi/PFtI0y",
|
||||||
|
"=djdC",
|
||||||
|
"-----END PGP PUBLIC KEY BLOCK-----",
|
||||||
|
].join("\n"),
|
||||||
|
sec: [
|
||||||
|
"-----BEGIN PGP PRIVATE KEY BLOCK-----",
|
||||||
|
"",
|
||||||
|
"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",
|
||||||
|
"=j2j0",
|
||||||
|
"-----END PGP PRIVATE KEY BLOCK-----",
|
||||||
|
].join("\n"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
PGP_TEST_KEY_PAIRS.forEach(function(keyPair) {
|
||||||
|
if (keyPair.password) {
|
||||||
|
TestRegister.addTests(
|
||||||
|
["", "nottherightpassword"].map(function(incorrectPW) {
|
||||||
|
var testName = "PGP Encrypt, PGP Decrypt: ensure error for incorrect password (pw [$pw], $ks, $name)";
|
||||||
|
testName = testName.replace("$ks", keyPair.size);
|
||||||
|
testName = testName.replace("$pw", incorrectPW);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testName,
|
||||||
|
input: "hello world",
|
||||||
|
expectedError: true,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "PGP Encrypt",
|
||||||
|
args: [keyPair.pub],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "PGP Decrypt",
|
||||||
|
args: [keyPair.sec, incorrectPW],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
["", "hello world"].forEach(function(input) {
|
||||||
|
TestRegister.addTests(
|
||||||
|
PGP_TEST_KEY_PAIRS.map(function(keyPair) {
|
||||||
|
var testName = "PGP Encrypt, PGP Decrypt ($pw, $ks) '$input'";
|
||||||
|
testName = testName.replace("$ks", keyPair.size);
|
||||||
|
testName = testName.replace("$pw", keyPair.password ? "pw" : "no pw");
|
||||||
|
testName = testName.replace("$input", input);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testName,
|
||||||
|
input: input,
|
||||||
|
expectedOutput: input,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "PGP Encrypt",
|
||||||
|
args: [keyPair.pub],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "PGP Decrypt",
|
||||||
|
args: [keyPair.sec, keyPair.password],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
TestRegister.addTests([{
|
||||||
|
name: "PGP Encrypt, PGP Decrypt: fails when incorrect password, empty string (1024)",
|
||||||
|
input: "",
|
||||||
|
expectedError: true,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "PGP Encrypt",
|
||||||
|
args: [PGP_TEST_KEY_PAIRS[1].pub],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "PGP Decrypt",
|
||||||
|
args: [PGP_TEST_KEY_PAIRS[1].sec, "gibberish"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}]);
|
||||||
|
|
||||||
|
TestRegister.addTests([{
|
||||||
|
name: "PGP Encrypt, PGP Decrypt: fails when incorrect password, hello world (1024)",
|
||||||
|
input: "hello world",
|
||||||
|
expectedError: true,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "PGP Encrypt",
|
||||||
|
args: [PGP_TEST_KEY_PAIRS[1].pub],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "PGP Decrypt",
|
||||||
|
args: [PGP_TEST_KEY_PAIRS[1].sec, "gibberish"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}]);
|
||||||
|
|
||||||
|
["hello world"].forEach(function(input) {
|
||||||
|
[
|
||||||
|
[PGP_TEST_KEY_PAIRS[0], PGP_TEST_KEY_PAIRS[1]],
|
||||||
|
[PGP_TEST_KEY_PAIRS[1], PGP_TEST_KEY_PAIRS[0]],
|
||||||
|
].forEach(function(pairOfKeyPairs) {
|
||||||
|
var alice = pairOfKeyPairs[0];
|
||||||
|
var bob = pairOfKeyPairs[1];
|
||||||
|
|
||||||
|
var testName = "PGP Sign ($alice), PGP Verify ($bob) '$input'";
|
||||||
|
testName = testName.replace("$alice", alice.name);
|
||||||
|
testName = testName.replace("$bob", bob.name);
|
||||||
|
testName = testName.replace("$input", input);
|
||||||
|
|
||||||
|
TestRegister.addTests([{
|
||||||
|
name: testName,
|
||||||
|
input: input,
|
||||||
|
expectedOutput: [
|
||||||
|
"Verified: true",
|
||||||
|
"Key ID: " + alice.keyID,
|
||||||
|
"Encrypted for: " + bob.name,
|
||||||
|
"Signed by: " + alice.name,
|
||||||
|
"Signed with: rsa_encrypt_sign/aes256",
|
||||||
|
"\n",
|
||||||
|
input,
|
||||||
|
].join("\n"),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "PGP Sign",
|
||||||
|
args: [bob.pub, alice.sec, alice.password],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "PGP Verify",
|
||||||
|
args: [alice.pub, bob.sec, bob.password],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
["", "hello world"].forEach(function(input) {
|
||||||
|
TestRegister.addTests(
|
||||||
|
PGP_TEST_KEY_PAIRS.map(function(keyPair) {
|
||||||
|
var testName = "Sign PGP Cleartext, Verify PGP Cleartext ($pw, $ks) '$input'";
|
||||||
|
testName = testName.replace("$ks", keyPair.size);
|
||||||
|
testName = testName.replace("$pw", keyPair.password ? "pw" : "no pw");
|
||||||
|
testName = testName.replace("$input", input);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testName,
|
||||||
|
input: input,
|
||||||
|
expectedOutput: [
|
||||||
|
"Verified: true",
|
||||||
|
"Key ID: " + keyPair.keyID,
|
||||||
|
"Signed by: " + keyPair.name,
|
||||||
|
"Signed with: rsa_encrypt_sign",
|
||||||
|
"\n",
|
||||||
|
input,
|
||||||
|
].join("\n"),
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Sign PGP Cleartext",
|
||||||
|
args: [keyPair.sec, keyPair.password],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "Verify PGP Cleartext",
|
||||||
|
args: [keyPair.pub],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "Find / Replace",
|
||||||
|
args: [
|
||||||
|
{option: "Regex", string: "Signed on: .*\r?\n"},
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
TestRegister.addTests(CYBERCHEF_GENERATED_KEY_PAIRS.map(function(keyPair) {
|
||||||
|
var testName = "Remove PGP ASCII Armour, Add PGP ASCII Armour: Public Key '$name'";
|
||||||
|
testName = testName.replace("$name", keyPair.name);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testName,
|
||||||
|
input: keyPair.pub,
|
||||||
|
expectedOutput: keyPair.pub,
|
||||||
|
ignoreWhitespace: true,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Remove PGP ASCII Armour",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "Add PGP ASCII Armour",
|
||||||
|
args: ["Public key"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
TestRegister.addTests(CYBERCHEF_GENERATED_KEY_PAIRS.map(function(keyPair) {
|
||||||
|
var testName = "Remove PGP ASCII Armour, Add PGP ASCII Armour: Private Key '$name'";
|
||||||
|
testName = testName.replace("$name", keyPair.name);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testName,
|
||||||
|
input: keyPair.sec,
|
||||||
|
expectedOutput: keyPair.sec,
|
||||||
|
ignoreWhitespace: true,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "Remove PGP ASCII Armour",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "Add PGP ASCII Armour",
|
||||||
|
args: ["Private key"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
PGP_TEST_KEY_PAIRS.forEach(function(keyPair) {
|
||||||
|
TestRegister.addTests(
|
||||||
|
["", "hello world"].map(function(message, messageIndex) {
|
||||||
|
var testName = "PGP Encrypt, Remove PGP ASCII Armour, Add PGP ASCII Armour, PGP Decrypt: Message $message '$name'";
|
||||||
|
testName = testName.replace("$message", messageIndex);
|
||||||
|
testName = testName.replace("$name", keyPair.name);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testName,
|
||||||
|
input: message,
|
||||||
|
expectedOutput: message,
|
||||||
|
ignoreWhitespace: true,
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
op: "PGP Encrypt",
|
||||||
|
args: [keyPair.pub],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "Remove PGP ASCII Armour",
|
||||||
|
args: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "To Hex",
|
||||||
|
args: ["None"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "From Hex",
|
||||||
|
args: ["None"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "Add PGP ASCII Armour",
|
||||||
|
args: ["Message"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: "PGP Decrypt",
|
||||||
|
args: [keyPair.sec, keyPair.password],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user