gracefully handle reformatting keys with no subkey packets

This commit is contained in:
Sanjana Rajan 2018-02-09 16:18:27 +01:00
parent 0a4e9461ca
commit 18e46ed6cf
2 changed files with 27 additions and 17 deletions

View File

@ -1272,6 +1272,9 @@ export function reformat(options) {
options.subkeyType = secretSubkeyPacket.algorithm; options.subkeyType = secretSubkeyPacket.algorithm;
} }
} }
if (!secretKeyPacket) {
throw new Error('Key does not contain a secret key packet');
}
return wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options); return wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options);
}); });
} }
@ -1280,7 +1283,9 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
// set passphrase protection // set passphrase protection
if (options.passphrase) { if (options.passphrase) {
secretKeyPacket.encrypt(options.passphrase); secretKeyPacket.encrypt(options.passphrase);
secretSubkeyPacket.encrypt(options.passphrase); if (secretSubkeyPacket) {
secretSubkeyPacket.encrypt(options.passphrase);
}
} }
var packetlist = new packet.List(); var packetlist = new packet.List();
@ -1336,26 +1341,30 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
}); });
}); });
var dataToSign = {}; if (secretSubkeyPacket) {
dataToSign.key = secretKeyPacket; var dataToSign = {};
dataToSign.bind = secretSubkeyPacket; dataToSign.key = secretKeyPacket;
var subkeySignaturePacket = new packet.Signature(); dataToSign.bind = secretSubkeyPacket;
subkeySignaturePacket.signatureType = enums.signature.subkey_binding; var subkeySignaturePacket = new packet.Signature();
subkeySignaturePacket.publicKeyAlgorithm = options.keyType; subkeySignaturePacket.signatureType = enums.signature.subkey_binding;
subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgo(secretSubkeyPacket); subkeySignaturePacket.publicKeyAlgorithm = options.keyType;
subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage]; subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgo(secretSubkeyPacket);
if (options.keyExpirationTime > 0) { subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage];
subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime; if (options.keyExpirationTime > 0) {
subkeySignaturePacket.keyNeverExpires = false; subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime;
} subkeySignaturePacket.keyNeverExpires = false;
await subkeySignaturePacket.sign(secretKeyPacket, dataToSign); }
await subkeySignaturePacket.sign(secretKeyPacket, dataToSign);
packetlist.push(secretSubkeyPacket); packetlist.push(secretSubkeyPacket);
packetlist.push(subkeySignaturePacket); packetlist.push(subkeySignaturePacket);
}
if (!options.unlocked) { if (!options.unlocked) {
secretKeyPacket.clearPrivateParams(); secretKeyPacket.clearPrivateParams();
secretSubkeyPacket.clearPrivateParams(); if (secretSubkeyPacket) {
secretSubkeyPacket.clearPrivateParams();
}
} }
return new Key(packetlist); return new Key(packetlist);

View File

@ -126,6 +126,7 @@ export function generateKey({ userIds=[], passphrase, numBits=2048, unlocked=fal
/** /**
* Reformats signature packets for a key and rewraps key object. * Reformats signature packets for a key and rewraps key object.
* @param {Key} privateKey private key to reformat
* @param {Array<Object>} userIds array of user IDs e.g. [{ name:'Phil Zimmermann', email:'phil@openpgp.org' }] * @param {Array<Object>} 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 {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 * @param {Boolean} unlocked (optional) If the returned secret part of the generated key is unlocked