GeneratePGPKeyPair.mjs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * @author tlwr [toby@toby.codes]
  3. * @author Matt C [matt@artemisbot.uk]
  4. * @author n1474335 [n1474335@gmail.com]
  5. * @copyright Crown Copyright 2017
  6. * @license Apache-2.0
  7. */
  8. import Operation from "../Operation.mjs";
  9. import kbpgp from "kbpgp";
  10. import { getSubkeySize, ASP } from "../lib/PGP.mjs";
  11. import * as es6promisify from "es6-promisify";
  12. const promisify = es6promisify.default ? es6promisify.default.promisify : es6promisify.promisify;
  13. /**
  14. * Generate PGP Key Pair operation
  15. */
  16. class GeneratePGPKeyPair extends Operation {
  17. /**
  18. * GeneratePGPKeyPair constructor
  19. */
  20. constructor() {
  21. super();
  22. this.name = "Generate PGP Key Pair";
  23. this.module = "PGP";
  24. this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.";
  25. this.infoURL = "https://wikipedia.org/wiki/Pretty_Good_Privacy";
  26. this.inputType = "string";
  27. this.outputType = "string";
  28. this.args = [
  29. {
  30. "name": "Key type",
  31. "type": "option",
  32. "value": ["RSA-1024", "RSA-2048", "RSA-4096", "ECC-256", "ECC-384"]
  33. },
  34. {
  35. "name": "Password (optional)",
  36. "type": "string",
  37. "value": ""
  38. },
  39. {
  40. "name": "Name (optional)",
  41. "type": "string",
  42. "value": ""
  43. },
  44. {
  45. "name": "Email (optional)",
  46. "type": "string",
  47. "value": ""
  48. }
  49. ];
  50. }
  51. /**
  52. * @param {string} input
  53. * @param {Object[]} args
  54. * @returns {string}
  55. */
  56. async run(input, args) {
  57. const [keyType, keySize] = args[0].split("-"),
  58. password = args[1],
  59. name = args[2],
  60. email = args[3];
  61. let userIdentifier = "";
  62. if (name) userIdentifier += name;
  63. if (email) userIdentifier += ` <${email}>`;
  64. let flags = kbpgp.const.openpgp.certify_keys;
  65. flags |= kbpgp.const.openpgp.sign_data;
  66. flags |= kbpgp.const.openpgp.auth;
  67. flags |= kbpgp.const.openpgp.encrypt_comm;
  68. flags |= kbpgp.const.openpgp.encrypt_storage;
  69. const keyGenerationOptions = {
  70. userid: userIdentifier,
  71. ecc: keyType === "ecc",
  72. primary: {
  73. "nbits": keySize,
  74. "flags": flags,
  75. "expire_in": 0
  76. },
  77. subkeys: [{
  78. "nbits": getSubkeySize(keySize),
  79. "flags": kbpgp.const.openpgp.sign_data,
  80. "expire_in": 86400 * 365 * 8
  81. }, {
  82. "nbits": getSubkeySize(keySize),
  83. "flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage,
  84. "expire_in": 86400 * 365 * 2
  85. }],
  86. asp: ASP
  87. };
  88. return new Promise(async (resolve, reject) => {
  89. try {
  90. const unsignedKey = await promisify(kbpgp.KeyManager.generate)(keyGenerationOptions);
  91. await promisify(unsignedKey.sign.bind(unsignedKey))({});
  92. const signedKey = unsignedKey,
  93. privateKeyExportOptions = {};
  94. if (password) privateKeyExportOptions.passphrase = password;
  95. const privateKey = await promisify(signedKey.export_pgp_private.bind(signedKey))(privateKeyExportOptions);
  96. const publicKey = await promisify(signedKey.export_pgp_public.bind(signedKey))({});
  97. resolve(privateKey + "\n" + publicKey.trim());
  98. } catch (err) {
  99. reject(`Error whilst generating key pair: ${err}`);
  100. }
  101. });
  102. }
  103. }
  104. export default GeneratePGPKeyPair;