Skip to content

Commit deca591

Browse files
authored
Merge pull request #43 from veraison/cowbon-patch-8
Enable sub-attesters content type selection and minor fixes
2 parents 222a456 + 2845ffe commit deca591

File tree

3 files changed

+65
-4
lines changed

3 files changed

+65
-4
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Ratsd currently supports the Trusted Secure Module `tsm` attester. You can speci
5959
```bash
6060
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
6161
```
62-
## Get evidence from the selected attester only
62+
### Get evidence from the selected attester only
6363

6464
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,
6565
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
7979
```
8080

8181
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.
82+
### Content type selection
83+
84+
Pick the desired output content type of each sub-attester
85+
by specifying field "content-type" in "attester-selection" as shown in
86+
the following example:
87+
```json
88+
"attester-selection": {
89+
"mock-tsm":{
90+
"content-type": "application/vnd.veraison.configfs-tsm+json",
91+
"privilege_level": "3"
92+
}
93+
}
94+
```

api/server.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,53 @@ func (s *Server) RatsdChares(w http.ResponseWriter, r *http.Request, param Ratsd
160160
return false
161161
}
162162

163+
outputCt := formatOut.Formats[0].ContentType
163164
params, hasOption := options[pn]
164165
if !hasOption || string(params) == "null" {
165166
params = json.RawMessage{}
167+
} else {
168+
attesterOptions := make(map[string]string)
169+
if err := json.Unmarshal(params, &attesterOptions); err != nil {
170+
errMsg := fmt.Sprintf(
171+
"failed to parse options for %s: %v", pn, err)
172+
p := &problems.DefaultProblem{
173+
Type: string(TagGithubCom2024VeraisonratsdErrorInvalidrequest),
174+
Title: string(InvalidRequest),
175+
Detail: errMsg,
176+
Status: http.StatusBadRequest,
177+
}
178+
s.reportProblem(w, p)
179+
return false
180+
}
181+
182+
validCt := false
183+
if desiredCt, ok := attesterOptions["content-type"]; ok {
184+
for _, f := range formatOut.Formats {
185+
if f.ContentType == desiredCt {
186+
outputCt = desiredCt
187+
validCt = true
188+
break
189+
}
190+
}
191+
192+
if !validCt {
193+
errMsg := fmt.Sprintf(
194+
"%s does not support content type %s", pn, desiredCt)
195+
p := &problems.DefaultProblem{
196+
Type: string(TagGithubCom2024VeraisonratsdErrorInvalidrequest),
197+
Title: string(InvalidRequest),
198+
Detail: errMsg,
199+
Status: http.StatusBadRequest,
200+
}
201+
s.reportProblem(w, p)
202+
return false
203+
}
204+
}
166205
}
167206

168-
s.logger.Info("output content type: ", formatOut.Formats[0].ContentType)
207+
s.logger.Info(pn, " output content type: ", outputCt)
169208
in := &compositor.EvidenceIn{
170-
ContentType: formatOut.Formats[0].ContentType,
209+
ContentType: outputCt,
171210
Nonce: nonce,
172211
Options: params,
173212
}

api/server_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,22 @@ func TestRatsdChares_invalid_body(t *testing.T) {
147147
tests := []struct{ name, body, msg string }{
148148
{"missing nonce", `{"noncee": "MIDBNH28iioisjPy"}`,
149149
"fail to retrieve nonce from the request"},
150-
{"invalid attester selecton",
150+
{"invalid attester selection",
151151
fmt.Sprintf(`{"nonce": "%s",
152152
"attester-selection": "attester-slection"}`, validNonce),
153153
"failed to parse attester selection: json: cannot unmarshal string into" +
154154
` Go value of type map[string]json.RawMessage`},
155155
{"no attester specified in selected mode", fmt.Sprintf(`{"nonce": "%s"}`, validNonce),
156156
"attester-selection must contain at least one attester"},
157+
{"invalid attester options",
158+
fmt.Sprintf(`{"nonce": "%s",
159+
"attester-selection": {"mock-tsm":"invalid"}}`, validNonce),
160+
"failed to parse options for mock-tsm: json: cannot unmarshal string into" +
161+
` Go value of type map[string]string`},
162+
{"request content type unavailable",
163+
fmt.Sprintf(`{"nonce": "%s",
164+
"attester-selection": {"mock-tsm":{"content-type":"invalid"}}}`, validNonce),
165+
"mock-tsm does not support content type invalid"},
157166
}
158167

159168
for _, tt := range tests {

0 commit comments

Comments
 (0)