From 18e46ed6cf466229e145e208b4b40e118bb55c24 Mon Sep 17 00:00:00 2001 From: Sanjana Rajan Date: Fri, 9 Feb 2018 16:18:27 +0100 Subject: [PATCH] gracefully handle reformatting keys with no subkey packets --- src/key.js | 43 ++++++++++++++++++++++++++----------------- src/openpgp.js | 1 + 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/key.js b/src/key.js index e1e095f3..4acc880c 100644 --- a/src/key.js +++ b/src/key.js @@ -1272,6 +1272,9 @@ export function reformat(options) { options.subkeyType = secretSubkeyPacket.algorithm; } } + if (!secretKeyPacket) { + throw new Error('Key does not contain a secret key packet'); + } return wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options); }); } @@ -1280,7 +1283,9 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) { // set passphrase protection if (options.passphrase) { secretKeyPacket.encrypt(options.passphrase); - secretSubkeyPacket.encrypt(options.passphrase); + if (secretSubkeyPacket) { + secretSubkeyPacket.encrypt(options.passphrase); + } } var packetlist = new packet.List(); @@ -1336,26 +1341,30 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) { }); }); - var dataToSign = {}; - dataToSign.key = secretKeyPacket; - dataToSign.bind = secretSubkeyPacket; - var subkeySignaturePacket = new packet.Signature(); - subkeySignaturePacket.signatureType = enums.signature.subkey_binding; - subkeySignaturePacket.publicKeyAlgorithm = options.keyType; - subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgo(secretSubkeyPacket); - subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage]; - if (options.keyExpirationTime > 0) { - subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime; - subkeySignaturePacket.keyNeverExpires = false; - } - await subkeySignaturePacket.sign(secretKeyPacket, dataToSign); + if (secretSubkeyPacket) { + var dataToSign = {}; + dataToSign.key = secretKeyPacket; + dataToSign.bind = secretSubkeyPacket; + var subkeySignaturePacket = new packet.Signature(); + subkeySignaturePacket.signatureType = enums.signature.subkey_binding; + subkeySignaturePacket.publicKeyAlgorithm = options.keyType; + subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgo(secretSubkeyPacket); + subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage]; + if (options.keyExpirationTime > 0) { + subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime; + subkeySignaturePacket.keyNeverExpires = false; + } + await subkeySignaturePacket.sign(secretKeyPacket, dataToSign); - packetlist.push(secretSubkeyPacket); - packetlist.push(subkeySignaturePacket); + packetlist.push(secretSubkeyPacket); + packetlist.push(subkeySignaturePacket); + } if (!options.unlocked) { secretKeyPacket.clearPrivateParams(); - secretSubkeyPacket.clearPrivateParams(); + if (secretSubkeyPacket) { + secretSubkeyPacket.clearPrivateParams(); + } } return new Key(packetlist); diff --git a/src/openpgp.js b/src/openpgp.js index 4f1651fb..2b38859f 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -126,6 +126,7 @@ export function generateKey({ userIds=[], passphrase, numBits=2048, unlocked=fal /** * Reformats signature packets for a key and rewraps key object. + * @param {Key} privateKey private key to reformat * @param {Array} userIds array of user IDs e.g. [{ name:'Phil Zimmermann', email:'phil@openpgp.org' }] * @param {String} passphrase (optional) The passphrase used to encrypt the resulting private key * @param {Boolean} unlocked (optional) If the returned secret part of the generated key is unlocked