From 68bf9e82973a046d8c94d8244f33d29f670cc78c Mon Sep 17 00:00:00 2001 From: Konstantinos Andrikopoulos Date: Wed, 12 May 2021 18:09:49 +0200 Subject: [PATCH] Add addSubkey utility function Add a utility function that can add subkeys to an existing PGP key. It supports both encrypted and unencrypted private keys. The specification of the subkeys is passed as-is to openpgp. --- lib/key/utils.js | 29 +++++++++++++++++++++++++++++ lib/pmcrypto.js | 3 ++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/key/utils.js b/lib/key/utils.js index aeb67248..f564fa53 100644 --- a/lib/key/utils.js +++ b/lib/key/utils.js @@ -1,6 +1,8 @@ import { openpgp } from '../openpgp'; import { serverTime } from '../serverTime'; import { DEFAULT_OFFSET } from '../constants'; +import { decryptPrivateKey } from './decrypt'; +import { encryptPrivateKey } from './encrypt'; // returns promise for generated RSA public and encrypted private keys export function generateKey({ passphrase, date = serverTime(), offset = DEFAULT_OFFSET, ...rest }) { @@ -165,3 +167,30 @@ export async function genPrivateEphemeralKey({ Curve, d, V, Fingerprint }) { false ); } + +/** + * Add subkeys to an existing private key + * + * @param{Object} Private key, passphrase, and additional options + * @param {String} The armored private key + * @param {String} The key passphrase if it is encrypted + * @param {Object} Options for subkey generation + * @retruns {String} The updated key in armored format + * @async + */ +export async function addSubkey({ armoredKey, passphrase = null, options}) { + var key; + if (passphrase !== null) { + key = await decryptPrivateKey(armoredKey, passphrase); + } else { + const read = await openpgp.key.readArmored(armoredKey); + key = read.keys[0]; + } + + const newKey = await key.addSubkey(options); + + if (passphrase !== null) { + return await encryptPrivateKey(newKey, passphrase); + } + return newKey.armor(); +} diff --git a/lib/pmcrypto.js b/lib/pmcrypto.js index b2bff1c0..2e8f4c1f 100644 --- a/lib/pmcrypto.js +++ b/lib/pmcrypto.js @@ -45,7 +45,8 @@ export { getMatchingKey, cloneKey, genPublicEphemeralKey, - genPrivateEphemeralKey + genPrivateEphemeralKey, + addSubkey } from './key/utils'; export { decryptPrivateKey, decryptSessionKey } from './key/decrypt';