How to verify an envelope properly?
shizhMSFT opened this issue · comments
The protocol specifies how to verify a single signature but does not specify how to verify signatures in an envelope.
The reference implementation in different repos varies:
- secure-systems-lab/dsse in python considers that an envelope is valid if one of the signatures is valid.
- in-toto/in-toto-golang in golang considers that an envelope is valid if all of the signatures are valid.
Should the DSSE spec define the verification process of an envelope or explicitly call out that the verification process is purely defined by the implementer?
Additionally, for the golang implementation, the adversary can make the verification pass if some signatures in the envelope are valid simply by removing the invalid sigantures out.
Agreed, it is deliberately vague about how to verify multiple signatures, as should be the case, as this is application-specific. In the extreme cases, you verify either no or all signatures, but the general case is ofc in between and we cannot set any prescriptions there. Perhaps you could propose some text to clarify this?
I've proposed #41 that the verification policy on multiple signatures is application-specific.
In fact, the reference implementation in this repo makes more sense.
Acoording to the envelope documentation,
An envelope MAY have more than one signature, which is equivalent to separate envelopes with individual signatures.
Anyone can decompose the envelope to multiple envelopes with a single signature in it.
Thanks for pointing this out, @shizhMSFT! I agree that this is a problem. It's pretty bad if we only have two implementations and they already diverge.
In addition to #41, I think we should update protocol.md to explain how to handle multiple signatures. Note that we already have something similar in in-toto/attestation. Maybe we should convert to psuedocode like that.
Basically, the steps are:
- Inputs: envelope + recognizedPublicKeys (each with an associated name)
- Receive and decode the envelope.
- Verify each signature against each public key ==> set of verified public key names.
- Reject if the set of verified public key names is not acceptable. Usually this is "at least N unique names" (most often N=1), but any application-specific logic may be used. It should never be the case that deleting a signature turns a REJECT into a PASS (e.g. "all signatures valid" is wrong).
- Reject if payload type not supported.
- Parse and decode payload...
Explaining this clearly is a bit tricky though. @shizhMSFT do you want to send a PR for this?
Edit: added note about "reject -> pass".
@MarkLodato Sent PR #45 for formalized verification.
/cc @gokarnm Similar procedures can be applied to Notary v2 with trust policy defined.