Implement handling of COSE_KeySet and TTL payload#42
Conversation
This is required to use the new cose.Key struct in order to parse a TTL (COSE_KeySet, which is an array pf COSE_Key objects, which the new version of go-cose contain parsing code for). Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Assisted-by: GitHub Copilot:claude-opus-4.8 Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
…stead of fetching keys. Assisted-by: GitHub Copilot:auto copilot-review Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
There was a problem hiding this comment.
Pull request overview
Adds COSE_KeySet support so ledger public keys can be supplied/serialized in a CBOR/COSE-native format (intended for ledger TTL scenarios), and updates the sign1util CLI to consume and produce these keysets.
Changes:
- Introduce
pkg/cosesign1.ParseKeySetAsMapto parse a COSE_KeySet (CBOR array of COSE_Key) into akid -> crypto.PublicKeymap. - Extend
cmd/sign1utilto accept preloaded per-ledger keysets (--ledger-keyset) and addfetch-ledger-keysetto fetch a ledger JWKS and write it as a COSE_KeySet. - Bump Go/tooling and dependency versions (CBOR + go-cose), and make
pkg/errorsa direct dependency.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/cosesign1/keyset.go | New COSE_KeySet parser to build kid -> PublicKey maps for receipt validation. |
| pkg/cosesign1/check.go | Documentation update describing how callers should obtain the kid -> PublicKey map. |
| cmd/sign1util/main.go | Add --ledger-keyset handling and new fetch-ledger-keyset subcommand. |
| cmd/sign1util/ccf_keyfetch.go | Return JWKS results as both map+list; add encoder to emit COSE_KeySet; support preloaded per-ledger keys. |
| go.mod | Bump go directive and update direct dependencies (cbor/go-cose) + add pkg/errors direct. |
| go.sum | Dependency checksum updates corresponding to the version bumps. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // map from key IDs to public keys, to be used for receipt validation. | ||
| // | ||
| // Reference: https://www.rfc-editor.org/rfc/rfc9052.html#name-cose-keys | ||
| func ParseKeySetAsMap(data []byte) (map[string]crypto.PublicKey, error) { |
There was a problem hiding this comment.
We don't have an actual known-good TTL to test against so leaving this for now.
There was a problem hiding this comment.
Can we not generate one from ESRP and check it in as a testcases after having validated it against the CDDL?
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
40cc0ca to
4657387
Compare
Assisted-by: GitHub Copilot:auto copilot-review Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Assisted-by: GitHub Copilot copilot-review Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
4657387 to
2769580
Compare
| // their `kid` as either a map or a list. If verifyCert is not nil, the leaf | ||
| // certificate presented by the server is passed to verifyCert. The issuer host | ||
| // is validated against allowedDomains before any network request is made. | ||
| func fetchIssuerJWKS(issuer string, allowedDomains []string, verifyCert CertVerifier) (outMap map[string]crypto.PublicKey, outList []kidWithParsedKey, err error) { |
There was a problem hiding this comment.
Recent versions of scitt-ccf-ledger implement .well-known/scitt-key, as well as /jwks.
It would be good to check if that's rolled out already or when it is, to switch to it, because:
- It's going to be the standard endpoint, and so it is more durable long term
- It does not require conversion from JWK to COSE_Key
There was a problem hiding this comment.
https://esrp-cts-dev.confidential-ledger.azure.com/.well-known/scitt-keys (or scitt-key) still returns 404. I will make this use the scitt-keys endpoint when it's available in a future PR.
| "time" | ||
|
|
||
| "github.com/Microsoft/cosesign1go/pkg/cosesign1" | ||
| "github.com/fxamacker/cbor/v2" |
There was a problem hiding this comment.
It's unfortunate there is not a go version of EverCBOR, I wonder if it's worth bringing up with Tahina?
| }, | ||
| cli.StringFlag{ | ||
| Name: "ttl", | ||
| Usage: "Optional path to a file containing an unsigned Transparency Trust List (TTL) payload, which is a CBOR map from issuer to COSE_KeySet. When a receipt's issuer is present in the TTL, its keys are used to validate the receipt instead of fetching the ledger's JWKS.", |
There was a problem hiding this comment.
COSE_Keys ideally, rather than JWKs
There was a problem hiding this comment.
Removed reference to JWKs here.
achamayou
left a comment
There was a problem hiding this comment.
LGTM, modulo a few wishes in comments.
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
TTLs (Transparency Trust Lists) are a signed list of ledger keys. This PR implement the parsing of its payload.
sign1util is enhanced to add ability to generate an unsigned TTL from cli, and also the ability to use an unsigned TTL with the
checkcommand.Reference:
https://www.rfc-editor.org/rfc/rfc9052.html#name-cose-keys
https://github.com/achamayou/scitt-ccf-ledger/blob/ttl/docs/transparent_trust_lists.md#payload