Explorar o código

Merge branch 'feature-add-pgp-kbpgp' of https://github.com/tlwr/CyberChef into tlwr-feature-add-pgp-kbpgp

n1474335 %!s(int64=7) %!d(string=hai) anos
pai
achega
1143c23ad9
Modificáronse 6 ficheiros con 982 adicións e 4 borrados
  1. 6 0
      .babelrc
  2. 452 4
      package-lock.json
  3. 6 0
      package.json
  4. 154 0
      src/core/config/OperationConfig.js
  5. 25 0
      src/core/config/modules/PGP.js
  6. 339 0
      src/core/operations/PGP.js

+ 6 - 0
.babelrc

@@ -1,4 +1,10 @@
 {
+    "plugins": [
+        ["transform-runtime", {
+            "polyfill": false,
+            "regenerator": true
+        }]
+    ],
     "presets": [
         ["env", {
             "targets": {

+ 452 - 4
package-lock.json

@@ -529,6 +529,17 @@
         }
       }
     },
+    "babel-helper-bindify-decorators": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz",
+      "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
     "babel-helper-builder-binary-assignment-operator-visitor": {
       "version": "6.24.1",
       "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
@@ -575,6 +586,18 @@
         "babel-types": "6.26.0"
       }
     },
+    "babel-helper-explode-class": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz",
+      "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
+      "dev": true,
+      "requires": {
+        "babel-helper-bindify-decorators": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
     "babel-helper-function-name": {
       "version": "6.24.1",
       "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
@@ -701,18 +724,83 @@
       "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
       "dev": true
     },
+    "babel-plugin-syntax-async-generators": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
+      "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
+      "dev": true
+    },
+    "babel-plugin-syntax-class-constructor-call": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
+      "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
+      "dev": true
+    },
+    "babel-plugin-syntax-class-properties": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
+      "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
+      "dev": true
+    },
+    "babel-plugin-syntax-decorators": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
+      "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
+      "dev": true
+    },
+    "babel-plugin-syntax-do-expressions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
+      "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
+      "dev": true
+    },
+    "babel-plugin-syntax-dynamic-import": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
+      "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
+      "dev": true
+    },
     "babel-plugin-syntax-exponentiation-operator": {
       "version": "6.13.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
       "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
       "dev": true
     },
+    "babel-plugin-syntax-export-extensions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
+      "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
+      "dev": true
+    },
+    "babel-plugin-syntax-function-bind": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
+      "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
+      "dev": true
+    },
+    "babel-plugin-syntax-object-rest-spread": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+      "dev": true
+    },
     "babel-plugin-syntax-trailing-function-commas": {
       "version": "6.22.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
       "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
       "dev": true
     },
+    "babel-plugin-transform-async-generator-functions": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
+      "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
+      "dev": true,
+      "requires": {
+        "babel-helper-remap-async-to-generator": "6.24.1",
+        "babel-plugin-syntax-async-generators": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
     "babel-plugin-transform-async-to-generator": {
       "version": "6.24.1",
       "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
@@ -724,6 +812,52 @@
         "babel-runtime": "6.26.0"
       }
     },
+    "babel-plugin-transform-class-constructor-call": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz",
+      "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-class-constructor-call": "6.18.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-class-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
+      "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-plugin-syntax-class-properties": "6.13.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-decorators": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz",
+      "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
+      "dev": true,
+      "requires": {
+        "babel-helper-explode-class": "6.24.1",
+        "babel-plugin-syntax-decorators": "6.13.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-do-expressions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz",
+      "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-do-expressions": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
     "babel-plugin-transform-es2015-arrow-functions": {
       "version": "6.22.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
@@ -969,6 +1103,36 @@
         "babel-runtime": "6.26.0"
       }
     },
+    "babel-plugin-transform-export-extensions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz",
+      "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-export-extensions": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-function-bind": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz",
+      "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-function-bind": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-object-rest-spread": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
+      "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-object-rest-spread": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
     "babel-plugin-transform-regenerator": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
@@ -978,6 +1142,15 @@
         "regenerator-transform": "0.10.1"
       }
     },
+    "babel-plugin-transform-runtime": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz",
+      "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
     "babel-plugin-transform-strict-mode": {
       "version": "6.24.1",
       "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
@@ -1043,6 +1216,85 @@
         "semver": "5.4.1"
       }
     },
+    "babel-preset-es2015": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz",
+      "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-check-es2015-constants": "6.22.0",
+        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
+        "babel-plugin-transform-es2015-classes": "6.24.1",
+        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
+        "babel-plugin-transform-es2015-destructuring": "6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
+        "babel-plugin-transform-es2015-for-of": "6.23.0",
+        "babel-plugin-transform-es2015-function-name": "6.24.1",
+        "babel-plugin-transform-es2015-literals": "6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
+        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
+        "babel-plugin-transform-es2015-object-super": "6.24.1",
+        "babel-plugin-transform-es2015-parameters": "6.24.1",
+        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
+        "babel-plugin-transform-es2015-spread": "6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
+        "babel-plugin-transform-es2015-template-literals": "6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
+        "babel-plugin-transform-regenerator": "6.26.0"
+      }
+    },
+    "babel-preset-stage-0": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz",
+      "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-do-expressions": "6.22.0",
+        "babel-plugin-transform-function-bind": "6.22.0",
+        "babel-preset-stage-1": "6.24.1"
+      }
+    },
+    "babel-preset-stage-1": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz",
+      "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-class-constructor-call": "6.24.1",
+        "babel-plugin-transform-export-extensions": "6.22.0",
+        "babel-preset-stage-2": "6.24.1"
+      }
+    },
+    "babel-preset-stage-2": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz",
+      "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-dynamic-import": "6.18.0",
+        "babel-plugin-transform-class-properties": "6.24.1",
+        "babel-plugin-transform-decorators": "6.24.1",
+        "babel-preset-stage-3": "6.24.1"
+      }
+    },
+    "babel-preset-stage-3": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz",
+      "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-trailing-function-commas": "6.22.0",
+        "babel-plugin-transform-async-generator-functions": "6.24.1",
+        "babel-plugin-transform-async-to-generator": "6.24.1",
+        "babel-plugin-transform-exponentiation-operator": "6.24.1",
+        "babel-plugin-transform-object-rest-spread": "6.26.0"
+      }
+    },
     "babel-register": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
@@ -1197,6 +1449,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 +1756,7 @@
       "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=",
       "dev": true
     },
+<<<<<<< HEAD
     "cacache": {
       "version": "10.0.4",
       "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
@@ -1567,6 +1825,12 @@
         "union-value": "1.0.0",
         "unset-value": "1.0.0"
       }
+=======
+    "bzip-deflate": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/bzip-deflate/-/bzip-deflate-1.0.0.tgz",
+      "integrity": "sha1-sC2wB+83vrzCk4Skssb08PTHlsk="
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
     },
     "caller-path": {
       "version": "0.1.0",
@@ -2525,8 +2789,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 +3178,68 @@
       }
     },
     "es6-promise": {
+<<<<<<< HEAD
       "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="
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
     },
     "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="
     },
+<<<<<<< HEAD
+=======
+    "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"
+      }
+    },
+    "es6-set": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1"
+      }
+    },
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3957,7 +4272,11 @@
       "dev": true,
       "requires": {
         "commondir": "1.0.1",
+<<<<<<< HEAD
         "make-dir": "1.2.0",
+=======
+        "make-dir": "1.1.0",
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
         "pkg-dir": "2.0.0"
       }
     },
@@ -6081,6 +6400,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 +7367,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 +7917,15 @@
       "dev": true
     },
     "make-dir": {
+<<<<<<< HEAD
       "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==",
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
       "dev": true,
       "requires": {
         "pify": "3.0.0"
@@ -7853,6 +8253,7 @@
         "moment": "2.20.1"
       }
     },
+<<<<<<< HEAD
     "move-concurrently": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -7876,6 +8277,14 @@
             "glob": "7.0.6"
           }
         }
+=======
+    "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"
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
       }
     },
     "ms": {
@@ -8605,6 +9014,15 @@
       "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",
@@ -9601,8 +10019,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 +10099,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 +12085,27 @@
       "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
       "dev": true
     },
+<<<<<<< HEAD
+=======
+    "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"
+      }
+    },
+    "tryit": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+      "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
+      "dev": true
+    },
+>>>>>>> aa3f781e18cbcae549538637573a807064f3c730
     "tty-browserify": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -11820,6 +12263,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",

+ 6 - 0
package.json

@@ -40,6 +40,10 @@
     "file-loader": "^1.1.10",
     "grunt": ">=1.0.2",
     "grunt-accessibility": "~6.0.0",
+    "babel-plugin-transform-runtime": "^6.23.0",
+    "babel-polyfill": "^6.26.0",
+    "babel-preset-es2015": "^6.24.1",
+    "babel-preset-stage-0": "^6.24.1",
     "grunt-chmod": "~1.1.1",
     "grunt-concurrent": "^2.3.1",
     "grunt-contrib-clean": "~1.1.0",
@@ -81,6 +85,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 +100,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",

+ 154 - 0
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,159 @@ const OperationConfig = {
         outputType: "string",
         args: []
     },
+    "Generate PGP Key Pair": {
+        module: "PGP",
+        manualBake: true,
+        description: "",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key type",
+                type: "option",
+                value: PGP.KEY_TYPES
+            },
+            {
+                name: "Key size",
+                type: "option",
+                value: PGP.KEY_SIZES
+            },
+            {
+                name: "Password (optional)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Name (optional)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Email (optional)",
+                type: "string",
+                value: ""
+            },
+        ]
+    },
+    "PGP Encrypt": {
+        module: "PGP",
+        manualBake: true,
+        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 kbpgp.js for the implementation of PGP.",
+        ].join("\n"),
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Public key of recipient",
+                type: "text",
+                value: ""
+            },
+        ]
+    },
+    "PGP Decrypt": {
+        module: "PGP",
+        manualBake: true,
+        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 kbpgp.js for the 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 Sign": {
+        module: "PGP",
+        manualBake: true,
+        description: [
+            "Input: the cleartext you want to sign.",
+            "<br><br>",
+            "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.",
+            "<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 kbpgp.js for the 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 Verify": {
+        module: "PGP",
+        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 kbpgp.js for the 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: "",
+            },
+        ]
+    },
 };
 
 

+ 25 - 0
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 Sign":              PGP.runSign,
+    "PGP Verify":            PGP.runVerify,
+};
+
+export default OpModules;

+ 339 - 0
src/core/operations/PGP.js

@@ -0,0 +1,339 @@
+/*eslint camelcase: ["error", {properties: "never"}]*/
+import * as kbpgp from "kbpgp";
+import promisify from "es6-promisify";
+
+const ECC_SIZES = ["256", "384"];
+const RSA_SIZES = ["1024", "2048", "4096"];
+const KEY_SIZES = RSA_SIZES.concat(ECC_SIZES);
+const KEY_TYPES = ["RSA", "ECC"];
+
+/**
+ * PGP operations.
+ *
+ * @author tlwr [toby@toby.codes]
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const PGP = {
+    KEY_SIZES: KEY_SIZES,
+
+    /**
+     * Validate PGP Key Size
+     * 
+     * @private
+     * @param {string} keySize
+     * @returns {Integer}
+     */
+    _validateKeySize(keySize, keyType) {
+        if (KEY_SIZES.indexOf(keySize) < 0) {
+            throw `Invalid key size ${keySize}, must be in ${JSON.stringify(KEY_SIZES)}`;
+        }
+
+        if (keyType === "ecc") {
+            if (ECC_SIZES.indexOf(keySize) >= 0) {
+                return parseInt(keySize, 10);
+            } else {
+                throw `Invalid key size ${keySize}, must be in ${JSON.stringify(ECC_SIZES)} for ECC`;
+            }
+        } else {
+            if (RSA_SIZES.indexOf(keySize) >= 0) {
+                return parseInt(keySize, 10);
+            } else {
+                throw `Invalid key size ${keySize}, must be in ${JSON.stringify(RSA_SIZES)} for RSA`;
+            }
+        }
+    },
+
+    /**
+     * Get size of subkey
+     * 
+     * @private
+     * @param {Integer} keySize
+     * @returns {Integer}
+     */
+    _getSubkeySize(keySize) {
+        return {
+            1024: 1024,
+            2048: 1024,
+            4096: 2048,
+            256:   256,
+            384:   256,
+        }[keySize];
+    },
+
+
+    KEY_TYPES: KEY_TYPES,
+
+    /**
+     * Validate PGP Key Type
+     * 
+     * @private
+     * @param {string} keyType
+     * @returns {string}
+     */
+    _validateKeyType(keyType) {
+        if (KEY_TYPES.indexOf(keyType) >= 0) return keyType.toLowerCase();
+        throw `Invalid key type ${keyType}, must be in ${JSON.stringify(KEY_TYPES)}`;
+    },
+
+    /**
+     * 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  = args[0],
+            keySize  = args[1],
+            password = args[2],
+            name     = args[3],
+            email    = args[4];
+
+        keyType = PGP._validateKeyType(keyType);
+        keySize = PGP._validateKeySize(keySize, keyType);
+
+        let userIdentifier = "";
+        if (name) userIdentifier += name;
+        if (email) userIdentifier += ` <${email}>`;
+
+        let flags = kbpgp.const.openpgp.certify_keys;
+        flags = flags | kbpgp.const.openpgp.sign_data;
+        flags = flags | kbpgp.const.openpgp.auth;
+        flags = flags | kbpgp.const.openpgp.encrypt_comm;
+        flags = 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
+            }],
+        };
+        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);
+            } catch (err) {
+                reject(`Error from kbpgp 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];
+
+        let key, encryptedMessage;
+
+        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,
+            });
+        } 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();
+
+        let plaintextMessage;
+        const key = await PGP._importPrivateKey(privateKey, passphrase);
+        keyring.add_key_manager(key);
+
+        try {
+            plaintextMessage = await promisify(kbpgp.unbox)({
+                armored: encryptedMessage,
+                keyfetch: keyring,
+            });
+        } 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];
+
+        let signedMessage;
+        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
+            });
+        } 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();
+
+        let unboxedLiterals;
+        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
+            });
+            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();
+                }
+            }
+        } catch (err) {
+            throw `Couldn't verify message: ${err}`;
+        }
+    },
+};
+
+export default PGP;