Merge pull request #793 from twiss/signature-errors
Check that one-pass signatures match their corresponding signature
This commit is contained in:
commit
3c45b6f18a
|
@ -554,8 +554,9 @@ Message.prototype.verify = async function(keys, date=new Date(), streaming) {
|
||||||
const signatureList = msg.packets.filterByTag(enums.packet.signature);
|
const signatureList = msg.packets.filterByTag(enums.packet.signature);
|
||||||
if (onePassSigList.length && !signatureList.length && msg.packets.stream) {
|
if (onePassSigList.length && !signatureList.length && msg.packets.stream) {
|
||||||
onePassSigList.forEach(onePassSig => {
|
onePassSigList.forEach(onePassSig => {
|
||||||
onePassSig.correspondingSig = new Promise(resolve => {
|
onePassSig.correspondingSig = new Promise((resolve, reject) => {
|
||||||
onePassSig.correspondingSigResolve = resolve;
|
onePassSig.correspondingSigResolve = resolve;
|
||||||
|
onePassSig.correspondingSigReject = reject;
|
||||||
});
|
});
|
||||||
onePassSig.signatureData = stream.fromAsync(async () => (await onePassSig.correspondingSig).signatureData);
|
onePassSig.signatureData = stream.fromAsync(async () => (await onePassSig.correspondingSig).signatureData);
|
||||||
onePassSig.hashed = onePassSig.hash(literalDataList[0], undefined, streaming);
|
onePassSig.hashed = onePassSig.hash(literalDataList[0], undefined, streaming);
|
||||||
|
@ -573,10 +574,7 @@ Message.prototype.verify = async function(keys, date=new Date(), streaming) {
|
||||||
await writer.close();
|
await writer.close();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
onePassSigList.forEach(onePassSig => {
|
onePassSigList.forEach(onePassSig => {
|
||||||
onePassSig.correspondingSigResolve({
|
onePassSig.correspondingSigReject(e);
|
||||||
tag: enums.packet.signature,
|
|
||||||
verify: () => undefined
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
await writer.abort(e);
|
await writer.abort(e);
|
||||||
}
|
}
|
||||||
|
@ -636,6 +634,13 @@ async function createVerificationObject(signature, literalDataList, keys, date=n
|
||||||
return new Signature(packetlist);
|
return new Signature(packetlist);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mark potential promise rejections as "handled". This is needed because in
|
||||||
|
// some cases, we reject them before the user has a reasonable chance to
|
||||||
|
// handle them (e.g. `await readToEnd(result.data); await result.verified` and
|
||||||
|
// the data stream errors).
|
||||||
|
verifiedSig.signature.catch(() => {});
|
||||||
|
verifiedSig.verified.catch(() => {});
|
||||||
|
|
||||||
return verifiedSig;
|
return verifiedSig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,13 +85,13 @@ OnePassSignature.prototype.read = function (bytes) {
|
||||||
|
|
||||||
// A one-octet signature type. Signature types are described in
|
// A one-octet signature type. Signature types are described in
|
||||||
// Section 5.2.1.
|
// Section 5.2.1.
|
||||||
this.signatureType = enums.read(enums.signature, bytes[mypos++]);
|
this.signatureType = bytes[mypos++];
|
||||||
|
|
||||||
// A one-octet number describing the hash algorithm used.
|
// A one-octet number describing the hash algorithm used.
|
||||||
this.hashAlgorithm = enums.read(enums.hash, bytes[mypos++]);
|
this.hashAlgorithm = bytes[mypos++];
|
||||||
|
|
||||||
// A one-octet number describing the public-key algorithm used.
|
// A one-octet number describing the public-key algorithm used.
|
||||||
this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[mypos++]);
|
this.publicKeyAlgorithm = bytes[mypos++];
|
||||||
|
|
||||||
// An eight-octet number holding the Key ID of the signing key.
|
// An eight-octet number holding the Key ID of the signing key.
|
||||||
this.issuerKeyId = new type_keyid();
|
this.issuerKeyId = new type_keyid();
|
||||||
|
@ -145,6 +145,14 @@ OnePassSignature.prototype.verify = async function() {
|
||||||
if (!correspondingSig || correspondingSig.tag !== enums.packet.signature) {
|
if (!correspondingSig || correspondingSig.tag !== enums.packet.signature) {
|
||||||
throw new Error('Corresponding signature packet missing');
|
throw new Error('Corresponding signature packet missing');
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
correspondingSig.signatureType !== this.signatureType ||
|
||||||
|
correspondingSig.hashAlgorithm !== this.hashAlgorithm ||
|
||||||
|
correspondingSig.publicKeyAlgorithm !== this.publicKeyAlgorithm ||
|
||||||
|
!correspondingSig.issuerKeyId.equals(this.issuerKeyId)
|
||||||
|
) {
|
||||||
|
throw new Error('Corresponding signature packet does not match one-pass signature packet');
|
||||||
|
}
|
||||||
correspondingSig.hashed = this.hashed;
|
correspondingSig.hashed = this.hashed;
|
||||||
return correspondingSig.verify.apply(correspondingSig, arguments);
|
return correspondingSig.verify.apply(correspondingSig, arguments);
|
||||||
};
|
};
|
||||||
|
|
|
@ -534,7 +534,7 @@ function tests() {
|
||||||
await openpgp.stream.cancel(verified.data, new Error('canceled by test'));
|
await openpgp.stream.cancel(verified.data, new Error('canceled by test'));
|
||||||
expect(canceled).to.be.true;
|
expect(canceled).to.be.true;
|
||||||
expect(verified.signatures).to.exist.and.have.length(1);
|
expect(verified.signatures).to.exist.and.have.length(1);
|
||||||
expect(await verified.signatures[0].verified).to.be.undefined;
|
await expect(verified.signatures[0].verified).to.be.rejectedWith('canceled');
|
||||||
} finally {
|
} finally {
|
||||||
openpgp.config.aead_protect = aead_protectValue;
|
openpgp.config.aead_protect = aead_protectValue;
|
||||||
openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteValue;
|
openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteValue;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user