Convert result.signatures to a Promise

Also, throw armor checksum errors inside the data stream
This commit is contained in:
Daniel Huigens 2018-06-20 14:22:58 +02:00
parent 0cabf72682
commit b6e988b6a6
3 changed files with 22 additions and 31 deletions

View File

@ -369,11 +369,22 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe
result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date) : await decrypted.verify(publicKeys, date, asStream); result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date) : await decrypted.verify(publicKeys, date, asStream);
result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText(); result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
result.data = await convertStream(result.data, asStream); result.data = await convertStream(result.data, asStream);
result.signatures = await convertStreamArray(result.signatures, asStream); result.signatures = stream.readToEnd(result.signatures, arr => arr);
if (asStream) { if (asStream) {
result.data = stream.transformPair(message.packets.stream, async (readable, writable) => { result.data = stream.transformPair(message.packets.stream, async (readable, writable) => {
await stream.pipe(result.data, writable); await stream.pipe(result.data, writable, {
preventClose: true
});
const writer = stream.getWriter(writable);
try {
await result.signatures;
await writer.close();
} catch(e) {
await writer.abort(e);
}
}); });
} else {
result.signatures = await result.signatures;
} }
result.filename = decrypted.getFilename(); result.filename = decrypted.getFilename();
return result; return result;
@ -461,7 +472,7 @@ export function verify({ message, publicKeys, asStream, signature=null, date=new
result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date, asStream); result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date, asStream);
result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData(); result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData();
result.data = await convertStream(result.data, asStream); result.data = await convertStream(result.data, asStream);
result.signatures = await convertStreamArray(result.signatures, asStream); result.signatures = stream.readToEnd(result.signatures, arr => arr);
return result; return result;
}).catch(onError.bind(null, 'Error verifying cleartext signed message')); }).catch(onError.bind(null, 'Error verifying cleartext signed message'));
} }
@ -619,27 +630,6 @@ async function convertStream(data, asStream) {
return data; return data;
} }
/**
* Convert data array to or from Stream
* @param {Object} data the data to convert
* @param {Boolean} asStream whether to return a ReadableStream
* @returns {Object} the parse data in the respective format
*/
async function convertStreamArray(data, asStream) {
if (!asStream && util.isStream(data)) {
return stream.readToEnd(data, arr => arr);
}
if (asStream && !util.isStream(data)) {
return new ReadableStream({
start(controller) {
data.forEach(controller.enqueue.bind(controller));
controller.close();
}
});
}
return data;
}
/** /**
* Global error handler that logs the stack trace and rethrows a high lvl error message. * Global error handler that logs the stack trace and rethrows a high lvl error message.

View File

@ -69,8 +69,9 @@ export function clonePackets(options) {
options.signature = options.signature.packets; options.signature = options.signature.packets;
} }
if (options.signatures) { if (options.signatures) {
if (util.isStream(options.signatures)) { if (options.signatures instanceof Promise) {
options.signatures = stream.transform(options.signatures, verificationObjectToClone); const signatures = options.signatures;
options.signatures = stream.fromAsync(async () => (await signatures).map(verificationObjectToClone));
} else { } else {
options.signatures.forEach(verificationObjectToClone); options.signatures.forEach(verificationObjectToClone);
} }
@ -116,7 +117,7 @@ export function parseClonedPackets(options) {
} }
if (options.signatures) { if (options.signatures) {
if (util.isStream(options.signatures)) { if (util.isStream(options.signatures)) {
options.signatures = stream.transform(options.signatures, packetlistCloneToSignatures); options.signatures = stream.readToEnd(options.signatures, arr => arr).then(signatures => signatures.map(packetlistCloneToSignatures));
} else { } else {
options.signatures = options.signatures.map(packetlistCloneToSignatures); options.signatures = options.signatures.map(packetlistCloneToSignatures);
} }

View File

@ -222,11 +222,11 @@ describe('Streaming', function() {
format: 'binary' format: 'binary'
}); });
expect(util.isStream(decrypted.data)).to.be.true; expect(util.isStream(decrypted.data)).to.be.true;
expect(util.isStream(decrypted.signatures)).to.be.true; expect(util.isStream(decrypted.signatures)).to.be.false;
expect(await openpgp.stream.getReader(openpgp.stream.clone(decrypted.data)).readBytes(1024)).to.deep.equal(plaintext[0]); expect(await openpgp.stream.getReader(openpgp.stream.clone(decrypted.data)).readBytes(1024)).to.deep.equal(plaintext[0]);
if (i > 10) throw new Error('Data did not arrive early.'); if (i > 10) throw new Error('Data did not arrive early.');
expect(await openpgp.stream.readToEnd(decrypted.data)).to.deep.equal(util.concatUint8Array(plaintext)); expect(await openpgp.stream.readToEnd(decrypted.data)).to.deep.equal(util.concatUint8Array(plaintext));
expect(await openpgp.stream.readToEnd(decrypted.signatures, arr => arr)).to.exist.and.have.length(0); expect(await decrypted.signatures).to.exist.and.have.length(0);
} finally { } finally {
openpgp.config.unsafe_stream = unsafe_streamValue; openpgp.config.unsafe_stream = unsafe_streamValue;
} }
@ -363,8 +363,8 @@ describe('Streaming', function() {
expect(util.isStream(decrypted.data)).to.be.true; expect(util.isStream(decrypted.data)).to.be.true;
expect(await openpgp.stream.getReader(openpgp.stream.clone(decrypted.data)).readBytes(10)).not.to.deep.equal(plaintext[0]); expect(await openpgp.stream.getReader(openpgp.stream.clone(decrypted.data)).readBytes(10)).not.to.deep.equal(plaintext[0]);
if (i > 10) throw new Error('Data did not arrive early.'); if (i > 10) throw new Error('Data did not arrive early.');
await openpgp.stream.readToEnd(decrypted.data); await expect(openpgp.stream.readToEnd(decrypted.data)).to.be.rejectedWith('Ascii armor integrity check on message failed');
expect(openpgp.stream.readToEnd(decrypted.signatures, arr => arr)).to.be.rejectedWith('Ascii armor integrity check on message failed'); await expect(decrypted.signatures).to.be.rejectedWith('Ascii armor integrity check on message failed');
} finally { } finally {
openpgp.config.unsafe_stream = unsafe_streamValue; openpgp.config.unsafe_stream = unsafe_streamValue;
} }