diff --git a/.babelrc b/.babelrc
index 92a857c..094c059 100644
--- a/.babelrc
+++ b/.babelrc
@@ -5,7 +5,7 @@
"chrome": 40,
"firefox": 35,
"edge": 14,
- "node": "6.5",
+ "node": "6.5"
},
"modules": false,
"useBuiltIns": true
diff --git a/Gruntfile.js b/Gruntfile.js
index 7a9890f..b767a09 100755
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -318,7 +318,7 @@ module.exports = function (grunt) {
chunks: false,
modules: false,
entrypoints: false,
- warningsFilter: /source-map/,
+ warningsFilter: [/source-map/, /dependency is an expression/],
}
},
start: {
diff --git a/package-lock.json b/package-lock.json
index 8a220bc..20c6d90 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1197,6 +1197,11 @@
"integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=",
"dev": true
},
+ "bn": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bn/-/bn-1.0.1.tgz",
+ "integrity": "sha1-oVOCXmsessLbdyYUmwR6B84KO7M="
+ },
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
@@ -1499,6 +1504,11 @@
"integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=",
"dev": true
},
+ "bzip-deflate": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/bzip-deflate/-/bzip-deflate-1.0.0.tgz",
+ "integrity": "sha1-sC2wB+83vrzCk4Skssb08PTHlsk="
+ },
"cacache": {
"version": "10.0.4",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
@@ -2525,8 +2535,7 @@
"deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
- "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
- "dev": true
+ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
},
"deep-extend": {
"version": "0.4.2",
@@ -2915,16 +2924,23 @@
}
},
"es6-promise": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
- "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
- "dev": true
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
+ "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI="
},
"es6-promise-polyfill": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz",
"integrity": "sha1-84kl8jyz4+jObNqP93T867sJDN4="
},
+ "es6-promisify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+ "requires": {
+ "es6-promise": "4.0.5"
+ }
+ },
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3957,7 +3973,7 @@
"dev": true,
"requires": {
"commondir": "1.0.1",
- "make-dir": "1.2.0",
+ "make-dir": "1.1.0",
"pkg-dir": "2.0.0"
}
},
@@ -6081,6 +6097,24 @@
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
"dev": true
},
+ "iced-error": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/iced-error/-/iced-error-0.0.12.tgz",
+ "integrity": "sha1-4KhhRigXzwzpdLE/ymEtOg1dEL4="
+ },
+ "iced-lock": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/iced-lock/-/iced-lock-1.1.0.tgz",
+ "integrity": "sha1-YRbvHKs6zW5rEIk7snumIv0/3nI=",
+ "requires": {
+ "iced-runtime": "1.0.3"
+ }
+ },
+ "iced-runtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/iced-runtime/-/iced-runtime-1.0.3.tgz",
+ "integrity": "sha1-LU9PuZmreqVDCxk8d6f85BGDGc4="
+ },
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
@@ -7030,12 +7064,69 @@
"resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.6.tgz",
"integrity": "sha1-RYbwCCPjAuWZokSke+IMYardD88="
},
+ "kbpgp": {
+ "version": "2.0.76",
+ "resolved": "https://registry.npmjs.org/kbpgp/-/kbpgp-2.0.76.tgz",
+ "integrity": "sha1-qKtufM8279812BNdfJb/bpSLMAI=",
+ "requires": {
+ "bn": "1.0.1",
+ "bzip-deflate": "1.0.0",
+ "deep-equal": "1.0.1",
+ "iced-error": "0.0.12",
+ "iced-lock": "1.1.0",
+ "iced-runtime": "1.0.3",
+ "keybase-ecurve": "1.0.0",
+ "keybase-nacl": "1.0.10",
+ "minimist": "1.2.0",
+ "pgp-utils": "0.0.34",
+ "purepack": "1.0.4",
+ "triplesec": "3.0.26",
+ "tweetnacl": "0.13.3"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "tweetnacl": {
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
+ "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
+ }
+ }
+ },
"kew": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
"integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
"dev": true
},
+ "keybase-ecurve": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/keybase-ecurve/-/keybase-ecurve-1.0.0.tgz",
+ "integrity": "sha1-xrxyrdpGA/0xhP7n6ZaU7Y/WmtI=",
+ "requires": {
+ "bn": "1.0.1"
+ }
+ },
+ "keybase-nacl": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/keybase-nacl/-/keybase-nacl-1.0.10.tgz",
+ "integrity": "sha1-OGWDHpSBUWSI33y9mJRn6VDYeos=",
+ "requires": {
+ "iced-runtime": "1.0.3",
+ "tweetnacl": "0.13.3",
+ "uint64be": "1.0.1"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
+ "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
+ }
+ }
+ },
"killable": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
@@ -7523,9 +7614,9 @@
"dev": true
},
"make-dir": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
- "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
+ "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
"dev": true,
"requires": {
"pify": "3.0.0"
@@ -7853,6 +7944,14 @@
"moment": "2.20.1"
}
},
+ "more-entropy": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/more-entropy/-/more-entropy-0.0.7.tgz",
+ "integrity": "sha1-Z7/G96hvJvvDeqyD/UbYjGHRCbU=",
+ "requires": {
+ "iced-runtime": "1.0.3"
+ }
+ },
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -8605,13 +8704,22 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
"dev": true
},
+ "pgp-utils": {
+ "version": "0.0.34",
+ "resolved": "https://registry.npmjs.org/pgp-utils/-/pgp-utils-0.0.34.tgz",
+ "integrity": "sha1-2E9J98GTteC5QV9cxcKmle15DCM=",
+ "requires": {
+ "iced-error": "0.0.12",
+ "iced-runtime": "1.0.3"
+ }
+ },
"phantomjs-prebuilt": {
"version": "2.1.16",
"resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
"integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
"dev": true,
"requires": {
- "es6-promise": "4.2.4",
+ "es6-promise": "4.0.5",
"extract-zip": "1.6.6",
"fs-extra": "1.0.0",
"hasha": "2.2.0",
@@ -9601,8 +9709,7 @@
"progress": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
- "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
- "dev": true
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74="
},
"promise": {
"version": "7.3.1",
@@ -9682,6 +9789,11 @@
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
"dev": true
},
+ "purepack": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/purepack/-/purepack-1.0.4.tgz",
+ "integrity": "sha1-CGKC/ZOShfWGZLqam7oxzbFlzNI="
+ },
"q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -11663,6 +11775,18 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
+ "triplesec": {
+ "version": "3.0.26",
+ "resolved": "https://registry.npmjs.org/triplesec/-/triplesec-3.0.26.tgz",
+ "integrity": "sha1-3/K7R1ikIzcuc5o5fYmR8Fl9CsE=",
+ "requires": {
+ "iced-error": "0.0.12",
+ "iced-lock": "1.1.0",
+ "iced-runtime": "1.0.3",
+ "more-entropy": "0.0.7",
+ "progress": "1.1.8"
+ }
+ },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -11820,6 +11944,11 @@
}
}
},
+ "uint64be": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz",
+ "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU="
+ },
"underscore": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
diff --git a/package.json b/package.json
index 6d9e75b..da3da80 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.3",
+ "babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"css-loader": "^0.28.10",
"eslint": "^4.18.1",
@@ -81,6 +82,7 @@
"ctph.js": "0.0.5",
"diff": "^3.4.0",
"escodegen": "^1.9.1",
+ "es6-promisify": "^5.0.0",
"esmangle": "^1.0.1",
"esprima": "^4.0.0",
"exif-parser": "^0.1.12",
@@ -95,6 +97,7 @@
"jsrsasign": "8.0.6",
"lodash": "^4.17.5",
"loglevel": "^1.6.1",
+ "kbpgp": "^2.0.76",
"loglevel-message-prefix": "^3.0.0",
"moment": "^2.20.1",
"moment-timezone": "^0.5.14",
diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js
index 61026d3..b2c404f 100755
--- a/src/core/config/Categories.js
+++ b/src/core/config/Categories.js
@@ -114,6 +114,11 @@ const Categories = [
"Hex to PEM",
"Hex to Object Identifier",
"Object Identifier to Hex",
+ "Generate PGP Key Pair",
+ "PGP Encrypt",
+ "PGP Decrypt",
+ "PGP Encrypt and Sign",
+ "PGP Decrypt and Verify",
]
},
{
diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js
old mode 100755
new mode 100644
index 71d3c46..32095c3
--- a/src/core/config/OperationConfig.js
+++ b/src/core/config/OperationConfig.js
@@ -28,6 +28,7 @@ import MAC from "../operations/MAC.js";
import MorseCode from "../operations/MorseCode.js";
import NetBIOS from "../operations/NetBIOS.js";
import PHP from "../operations/PHP.js";
+import PGP from "../operations/PGP.js";
import PublicKey from "../operations/PublicKey.js";
import Punycode from "../operations/Punycode.js";
import Regex from "../operations/Regex.js";
@@ -4159,6 +4160,150 @@ const OperationConfig = {
outputType: "string",
args: []
},
+ "Generate PGP Key Pair": {
+ module: "PGP",
+ description: "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.",
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Key type",
+ type: "option",
+ value: PGP.KEY_TYPES
+ },
+ {
+ name: "Password (optional)",
+ type: "string",
+ value: ""
+ },
+ {
+ name: "Name (optional)",
+ type: "string",
+ value: ""
+ },
+ {
+ name: "Email (optional)",
+ type: "string",
+ value: ""
+ },
+ ]
+ },
+ "PGP Encrypt": {
+ module: "PGP",
+ description: [
+ "Input: the message you want to encrypt.",
+ "
",
+ "Arguments: the ASCII-armoured PGP public key of the recipient.",
+ "
",
+ "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
+ "
",
+ "This function uses the Keybase implementation of PGP.",
+ ].join("\n"),
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Public key of recipient",
+ type: "text",
+ value: ""
+ },
+ ]
+ },
+ "PGP Decrypt": {
+ module: "PGP",
+ description: [
+ "Input: the ASCII-armoured PGP message you want to decrypt.",
+ "
",
+ "Arguments: the ASCII-armoured PGP private key of the recipient, ",
+ "(and the private key password if necessary).",
+ "
",
+ "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
+ "
",
+ "This function uses the Keybase implementation of PGP.",
+ ].join("\n"),
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Private key of recipient",
+ type: "text",
+ value: ""
+ },
+ {
+ name: "Private key passphrase",
+ type: "string",
+ value: ""
+ },
+ ]
+ },
+ "PGP Encrypt and Sign": {
+ module: "PGP",
+ description: [
+ "Input: the cleartext you want to sign.",
+ "
",
+ "Arguments: the ASCII-armoured private key of the signer (plus the private key password if necessary)",
+ "and the ASCII-armoured PGP public key of the recipient.",
+ "
",
+ "This operation uses PGP to produce an encrypted digital signature.",
+ "
",
+ "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
+ "
",
+ "This function uses the Keybase implementation of PGP.",
+ ].join("\n"),
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Private key of signer",
+ type: "text",
+ value: ""
+ },
+ {
+ name: "Private key passphrase",
+ type: "string",
+ value: ""
+ },
+ {
+ name: "Public key of recipient",
+ type: "text",
+ value: ""
+ },
+ ]
+ },
+ "PGP Decrypt and Verify": {
+ module: "PGP",
+ description: [
+ "Input: the ASCII-armoured encrypted PGP message you want to verify.",
+ "
",
+ "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).",
+ "
",
+ "This operation uses PGP to decrypt and verify an encrypted digital signature.",
+ "
",
+ "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.",
+ "
",
+ "This function uses the Keybase implementation of PGP.",
+ ].join("\n"),
+ inputType: "string",
+ outputType: "string",
+ args: [
+ {
+ name: "Public key of signer",
+ type: "text",
+ value: "",
+ },
+ {
+ name: "Private key of recipient",
+ type: "text",
+ value: "",
+ },
+ {
+ name: "Private key password",
+ type: "string",
+ value: "",
+ },
+ ]
+ },
};
diff --git a/src/core/config/modules/PGP.js b/src/core/config/modules/PGP.js
new file mode 100644
index 0000000..89246cb
--- /dev/null
+++ b/src/core/config/modules/PGP.js
@@ -0,0 +1,25 @@
+import PGP from "../../operations/PGP.js";
+
+
+/**
+ * PGP module.
+ *
+ * Libraries:
+ * - kbpgp
+ *
+ * @author tlwr [toby@toby.codes]
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.PGP = {
+ "Generate PGP Key Pair": PGP.runGenerateKeyPair,
+ "PGP Encrypt": PGP.runEncrypt,
+ "PGP Decrypt": PGP.runDecrypt,
+ "PGP Encrypt and Sign": PGP.runSign,
+ "PGP Decrypt and Verify": PGP.runVerify,
+};
+
+export default OpModules;
diff --git a/src/core/operations/PGP.js b/src/core/operations/PGP.js
new file mode 100755
index 0000000..95fbdcc
--- /dev/null
+++ b/src/core/operations/PGP.js
@@ -0,0 +1,358 @@
+import * as kbpgp from "kbpgp";
+import promisify from "es6-promisify";
+
+
+/**
+ * PGP operations.
+ *
+ * @author tlwr [toby@toby.codes]
+ * @author Matt C [matt@artemisbot.uk]
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const PGP = {
+
+ /**
+ * @constant
+ * @default
+ */
+ KEY_TYPES: ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"],
+
+
+ /**
+ * Get size of subkey
+ *
+ * @private
+ * @param {number} keySize
+ * @returns {number}
+ */
+ _getSubkeySize(keySize) {
+ return {
+ 1024: 1024,
+ 2048: 1024,
+ 4096: 2048,
+ 256: 256,
+ 384: 256,
+ }[keySize];
+ },
+
+
+ /**
+ * Progress callback
+ *
+ * @private
+ */
+ _ASP: new 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);
+ }
+ }),
+
+
+ /**
+ * Import private key and unlock if necessary
+ *
+ * @private
+ * @param {string} privateKey
+ * @param {string} [passphrase]
+ * @returns {Object}
+ */
+ async _importPrivateKey(privateKey, passphrase) {
+ try {
+ const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
+ armored: privateKey,
+ });
+ if (key.is_pgp_locked() && passphrase) {
+ if (passphrase) {
+ await promisify(key.unlock_pgp, key)({
+ passphrase
+ });
+ } else if (!passphrase) {
+ throw "Did not provide passphrase with locked private key.";
+ }
+ }
+ return key;
+ } catch (err) {
+ throw `Could not import private key: ${err}`;
+ }
+ },
+
+
+ /**
+ * Import public key
+ *
+ * @private
+ * @param {string} publicKey
+ * @returns {Object}
+ */
+ async _importPublicKey (publicKey) {
+ try {
+ const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
+ armored: publicKey,
+ });
+ return key;
+ } catch (err) {
+ throw `Could not import public key: ${err}`;
+ }
+ },
+
+
+ /**
+ * Generate PGP Key Pair operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ runGenerateKeyPair(input, args) {
+ let [keyType, keySize] = args[0].split("-"),
+ password = args[1],
+ name = args[2],
+ email = args[3],
+ 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;
+
+ let keyGenerationOptions = {
+ userid: userIdentifier,
+ ecc: keyType === "ecc",
+ primary: {
+ "nbits": keySize,
+ "flags": flags,
+ "expire_in": 0
+ },
+ subkeys: [{
+ "nbits": PGP._getSubkeySize(keySize),
+ "flags": kbpgp.const.openpgp.sign_data,
+ "expire_in": 86400 * 365 * 8
+ }, {
+ "nbits": PGP._getSubkeySize(keySize),
+ "flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage,
+ "expire_in": 86400 * 365 * 2
+ }],
+ asp: PGP._ASP
+ };
+
+ return new Promise(async (resolve, reject) => {
+ try {
+ const unsignedKey = await promisify(kbpgp.KeyManager.generate)(keyGenerationOptions);
+ await promisify(unsignedKey.sign, unsignedKey)({});
+ let signedKey = unsignedKey;
+ let privateKeyExportOptions = {};
+ if (password) privateKeyExportOptions.passphrase = password;
+ const privateKey = await promisify(signedKey.export_pgp_private, signedKey)(privateKeyExportOptions);
+ const publicKey = await promisify(signedKey.export_pgp_public, signedKey)({});
+ resolve(privateKey + "\n" + publicKey.trim());
+ } catch (err) {
+ reject(`Error whilst generating key pair: ${err}`);
+ }
+ });
+ },
+
+
+ /**
+ * PGP Encrypt operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async runEncrypt(input, args) {
+ let plaintextMessage = input,
+ plainPubKey = args[0],
+ 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": PGP._ASP
+ });
+ } catch (err) {
+ throw `Couldn't encrypt message with provided public key: ${err}`;
+ }
+
+ return encryptedMessage.toString();
+ },
+
+
+ /**
+ * PGP Decrypt operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async runDecrypt(input, args) {
+ let encryptedMessage = input,
+ privateKey = args[0],
+ passphrase = args[1],
+ keyring = new kbpgp.keyring.KeyRing(),
+ plaintextMessage;
+
+ if (!privateKey) return "Enter the private key of the recipient.";
+
+ const key = await PGP._importPrivateKey(privateKey, passphrase);
+ keyring.add_key_manager(key);
+
+ try {
+ plaintextMessage = await promisify(kbpgp.unbox)({
+ armored: encryptedMessage,
+ keyfetch: keyring,
+ asp: PGP._ASP
+ });
+ } catch (err) {
+ throw `Couldn't decrypt message with provided private key: ${err}`;
+ }
+
+ return plaintextMessage.toString();
+ },
+
+
+ /**
+ * PGP Sign Message operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async runSign(input, args) {
+ let message = input,
+ privateKey = args[0],
+ passphrase = args[1],
+ publicKey = args[2],
+ signedMessage;
+
+ if (!privateKey) return "Enter the private key of the signer.";
+ if (!publicKey) return "Enter the public key of the recipient.";
+ const privKey = await PGP._importPrivateKey(privateKey, passphrase);
+ const pubKey = await PGP._importPublicKey(publicKey);
+
+ try {
+ signedMessage = await promisify(kbpgp.box)({
+ "msg": message,
+ "encrypt_for": pubKey,
+ "sign_with": privKey,
+ "asp": PGP._ASP
+ });
+ } catch (err) {
+ throw `Couldn't sign message: ${err}`;
+ }
+
+ return signedMessage;
+ },
+
+
+ /**
+ * PGP Verify Message operation.
+ *
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ async runVerify(input, args) {
+ let signedMessage = input,
+ publicKey = args[0],
+ privateKey = args[1],
+ passphrase = args[2],
+ keyring = new kbpgp.keyring.KeyRing(),
+ unboxedLiterals;
+
+ if (!publicKey) return "Enter the public key of the signer.";
+ if (!privateKey) return "Enter the private key of the recipient.";
+ const privKey = await PGP._importPrivateKey(privateKey, passphrase);
+ const pubKey = await PGP._importPublicKey(publicKey);
+ keyring.add_key_manager(privKey);
+ keyring.add_key_manager(pubKey);
+
+ try {
+ unboxedLiterals = await promisify(kbpgp.unbox)({
+ armored: signedMessage,
+ keyfetch: keyring,
+ asp: PGP._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 PGP;
diff --git a/webpack.config.js b/webpack.config.js
index 362bea7..d4b27da 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -109,7 +109,7 @@ module.exports = {
chunks: false,
modules: false,
entrypoints: false,
- warningsFilter: /source-map/,
+ warningsFilter: [/source-map/, /dependency is an expression/],
},
node: {
fs: "empty"