Merge pull request #894 from twiss/dont-throw-verification-errors-workers
Fix one-pass signature verification when using a Worker
This commit is contained in:
commit
ee01883a52
|
@ -81,13 +81,18 @@ function verificationObjectToClone(verObject) {
|
|||
const signature = verObject.signature;
|
||||
verObject.signature = stream.fromAsync(async () => {
|
||||
const packets = (await signature).packets;
|
||||
await verified;
|
||||
delete packets[0].signature;
|
||||
try {
|
||||
await verified;
|
||||
delete packets[0].signature;
|
||||
} catch(e) {}
|
||||
return packets;
|
||||
});
|
||||
} else {
|
||||
verObject.signature = verObject.signature.packets;
|
||||
}
|
||||
if (verObject.error) {
|
||||
verObject.error = verObject.error.message;
|
||||
}
|
||||
return verObject;
|
||||
}
|
||||
|
||||
|
@ -151,10 +156,15 @@ function packetlistCloneToSignatures(clone) {
|
|||
clone.keyid = type_keyid.fromClone(clone.keyid);
|
||||
if (util.isStream(clone.signature)) {
|
||||
clone.signature = stream.readToEnd(clone.signature, ([signature]) => new Signature(List.fromStructuredClone(signature)));
|
||||
clone.signature.catch(() => {});
|
||||
} else {
|
||||
clone.signature = new Signature(List.fromStructuredClone(clone.signature));
|
||||
}
|
||||
clone.verified = stream.readToEnd(clone.verified, ([verified]) => verified);
|
||||
clone.verified.catch(() => {});
|
||||
if (clone.error) {
|
||||
clone.error = new Error(clone.error);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,6 +223,9 @@ List.fromStructuredClone = function(packetlistClone) {
|
|||
packet.packets = new List();
|
||||
}
|
||||
}
|
||||
if (packetlistClone.stream) {
|
||||
packetlist.stream = stream.transform(packetlistClone.stream, packet => packets.fromStructuredClone(packet));
|
||||
}
|
||||
return packetlist;
|
||||
};
|
||||
|
||||
|
|
17
src/util.js
17
src/util.js
|
@ -83,10 +83,15 @@ export default {
|
|||
const { port1, port2 } = new MessageChannel();
|
||||
port1.onmessage = async function({ data: { action } }) {
|
||||
if (action === 'read') {
|
||||
const result = await reader.read();
|
||||
port1.postMessage(result, util.getTransferables(result, true));
|
||||
try {
|
||||
const result = await reader.read();
|
||||
port1.postMessage(result, util.getTransferables(result));
|
||||
} catch(e) {
|
||||
port1.postMessage({ error: e.message });
|
||||
}
|
||||
} else if (action === 'cancel') {
|
||||
port1.postMessage(await transformed.cancel());
|
||||
await transformed.cancel();
|
||||
port1.postMessage();
|
||||
}
|
||||
};
|
||||
obj[key] = port2;
|
||||
|
@ -116,8 +121,10 @@ export default {
|
|||
pull(controller) {
|
||||
return new Promise(resolve => {
|
||||
value.onmessage = evt => {
|
||||
const { done, value } = evt.data;
|
||||
if (!done) {
|
||||
const { done, value, error } = evt.data;
|
||||
if (error) {
|
||||
controller.error(new Error(error));
|
||||
} else if (!done) {
|
||||
controller.enqueue(value);
|
||||
} else {
|
||||
controller.close();
|
||||
|
|
|
@ -113,10 +113,10 @@ function delegate(id, method, options) {
|
|||
response({ id:id, event:'method-return', err:'Unknown Worker Event' });
|
||||
return;
|
||||
}
|
||||
// parse cloned packets
|
||||
options = openpgp.packet.clone.parseClonedPackets(options, method);
|
||||
// construct ReadableStreams from MessagePorts
|
||||
openpgp.util.restoreStreams(options);
|
||||
// parse cloned packets
|
||||
options = openpgp.packet.clone.parseClonedPackets(options, method);
|
||||
openpgp[method](options).then(function(data) {
|
||||
// clone packets (for web worker structured cloning algorithm)
|
||||
response({ id:id, event:'method-return', data:openpgp.packet.clone.clonePackets(data) });
|
||||
|
|
|
@ -689,9 +689,10 @@ zmuVOdNuWQqxT9Sqa84=
|
|||
});
|
||||
});
|
||||
|
||||
it('Verify signed message with trailing spaces from GPG', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
function tests() {
|
||||
it('Verify signed message with trailing spaces from GPG', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1
|
||||
|
||||
owGbwMvMyMT4oOW7S46CznTG01El3MUFicmpxbolqcUlUTev14K5Vgq8XGCGQmJe
|
||||
|
@ -703,26 +704,26 @@ yYDnCgA=
|
|||
=15ki
|
||||
-----END PGP MESSAGE-----`;
|
||||
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(msg_armor);
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(msg_armor);
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
|
||||
return openpgp.verify({ publicKeys:[pubKey], message:sMsg }).then(function(cleartextSig) {
|
||||
expect(cleartextSig).to.exist;
|
||||
expect(openpgp.util.nativeEOL(openpgp.util.Uint8Array_to_str(cleartextSig.data))).to.equal(plaintext);
|
||||
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);
|
||||
return openpgp.verify({ publicKeys: [pubKey], message: sMsg }).then(function(cleartextSig) {
|
||||
expect(cleartextSig).to.exist;
|
||||
expect(openpgp.util.nativeEOL(openpgp.util.Uint8Array_to_str(cleartextSig.data))).to.equal(plaintext);
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Streaming verify signed message with trailing spaces from GPG', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
it('Streaming verify signed message with trailing spaces from GPG', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
Version: GnuPG v1
|
||||
|
||||
owGbwMvMyMT4oOW7S46CznTG01El3MUFicmpxbolqcUlUTev14K5Vgq8XGCGQmJe
|
||||
|
@ -734,32 +735,62 @@ yYDnCgA=
|
|||
=15ki
|
||||
-----END PGP MESSAGE-----`.split('');
|
||||
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(new ReadableStream({
|
||||
async pull(controller) {
|
||||
await new Promise(setTimeout);
|
||||
controller.enqueue(msg_armor.shift());
|
||||
if (!msg_armor.length) controller.close();
|
||||
}
|
||||
}));
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(new ReadableStream({
|
||||
async pull(controller) {
|
||||
await new Promise(setTimeout);
|
||||
controller.enqueue(msg_armor.shift());
|
||||
if (!msg_armor.length) controller.close();
|
||||
}
|
||||
}));
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
|
||||
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);
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
expect(await cleartextSig.signatures[0].verified).to.be.true;
|
||||
expect((await cleartextSig.signatures[0].signature).packets.length).to.equal(1);
|
||||
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);
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
expect(await cleartextSig.signatures[0].verified).to.be.true;
|
||||
expect((await cleartextSig.signatures[0].signature).packets.length).to.equal(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Streaming verify signed message with missing signature packet', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
it('Verify signed message with missing signature packet', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
Version: OpenPGP.js v3.1.3
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
yFgBO8LLzMjE+KDlu0uOgs50xtNRJdzFBYnJqcW6JanFJVE3r9eCuVYKvFxg
|
||||
hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
|
||||
|
||||
=D6TZ
|
||||
-----END PGP MESSAGE-----`;
|
||||
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(msg_armor);
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
|
||||
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);
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
expect(cleartextSig.signatures[0].valid).to.be.null;
|
||||
expect(cleartextSig.signatures[0].error.message).to.equal('Corresponding signature packet missing');
|
||||
expect(cleartextSig.signatures[0].signature.packets.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Streaming verify signed message with missing signature packet', async function() {
|
||||
const msg_armor =
|
||||
`-----BEGIN PGP MESSAGE-----
|
||||
Version: OpenPGP.js v3.1.3
|
||||
Comment: https://openpgpjs.org
|
||||
|
||||
|
@ -769,27 +800,40 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
|
|||
=D6TZ
|
||||
-----END PGP MESSAGE-----`.split('');
|
||||
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(new ReadableStream({
|
||||
async pull(controller) {
|
||||
await new Promise(setTimeout);
|
||||
controller.enqueue(msg_armor.shift());
|
||||
if (!msg_armor.length) controller.close();
|
||||
}
|
||||
}));
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
const plaintext = 'space: \nspace and tab: \t\nno trailing space\n \ntab:\t\ntab and space:\t ';
|
||||
const sMsg = await openpgp.message.readArmored(new ReadableStream({
|
||||
async pull(controller) {
|
||||
await new Promise(setTimeout);
|
||||
controller.enqueue(msg_armor.shift());
|
||||
if (!msg_armor.length) controller.close();
|
||||
}
|
||||
}));
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
const keyids = sMsg.getSigningKeyIds();
|
||||
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
expect(pubKey.getKeys(keyids[0])).to.not.be.empty;
|
||||
|
||||
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);
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
await expect(cleartextSig.signatures[0].verified).to.be.rejectedWith('Corresponding signature packet missing');
|
||||
expect((await cleartextSig.signatures[0].signature).packets.length).to.equal(0);
|
||||
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);
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
await expect(cleartextSig.signatures[0].verified).to.be.rejectedWith('Corresponding signature packet missing');
|
||||
expect((await cleartextSig.signatures[0].signature).packets.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
tests();
|
||||
|
||||
tryTests('With Worker', tests, {
|
||||
if: typeof window !== 'undefined' && window.Worker,
|
||||
before: async function() {
|
||||
await openpgp.initWorker({ path: '../dist/openpgp.worker.js' });
|
||||
},
|
||||
after: function() {
|
||||
openpgp.destroyWorker();
|
||||
}
|
||||
});
|
||||
|
||||
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same string cleartext and valid signatures', async function() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user