mirror of
https://github.com/gchq/CyberChef.git
synced 2024-11-16 00:48:31 +01:00
Ported x86 Disassembler & PGP ops
This commit is contained in:
parent
b8d39f49b2
commit
2b0c327001
7 changed files with 694 additions and 0 deletions
116
src/core/lib/PGP.mjs
Normal file
116
src/core/lib/PGP.mjs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
* PGP functions.
|
||||||
|
*
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
*
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as kbpgp from "kbpgp";
|
||||||
|
import { promisify } from "es6-promisify";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Progress callback
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export const ASP = kbpgp.ASP({
|
||||||
|
"progress_hook": info => {
|
||||||
|
let msg = "";
|
||||||
|
|
||||||
|
switch (info.what) {
|
||||||
|
case "guess":
|
||||||
|
msg = "Guessing a prime";
|
||||||
|
break;
|
||||||
|
case "fermat":
|
||||||
|
msg = "Factoring prime using Fermat's factorization method";
|
||||||
|
break;
|
||||||
|
case "mr":
|
||||||
|
msg = "Performing Miller-Rabin primality test";
|
||||||
|
break;
|
||||||
|
case "passed_mr":
|
||||||
|
msg = "Passed Miller-Rabin primality test";
|
||||||
|
break;
|
||||||
|
case "failed_mr":
|
||||||
|
msg = "Failed Miller-Rabin primality test";
|
||||||
|
break;
|
||||||
|
case "found":
|
||||||
|
msg = "Prime found";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg = `Stage: ${info.what}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ENVIRONMENT_IS_WORKER())
|
||||||
|
self.sendStatusMessage(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get size of subkey
|
||||||
|
*
|
||||||
|
* @param {number} keySize
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
export function getSubkeySize(keySize) {
|
||||||
|
return {
|
||||||
|
1024: 1024,
|
||||||
|
2048: 1024,
|
||||||
|
4096: 2048,
|
||||||
|
256: 256,
|
||||||
|
384: 256,
|
||||||
|
}[keySize];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import private key and unlock if necessary
|
||||||
|
*
|
||||||
|
* @param {string} privateKey
|
||||||
|
* @param {string} [passphrase]
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export async function importPrivateKey(privateKey, passphrase) {
|
||||||
|
try {
|
||||||
|
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||||
|
armored: privateKey,
|
||||||
|
opts: {
|
||||||
|
"no_check_keys": true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (key.is_pgp_locked()) {
|
||||||
|
if (passphrase) {
|
||||||
|
await promisify(key.unlock_pgp.bind(key))({
|
||||||
|
passphrase
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw "Did not provide passphrase with locked private key.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
} catch (err) {
|
||||||
|
throw `Could not import private key: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import public key
|
||||||
|
*
|
||||||
|
* @param {string} publicKey
|
||||||
|
* @returns {Object}
|
||||||
|
*/
|
||||||
|
export async function importPublicKey (publicKey) {
|
||||||
|
try {
|
||||||
|
const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||||
|
armored: publicKey,
|
||||||
|
opts: {
|
||||||
|
"no_check_keys": true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return key;
|
||||||
|
} catch (err) {
|
||||||
|
throw `Could not import public key: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
127
src/core/operations/DisassembleX86.mjs
Normal file
127
src/core/operations/DisassembleX86.mjs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/**
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import disassemble from "../vendor/DisassembleX86-64.js";
|
||||||
|
/**
|
||||||
|
* Disassemble x86 operation
|
||||||
|
*/
|
||||||
|
class DisassembleX86 extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassembleX86 constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Disassemble x86";
|
||||||
|
this.module = "Shellcode";
|
||||||
|
this.description = "Disassembly is the process of translating machine language into assembly language.<br><br>This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.<br><br>Input should be in hexadecimal.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Bit mode",
|
||||||
|
"type": "option",
|
||||||
|
"value": ["64", "32", "16"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Compatibility",
|
||||||
|
"type": "option",
|
||||||
|
"value": [
|
||||||
|
"Full x86 architecture",
|
||||||
|
"Knights Corner",
|
||||||
|
"Larrabee",
|
||||||
|
"Cyrix",
|
||||||
|
"Geode",
|
||||||
|
"Centaur",
|
||||||
|
"X86/486"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Code Segment (CS)",
|
||||||
|
"type": "number",
|
||||||
|
"value": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Offset (IP)",
|
||||||
|
"type": "number",
|
||||||
|
"value": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Show instruction hex",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Show instruction position",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const mode = args[0],
|
||||||
|
compatibility = args[1],
|
||||||
|
codeSegment = args[2],
|
||||||
|
offset = args[3],
|
||||||
|
showInstructionHex = args[4],
|
||||||
|
showInstructionPos = args[5];
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case "64":
|
||||||
|
disassemble.setBitMode(2);
|
||||||
|
break;
|
||||||
|
case "32":
|
||||||
|
disassemble.setBitMode(1);
|
||||||
|
break;
|
||||||
|
case "16":
|
||||||
|
disassemble.setBitMode(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw "Invalid mode value";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (compatibility) {
|
||||||
|
case "Full x86 architecture":
|
||||||
|
disassemble.CompatibilityMode(0);
|
||||||
|
break;
|
||||||
|
case "Knights Corner":
|
||||||
|
disassemble.CompatibilityMode(1);
|
||||||
|
break;
|
||||||
|
case "Larrabee":
|
||||||
|
disassemble.CompatibilityMode(2);
|
||||||
|
break;
|
||||||
|
case "Cyrix":
|
||||||
|
disassemble.CompatibilityMode(3);
|
||||||
|
break;
|
||||||
|
case "Geode":
|
||||||
|
disassemble.CompatibilityMode(4);
|
||||||
|
break;
|
||||||
|
case "Centaur":
|
||||||
|
disassemble.CompatibilityMode(5);
|
||||||
|
break;
|
||||||
|
case "X86/486":
|
||||||
|
disassemble.CompatibilityMode(6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
disassemble.SetBasePosition(codeSegment + ":" + offset);
|
||||||
|
disassemble.setShowInstructionHex(showInstructionHex);
|
||||||
|
disassemble.setShowInstructionPos(showInstructionPos);
|
||||||
|
disassemble.LoadBinCode(input.replace(/\s/g, ""));
|
||||||
|
return disassemble.LDisassemble();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DisassembleX86;
|
114
src/core/operations/GeneratePGPKeyPair.mjs
Normal file
114
src/core/operations/GeneratePGPKeyPair.mjs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @author Matt C [matt@artemisbot.uk]
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import * as kbpgp from "kbpgp";
|
||||||
|
import { promisify } from "es6-promisify";
|
||||||
|
import { getSubkeySize, ASP } from "../lib/PGP";
|
||||||
|
/**
|
||||||
|
* Generate PGP Key Pair operation
|
||||||
|
*/
|
||||||
|
class GeneratePGPKeyPair extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GeneratePGPKeyPair constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Generate PGP Key Pair";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Key type",
|
||||||
|
"type": "option",
|
||||||
|
"value": ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Password (optional)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Name (optional)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Email (optional)",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [keyType, keySize] = args[0].split("-"),
|
||||||
|
password = args[1],
|
||||||
|
name = args[2],
|
||||||
|
email = args[3];
|
||||||
|
let userIdentifier = "";
|
||||||
|
|
||||||
|
if (name) userIdentifier += name;
|
||||||
|
if (email) userIdentifier += ` <${email}>`;
|
||||||
|
|
||||||
|
let flags = kbpgp.const.openpgp.certify_keys;
|
||||||
|
flags |= kbpgp.const.openpgp.sign_data;
|
||||||
|
flags |= kbpgp.const.openpgp.auth;
|
||||||
|
flags |= kbpgp.const.openpgp.encrypt_comm;
|
||||||
|
flags |= kbpgp.const.openpgp.encrypt_storage;
|
||||||
|
|
||||||
|
const keyGenerationOptions = {
|
||||||
|
userid: userIdentifier,
|
||||||
|
ecc: keyType === "ecc",
|
||||||
|
primary: {
|
||||||
|
"nbits": keySize,
|
||||||
|
"flags": flags,
|
||||||
|
"expire_in": 0
|
||||||
|
},
|
||||||
|
subkeys: [{
|
||||||
|
"nbits": getSubkeySize(keySize),
|
||||||
|
"flags": kbpgp.const.openpgp.sign_data,
|
||||||
|
"expire_in": 86400 * 365 * 8
|
||||||
|
}, {
|
||||||
|
"nbits": getSubkeySize(keySize),
|
||||||
|
"flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage,
|
||||||
|
"expire_in": 86400 * 365 * 2
|
||||||
|
}],
|
||||||
|
asp: ASP
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
const unsignedKey = await promisify(kbpgp.KeyManager.generate)(keyGenerationOptions);
|
||||||
|
await promisify(unsignedKey.sign.bind(unsignedKey))({});
|
||||||
|
|
||||||
|
const signedKey = unsignedKey,
|
||||||
|
privateKeyExportOptions = {};
|
||||||
|
|
||||||
|
if (password) privateKeyExportOptions.passphrase = password;
|
||||||
|
const privateKey = await promisify(signedKey.export_pgp_private.bind(signedKey))(privateKeyExportOptions);
|
||||||
|
const publicKey = await promisify(signedKey.export_pgp_public.bind(signedKey))({});
|
||||||
|
resolve(privateKey + "\n" + publicKey.trim());
|
||||||
|
} catch (err) {
|
||||||
|
reject(`Error whilst generating key pair: ${err}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GeneratePGPKeyPair;
|
74
src/core/operations/PGPDecrypt.mjs
Normal file
74
src/core/operations/PGPDecrypt.mjs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import * as kbpgp from "kbpgp";
|
||||||
|
import { promisify } from "es6-promisify";
|
||||||
|
import { ASP, importPrivateKey } from "../lib/PGP";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Decrypt operation
|
||||||
|
*/
|
||||||
|
class PGPDecrypt extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPDecrypt constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Decrypt";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the ASCII-armoured PGP message you want to decrypt.\n<br><br>\nArguments: the ASCII-armoured PGP private key of the recipient, \n(and the private key password if necessary).\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Private key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key passphrase",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const encryptedMessage = input,
|
||||||
|
privateKey = args[0],
|
||||||
|
passphrase = args[1],
|
||||||
|
keyring = new kbpgp.keyring.KeyRing();
|
||||||
|
let plaintextMessage;
|
||||||
|
|
||||||
|
if (!privateKey) return "Enter the private key of the recipient.";
|
||||||
|
|
||||||
|
const key = await importPrivateKey(privateKey, passphrase);
|
||||||
|
keyring.add_key_manager(key);
|
||||||
|
|
||||||
|
try {
|
||||||
|
plaintextMessage = await promisify(kbpgp.unbox)({
|
||||||
|
armored: encryptedMessage,
|
||||||
|
keyfetch: keyring,
|
||||||
|
asp: ASP
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw `Couldn't decrypt message with provided private key: ${err}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return plaintextMessage.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPDecrypt;
|
111
src/core/operations/PGPDecryptAndVerify.mjs
Normal file
111
src/core/operations/PGPDecryptAndVerify.mjs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import * as kbpgp from "kbpgp";
|
||||||
|
import { promisify } from "es6-promisify";
|
||||||
|
import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Decrypt and Verify operation
|
||||||
|
*/
|
||||||
|
class PGPDecryptAndVerify extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPDecryptAndVerify constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Decrypt and Verify";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the ASCII-armoured encrypted PGP message you want to verify.\n<br><br>\nArguments: the ASCII-armoured PGP public key of the signer, \nthe ASCII-armoured private key of the recipient (and the private key password if necessary).\n<br><br>\nThis operation uses PGP to decrypt and verify an encrypted digital signature.\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Public key of signer",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key password",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const signedMessage = input,
|
||||||
|
publicKey = args[0],
|
||||||
|
privateKey = args[1],
|
||||||
|
passphrase = args[2],
|
||||||
|
keyring = new kbpgp.keyring.KeyRing();
|
||||||
|
let unboxedLiterals;
|
||||||
|
|
||||||
|
if (!publicKey) return "Enter the public key of the signer.";
|
||||||
|
if (!privateKey) return "Enter the private key of the recipient.";
|
||||||
|
const privKey = await importPrivateKey(privateKey, passphrase);
|
||||||
|
const pubKey = await importPublicKey(publicKey);
|
||||||
|
keyring.add_key_manager(privKey);
|
||||||
|
keyring.add_key_manager(pubKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
unboxedLiterals = await promisify(kbpgp.unbox)({
|
||||||
|
armored: signedMessage,
|
||||||
|
keyfetch: keyring,
|
||||||
|
asp: ASP
|
||||||
|
});
|
||||||
|
const ds = unboxedLiterals[0].get_data_signer();
|
||||||
|
if (ds) {
|
||||||
|
const km = ds.get_key_manager();
|
||||||
|
if (km) {
|
||||||
|
const signer = km.get_userids_mark_primary()[0].components;
|
||||||
|
let text = "Signed by ";
|
||||||
|
if (signer.email || signer.username || signer.comment) {
|
||||||
|
if (signer.username) {
|
||||||
|
text += `${signer.username} `;
|
||||||
|
}
|
||||||
|
if (signer.comment) {
|
||||||
|
text += `${signer.comment} `;
|
||||||
|
}
|
||||||
|
if (signer.email) {
|
||||||
|
text += `<${signer.email}>`;
|
||||||
|
}
|
||||||
|
text += "\n";
|
||||||
|
}
|
||||||
|
text += [
|
||||||
|
`PGP fingerprint: ${km.get_pgp_fingerprint().toString("hex")}`,
|
||||||
|
`Signed on ${new Date(ds.sig.hashed_subpackets[0].time * 1000).toUTCString()}`,
|
||||||
|
"----------------------------------\n"
|
||||||
|
].join("\n");
|
||||||
|
text += unboxedLiterals.toString();
|
||||||
|
return text.trim();
|
||||||
|
} else {
|
||||||
|
return "Could not identify a key manager.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "The data does not appear to be signed.";
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return `Couldn't verify message: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPDecryptAndVerify;
|
72
src/core/operations/PGPEncrypt.mjs
Normal file
72
src/core/operations/PGPEncrypt.mjs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import * as kbpgp from "kbpgp";
|
||||||
|
import { promisify } from "es6-promisify";
|
||||||
|
import { ASP } from "../lib/PGP";
|
||||||
|
/**
|
||||||
|
* PGP Encrypt operation
|
||||||
|
*/
|
||||||
|
class PGPEncrypt extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPEncrypt constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Encrypt";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the message you want to encrypt.\n<br><br>\nArguments: the ASCII-armoured PGP public key of the recipient.\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Public key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const plaintextMessage = input,
|
||||||
|
plainPubKey = args[0];
|
||||||
|
let key,
|
||||||
|
encryptedMessage;
|
||||||
|
|
||||||
|
if (!plainPubKey) return "Enter the public key of the recipient.";
|
||||||
|
|
||||||
|
try {
|
||||||
|
key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
|
||||||
|
armored: plainPubKey,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw `Could not import public key: ${err}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
encryptedMessage = await promisify(kbpgp.box)({
|
||||||
|
"msg": plaintextMessage,
|
||||||
|
"encrypt_for": key,
|
||||||
|
"asp": ASP
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw `Couldn't encrypt message with provided public key: ${err}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encryptedMessage.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPEncrypt;
|
80
src/core/operations/PGPEncryptAndSign.mjs
Normal file
80
src/core/operations/PGPEncryptAndSign.mjs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* @author tlwr [toby@toby.codes]
|
||||||
|
* @copyright Crown Copyright 2017
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation";
|
||||||
|
import * as kbpgp from "kbpgp";
|
||||||
|
import { promisify } from "es6-promisify";
|
||||||
|
import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGP Encrypt and Sign operation
|
||||||
|
*/
|
||||||
|
class PGPEncryptAndSign extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGPEncryptAndSign constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "PGP Encrypt and Sign";
|
||||||
|
this.module = "PGP";
|
||||||
|
this.description = "Input: the cleartext you want to sign.\n<br><br>\nArguments: the ASCII-armoured private key of the signer (plus the private key password if necessary)\nand the ASCII-armoured PGP public key of the recipient.\n<br><br>\nThis operation uses PGP to produce an encrypted digital signature.\n<br><br>\nPretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.\n<br><br>\nThis function uses the Keybase implementation of PGP.";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
"name": "Private key of signer",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Private key passphrase",
|
||||||
|
"type": "string",
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Public key of recipient",
|
||||||
|
"type": "text",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async run(input, args) {
|
||||||
|
const message = input,
|
||||||
|
privateKey = args[0],
|
||||||
|
passphrase = args[1],
|
||||||
|
publicKey = args[2];
|
||||||
|
let signedMessage;
|
||||||
|
|
||||||
|
if (!privateKey) return "Enter the private key of the signer.";
|
||||||
|
if (!publicKey) return "Enter the public key of the recipient.";
|
||||||
|
const privKey = await importPrivateKey(privateKey, passphrase);
|
||||||
|
const pubKey = await importPublicKey(publicKey);
|
||||||
|
|
||||||
|
try {
|
||||||
|
signedMessage = await promisify(kbpgp.box)({
|
||||||
|
"msg": message,
|
||||||
|
"encrypt_for": pubKey,
|
||||||
|
"sign_with": privKey,
|
||||||
|
"asp": ASP
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
throw `Couldn't sign message: ${err}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PGPEncryptAndSign;
|
Loading…
Reference in a new issue