diff --git a/src/cleartext.js b/src/cleartext.js index cf12f9e6..e5909392 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -86,10 +86,15 @@ CleartextMessage.prototype.signDetached = async function(privateKeys) { if (privateKey.isPublic()) { throw new Error('Need private key for signing'); } + await privateKey.verifyPrimaryUser(); + var signingKeyPacket = privateKey.getSigningKeyPacket(); + if (!signingKeyPacket) { + throw new Error('Could not find valid key packet for signing in key ' + + privateKey.primaryKey.getKeyId().toHex()); + } var signaturePacket = new packet.Signature(); signaturePacket.signatureType = enums.signature.text; signaturePacket.hashAlgorithm = config.prefer_hash_algorithm; - var signingKeyPacket = privateKey.getSigningKeyPacket(); signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; if (!signingKeyPacket.isDecrypted) { throw new Error('Private key is not decrypted.'); @@ -124,12 +129,13 @@ CleartextMessage.prototype.verifyDetached = function(signature, keys) { literalDataPacket.setText(this.text); return Promise.all(signatureList.map(async function(signature) { var keyPacket = null; - for (var j = 0; j < keys.length; j++) { - keyPacket = keys[j].getSigningKeyPacket(signature.issuerKeyId); - if (keyPacket) { - break; + await Promise.all(keys.map(async function(key) { + await key.verifyPrimaryUser(); + var result = key.getSigningKeyPacket(signature.issuerKeyId, config.verify_expired_keys); + if (result) { + keyPacket = result; } - } + })); var verifiedSig = {}; if (keyPacket) { diff --git a/test/general/key.js b/test/general/key.js index 2722b07d..47974849 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -742,7 +742,9 @@ describe('Key', function() { var pubKey = openpgp.key.readArmored(twoKeys).keys[1]; expect(pubKey).to.exist; expect(pubKey).to.be.an.instanceof(openpgp.key.Key); - expect(pubKey.getExpirationTime().toISOString()).to.be.equal('2018-11-26T10:58:29.000Z'); + return pubKey.verifyPrimaryUser().then(() => { + expect(pubKey.getExpirationTime().toISOString()).to.be.equal('2018-11-26T10:58:29.000Z'); + }); }); it('Method getExpirationTime V4 SubKey', function() { @@ -890,26 +892,32 @@ describe('Key', function() { it('getPreferredSymAlgo() - one key - AES256', function() { var key1 = openpgp.key.readArmored(twoKeys).keys[0]; - var prefAlgo = openpgp.key.getPreferredSymAlgo([key1]); - expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256); + return key1.verifyPrimaryUser().then(() => { + var prefAlgo = openpgp.key.getPreferredSymAlgo([key1]); + expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256); + }); }); it('getPreferredSymAlgo() - two key - AES128', function() { var keys = openpgp.key.readArmored(twoKeys).keys; var key1 = keys[0]; var key2 = keys[1]; - key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = [6,7,3]; - var prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]); - expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128); + return Promise.all([key1.verifyPrimaryUser(), key2.verifyPrimaryUser()]).then(() => { + key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = [6,7,3]; + var prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]); + expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128); + }); }); it('getPreferredSymAlgo() - two key - one without pref', function() { var keys = openpgp.key.readArmored(twoKeys).keys; var key1 = keys[0]; var key2 = keys[1]; - key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = null; - var prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]); - expect(prefAlgo).to.equal(openpgp.config.encryption_cipher); + return Promise.all([key1.verifyPrimaryUser(), key2.verifyPrimaryUser()]).then(() => { + key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = null; + var prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]); + expect(prefAlgo).to.equal(openpgp.config.encryption_cipher); + }); }); it('Preferences of generated key', function() { @@ -944,10 +952,12 @@ describe('Key', function() { it('getPrimaryUser()', function() { var key = openpgp.key.readArmored(pub_sig_test).keys[0]; - var 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); + return key.verifyPrimaryUser().then(() => { + var 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); + }); }); it('Generated key is not unlocked by default', function() { @@ -1020,59 +1030,68 @@ describe('Key', function() { return openpgp.generateKey(opt).then(function(key) { key = key.key; - var expiration = key.getExpirationTime(); - expect(expiration).to.exist; + return key.verifyPrimaryUser().then(() => { + var expiration = key.getExpirationTime(); + expect(expiration).to.exist; - var actual_delta = (new Date(expiration) - new Date()) / 1000; - expect(Math.abs(actual_delta - expect_delta)).to.be.below(60); + var actual_delta = (new Date(expiration) - new Date()) / 1000; + expect(Math.abs(actual_delta - expect_delta)).to.be.below(60); - var subKeyExpiration = key.subKeys[0].getExpirationTime(); - expect(subKeyExpiration).to.exist; + var subKeyExpiration = key.subKeys[0].getExpirationTime(); + expect(subKeyExpiration).to.exist; - var actual_subKeyDelta = (new Date(subKeyExpiration) - new Date()) / 1000; - expect(Math.abs(actual_subKeyDelta - expect_delta)).to.be.below(60); + var 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(done) { + it('Sign and verify key - primary user', function() { var key = openpgp.key.readArmored(pub_sig_test).keys[0]; var privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; privateKey.decrypt('hello world'); - key.signPrimaryUser([privateKey]).then(key => { - key.verifyPrimaryUser([privateKey]).then(signatures => { + return key.signPrimaryUser([privateKey]).then(key => { + return Promise.all( + [key.verifyPrimaryUser([privateKey]), privateKey.verifyPrimaryUser()] + ).then(results => { + var 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; - done(); }); }); }); - it('Sign key and verify with wrong key - primary user', function(done) { + it('Sign key and verify with wrong key - primary user', function() { var key = openpgp.key.readArmored(pub_sig_test).keys[0]; var privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; var wrongKey = openpgp.key.readArmored(wrong_key).keys[0]; privateKey.decrypt('hello world'); - key.signPrimaryUser([privateKey]).then(key => { - key.verifyPrimaryUser([wrongKey]).then(signatures => { + return key.signPrimaryUser([privateKey]).then(key => { + return Promise.all( + [key.verifyPrimaryUser([wrongKey]), privateKey.verifyPrimaryUser()] + ).then(results => { + var 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; - done(); }); }); }); - it('Sign and verify key - all users', function(done) { + it('Sign and verify key - all users', function() { var key = openpgp.key.readArmored(multi_uid_key).keys[0]; var privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; privateKey.decrypt('hello world'); - key.signAllUsers([privateKey]).then(key => { - key.verifyAllUsers([privateKey]).then(signatures => { + return key.signAllUsers([privateKey]).then(key => { + return Promise.all( + [key.verifyAllUsers([privateKey]), key.verifyPrimaryUser(), privateKey.verifyPrimaryUser()] + ).then(results => { + var 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()); @@ -1086,18 +1105,20 @@ describe('Key', function() { 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; - done(); }); }); }); - it('Sign key and verify with wrong key - all users', function(done) { + it('Sign key and verify with wrong key - all users', function() { var key = openpgp.key.readArmored(multi_uid_key).keys[0]; var privateKey = openpgp.key.readArmored(priv_key_rsa).keys[0]; var wrongKey = openpgp.key.readArmored(wrong_key).keys[0]; privateKey.decrypt('hello world'); - key.signAllUsers([privateKey]).then(key => { - key.verifyAllUsers([wrongKey]).then(signatures => { + return key.signAllUsers([privateKey]).then(key => { + return Promise.all( + [key.verifyAllUsers([wrongKey]), key.verifyPrimaryUser(), privateKey.verifyPrimaryUser()] + ).then(results => { + var 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()); @@ -1111,7 +1132,6 @@ describe('Key', function() { 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; - done(); }); }); }); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 09b4eee1..9f874e21 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -405,7 +405,7 @@ describe('OpenPGP.js public api tests', function() { describe('encrypt, decrypt, sign, verify - integration tests', function() { var privateKey, publicKey, zero_copyVal, use_nativeVal, aead_protectVal; - beforeEach(function() { + beforeEach(function(done) { publicKey = openpgp.key.readArmored(pub_key); expect(publicKey.keys).to.have.length(1); expect(publicKey.err).to.not.exist; @@ -415,6 +415,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()); }); afterEach(function() { @@ -515,8 +516,9 @@ describe('OpenPGP.js public api tests', function() { describe('encryptSessionKey, decryptSessionKey', function() { var sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]); - beforeEach(function() { + beforeEach(function(done) { expect(privateKey.keys[0].decrypt(passphrase)).to.be.true; + privateKey.keys[0].verifyPrimaryUser().then(() => done()); }); it('should encrypt with public key', function() { @@ -609,8 +611,9 @@ describe('OpenPGP.js public api tests', function() { '=6XMW\r\n' + '-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n'; - beforeEach(function() { + beforeEach(function(done) { expect(privateKey.keys[0].decrypt(passphrase)).to.be.true; + privateKey.keys[0].verifyPrimaryUser().then(() => done()); }); it('should encrypt then decrypt', function() { @@ -830,8 +833,10 @@ describe('OpenPGP.js public api tests', function() { expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].valid).to.be.true; - expect(decrypted.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(decrypted.signatures[1].signature.packets.length).to.equal(1); + 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); + }); }); }); @@ -1127,8 +1132,10 @@ describe('OpenPGP.js public api tests', function() { expect(encrypted.data).to.exist; expect(encrypted.data).to.equal(plaintext); expect(encrypted.signatures[0].valid).to.be.true; - expect(encrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(encrypted.signatures[0].signature.packets.length).to.equal(1); + return privKeyDE.verifyPrimaryUser().then(() => { + expect(encrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); + expect(encrypted.signatures[0].signature.packets.length).to.equal(1); + }); }); }); }); diff --git a/test/general/signature.js b/test/general/signature.js index efe2db14..1c1089bd 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -432,7 +432,7 @@ describe("Signature", function() { var sMsg = openpgp.message.readArmored(signedArmor); var pub_key = openpgp.key.readArmored(pub_key_arm2).keys[0]; - sMsg.verify([pub_key]).then(verified => { + return sMsg.verify([pub_key]).then(verified => { expect(verified).to.exist; expect(verified).to.have.length(1); expect(verified[0].valid).to.be.true; @@ -544,7 +544,7 @@ describe("Signature", function() { expect(sMsg.getText()).to.equal(plaintext); - sMsg.verify([pubKey2, pubKey3]).then(verifiedSig => { + return sMsg.verify([pubKey2, pubKey3]).then(verifiedSig => { expect(verifiedSig).to.exist; expect(verifiedSig).to.have.length(2); expect(verifiedSig[0].valid).to.be.true; @@ -604,7 +604,7 @@ describe("Signature", function() { var plaintext = 'short message\nnext line\n한국어/조선말'; var pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0]; var privKey = openpgp.key.readArmored(priv_key_arm2).keys[0]; - privKey.getSigningKeyPacket().decrypt('hello world'); + privKey.primaryKey.decrypt('hello world'); return openpgp.sign({ privateKeys:[privKey], data:plaintext }).then(function(signed) { @@ -618,14 +618,13 @@ describe("Signature", function() { expect(cleartextSig.signatures[0].valid).to.be.true; expect(cleartextSig.signatures[0].signature.packets.length).to.equal(1); }); - }); it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - armored', function() { var plaintext = openpgp.util.str2Uint8Array('short message\nnext line\n한국어/조선말'); var pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0]; var privKey = openpgp.key.readArmored(priv_key_arm2).keys[0]; - privKey.getSigningKeyPacket().decrypt('hello world'); + privKey.primaryKey.decrypt('hello world'); return openpgp.sign({ privateKeys:[privKey], data:plaintext }).then(function(signed) { @@ -639,14 +638,13 @@ describe("Signature", function() { expect(cleartextSig.signatures[0].valid).to.be.true; expect(cleartextSig.signatures[0].signature.packets.length).to.equal(1); }); - }); it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - not armored', function() { var plaintext = openpgp.util.str2Uint8Array('short message\nnext line\n한국어/조선말'); var pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0]; var privKey = openpgp.key.readArmored(priv_key_arm2).keys[0]; - privKey.getSigningKeyPacket().decrypt('hello world'); + privKey.primaryKey.decrypt('hello world'); return openpgp.sign({ privateKeys:[privKey], data:plaintext, armor:false }).then(function(signed) { @@ -660,6 +658,31 @@ describe("Signature", function() { expect(cleartextSig.signatures[0].valid).to.be.true; expect(cleartextSig.signatures[0].signature.packets.length).to.equal(1); }); + }); + + it('Verify test with expired verification public key and verify_expired_keys set to false', function() { + openpgp.config.verify_expired_keys = false; + var pubKey = openpgp.key.readArmored(pub_expired).keys[0]; + var message = openpgp.message.readArmored(msg_sig_expired); + return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) { + expect(verified).to.exist; + expect(verified.signatures).to.have.length(1); + expect(verified.signatures[0].valid).to.not.be.true; + expect(verified.signatures[0].signature.packets.length).to.equal(1); + }); + + }); + + it('Verify test with expired verification public key and verify_expired_keys set to true', function() { + openpgp.config.verify_expired_keys = true; + var pubKey = openpgp.key.readArmored(pub_expired).keys[0]; + var message = openpgp.message.readArmored(msg_sig_expired); + return openpgp.verify({ publicKeys:[pubKey], message:message }).then(function(verified) { + expect(verified).to.exist; + expect(verified.signatures).to.have.length(1); + expect(verified.signatures[0].valid).to.be.true; + expect(verified.signatures[0].signature.packets.length).to.equal(1); + }); });