From 6e4a06b7d7c07ebaafef4712855e01fa86dbf4ba Mon Sep 17 00:00:00 2001 From: Ian Chin Wang Date: Wed, 19 Mar 2025 14:44:52 -0400 Subject: [PATCH 1/3] Improve printing in api/server Signed-off-by: Ian Chin Wang --- api/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server.go b/api/server.go index 21b4c7c..3a6ecfe 100644 --- a/api/server.go +++ b/api/server.go @@ -165,7 +165,7 @@ func (s *Server) RatsdChares(w http.ResponseWriter, r *http.Request, param Ratsd params = json.RawMessage{} } - s.logger.Info("output content type: ", formatOut.Formats[0].ContentType) + s.logger.Info(pn, " output content type: ", formatOut.Formats[0].ContentType) in := &compositor.EvidenceIn{ ContentType: formatOut.Formats[0].ContentType, Nonce: nonce, From 508fc208ed879027a1cc0a58c522cf4e0b9b4ab9 Mon Sep 17 00:00:00 2001 From: Ian Chin Wang Date: Thu, 4 Sep 2025 10:34:34 -0400 Subject: [PATCH 2/3] Enable sub-attesters content type selection Now users may pick the desired output content type of each sub-attester by specifying field "content-type" in "attester-selection" as shown in the following example: "attester-selection": { "mock-tsm":{ "content-type": "application/vnd.veraison.configfs-tsm+json", "privilege_level": "3" } } Signed-off-by: Ian Chin Wang --- README.md | 15 ++++++++++++++- api/server.go | 43 +++++++++++++++++++++++++++++++++++++++++-- api/server_test.go | 9 +++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fbdfb65..63a83b3 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Ratsd currently supports the Trusted Secure Module `tsm` attester. You can speci ```bash curl -X POST http://localhost:8895/ratsd/chares -H "Content-type: application/vnd.veraison.chares+json" -d '{"nonce": "TUlEQk5IMjhpaW9pc2pQeXh4eHh4eHh4eHh4eHh4eHhNSURCTkgyOGlpb2lzalB5eHh4eHh4eHh4eHh4eHh4eA", tsm-report:{"privilege_level": "$level"}}' # Replace $level with a number from 0 to 3 ``` -## Get evidence from the selected attester only +### Get evidence from the selected attester only If more than one leaf attesters present, ratsd adds the evidence generated by all attesters to the response of `/ratsd/chares`. To limit the output to the selected attester, add `list-options: selected` to config.yaml, then specify the name of each attester along with the associated options in `attester-selection`. If the user does not wish to specify the attester-specific option, "$attester_name": "null" should be specified. The following is an example of the request: @@ -79,3 +79,16 @@ If more than one leaf attesters present, ratsd adds the evidence generated by al ``` If `list-options` is not set, or if it's set to `all` in config.yaml, ratsd populates the EAT with CMW from all available attesters as the default behavior. +### Content type selection + +Pick the desired output content type of each sub-attester +by specifying field "content-type" in "attester-selection" as shown in +the following example: +```json +"attester-selection": { + "mock-tsm":{ + "content-type": "application/vnd.veraison.configfs-tsm+json", + "privilege_level": "3" + } +} +``` diff --git a/api/server.go b/api/server.go index 3a6ecfe..264dff5 100644 --- a/api/server.go +++ b/api/server.go @@ -160,14 +160,53 @@ func (s *Server) RatsdChares(w http.ResponseWriter, r *http.Request, param Ratsd return false } + outputCt := formatOut.Formats[0].ContentType params, hasOption := options[pn] if !hasOption || string(params) == "null" { params = json.RawMessage{} + } else { + attesterOptions := make(map[string]string) + if err := json.Unmarshal(params, &attesterOptions); err != nil { + errMsg := fmt.Sprintf( + "failed to parse options for %s: %v", pn, err) + p := &problems.DefaultProblem{ + Type: string(TagGithubCom2024VeraisonratsdErrorInvalidrequest), + Title: string(InvalidRequest), + Detail: errMsg, + Status: http.StatusBadRequest, + } + s.reportProblem(w, p) + return false + } + + validCt := false + if desiredCt, ok := attesterOptions["content-type"]; ok { + for _, f := range formatOut.Formats { + if f.ContentType == desiredCt { + outputCt = desiredCt + validCt = true + break + } + } + + if !validCt { + errMsg := fmt.Sprintf( + "%s does not support content type %s", pn, desiredCt) + p := &problems.DefaultProblem{ + Type: string(TagGithubCom2024VeraisonratsdErrorInvalidrequest), + Title: string(InvalidRequest), + Detail: errMsg, + Status: http.StatusBadRequest, + } + s.reportProblem(w, p) + return false + } + } } - s.logger.Info(pn, " output content type: ", formatOut.Formats[0].ContentType) + s.logger.Info(pn, " output content type: ", outputCt) in := &compositor.EvidenceIn{ - ContentType: formatOut.Formats[0].ContentType, + ContentType: outputCt, Nonce: nonce, Options: params, } diff --git a/api/server_test.go b/api/server_test.go index 14eded2..08bb222 100644 --- a/api/server_test.go +++ b/api/server_test.go @@ -154,6 +154,15 @@ func TestRatsdChares_invalid_body(t *testing.T) { ` Go value of type map[string]json.RawMessage`}, {"no attester specified in selected mode", fmt.Sprintf(`{"nonce": "%s"}`, validNonce), "attester-selection must contain at least one attester"}, + {"invalid attester options", + fmt.Sprintf(`{"nonce": "%s", + "attester-selection": {"mock-tsm":"invalid"}}`, validNonce), + "failed to parse options for mock-tsm: json: cannot unmarshal string into" + + ` Go value of type map[string]string`}, + {"request content type unavailable", + fmt.Sprintf(`{"nonce": "%s", + "attester-selection": {"mock-tsm":{"content-type":"invalid"}}}`, validNonce), + "mock-tsm does not support content type invalid"}, } for _, tt := range tests { From 2845ffebf5bac95a93a598a009aa65fa00faa878 Mon Sep 17 00:00:00 2001 From: Ian Chin Wang Date: Wed, 19 Mar 2025 15:50:11 -0400 Subject: [PATCH 3/3] Fix typo "selecton" to "selection" Signed-off-by: Ian Chin Wang --- api/server_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server_test.go b/api/server_test.go index 08bb222..b6c1957 100644 --- a/api/server_test.go +++ b/api/server_test.go @@ -147,7 +147,7 @@ func TestRatsdChares_invalid_body(t *testing.T) { tests := []struct{ name, body, msg string }{ {"missing nonce", `{"noncee": "MIDBNH28iioisjPy"}`, "fail to retrieve nonce from the request"}, - {"invalid attester selecton", + {"invalid attester selection", fmt.Sprintf(`{"nonce": "%s", "attester-selection": "attester-slection"}`, validNonce), "failed to parse attester selection: json: cannot unmarshal string into" +