diff --git a/src/core/operations/GeneratePGPKeyPair.mjs b/src/core/operations/GeneratePGPKeyPair.mjs index a26b5cc84b..e3fd674206 100644 --- a/src/core/operations/GeneratePGPKeyPair.mjs +++ b/src/core/operations/GeneratePGPKeyPair.mjs @@ -12,6 +12,7 @@ import { getSubkeySize, ASP } from "../lib/PGP.mjs"; import { cryptNotice } from "../lib/Crypt.mjs"; import * as es6promisify from "es6-promisify"; const promisify = es6promisify.default ? es6promisify.default.promisify : es6promisify.promisify; +const KEY_FLAGS = kbpgp.const.openpgp.key_flags; /** @@ -73,11 +74,11 @@ class GeneratePGPKeyPair extends Operation { 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 flags = KEY_FLAGS.certify_keys; + flags |= KEY_FLAGS.sign_data; + flags |= KEY_FLAGS.auth; + flags |= KEY_FLAGS.encrypt_comm; + flags |= KEY_FLAGS.encrypt_storage; const keyGenerationOptions = { userid: userIdentifier, @@ -89,11 +90,11 @@ class GeneratePGPKeyPair extends Operation { }, subkeys: [{ "nbits": getSubkeySize(keySize), - "flags": kbpgp.const.openpgp.sign_data, + "flags": KEY_FLAGS.sign_data, "expire_in": 86400 * 365 * 8 }, { "nbits": getSubkeySize(keySize), - "flags": kbpgp.const.openpgp.encrypt_comm | kbpgp.const.openpgp.encrypt_storage, + "flags": KEY_FLAGS.encrypt_comm | KEY_FLAGS.encrypt_storage, "expire_in": 86400 * 365 * 2 }], asp: ASP diff --git a/tests/node/index.mjs b/tests/node/index.mjs index f872f8f48f..52670d48a0 100644 --- a/tests/node/index.mjs +++ b/tests/node/index.mjs @@ -18,6 +18,7 @@ import { import TestRegister from "../lib/TestRegister.mjs"; import "./tests/nodeApi.mjs"; import "./tests/operations.mjs"; +import "./tests/PGP.mjs"; import "./tests/File.mjs"; import "./tests/Dish.mjs"; import "./tests/NodeDish.mjs"; diff --git a/tests/node/tests/PGP.mjs b/tests/node/tests/PGP.mjs new file mode 100644 index 0000000000..2a695ea3a2 --- /dev/null +++ b/tests/node/tests/PGP.mjs @@ -0,0 +1,69 @@ +/** + * PGP node tests. + * + * @author C85297 [95289555+C85297@users.noreply.github.com] + * @copyright Crown Copyright 2026 + * @license Apache-2.0 + */ + +import assert from "assert"; +import kbpgp from "kbpgp"; +import * as es6promisify from "es6-promisify"; + +import TestRegister from "../../lib/TestRegister.mjs"; +import it from "../assertionHandler.mjs"; +import GeneratePGPKeyPair from "../../../src/core/operations/GeneratePGPKeyPair.mjs"; + +const promisify = es6promisify.default ? es6promisify.default.promisify : es6promisify.promisify; + +const PUBLIC_KEY_BLOCK = /-----BEGIN PGP PUBLIC KEY BLOCK-----[\s\S]*-----END PGP PUBLIC KEY BLOCK-----/; + +/** + * Generate a PGP key pair and import the generated public key. + * + * @param {string} keyType + * @returns {Promise} + */ +async function generateAndImportPublicKey(keyType) { + const operation = new GeneratePGPKeyPair(); + const generatedKeyPair = await operation.run("", [ + keyType, + "", + "User", + "akb@notreal.gchq.gov.uk" + ]); + + const publicKey = generatedKeyPair.match(PUBLIC_KEY_BLOCK); + + assert(publicKey, "Generated key pair should contain an ASCII-armoured public key"); + + return promisify(kbpgp.KeyManager.import_from_armored_pgp)({ + armored: publicKey[0], + opts: { + "no_check_keys": true + } + }); +} + +TestRegister.addApiTests([ + it("Generate PGP Key Pair: ECC keys should include ECDSA signing and ECDH encryption subkeys", async () => { + const publicKey = await generateAndImportPublicKey("ECC-256"); + const subkeyAlgorithms = publicKey.subkeys.map(subkey => subkey.key.type); + + assert.strictEqual( + publicKey.primary.key.type, + kbpgp.const.openpgp.public_key_algorithms.ECDSA, + "Generated ECC PGP primary key should use ECDSA" + ); + + assert( + subkeyAlgorithms.includes(kbpgp.const.openpgp.public_key_algorithms.ECDSA), + "Generated ECC PGP key should include an ECDSA signing subkey" + ); + + assert( + subkeyAlgorithms.includes(kbpgp.const.openpgp.public_key_algorithms.ECDH), + "Generated ECC PGP key should include an ECDH encryption subkey" + ); + }) +]);