diff --git a/src/openpgp.js b/src/openpgp.js index e4e01730..6ea51b1e 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -370,7 +370,8 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe } const result = {}; - result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date); + result.signatures = signature ? message.verifyDetached(signature, publicKeys, date) : message.verify(publicKeys, date); + if (!asStream) result.signatures = await result.signatures; result.data = format === 'binary' ? message.getLiteralData() : message.getText(); result.data = await convertStream(result.data, asStream); result.filename = message.getFilename(); @@ -456,9 +457,8 @@ export function verify({ message, publicKeys, asStream, signature=null, date=new return Promise.resolve().then(async function() { const result = {}; - result.signatures = signature ? - await message.verifyDetached(signature, publicKeys, date) : - await message.verify(publicKeys, date); + result.signatures = signature ? message.verifyDetached(signature, publicKeys, date) : message.verify(publicKeys, date); + if (!asStream) result.signatures = await result.signatures; result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData(); result.data = await convertStream(result.data, asStream); return result; diff --git a/src/packet/clone.js b/src/packet/clone.js index 5253a9f9..eb20c875 100644 --- a/src/packet/clone.js +++ b/src/packet/clone.js @@ -28,6 +28,7 @@ import { CleartextMessage } from '../cleartext'; import { Signature } from '../signature'; import List from './packetlist'; import type_keyid from '../type/keyid'; +import stream from '../stream'; import util from '../util'; @@ -68,7 +69,12 @@ export function clonePackets(options) { options.signature = options.signature.packets; } if (options.signatures) { - options.signatures = options.signatures.map(sig => verificationObjectToClone(sig)); + if (options.signatures instanceof Promise) { + const signatures = options.signatures; + options.signatures = stream.fromAsync(async () => (await signatures).map(verificationObjectToClone)); + } else { + options.signatures.forEach(verificationObjectToClone); + } } return options; } @@ -110,7 +116,13 @@ export function parseClonedPackets(options) { options.message = packetlistCloneToMessage(options.message); } if (options.signatures) { - options.signatures = options.signatures.map(packetlistCloneToSignatures); + if (util.isStream(options.signatures)) { + options.signatures = stream.readToEnd(options.signatures, arr => arr).then(([signatures]) => { + return signatures.map(packetlistCloneToSignatures); + }); + } else { + options.signatures = options.signatures.map(packetlistCloneToSignatures); + } } if (options.signature) { options.signature = packetlistCloneToSignature(options.signature); diff --git a/src/worker/async_proxy.js b/src/worker/async_proxy.js index 28de7f41..2f1a7a42 100644 --- a/src/worker/async_proxy.js +++ b/src/worker/async_proxy.js @@ -149,7 +149,7 @@ AsyncProxy.prototype.delegate = function(method, options) { this.workers[workerId].requests++; // remember to handle parsing cloned packets from worker - this.tasks[id] = { resolve: data => resolve(util.restoreStreams(packet.clone.parseClonedPackets(data, method))), reject }; + this.tasks[id] = { resolve: data => resolve(packet.clone.parseClonedPackets(util.restoreStreams(data), method)), reject }; }); }; diff --git a/test/general/signature.js b/test/general/signature.js index 2f932d0a..5bedfc43 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -680,6 +680,7 @@ yYDnCgA= return openpgp.verify({ publicKeys:[pubKey], message:sMsg }).then(async function(cleartextSig) { expect(cleartextSig).to.exist; expect(openpgp.util.nativeEOL(openpgp.util.Uint8Array_to_str(await openpgp.stream.readToEnd(cleartextSig.data)))).to.equal(plaintext); + cleartextSig.signatures = await cleartextSig.signatures; expect(cleartextSig.signatures).to.have.length(1); expect(cleartextSig.signatures[0].valid).to.be.true; expect(cleartextSig.signatures[0].signature.packets.length).to.equal(1); diff --git a/test/general/streaming.js b/test/general/streaming.js index d85c4cdd..2a20065c 100644 --- a/test/general/streaming.js +++ b/test/general/streaming.js @@ -48,6 +48,8 @@ describe('Streaming', function() { data, passwords: ['test'], }); + await openpgp.stream.getReader(openpgp.stream.clone(encrypted.data)).readBytes(1000); + if (i > 10) throw new Error('Data did not arrive early.'); const msgAsciiArmored = await openpgp.stream.readToEnd(encrypted.data); const message = await openpgp.message.readArmored(msgAsciiArmored); const decrypted = await openpgp.decrypt({ @@ -90,12 +92,15 @@ describe('Streaming', function() { it('Encrypt and decrypt larger message roundtrip (draft04)', async function() { let aead_protectValue = openpgp.config.aead_protect; + let aead_chunk_size_byteValue = openpgp.config.aead_chunk_size_byte; openpgp.config.aead_protect = true; + openpgp.config.aead_chunk_size_byte = 4; try { let plaintext = []; let i = 0; const data = new ReadableStream({ async pull(controller) { + await new Promise(setTimeout); if (i++ < 10) { let randomBytes = await openpgp.crypto.random.getRandomBytes(1024); controller.enqueue(randomBytes); @@ -118,9 +123,12 @@ describe('Streaming', function() { format: 'binary' }); expect(util.isStream(decrypted.data)).to.be.true; + await openpgp.stream.getReader(openpgp.stream.clone(decrypted.data)).readBytes(1000); + if (i > 10) throw new Error('Data did not arrive early.'); expect(await openpgp.stream.readToEnd(decrypted.data)).to.deep.equal(util.concatUint8Array(plaintext)); } finally { openpgp.config.aead_protect = aead_protectValue; + openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteValue; } }); });