Don't hang when signature packet corresponding to one-pass sig is missing
This commit is contained in:
parent
150222bee5
commit
3751731330
|
@ -545,7 +545,7 @@ Message.prototype.verify = async function(keys, date=new Date(), streaming) {
|
|||
if (literalDataList.length !== 1) {
|
||||
throw new Error('Can only verify message with one literal data packet.');
|
||||
}
|
||||
const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature);
|
||||
const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature).reverse();
|
||||
const signatureList = msg.packets.filterByTag(enums.packet.signature);
|
||||
if (onePassSigList.length && !signatureList.length && msg.packets.stream) {
|
||||
onePassSigList.forEach(onePassSig => {
|
||||
|
@ -555,25 +555,28 @@ Message.prototype.verify = async function(keys, date=new Date(), streaming) {
|
|||
onePassSig.signatureData = stream.fromAsync(async () => (await onePassSig.correspondingSig).signatureData);
|
||||
onePassSig.hashed = onePassSig.hash(literalDataList[0], undefined, streaming);
|
||||
});
|
||||
const verificationObjects = await createVerificationObjects(onePassSigList, literalDataList, keys, date);
|
||||
msg.packets.stream = stream.transformPair(msg.packets.stream, async (readable, writable) => {
|
||||
const reader = stream.getReader(readable);
|
||||
const writer = stream.getWriter(writable);
|
||||
try {
|
||||
await stream.readToEnd(stream.transform(readable, signature => {
|
||||
onePassSigList.pop().correspondingSigResolve(signature);
|
||||
}));
|
||||
for (let i = 0; i < onePassSigList.length; i++) {
|
||||
const { value: signature } = await reader.read();
|
||||
onePassSigList[i].correspondingSigResolve(signature);
|
||||
}
|
||||
await reader.readToEnd();
|
||||
await writer.ready;
|
||||
await writer.close();
|
||||
} catch(e) {
|
||||
onePassSigList.forEach(onePassSig => {
|
||||
onePassSig.correspondingSigResolve({
|
||||
tag: enums.packet.signature,
|
||||
verify: () => undefined
|
||||
});
|
||||
});
|
||||
await writer.abort(e);
|
||||
}
|
||||
});
|
||||
return verificationObjects.reverse();
|
||||
return createVerificationObjects(onePassSigList, literalDataList, keys, date);
|
||||
}
|
||||
return createVerificationObjects(signatureList, literalDataList, keys, date);
|
||||
};
|
||||
|
|
|
@ -142,6 +142,9 @@ OnePassSignature.prototype.calculateTrailer = Signature.prototype.calculateTrail
|
|||
|
||||
OnePassSignature.prototype.verify = async function() {
|
||||
const correspondingSig = await this.correspondingSig;
|
||||
if (!correspondingSig || correspondingSig.tag !== enums.packet.signature) {
|
||||
throw new Error('Corresponding signature packet missing');
|
||||
}
|
||||
correspondingSig.hashed = this.hashed;
|
||||
return correspondingSig.verify.apply(correspondingSig, arguments);
|
||||
};
|
||||
|
|
|
@ -600,6 +600,41 @@ yYDnCgA=
|
|||
});
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
yFgBO8LLzMjE+KDlu0uOgs50xtNRJdzFBYnJqcW6JanFJVE3r9eCuVYKvFxg
|
||||
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 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);
|
||||
await expect(cleartextSig.signatures[0].verified).to.be.rejectedWith('Corresponding signature packet missing');
|
||||
expect((await cleartextSig.signatures[0].signature).packets.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same string cleartext and valid signatures', async function() {
|
||||
const plaintext = 'short message\nnext line \n한국어/조선말';
|
||||
const pubKey = (await openpgp.key.readArmored(pub_key_arm2)).keys[0];
|
||||
|
|
Loading…
Reference in New Issue
Block a user