From 13c29b1fc9d0f1459d61581e6802369f9f34434d Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 26 Oct 2018 15:21:17 +0200 Subject: [PATCH] Fix decryption with multiple passwords --- src/message.js | 13 +++++++++---- test/general/openpgp.js | 33 ++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/message.js b/src/message.js index 3ebf07c7..c40ce8d8 100644 --- a/src/message.js +++ b/src/message.js @@ -158,8 +158,15 @@ Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) { if (!symESKeyPacketlist) { throw new Error('No symmetrically encrypted session key packet found.'); } - await Promise.all(symESKeyPacketlist.map(async function(keyPacket) { - await Promise.all(passwords.map(async function(password) { + await Promise.all(passwords.map(async function(password, i) { + let packets; + if (i) { + packets = new packet.List(); + await packets.read(symESKeyPacketlist.write()); + } else { + packets = symESKeyPacketlist; + } + await Promise.all(packets.map(async function(keyPacket) { try { await keyPacket.decrypt(password); keyPackets.push(keyPacket); @@ -167,8 +174,6 @@ Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) { util.print_debug_error(err); } })); - stream.cancel(keyPacket.encrypted); // Don't keep copy of encrypted data in memory. - keyPacket.encrypted = null; })); } else if (privateKeys) { const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index c38793af..3564a6e0 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -1668,18 +1668,6 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() { }); }); - it('should decrypt with two passwords message which GPG fails on', async function () { - - const decOpt = { - message: await openpgp.message.readArmored(twoPasswordGPGFail), - passwords: password2 - }; - return openpgp.decrypt(decOpt).then(function (decrypted) { - expect(decrypted.data).to.equal('short message\nnext line\n한국어/조선말'); - expect(decrypted.signatures.length).to.equal(0); - }); - }); - it('should encrypt and decrypt with password and not ascii armor', function () { const encOpt = { message: openpgp.message.fromText(plaintext), @@ -1776,7 +1764,7 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() { } - describe('AES / RSA sign, verify', function() { + describe('AES / RSA encrypt, decrypt, sign, verify', function() { const wrong_pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n' + 'Version: OpenPGP.js v0.9.0\r\n' + 'Comment: Hoodiecrow - https://hoodiecrow.com\r\n' + @@ -2248,6 +2236,25 @@ describe('[Sauce Labs Group 2] OpenPGP.js public api tests', function() { }); }); + it('should decrypt with two passwords message which GPG fails on', async function() { + const decOpt = { + message: await openpgp.message.readArmored(twoPasswordGPGFail), + passwords: password2 + }; + return openpgp.decrypt(decOpt).then(function(decrypted) { + expect(decrypted.data).to.equal('short message\nnext line\n한국어/조선말'); + expect(decrypted.signatures.length).to.equal(0); + }); + }); + + it('should decrypt with three passwords', async function() { + const messageBinary = openpgp.util.b64_to_Uint8Array('wy4ECQMIElIx/jiwJV9gp/MZ/ElZwUfHrzOBfOtM8VmgDy76F7eSGWH26tAlx3WI0kMBZv6Tlc1Y6baaZ6MEcOLTG/C7uzHH7KMfuQFd3fcMaVcDawk9EEy/CybiGBE+acT6id2pemHQy6Nk76d9UUTFubcB'); + const message = await openpgp.message.read(messageBinary); + const passwords = ['Test', 'Pinata', 'a']; + const decrypted = await openpgp.decrypt({ message, passwords }); + expect(decrypted.data).to.equal('Hello world'); + }); + }); describe('Errors', function() {