diff --git a/src/key.js b/src/key.js index 7c8d7293..71e23c71 100644 --- a/src/key.js +++ b/src/key.js @@ -188,13 +188,9 @@ Key.prototype.getKeyIds = function() { * @returns {Array} array of userids */ Key.prototype.getUserIds = function() { - const userids = []; - for (let i = 0; i < this.users.length; i++) { - if (this.users[i].userId) { - userids.push(util.Uint8Array_to_str(this.users[i].userId.write())); - } - } - return userids; + return this.users.map(user => { + return user.userId ? util.encode_utf8(user.userId.userid) : null; + }).filter(userid => userid !== null); }; /** @@ -254,33 +250,34 @@ Key.prototype.armor = function() { }; function isValidSigningKeyPacket(keyPacket, signature, date=new Date()) { - const normDate = util.normalizeDate(date); return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsa_encrypt) && keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.elgamal) && keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdh) && (!signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.sign_data) !== 0) && - signature.verified && !signature.revoked && !signature.isExpired(normDate) && - (normDate === null || (keyPacket.created <= normDate && normDate < getExpirationTime(keyPacket, signature, Infinity))); + signature.verified && !signature.revoked && !signature.isExpired(date) && + !isDataExpired(keyPacket, signature, date); } /** * Returns first key packet or key packet by given keyId that is available for signing and verification - * - * NOTE: call verifyKeyPackets before calling this function. * @param {module:type/keyid} keyId, optional * @param {Date} date use the given date for verification instead of the current time * @returns {(module:packet/secret_subkey| module:packet/secret_key|null)} key packet or null if no signing key has been found */ -Key.prototype.getSigningKeyPacket = function (keyId=null, date=new Date()) { - const primaryUser = this.getPrimaryUser(date); - if (primaryUser && (!keyId || this.primaryKey.getKeyId().equals(keyId)) && - isValidSigningKeyPacket(this.primaryKey, primaryUser.selfCertificate, date)) { - return this.primaryKey; +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; @@ -288,7 +285,6 @@ Key.prototype.getSigningKeyPacket = function (keyId=null, date=new Date()) { } } } - // TODO how to throw descriptive error? return null; }; @@ -301,14 +297,12 @@ function isValidEncryptionKeyPacket(keyPacket, signature, date=new Date()) { (!signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.encrypt_communication) !== 0 || (signature.keyFlags[0] & enums.keyFlags.encrypt_storage) !== 0) && - signature.verified && !signature.revoked && !signature.isExpired(normDate) && - (normDate === null || (keyPacket.created <= normDate && normDate < getExpirationTime(keyPacket, signature, Infinity))); + signature.verified && !signature.revoked && !signature.isExpired(date) && + !isDataExpired(keyPacket, signature, date); } /** * Returns first key packet or key packet by given keyId that is available for encryption or decryption - * - * NOTE: call verifyKeyPackets before calling this function. * @param {module:type/keyid} keyId, optional * @param {Date} date, optional * @returns {(module:packet/public_subkey| @@ -316,11 +310,14 @@ function isValidEncryptionKeyPacket(keyPacket, signature, date=new Date()) { * module:packet/secret_key| * module:packet/public_key|null)} key packet or null if no encryption key has been found */ -Key.prototype.getEncryptionKeyPacket = function(keyId, 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; @@ -329,12 +326,12 @@ Key.prototype.getEncryptionKeyPacket = function(keyId, date=new Date()) { } } // if no valid subkey for encryption, evaluate primary key - const primaryUser = this.getPrimaryUser(date); - if (primaryUser && (!keyId || this.primaryKey.getKeyId().equals(keyId)) && - isValidEncryptionKeyPacket(this.primaryKey, primaryUser.selfCertificate, date)) { - return this.primaryKey; + const primaryUser = await this.getPrimaryUser(date); + if (primaryUser && (!keyId || primaryKey.getKeyId().equals(keyId)) && + isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification, date) && + await this.verifyPrimaryKey(date)) { + return primaryKey; } - // TODO how to throw descriptive error? return null; }; @@ -423,37 +420,26 @@ Key.prototype.verifyKeyPackets = async function(keyId=null, date=new Date()) { * @returns {Promise} The status of the primary key */ Key.prototype.verifyPrimaryKey = async function(date=new Date()) { + const primaryKey = this.primaryKey; // check for key revocation signatures if (await this.isRevoked(null, null, date)) { return enums.keyStatus.revoked; } - const creationTime = this.primaryKey.created.getTime(); - const currentTime = util.normalizeDate(date); - // check V3 expiration time - if (date !== null && this.primaryKey.version === 3) { - const expirationTimeV3 = creationTime + (this.primaryKey.expirationTimeV3*24*3600*1000 || Infinity); - if (!(creationTime <= currentTime && currentTime < expirationTimeV3)) { - return enums.keyStatus.expired; - } - } // check for at least one self signature. Self signature of user ID not mandatory // See {@link https://tools.ietf.org/html/rfc4880#section-11.1} if (!this.users.some(user => user.userId && user.selfCertifications.length)) { return enums.keyStatus.no_self_cert; } - // check for valid self signature - await this.verifyPrimaryUser(); - const primaryUser = this.getPrimaryUser(date); - if (!primaryUser) { + // check for valid, unrevoked, unexpired self signature + const { user, selfCertification } = await this.getPrimaryUser(date); + if (!user) { return enums.keyStatus.invalid; } - // check V4 expiration time - if (date !== null && this.primaryKey.version === 4) { - const expirationTime = primaryUser.selfCertificate.keyNeverExpires === false ? - creationTime + primaryUser.selfCertificate.keyExpirationTime*1000 : Infinity; - if (!(creationTime <= currentTime && currentTime < expirationTime)) { - return enums.keyStatus.expired; - } + // check for expiration time + const currentTime = util.normalizeDate(date); + if ((primaryKey.version === 3 && isDataExpired(primaryKey, null, date)) || + (primaryKey.version === 4 && isDataExpired(primaryKey, selfCertification, date))) { + return enums.keyStatus.expired; } return enums.keyStatus.valid; }; @@ -462,64 +448,46 @@ Key.prototype.verifyPrimaryKey = async function(date=new Date()) { * Returns the expiration time of the primary key or null if key does not expire * @returns {Date|null} */ -Key.prototype.getExpirationTime = function() { +Key.prototype.getExpirationTime = async function() { if (this.primaryKey.version === 3) { return getExpirationTime(this.primaryKey); } if (this.primaryKey.version === 4) { - const primaryUser = this.getPrimaryUser(); + const primaryUser = await this.getPrimaryUser(); if (!primaryUser) { return null; } - return getExpirationTime(this.primaryKey, primaryUser.selfCertificate); + return getExpirationTime(this.primaryKey, primaryUser.selfCertification); } }; - -function getExpirationTime(keyPacket, selfCertificate, defaultValue=null) { - // check V3 expiration time - if (keyPacket.version === 3 && keyPacket.expirationTimeV3 !== 0) { - return new Date(keyPacket.created.getTime() + keyPacket.expirationTimeV3*24*3600*1000); - } - // check V4 expiration time - if (keyPacket.version === 4 && selfCertificate.keyNeverExpires === false) { - return new Date(keyPacket.created.getTime() + selfCertificate.keyExpirationTime*1000); - } - return defaultValue; -} - /** * Returns primary user and most significant (latest valid) self signature * - if multiple primary users exist, returns the one with the latest self signature * - otherwise, returns the user with the latest self signature - * - * NOTE: call verifyPrimaryUser before calling this function. - * This is because getPrimaryUser isn't async, so it cannot validate and instead - * relies on already validated certificates. * @param {Date} date use the given date for verification instead of the current time - * @returns {{user: Array, selfCertificate: Array}|null} The primary user and the self signature + * @returns {{user: Array, selfCertification: Array}|null} The primary user and the self signature */ -Key.prototype.getPrimaryUser = function(date=new Date()) { +Key.prototype.getPrimaryUser = async function(date=new Date()) { + // FIXME + await this.verifyPrimaryUser(); let primaryUsers = []; - for (let i = 0; i < this.users.length; i++) { - // here we only check the primary user ID, ignoring the primary user attribute - if (!this.users[i].userId || !this.users[i].selfCertifications.length) { - continue; + this.users.forEach((user, i) => { + if (!user.userId) { + return; } - for (let j = 0; j < this.users[i].selfCertifications.length; j++) { + user.selfCertifications.forEach(cert => { // only consider already validated certificates - if (!this.users[i].selfCertifications[j].verified || - this.users[i].selfCertifications[j].revoked || - this.users[i].selfCertifications[j].isExpired(date)) { - continue; + if (!cert.verified || cert.revoked || cert.isExpired(date)) { + return; } - primaryUsers.push({ index: i, user: this.users[i], selfCertificate: this.users[i].selfCertifications[j] }); - } - } + primaryUsers.push({ index: i, user: user, selfCertification: cert }); + }); + }); // sort by primary user flag and signature creation time primaryUsers = primaryUsers.sort(function(a, b) { - const A = a.selfCertificate; - const B = b.selfCertificate; + const A = a.selfCertification; + const B = b.selfCertification; return (B.isPrimaryUserID - A.isPrimaryUserID) || (B.created - A.created); }); return primaryUsers.pop(); @@ -629,8 +597,7 @@ Key.prototype.revoke = function() { * @returns {Promise} new public key with new certificate signature */ Key.prototype.signPrimaryUser = async function(privateKeys) { - await this.verifyPrimaryUser(); - const { index, user } = this.getPrimaryUser() || {}; + const { index, user } = await this.getPrimaryUser() || {}; if (!user) { throw new Error('Could not find primary user'); } @@ -668,34 +635,32 @@ Key.prototype.verifyPrimaryUser = async function(keys) { let lastCreated = null; let lastPrimaryUserID = null; await Promise.all(this.users.map(async function(user) { - // here we verify both the primary user ID or the primary user attribute - if (!(user.userId || user.userAttribute) || !user.selfCertifications.length) { + if (!user.userId && !user.userAttribute) { return; } const dataToVerify = { userid: user.userId || user.userAttribute, key: primaryKey }; // TODO replace when Promise.forEach is implemented for (let i = 0; i < user.selfCertifications.length; i++) { - const selfCertification = user.selfCertifications[i]; + const cert = user.selfCertifications[i]; // skip if certificate is not the most recent - if ((selfCertification.isPrimaryUserID && - selfCertification.isPrimaryUserID < lastPrimaryUserID) || - (!lastPrimaryUserID && selfCertification.created < lastCreated)) { + if ((cert.isPrimaryUserID && cert.isPrimaryUserID < lastPrimaryUserID) || + (!lastPrimaryUserID && cert.created < lastCreated)) { return; } // skip if certificates is invalid, revoked, or expired // eslint-disable-next-line no-await-in-loop - if (!(selfCertification.verified || await selfCertification.verify(primaryKey, dataToVerify))) { + if (!(cert.verified || await cert.verify(primaryKey, dataToVerify))) { return; } // eslint-disable-next-line no-await-in-loop - if (selfCertification.revoked || await user.isRevoked(primaryKey, selfCertification)) { + if (cert.revoked || await user.isRevoked(primaryKey, cert)) { return; } - if (selfCertification.isExpired()) { + if (cert.isExpired()) { return; } - lastPrimaryUserID = selfCertification.isPrimaryUserID; - lastCreated = selfCertification.created; + lastPrimaryUserID = cert.isPrimaryUserID; + lastCreated = cert.created; primaryUsers.push(user); } })); @@ -776,11 +741,10 @@ User.prototype.sign = async function(primaryKey, privateKeys) { if (privateKey.primaryKey.getFingerprint() === primaryKey.getFingerprint()) { throw new Error('Not implemented for self signing'); } - await privateKey.verifyKeyPackets(); - const signingKeyPacket = privateKey.getSigningKeyPacket(); + const signingKeyPacket = await privateKey.getSigningKeyPacket(); if (!signingKeyPacket) { - throw new Error(`Could not find valid signing key packet in key ${ - privateKey.primaryKey.getKeyId().toHex()}`); + throw new Error('Could not find valid signing key packet in key ' + + privateKey.primaryKey.getKeyId().toHex()); } if (!signingKeyPacket.isDecrypted) { throw new Error('Private key is not decrypted.'); @@ -790,7 +754,7 @@ User.prototype.sign = async function(primaryKey, privateKeys) { signaturePacket.signatureType = enums.write(enums.signature, enums.signature.cert_generic); signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data]; signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; - signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey); + signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey); signaturePacket.signingKeyId = signingKeyPacket.getKeyId(); signaturePacket.sign(signingKeyPacket, dataToSign); return signaturePacket; @@ -835,8 +799,7 @@ User.prototype.verifyCertificate = async function(primaryKey, certificate, keys, const dataToVerify = { userid: this.userId || this.userAttribute, key: primaryKey }; const results = await Promise.all(keys.map(async function(key) { if (!key.getKeyIds().some(id => id.equals(keyid))) { return; } - await key.verifyKeyPackets(); - const keyPacket = key.getSigningKeyPacket(keyid, date); + const keyPacket = await key.getSigningKeyPacket(keyid, date); if (certificate.revoked || await that.isRevoked(primaryKey, certificate, keyPacket)) { return enums.keyStatus.revoked; } @@ -979,17 +942,12 @@ SubKey.prototype.isRevoked = async function(primaryKey, signature, key, date=new SubKey.prototype.verify = async function(primaryKey, date=new Date()) { const that = this; const dataToVerify = { key: primaryKey, bind: this.subKey }; - const creationTime = this.subKey.created.getTime(); - const currentTime = util.normalizeDate(date); - // check V3 expiration time - if (currentTime !== null && this.subKey.version === 3) { - const expirationTime = creationTime + (this.subKey.expirationTimeV3*24*3600*1000 || Infinity); - if (!(creationTime <= currentTime && currentTime < expirationTime)) { - return enums.keyStatus.expired; - } + // check for V3 expiration time + if (this.subKey.version === 3 && isDataExpired(this.subKey, null, date)) { + return enums.keyStatus.expired; } - // check subkey binding signatures (at least one valid binding sig needed) - // TODO replace when Promise.some or Promise.any are implemented + // check subkey binding signatures + // note: binding signatures can have different keyFlags, so we verify all. const results = [enums.keyStatus.invalid].concat( await Promise.all(this.bindingSignatures.map(async function(bindingSignature) { // check binding signature is verified @@ -1000,18 +958,10 @@ SubKey.prototype.verify = async function(primaryKey, date=new Date()) { if (bindingSignature.revoked || await that.isRevoked(primaryKey, bindingSignature, null, date)) { return enums.keyStatus.revoked; } - // check binding signature is not expired + // check binding signature is not expired (ie, check for V4 expiration time) if (bindingSignature.isExpired(date)) { return enums.keyStatus.expired; } - // check V4 expiration time - if (that.subKey.version === 4 && currentTime !== null) { - const expirationTime = bindingSignature.keyNeverExpires === false ? - (creationTime + bindingSignature.keyExpirationTime*1000) : Infinity; - if (!(creationTime <= currentTime && currentTime < expirationTime)) { - return enums.keyStatus.expired; // last V4 expired binding signature - } - } return enums.keyStatus.valid; // found a binding signature that passed all checks })) ); @@ -1284,7 +1234,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) { const signaturePacket = new packet.Signature(); signaturePacket.signatureType = enums.signature.cert_generic; signaturePacket.publicKeyAlgorithm = options.keyType; - signaturePacket.hashAlgorithm = getPreferredHashAlgo(secretKeyPacket); + signaturePacket.hashAlgorithm = await getPreferredHashAlgo(secretKeyPacket); signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data]; signaturePacket.preferredSymmetricAlgorithms = []; // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support) @@ -1329,7 +1279,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) { const subkeySignaturePacket = new packet.Signature(); subkeySignaturePacket.signatureType = enums.signature.subkey_binding; subkeySignaturePacket.publicKeyAlgorithm = options.keyType; - subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgo(secretSubkeyPacket); + subkeySignaturePacket.hashAlgorithm = await getPreferredHashAlgo(secretSubkeyPacket); subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage]; if (options.keyExpirationTime > 0) { subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime; @@ -1387,18 +1337,41 @@ async function isDataRevoked(primaryKey, dataToVerify, revocations, signature, k return revocationKeyIds.length > 0; } +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) || + (signature && signature.isExpired(date)); + } + return false; +} + +function getExpirationTime(keyPacket, signature) { + let expirationTime; + // check V3 expiration time + if (keyPacket.version === 3 && keyPacket.expirationTimeV3 !== 0) { + expirationTime = keyPacket.created.getTime() + keyPacket.expirationTimeV3*24*3600*1000; + } + // check V4 expiration time + if (keyPacket.version === 4 && signature.keyNeverExpires === false) { + expirationTime = signature.created.getTime() + signature.keyExpirationTime*1000; + } + return expirationTime ? new Date(expirationTime) : Infinity; +} + /** * Returns the preferred signature hash algorithm of a key * @param {object} key * @returns {String} */ -export function getPreferredHashAlgo(key) { +export async function getPreferredHashAlgo(key) { let hash_algo = config.prefer_hash_algorithm; let pref_algo = hash_algo; if (key instanceof Key) { - const primaryUser = key.getPrimaryUser(); - if (primaryUser && primaryUser.selfCertificate.preferredHashAlgorithms) { - [pref_algo] = primaryUser.selfCertificate.preferredHashAlgorithms; + const primaryUser = await key.getPrimaryUser(); + if (primaryUser && primaryUser.selfCertification.preferredHashAlgorithms) { + [pref_algo] = primaryUser.selfCertification.preferredHashAlgorithms; hash_algo = crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ? pref_algo : hash_algo; } @@ -1426,19 +1399,19 @@ export function getPreferredHashAlgo(key) { * @param {Array} keys Set of keys * @returns {enums.symmetric} Preferred symmetric algorithm */ -export function getPreferredSymAlgo(keys) { +export async function getPreferredSymAlgo(keys) { const prioMap = {}; - keys.forEach(function(key) { - const primaryUser = key.getPrimaryUser(); - if (!primaryUser || !primaryUser.selfCertificate.preferredSymmetricAlgorithms) { + await Promise.all(keys.map(async function(key) { + const primaryUser = await key.getPrimaryUser(); + if (!primaryUser || !primaryUser.selfCertification.preferredSymmetricAlgorithms) { return config.encryption_cipher; } - primaryUser.selfCertificate.preferredSymmetricAlgorithms.forEach(function(algo, index) { + primaryUser.selfCertification.preferredSymmetricAlgorithms.forEach(function(algo, index) { const entry = prioMap[algo] || (prioMap[algo] = { prio: 0, count: 0, algo: algo }); entry.prio += 64 >> index; entry.count++; }); - }); + })); let prefAlgo = { prio: 0, algo: config.encryption_cipher }; for (const algo in prioMap) { try { diff --git a/src/message.js b/src/message.js index dcfe0836..0ce048b9 100644 --- a/src/message.js +++ b/src/message.js @@ -253,7 +253,7 @@ Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard symAlgo = sessionKey.algorithm; sessionKey = sessionKey.data; } else if (keys && keys.length) { - symAlgo = enums.read(enums.symmetric, getPreferredSymAlgo(keys)); + symAlgo = enums.read(enums.symmetric, await getPreferredSymAlgo(keys)); } else if (passwords && passwords.length) { symAlgo = enums.read(enums.symmetric, config.encryption_cipher); } else { @@ -303,8 +303,7 @@ export async function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwor if (publicKeys) { const results = await Promise.all(publicKeys.map(async function(publicKey) { - await publicKey.verifyKeyPackets(undefined, date); - const encryptionKeyPacket = publicKey.getEncryptionKeyPacket(undefined, date); + const encryptionKeyPacket = await publicKey.getEncryptionKeyPacket(undefined, date); if (!encryptionKeyPacket) { throw new Error('Could not find valid key packet for encryption in key ' + publicKey.primaryKey.getKeyId().toHex()); @@ -397,15 +396,14 @@ Message.prototype.sign = async function(privateKeys=[], signature=null, date=new if (privateKey.isPublic()) { throw new Error('Need private key for signing'); } - await privateKey.verifyKeyPackets(undefined, date); - const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date); + const signingKeyPacket = await privateKey.getSigningKeyPacket(undefined, date); if (!signingKeyPacket) { throw new Error('Could not find valid key packet for signing in key ' + privateKey.primaryKey.getKeyId().toHex()); } const onePassSig = new packet.OnePassSignature(); onePassSig.type = signatureType; - onePassSig.hashAlgorithm = getPreferredHashAlgo(privateKey); + onePassSig.hashAlgorithm = await getPreferredHashAlgo(privateKey); onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm; onePassSig.signingKeyId = signingKeyPacket.getKeyId(); if (i === privateKeys.length - 1) { @@ -476,8 +474,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig if (privateKey.isPublic()) { throw new Error('Need private key for signing'); } - await privateKey.verifyKeyPackets(undefined, date); - const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date); + const signingKeyPacket = await privateKey.getSigningKeyPacket(undefined, date); if (!signingKeyPacket) { throw new Error('Could not find valid key packet for signing in key ' + privateKey.primaryKey.getKeyId().toHex()); @@ -488,7 +485,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig const signaturePacket = new packet.Signature(date); signaturePacket.signatureType = signatureType; signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; - signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey); + signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey); await signaturePacket.sign(signingKeyPacket, literalDataPacket); return signaturePacket; })).then(signatureList => { @@ -550,8 +547,7 @@ export async function createVerificationObjects(signatureList, literalDataList, let keyPacket = null; await Promise.all(keys.map(async function(key) { // Look for the unique key packet that matches issuerKeyId of signature - await key.verifyKeyPackets(signature.issuerKeyId, date); - const result = key.getSigningKeyPacket(signature.issuerKeyId, date); + const result = await key.getSigningKeyPacket(signature.issuerKeyId, date); if (result) { keyPacket = result; } diff --git a/src/packet/signature.js b/src/packet/signature.js index d2bf41ef..8f405adf 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -667,9 +667,9 @@ Signature.prototype.verify = async function (key, data) { * @return {Boolean} true if expired */ Signature.prototype.isExpired = function (date=new Date()) { - if (date !== null) { + const normDate = util.normalizeDate(date); + if (normDate !== null) { const expirationTime = !this.signatureNeverExpires ? this.created.getTime() + this.signatureExpirationTime*1000 : Infinity; - const normDate = util.normalizeDate(date); return !(this.created <= normDate && normDate < expirationTime); } return false; diff --git a/test/general/key.js b/test/general/key.js index 56be6152..c9d36904 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -761,7 +761,7 @@ describe('Key', function() { )).to.eventually.equal(openpgp.enums.keyStatus.revoked).notify(done); }); - it('Evaluate key flags to find valid encryption key packet', function() { + it('Evaluate key flags to find valid encryption key packet', async function() { const pubKeys = openpgp.key.readArmored(pub_sig_test); expect(pubKeys).to.exist; expect(pubKeys.err).to.not.exist; @@ -771,24 +771,25 @@ describe('Key', function() { // remove subkeys pubKey.subKeys = []; // primary key has only key flags for signing - const keyPacket = pubKey.getEncryptionKeyPacket(); + await pubKey.verifyKeyPackets(); + const keyPacket = await pubKey.getEncryptionKeyPacket(); expect(keyPacket).to.not.exist; }); - it('Method getExpirationTime V4 Key', function() { + it('Method getExpirationTime V4 Key', async function() { const pubKey = openpgp.key.readArmored(twoKeys).keys[1]; expect(pubKey).to.exist; expect(pubKey).to.be.an.instanceof(openpgp.key.Key); - return pubKey.verifyPrimaryUser().then(() => { - expect(pubKey.getExpirationTime().toISOString()).to.be.equal('2018-11-26T10:58:29.000Z'); - }); + const expirationTime = await pubKey.getExpirationTime(); + expect(expirationTime.toISOString()).to.be.equal('2018-11-26T10:58:29.000Z'); }); - it('Method getExpirationTime V4 SubKey', function() { + it('Method getExpirationTime V4 SubKey', async function() { const pubKey = openpgp.key.readArmored(twoKeys).keys[1]; expect(pubKey).to.exist; expect(pubKey).to.be.an.instanceof(openpgp.key.Key); - expect(pubKey.subKeys[0].getExpirationTime().toISOString()).to.be.equal('2018-11-26T10:58:29.000Z'); + const expirationTime = await pubKey.subKeys[0].getExpirationTime(); + expect(expirationTime.toISOString()).to.be.equal('2018-11-26T10:58:29.000Z'); }); it('update() - throw error if fingerprints not equal', function(done) { @@ -926,34 +927,30 @@ describe('Key', function() { }); }); - it('getPreferredSymAlgo() - one key - AES256', function() { + it('getPreferredSymAlgo() - one key - AES256', async function() { const key1 = openpgp.key.readArmored(twoKeys).keys[0]; - return key1.verifyPrimaryUser().then(() => { - const prefAlgo = openpgp.key.getPreferredSymAlgo([key1]); - expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256); - }); + const prefAlgo = await openpgp.key.getPreferredSymAlgo([key1]); + expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256); }); - it('getPreferredSymAlgo() - two key - AES128', function() { + it('getPreferredSymAlgo() - two key - AES128', async function() { const keys = openpgp.key.readArmored(twoKeys).keys; const key1 = keys[0]; const key2 = keys[1]; - return Promise.all([key1.verifyPrimaryUser(), key2.verifyPrimaryUser()]).then(() => { - key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = [6,7,3]; - const prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]); - expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128); - }); + const primaryUser = await key2.getPrimaryUser(); + primaryUser.selfCertification.preferredSymmetricAlgorithms = [6,7,3]; + const prefAlgo = await openpgp.key.getPreferredSymAlgo([key1, key2]); + expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128); }); - it('getPreferredSymAlgo() - two key - one without pref', function() { + it('getPreferredSymAlgo() - two key - one without pref', async function() { const keys = openpgp.key.readArmored(twoKeys).keys; const key1 = keys[0]; const key2 = keys[1]; - return Promise.all([key1.verifyPrimaryUser(), key2.verifyPrimaryUser()]).then(() => { - key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = null; - const prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]); - expect(prefAlgo).to.equal(openpgp.config.encryption_cipher); - }); + const primaryUser = await key2.getPrimaryUser(); + primaryUser.selfCertification.preferredSymmetricAlgorithms = null; + const prefAlgo = await openpgp.key.getPreferredSymAlgo([key1, key2]); + expect(prefAlgo).to.equal(openpgp.config.encryption_cipher); }); it('Preferences of generated key', function() { @@ -986,14 +983,12 @@ describe('Key', function() { expect(key.users[1].userAttribute).eql(key2.users[1].userAttribute); }); - it('getPrimaryUser()', function() { + it('getPrimaryUser()', async function() { const key = openpgp.key.readArmored(pub_sig_test).keys[0]; - return key.verifyPrimaryUser().then(() => { - const primUser = key.getPrimaryUser(); - expect(primUser).to.exist; - expect(primUser.user.userId.userid).to.equal('Signature Test '); - expect(primUser.selfCertificate).to.be.an.instanceof(openpgp.packet.Signature); - }); + const primUser = await key.getPrimaryUser(); + expect(primUser).to.exist; + expect(primUser.user.userId.userid).to.equal('Signature Test '); + expect(primUser.selfCertification).to.be.an.instanceof(openpgp.packet.Signature); }); it('Generated key is not unlocked by default', function() { @@ -1001,10 +996,10 @@ describe('Key', function() { if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys let key; return openpgp.generateKey(opt).then(function(newKey) { - key = newKey; - return openpgp.message.fromText('hello').encrypt([key.key]); + key = newKey.key; + return openpgp.message.fromText('hello').encrypt([key]); }).then(function(msg) { - return msg.message.decrypt([key.key]); + return msg.message.decrypt([key]); }).catch(function(err) { expect(err.message).to.equal('Private key is not decrypted.'); }); @@ -1061,113 +1056,99 @@ describe('Key', function() { const userId = 'test '; const opt = {numBits: 512, userIds: userId, passphrase: '123', keyExpirationTime: expect_delta}; if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys - return openpgp.generateKey(opt).then(function(key) { + return openpgp.generateKey(opt).then(async function(key) { key = key.key; - return key.verifyPrimaryUser().then(() => { - const expiration = key.getExpirationTime(); - expect(expiration).to.exist; + const expiration = await key.getExpirationTime(); + expect(expiration).to.exist; - const actual_delta = (new Date(expiration) - new Date()) / 1000; - expect(Math.abs(actual_delta - expect_delta)).to.be.below(60); + const actual_delta = (new Date(expiration) - new Date()) / 1000; + expect(Math.abs(actual_delta - expect_delta)).to.be.below(60); - const subKeyExpiration = key.subKeys[0].getExpirationTime(); - expect(subKeyExpiration).to.exist; + const subKeyExpiration = await key.subKeys[0].getExpirationTime(); + expect(subKeyExpiration).to.exist; - const actual_subKeyDelta = (new Date(subKeyExpiration) - new Date()) / 1000; - expect(Math.abs(actual_subKeyDelta - expect_delta)).to.be.below(60); - }); + const actual_subKeyDelta = (new Date(subKeyExpiration) - new Date()) / 1000; + expect(Math.abs(actual_subKeyDelta - expect_delta)).to.be.below(60); }); }); - it('Sign and verify key - primary user', function() { - const key = openpgp.key.readArmored(pub_sig_test).keys[0]; + it('Sign and verify key - primary user', async function() { + let publicKey = openpgp.key.readArmored(pub_sig_test).keys[0]; const privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; - privateKey.decrypt('hello world'); - return key.signPrimaryUser([privateKey]).then(key => { - return Promise.all( - [key.verifyPrimaryUser([privateKey]), privateKey.verifyPrimaryUser()] - ).then(results => { - const signatures = results[0]; - expect(signatures.length).to.equal(2); - expect(signatures[0].keyid.toHex()).to.equal(key.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[0].valid).to.be.null; - expect(signatures[1].keyid.toHex()).to.equal(privateKey.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[1].valid).to.be.true; - }); - }); + await privateKey.decrypt('hello world'); + publicKey = await publicKey.signPrimaryUser([privateKey]); + const signatures = await publicKey.verifyPrimaryUser([privateKey]); + const publicKeyPacket = await publicKey.getSigningKeyPacket(); + const privateKeyPacket = await privateKey.getSigningKeyPacket(); + expect(signatures.length).to.equal(2); + expect(signatures[0].keyid.toHex()).to.equal(publicKeyPacket.getKeyId().toHex()); + expect(signatures[0].valid).to.be.null; + expect(signatures[1].keyid.toHex()).to.equal(privateKeyPacket.getKeyId().toHex()); + expect(signatures[1].valid).to.be.true; }); - it('Sign key and verify with wrong key - primary user', function() { - const key = openpgp.key.readArmored(pub_sig_test).keys[0]; + it('Sign key and verify with wrong key - primary user', async function() { + let publicKey = openpgp.key.readArmored(pub_sig_test).keys[0]; const privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; const wrongKey = openpgp.key.readArmored(wrong_key).keys[0]; - privateKey.decrypt('hello world'); - return key.signPrimaryUser([privateKey]).then(key => { - return Promise.all( - [key.verifyPrimaryUser([wrongKey]), privateKey.verifyPrimaryUser()] - ).then(results => { - const signatures = results[0]; - expect(signatures.length).to.equal(2); - expect(signatures[0].keyid.toHex()).to.equal(key.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[0].valid).to.be.null; - expect(signatures[1].keyid.toHex()).to.equal(privateKey.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[1].valid).to.be.null; - }); - }); + await privateKey.decrypt('hello world'); + publicKey = await publicKey.signPrimaryUser([privateKey]); + const signatures = await publicKey.verifyPrimaryUser([wrongKey]); + const publicKeyPacket = await publicKey.getSigningKeyPacket(); + const privateKeyPacket = await privateKey.getSigningKeyPacket(); + expect(signatures.length).to.equal(2); + expect(signatures[0].keyid.toHex()).to.equal(publicKeyPacket.getKeyId().toHex()); + expect(signatures[0].valid).to.be.null; + expect(signatures[1].keyid.toHex()).to.equal(privateKeyPacket.getKeyId().toHex()); + expect(signatures[1].valid).to.be.null; }); - it('Sign and verify key - all users', function() { - const key = openpgp.key.readArmored(multi_uid_key).keys[0]; + it('Sign and verify key - all users', async function() { + let publicKey = openpgp.key.readArmored(multi_uid_key).keys[0]; const privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; - privateKey.decrypt('hello world'); - return key.signAllUsers([privateKey]).then(key => { - return Promise.all( - [key.verifyAllUsers([privateKey]), key.verifyPrimaryUser(), privateKey.verifyPrimaryUser()] - ).then(results => { - const signatures = results[0]; - expect(signatures.length).to.equal(4); - expect(signatures[0].userid).to.equal(key.users[0].userId.userid); - expect(signatures[0].keyid.toHex()).to.equal(key.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[0].valid).to.be.null; - expect(signatures[1].userid).to.equal(key.users[0].userId.userid); - expect(signatures[1].keyid.toHex()).to.equal(privateKey.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[1].valid).to.be.true; - expect(signatures[2].userid).to.equal(key.users[1].userId.userid); - expect(signatures[2].keyid.toHex()).to.equal(key.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[2].valid).to.be.null; - expect(signatures[3].userid).to.equal(key.users[1].userId.userid); - expect(signatures[3].keyid.toHex()).to.equal(privateKey.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[3].valid).to.be.true; - }); - }); + await privateKey.decrypt('hello world'); + publicKey = await publicKey.signAllUsers([privateKey]); + const signatures = await publicKey.verifyAllUsers([privateKey]); + const publicKeyPacket = await publicKey.getSigningKeyPacket(); + const privateKeyPacket = await privateKey.getSigningKeyPacket(); + expect(signatures.length).to.equal(4); + expect(signatures[0].userid).to.equal(publicKey.users[0].userId.userid); + expect(signatures[0].keyid.toHex()).to.equal(publicKeyPacket.getKeyId().toHex()); + expect(signatures[0].valid).to.be.null; + expect(signatures[1].userid).to.equal(publicKey.users[0].userId.userid); + expect(signatures[1].keyid.toHex()).to.equal(privateKeyPacket.getKeyId().toHex()); + expect(signatures[1].valid).to.be.true; + expect(signatures[2].userid).to.equal(publicKey.users[1].userId.userid); + expect(signatures[2].keyid.toHex()).to.equal(publicKeyPacket.getKeyId().toHex()); + expect(signatures[2].valid).to.be.null; + expect(signatures[3].userid).to.equal(publicKey.users[1].userId.userid); + expect(signatures[3].keyid.toHex()).to.equal(privateKeyPacket.getKeyId().toHex()); + expect(signatures[3].valid).to.be.true; }); - it('Sign key and verify with wrong key - all users', function() { - const key = openpgp.key.readArmored(multi_uid_key).keys[0]; + it('Sign key and verify with wrong key - all users', async function() { + let publicKey = openpgp.key.readArmored(multi_uid_key).keys[0]; const privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; const wrongKey = openpgp.key.readArmored(wrong_key).keys[0]; - privateKey.decrypt('hello world'); - return key.signAllUsers([privateKey]).then(key => { - return Promise.all( - [key.verifyAllUsers([wrongKey]), key.verifyPrimaryUser(), privateKey.verifyPrimaryUser()] - ).then(results => { - const signatures = results[0]; - expect(signatures.length).to.equal(4); - expect(signatures[0].userid).to.equal(key.users[0].userId.userid); - expect(signatures[0].keyid.toHex()).to.equal(key.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[0].valid).to.be.null; - expect(signatures[1].userid).to.equal(key.users[0].userId.userid); - expect(signatures[1].keyid.toHex()).to.equal(privateKey.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[1].valid).to.be.null; - expect(signatures[2].userid).to.equal(key.users[1].userId.userid); - expect(signatures[2].keyid.toHex()).to.equal(key.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[2].valid).to.be.null; - expect(signatures[3].userid).to.equal(key.users[1].userId.userid); - expect(signatures[3].keyid.toHex()).to.equal(privateKey.getSigningKeyPacket().getKeyId().toHex()); - expect(signatures[3].valid).to.be.null; - }); - }); + await privateKey.decrypt('hello world'); + publicKey = await publicKey.signAllUsers([privateKey]); + const signatures = await publicKey.verifyAllUsers([wrongKey]); + const publicKeyPacket = await publicKey.getSigningKeyPacket(); + const privateKeyPacket = await privateKey.getSigningKeyPacket() + expect(signatures.length).to.equal(4); + expect(signatures[0].userid).to.equal(publicKey.users[0].userId.userid); + expect(signatures[0].keyid.toHex()).to.equal(publicKeyPacket.getKeyId().toHex()); + expect(signatures[0].valid).to.be.null; + expect(signatures[1].userid).to.equal(publicKey.users[0].userId.userid); + expect(signatures[1].keyid.toHex()).to.equal(privateKeyPacket.getKeyId().toHex()); + expect(signatures[1].valid).to.be.null; + expect(signatures[2].userid).to.equal(publicKey.users[1].userId.userid); + expect(signatures[2].keyid.toHex()).to.equal(publicKeyPacket.getKeyId().toHex()); + expect(signatures[2].valid).to.be.null; + expect(signatures[3].userid).to.equal(publicKey.users[1].userId.userid); + expect(signatures[3].keyid.toHex()).to.equal(privateKeyPacket.getKeyId().toHex()); + expect(signatures[3].valid).to.be.null; }); it('Reformat key without passphrase', function() { @@ -1213,9 +1194,12 @@ describe('Key', function() { expect(newKey.users[0].userId.userid).to.equal(userId); expect(newKey.primaryKey.isDecrypted).to.be.true; return openpgp.sign({data: 'hello', privateKeys: newKey, armor: true}).then(function(signed) { - return openpgp.verify({message: openpgp.cleartext.readArmored(signed.data), publicKeys: newKey.toPublic()}).then(function(verified) { + return openpgp.verify( + {message: openpgp.cleartext.readArmored(signed.data), publicKeys: newKey.toPublic()} + ).then(async function(verified) { expect(verified.signatures[0].valid).to.be.true; - expect(verified.signatures[0].keyid.toHex()).to.equal(newKey.getSigningKeyPacket().getKeyId().toHex()); + const newKeyPacket = await newKey.getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(newKeyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1277,11 +1261,10 @@ describe('Key', function() { }); }); - it('Find a valid subkey binding signature among many invalid ones', function() { - const k = openpgp.key.readArmored(valid_binding_sig_among_many_expired_sigs_pub).keys[0]; - return k.verifyKeyPackets().then(() => { - expect(k.getEncryptionKeyPacket()).to.not.be.null; - }) + it('Find a valid subkey binding signature among many invalid ones', async function() { + const key = openpgp.key.readArmored(valid_binding_sig_among_many_expired_sigs_pub).keys[0]; + await key.verifyKeyPackets(); + expect(await key.getEncryptionKeyPacket()).to.not.be.null; }); it('Reject encryption with revoked subkey', function() { diff --git a/test/general/openpgp.js b/test/general/openpgp.js index e678d292..c96746c0 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -626,7 +626,7 @@ describe('OpenPGP.js public api tests', function() { zero_copyVal = openpgp.config.zero_copy; use_nativeVal = openpgp.config.use_native; aead_protectVal = openpgp.config.aead_protect; - privateKey.keys[0].verifyPrimaryUser().then(() => done()); + done(); }); afterEach(function() { @@ -729,7 +729,6 @@ describe('OpenPGP.js public api tests', function() { beforeEach(async function() { expect(await privateKey.keys[0].decrypt(passphrase)).to.be.true; - await privateKey.keys[0].verifyPrimaryUser(); return true; }); @@ -868,12 +867,8 @@ describe('OpenPGP.js public api tests', function() { '=6XMW\r\n' + '-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n'; - beforeEach( async function () { + beforeEach(async function () { expect(await privateKey.keys[0].decrypt(passphrase)).to.be.true; - await privateKey.keys[0].verifyPrimaryUser(); - await privateKey_2000_2008.keys[0].verifyPrimaryUser(); - await privateKey_1337.keys[0].verifyPrimaryUser(); - await privateKey_2038_2045.keys[0].verifyPrimaryUser(); return true; }); @@ -1039,10 +1034,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1060,10 +1056,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(''); expect(decrypted.signatures[0].valid).to.be.true; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1083,10 +1080,11 @@ describe('OpenPGP.js public api tests', function() { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1116,10 +1114,11 @@ describe('OpenPGP.js public api tests', function() { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1153,16 +1152,17 @@ describe('OpenPGP.js public api tests', function() { }).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { + let keyPacket; expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].valid).to.be.true; - return privKeyDE.verifyPrimaryUser().then(() => { - expect(decrypted.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(decrypted.signatures[1].signature.packets.length).to.equal(1); - }); + keyPacket = await privKeyDE.getSigningKeyPacket(); + expect(decrypted.signatures[1].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); + expect(decrypted.signatures[1].signature.packets.length).to.equal(1); }); }); @@ -1191,10 +1191,11 @@ describe('OpenPGP.js public api tests', function() { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1222,10 +1223,11 @@ describe('OpenPGP.js public api tests', function() { }).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1243,10 +1245,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1264,10 +1267,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(''); expect(decrypted.signatures[0].valid).to.be.null; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1284,10 +1288,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1307,10 +1312,11 @@ describe('OpenPGP.js public api tests', function() { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1335,16 +1341,17 @@ describe('OpenPGP.js public api tests', function() { return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); - }).then(function (decrypted) { + }).then(async function (decrypted) { + let keyPacket; expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].valid).to.be.true; - return privKeyDE.verifyPrimaryUser().then(() => { - expect(decrypted.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(decrypted.signatures[1].signature.packets.length).to.equal(1); - }); + keyPacket = await privKeyDE.getSigningKeyPacket(); + expect(decrypted.signatures[1].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); + expect(decrypted.signatures[1].signature.packets.length).to.equal(1); }); }); @@ -1360,10 +1367,11 @@ describe('OpenPGP.js public api tests', function() { expect(signed.data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/); verifyOpt.message = openpgp.cleartext.readArmored(signed.data); return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1383,16 +1391,17 @@ describe('OpenPGP.js public api tests', function() { expect(signed.data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/); verifyOpt.message = openpgp.cleartext.readArmored(signed.data); return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { + let keyPacket; expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[1].valid).to.be.true; - return privKeyDE.verifyPrimaryUser().then(() => { - expect(verified.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(verified.signatures[1].signature.packets.length).to.equal(1); - }); + keyPacket = await privKeyDE.getSigningKeyPacket(); + expect(verified.signatures[1].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); + expect(verified.signatures[1].signature.packets.length).to.equal(1); }); }); @@ -1409,10 +1418,11 @@ describe('OpenPGP.js public api tests', function() { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1428,10 +1438,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = openpgp.cleartext.readArmored(signed.data); return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.null; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1449,10 +1460,11 @@ describe('OpenPGP.js public api tests', function() { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.null; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1469,10 +1481,11 @@ describe('OpenPGP.js public api tests', function() { return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = signed.message; return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1492,12 +1505,13 @@ describe('OpenPGP.js public api tests', function() { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = signed.signature; return openpgp.verify(verifyOpt); - }).then(function (verified) { + }).then(async function (verified) { expect(verified.data).to.equal(plaintext); expect(+verified.signatures[0].signature.packets[0].created).to.be.lte(+openpgp.util.normalizeDate()); expect(+verified.signatures[0].signature.packets[0].created).to.be.gte(+start); expect(verified.signatures[0].valid).to.be.true; - expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); + const keyPacket = await privateKey.keys[0].getSigningKeyPacket(); + expect(verified.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); @@ -1688,14 +1702,13 @@ describe('OpenPGP.js public api tests', function() { publicKeys: pubKeyDE, message: openpgp.message.readArmored(encrypted.data) }); - }).then(function (decrypted) { + }).then(async function (decrypted) { expect(decrypted.data).to.exist; expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; - return privKeyDE.verifyPrimaryUser().then(() => { - expect(decrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(decrypted.signatures[0].signature.packets.length).to.equal(1); - }); + const keyPacket = await privKeyDE.getSigningKeyPacket(); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(keyPacket.getKeyId().toHex()); + expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); });