rekor
rekor copied to clipboard
in-toto records don't contain signatures
Currently the in-toto type does not contain any signatures. This prevents users of in-toto records from verifying attestations that are stored in rekor's attestation stores.
Additionally, the IntotoObj.content.hash refers to the hash of the entire DSSE envelope where the Attestation in the stores only contains the payload of the DSSE. This prevents us from ensuring the attestation returned to us from Rekor's stores is what the IntotoObj on the merkle tree is describing unless we can reassemble the entire DSSE envelope byte-for-byte, which includes the signature.
@SantiagoTorres proposes storing the entire DSSE envelope as the Attestation
Stepping back a bit, I think we might want to rename (or maybe alias for compatibility) the in-toto type to be a DSSE envelope, since that's more semantically correct. An envelope stores:
{
"payload": "<Base64(SERIALIZED_BODY)>",
"payloadType": "<PAYLOAD_TYPE>",
"signatures": [{
"keyid": "<KEYID>",
"sig": "<Base64(SIGNATURE)>"
}]
}
A rekor entry is meant to encapsulate everything needed to verify the signature on a signed object. So we'd want to store:
- The hash of the "signed" content
- The public key(s)
- The signature(s)
Since envelopes can contain multiple signatures, we have a few options:
- Store one entry in rekor for one envelope, validating all the signatures (and then requiring multiple public keys)
- Store one entry in rekor for one envelope, validating at least one of the signatures (and only requiring one public key)
- Store multiple entries in rekor for one envelope, each with one valid signature and key
I think I prefer option 1 here, but I'm not strongly convinced.
Since DSSE uses PAE, we'll need to make sure the hash we store is in the PAE format, which includes the payloadType.
How often does someone append signatures on to an envelope and then trigger an upload without knowing the public key of the previous sig? If (1) is locked in, it would prevent someone from uploading to rekor in that situation.
(2) seems like a bad idea. The choice of the public key that would be in the entry isn't canonical, so someone reconstructing the entry wouldn't know ahead of time. I have a preference for (1) or (3)
Would you imagine (3) would deconstruct the envelope and throw away the sigs whose public keys aren't provided?
For what my 2 cents is worth,
How often does someone append signatures on to an envelope and then trigger an upload without knowing the public key of the previous sig?
This is a really good point. I personally can't imagine a case where I'd append a signature to something without verifying existing signatures but there's nothing preventing that use case from happening.
Would you imagine (3) would deconstruct the envelope and throw away the sigs whose public keys aren't provided?
I think throwing away unverified signatures may be the only real option there otherwise it would seem to have the same issue of option 2
I've only been able to work on this sporadically through the last week, but so far this is the rough code I have going down the path of option 1:
https://github.com/testifysec/rekor/commit/14666fd96a6126d7fb69c2749334fc1ea6f43a03
Haven't had a chance to test it yet
this should be fixed by #973