From 9691dc9c99b5f343aea9e8cfa1f170221ea88124 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 21 Dec 2018 12:24:59 -0500 Subject: [PATCH] Fix getExpirationTime with capabilities and an expired signing subkey When the latest subkey with the requested capabilities is expired, and the primary key has the requested capabilities, return the primary key expiry instead. Also, change isExpired/isDataExpired to still return false at the date returned by getExpirationTime, so that the latter returns the last date that the key can still be used. --- src/key.js | 10 +++++++--- src/packet/signature.js | 2 +- src/util.js | 2 +- test/general/key.js | 11 +++++++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/key.js b/src/key.js index 7b98420f..5588b18c 100644 --- a/src/key.js +++ b/src/key.js @@ -510,13 +510,17 @@ Key.prototype.getExpirationTime = async function(capabilities, keyId, userId) { const sigExpiry = selfCert.getExpirationTime(); let expiry = keyExpiry < sigExpiry ? keyExpiry : sigExpiry; if (capabilities === 'encrypt' || capabilities === 'encrypt_sign') { - const encryptKey = await this.getEncryptionKey(keyId, null, userId); + const encryptKey = + await this.getEncryptionKey(keyId, expiry, userId) || + await this.getEncryptionKey(keyId, null, userId); if (!encryptKey) return null; const encryptExpiry = await encryptKey.getExpirationTime(this.keyPacket); if (encryptExpiry < expiry) expiry = encryptExpiry; } if (capabilities === 'sign' || capabilities === 'encrypt_sign') { - const signKey = await this.getSigningKey(keyId, null, userId); + const signKey = + await this.getSigningKey(keyId, expiry, userId) || + await this.getSigningKey(keyId, null, userId); if (!signKey) return null; const signExpiry = await signKey.getExpirationTime(this.keyPacket); if (signExpiry < expiry) expiry = signExpiry; @@ -1632,7 +1636,7 @@ function isDataExpired(keyPacket, signature, date=new Date()) { const normDate = util.normalizeDate(date); if (normDate !== null) { const expirationTime = getExpirationTime(keyPacket, signature); - return !(keyPacket.created <= normDate && normDate < expirationTime) || + return !(keyPacket.created <= normDate && normDate <= expirationTime) || (signature && signature.isExpired(date)); } return false; diff --git a/src/packet/signature.js b/src/packet/signature.js index bd78c8f3..249e3a6e 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -727,7 +727,7 @@ Signature.prototype.isExpired = function (date=new Date()) { const normDate = util.normalizeDate(date); if (normDate !== null) { const expirationTime = this.getExpirationTime(); - return !(this.created <= normDate && normDate < expirationTime); + return !(this.created <= normDate && normDate <= expirationTime); } return false; }; diff --git a/src/util.js b/src/util.js index 584394e5..dbc8de3f 100644 --- a/src/util.js +++ b/src/util.js @@ -165,7 +165,7 @@ export default { }, normalizeDate: function (time = Date.now()) { - return time === null ? time : new Date(Math.floor(+time / 1000) * 1000); + return time === null || time === Infinity ? time : new Date(Math.floor(+time / 1000) * 1000); }, /** diff --git a/test/general/key.js b/test/general/key.js index 71c7789a..8e1d8fbf 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -1983,12 +1983,23 @@ describe('Key', function() { const pubKey = (await openpgp.key.readArmored(priv_key_2000_2008)).keys[0]; expect(pubKey).to.exist; expect(pubKey).to.be.an.instanceof(openpgp.key.Key); + pubKey.users[0].selfCertifications[0].keyFlags = [1]; const expirationTime = await pubKey.getExpirationTime(); expect(expirationTime).to.equal(Infinity); const encryptExpirationTime = await pubKey.getExpirationTime('encrypt_sign'); expect(encryptExpirationTime.toISOString()).to.equal('2008-02-12T17:12:08.000Z'); }); + it('Method getExpirationTime V4 Key with capabilities - capable primary key', async function() { + const pubKey = (await openpgp.key.readArmored(priv_key_2000_2008)).keys[0]; + expect(pubKey).to.exist; + expect(pubKey).to.be.an.instanceof(openpgp.key.Key); + const expirationTime = await pubKey.getExpirationTime(); + expect(expirationTime).to.equal(Infinity); + const encryptExpirationTime = await pubKey.getExpirationTime('encrypt_sign'); + expect(encryptExpirationTime).to.equal(Infinity); + }); + it('update() - throw error if fingerprints not equal', async function() { const keys = (await openpgp.key.readArmored(twoKeys)).keys; await expect(keys[0].update.bind(