From 38508b33d12af382c8647ff8cc887e3885994543 Mon Sep 17 00:00:00 2001 From: Sanjana Rajan Date: Mon, 12 Mar 2018 23:17:07 +0100 Subject: [PATCH] if primary key is invalid, so are subkeys --- src/key.js | 87 ++++++++++++++++----------------------------- test/general/key.js | 2 +- 2 files changed, 32 insertions(+), 57 deletions(-) diff --git a/src/key.js b/src/key.js index 75fd19f6..166499cb 100644 --- a/src/key.js +++ b/src/key.js @@ -269,19 +269,20 @@ function isValidSigningKeyPacket(keyPacket, signature, date=new Date()) { */ Key.prototype.getSigningKeyPacket = async function (keyId=null, date=new Date()) { const primaryKey = this.primaryKey; - const primaryUser = await this.getPrimaryUser(date); - if (primaryUser && (!keyId || primaryKey.getKeyId().equals(keyId)) && - isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification, date) && - await this.verifyPrimaryKey(date)) { - return primaryKey; - } - for (let i = 0; i < this.subKeys.length; i++) { - if (!keyId || this.subKeys[i].subKey.getKeyId().equals(keyId)) { - // eslint-disable-next-line no-await-in-loop - await this.subKeys[i].verify(primaryKey, date); - for (let j = 0; j < this.subKeys[i].bindingSignatures.length; j++) { - if (isValidSigningKeyPacket(this.subKeys[i].subKey, this.subKeys[i].bindingSignatures[j], date)) { - return this.subKeys[i].subKey; + if (await this.verifyPrimaryKey(date) === enums.keyStatus.valid) { + const primaryUser = await this.getPrimaryUser(date); + if (primaryUser && (!keyId || primaryKey.getKeyId().equals(keyId)) && + isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification, date)) { + return primaryKey; + } + for (let i = 0; i < this.subKeys.length; i++) { + if (!keyId || this.subKeys[i].subKey.getKeyId().equals(keyId)) { + // eslint-disable-next-line no-await-in-loop + await this.subKeys[i].verify(primaryKey, date); + for (let j = 0; j < this.subKeys[i].bindingSignatures.length; j++) { + if (isValidSigningKeyPacket(this.subKeys[i].subKey, this.subKeys[i].bindingSignatures[j], date)) { + return this.subKeys[i].subKey; + } } } } @@ -314,25 +315,26 @@ function isValidEncryptionKeyPacket(keyPacket, signature, date=new Date()) { */ Key.prototype.getEncryptionKeyPacket = async function(keyId, date=new Date()) { const primaryKey = this.primaryKey; - // V4: by convention subkeys are preferred for encryption service - // V3: keys MUST NOT have subkeys - for (let i = 0; i < this.subKeys.length; i++) { - if (!keyId || this.subKeys[i].subKey.getKeyId().equals(keyId)) { - // eslint-disable-next-line no-await-in-loop - await this.subKeys[i].verify(primaryKey, date); - for (let j = 0; j < this.subKeys[i].bindingSignatures.length; j++) { - if (isValidEncryptionKeyPacket(this.subKeys[i].subKey, this.subKeys[i].bindingSignatures[j], date)) { - return this.subKeys[i].subKey; + if (await this.verifyPrimaryKey(date) === enums.keyStatus.valid) { + // V4: by convention subkeys are preferred for encryption service + // V3: keys MUST NOT have subkeys + for (let i = 0; i < this.subKeys.length; i++) { + if (!keyId || this.subKeys[i].subKey.getKeyId().equals(keyId)) { + // eslint-disable-next-line no-await-in-loop + await this.subKeys[i].verify(primaryKey, date); + for (let j = 0; j < this.subKeys[i].bindingSignatures.length; j++) { + if (isValidEncryptionKeyPacket(this.subKeys[i].subKey, this.subKeys[i].bindingSignatures[j], date)) { + return this.subKeys[i].subKey; + } } } } - } - // if no valid subkey for encryption, evaluate primary key - const primaryUser = await this.getPrimaryUser(date); - if (primaryUser && (!keyId || primaryKey.getKeyId().equals(keyId)) && - isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification, date) && - await this.verifyPrimaryKey(date)) { - return primaryKey; + // if no valid subkey for encryption, evaluate primary key + const primaryUser = await this.getPrimaryUser(date); + if (primaryUser && (!keyId || primaryKey.getKeyId().equals(keyId)) && + isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification, date)) { + return primaryKey; + } } return null; }; @@ -392,33 +394,6 @@ Key.prototype.isRevoked = async function(signature, key, date=new Date()) { ); }; -/** - * Returns a packetlist containing all verified public or private key packets matching keyId. - * If keyId is not present, returns all verified key packets starting with the primary key. - * Verification is in the context of given date. - * @param {type/keyid} keyId - * @param {Date} date Use the given date instead of the current time - * @returns {Promise} - * @async - */ -Key.prototype.verifyKeyPackets = async function(keyId=null, date=new Date()) { - const packets = new packet.List(); - const { primaryKey } = this; - if (await this.verifyPrimaryKey(date)) { - if (!keyId || primaryKey.getKeyId().equals(keyId)) { - packets.push(primaryKey); - } - } - await Promise.all(this.subKeys.map(async subKey => { - if (!keyId || subKey.subKey.getKeyId().equals(keyId)) { - if (await subKey.verify(primaryKey, date)) { - packets.push(subKey.subKey); - } - } - })); - return packets; -}; - /** * Verify primary key. Checks for revocation signatures, expiration time * and valid self signature diff --git a/test/general/key.js b/test/general/key.js index 2f25fde0..71282267 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -773,7 +773,7 @@ describe('Key', function() { const pubKey = pubKeys.keys[0]; expect(pubKey).to.exist; - const packetlist = new openpgp.packet.Packetlist(); + const packetlist = new openpgp.packet.List(); packetlist.read(openpgp.armor.decode(pub_sig_test).data);