Skip to content

Commit c2da15a

Browse files
feat(lead verifier): verification API support
Add transparent support for the "lead verifier" mode where the usual challenge-response API accepts verification requests for composite evidence and dispatches them to the CE handler endpoint in VTS. The existing verification API logic is extended to: 1. Advertise collection types during content negotiation, as well as via the discovery interface. 2. Recognise requests for collection types that do not have an associated scheme plugin, and forward them to the CE handler. Signed-off-by: Thomas Fossati <[email protected]>
1 parent 0007733 commit c2da15a

File tree

12 files changed

+412
-32
lines changed

12 files changed

+412
-32
lines changed

api/api.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@ import "mime"
88
// parameters) and returns it in normalized form, i.e., with lowercase type,
99
// subtype and, optionally, parameter name. An error is returned if the
1010
// supplied media type is invalid.
11-
func NormalizeMediaType(mt string) (string, error) {
11+
// If dropParams is true, any parameters in the supplied media type are
12+
// discarded in the returned normalized media type.
13+
func NormalizeMediaType(mt string, dropParams bool) (string, error) {
1214
m, p, err := mime.ParseMediaType(mt)
1315
if err != nil {
1416
return "", err
1517
}
1618

19+
if dropParams {
20+
p = nil
21+
}
22+
1723
return mime.FormatMediaType(m, p), nil
1824
}

capability/well-known.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ const (
1111
)
1212

1313
type WellKnownInfo struct {
14-
PublicKey jwk.Key `json:"ear-verification-key,omitempty"`
15-
MediaTypes []string `json:"media-types,omitempty"`
16-
Schemes []string `json:"attestation-schemes,omitempty"`
17-
Version string `json:"version"`
18-
ServiceState string `json:"service-state"`
19-
ApiEndpoints map[string]string `json:"api-endpoints"`
14+
PublicKey jwk.Key `json:"ear-verification-key,omitempty"`
15+
MediaTypes []string `json:"media-types,omitempty"`
16+
CompositeEvidenceMediaTypes []string `json:"composite-evidence-media-types,omitempty"`
17+
Schemes []string `json:"attestation-schemes,omitempty"`
18+
Version string `json:"version"`
19+
ServiceState string `json:"service-state"`
20+
ApiEndpoints map[string]string `json:"api-endpoints"`
2021
}
2122

2223
var ssTrans = map[string]string{
@@ -38,19 +39,21 @@ func ServiceStateToAPI(ss string) string {
3839
func NewWellKnownInfoObj(
3940
key jwk.Key,
4041
mediaTypes []string,
42+
compositeEvidenceMediaTypes []string,
4143
schemes []string,
4244
version string,
4345
serviceState string,
4446
endpoints map[string]string,
4547
) (*WellKnownInfo, error) {
4648
// MUST be kept in sync with proto/state.proto
4749
obj := &WellKnownInfo{
48-
PublicKey: key,
49-
MediaTypes: mediaTypes,
50-
Schemes: schemes,
51-
Version: version,
52-
ServiceState: ServiceStateToAPI(serviceState),
53-
ApiEndpoints: endpoints,
50+
PublicKey: key,
51+
MediaTypes: mediaTypes,
52+
CompositeEvidenceMediaTypes: compositeEvidenceMediaTypes,
53+
Schemes: schemes,
54+
Version: version,
55+
ServiceState: ServiceStateToAPI(serviceState),
56+
ApiEndpoints: endpoints,
5457
}
5558

5659
return obj, nil

management/api/handler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ func (o Handler) GetManagementWellKnownInfo(c *gin.Context) {
256256
obj, err := capability.NewWellKnownInfoObj(
257257
nil, // key
258258
nil, // media types
259+
nil, // composite evidence media types
259260
o.Manager.SupportedSchemes,
260261
config.Version,
261262
"SERVICE_STATUS_READY",

provisioning/api/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func (o *Handler) GetWellKnownProvisioningInfo(c *gin.Context) {
207207
endpoints := getProvisioningEndpoints()
208208

209209
// Get final object with well known information
210-
obj, err := capability.NewWellKnownInfoObj(nil, mediaTypes, nil, version, state, endpoints)
210+
obj, err := capability.NewWellKnownInfoObj(nil, mediaTypes, nil, nil, version, state, endpoints)
211211
if err != nil {
212212
ReportProblem(c,
213213
http.StatusInternalServerError,

provisioning/provisioner/provisioner.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ func New(vtsClient vtsclient.IVTSClient) IProvisioner {
2727
}
2828

2929
func (p *Provisioner) IsSupportedMediaType(mt string) (bool, error) {
30-
normalizedMediaType, err := api.NormalizeMediaType(mt)
30+
dropParams := false
31+
normalizedMediaType, err := api.NormalizeMediaType(mt, dropParams)
3132
if err != nil {
3233
return false, fmt.Errorf("%w: validation failed for %s (%v)", ErrInputParam, mt, err)
3334
}

verification/api/handler.go

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ func (o *Handler) SubmitEvidence(c *gin.Context) {
357357
}
358358
}
359359

360-
isSupported, err := o.Verifier.IsSupportedMediaType(mediaType)
360+
isSupportedMediaType, err := o.Verifier.IsSupportedMediaType(mediaType)
361361
if err != nil {
362362
status := http.StatusInternalServerError
363363
if errors.Unwrap(err) == verifier.ErrInputParam {
@@ -368,6 +368,19 @@ func (o *Handler) SubmitEvidence(c *gin.Context) {
368368
return
369369
}
370370

371+
isSupportedCompositeEvidenceMediaType, err := o.Verifier.IsSupportedCompositeEvidenceMediaType(mediaType)
372+
if err != nil {
373+
status := http.StatusInternalServerError
374+
if errors.Unwrap(err) == verifier.ErrInputParam {
375+
status = http.StatusBadRequest
376+
}
377+
378+
ReportProblem(c, status, fmt.Sprintf("could not check composite evidence media type with verifier: %v", err))
379+
return
380+
}
381+
382+
isSupported := isSupportedMediaType || isSupportedCompositeEvidenceMediaType
383+
371384
if !isSupported {
372385
supportedMediaTypes, err := o.Verifier.SupportedMediaTypes()
373386
if err != nil {
@@ -379,6 +392,18 @@ func (o *Handler) SubmitEvidence(c *gin.Context) {
379392
return
380393
}
381394

395+
supportedCompositeEvidenceMediaTypes, err := o.Verifier.SupportedCompositeEvidenceMediaTypes()
396+
if err != nil {
397+
ReportProblem(c,
398+
http.StatusInternalServerError,
399+
fmt.Sprintf("could not get supported composite evidence media types from verifier: %v",
400+
err),
401+
)
402+
return
403+
}
404+
405+
supportedMediaTypes = append(supportedMediaTypes, supportedCompositeEvidenceMediaTypes...)
406+
382407
c.Header("Accept", strings.Join(supportedMediaTypes, ", "))
383408
ReportProblem(c,
384409
http.StatusUnsupportedMediaType,
@@ -411,8 +436,16 @@ func (o *Handler) SubmitEvidence(c *gin.Context) {
411436
// reported if something in the verifier or the connection goes wrong.
412437
// Any problems with the evidence are expected to be reported via the
413438
// attestation result.
414-
attestationResult, err := o.Verifier.ProcessEvidence(tenantID, session.Nonce,
415-
evidence, mediaType)
439+
var attestationResult []byte
440+
441+
if isSupportedMediaType {
442+
attestationResult, err = o.Verifier.ProcessEvidence(tenantID, session.Nonce,
443+
evidence, mediaType)
444+
} else if isSupportedCompositeEvidenceMediaType {
445+
attestationResult, err = o.Verifier.ProcessCompositeEvidence(tenantID, session.Nonce,
446+
evidence, mediaType)
447+
}
448+
416449
if err != nil {
417450
o.logger.Error(err)
418451
session.SetStatus(StatusFailed)
@@ -474,11 +507,27 @@ func (o *Handler) NewChallengeResponse(c *gin.Context) {
474507
if err != nil {
475508
ReportProblem(c,
476509
http.StatusInternalServerError,
477-
fmt.Sprintf("could not get media types form verifier: %v", err),
510+
fmt.Sprintf("could not get media types from verifier: %v", err),
478511
)
479512
return
480513
}
481514

515+
// In lead-verifier mode, we need to get the supported collection media types
516+
// from the verifier as well, to be able to create sessions that can accept
517+
// composite evidence.
518+
supportedCollectionMediaTypes, err := o.Verifier.SupportedCompositeEvidenceMediaTypes()
519+
if err != nil {
520+
ReportProblem(c,
521+
http.StatusInternalServerError,
522+
fmt.Sprintf("could not get collection media types from verifier: %v", err),
523+
)
524+
return
525+
}
526+
527+
// Note that if the node is not a lead-verifier, the supported collection
528+
// media types list is empty, which makes the following a no-op.
529+
supportedMediaTypes = append(supportedMediaTypes, supportedCollectionMediaTypes...)
530+
482531
id, session, err := newSession(nonce, supportedMediaTypes, ConfigSessionTTL)
483532
if err != nil {
484533
ReportProblem(c,
@@ -529,15 +578,20 @@ func (o *Handler) getVerificationMediaTypes() ([]string, error) {
529578
return o.Verifier.SupportedMediaTypes()
530579
}
531580

581+
func (o *Handler) getSupportedCompositeEvidenceMediaTypes() ([]string, error) {
582+
return o.Verifier.SupportedCompositeEvidenceMediaTypes()
583+
}
584+
532585
func (o *Handler) getVerificationServerVersionAndState() (string, string, error) {
533586
vtsState, err := o.Verifier.GetVTSState()
534587
if err != nil {
535588
return "", "", err
536589
}
590+
537591
version := vtsState.ServerVersion
538592
state := vtsState.Status.String()
539-
return version, state, nil
540593

594+
return version, state, nil
541595
}
542596

543597
func getVerificationEndpoints() map[string]string {
@@ -574,6 +628,16 @@ func (o *Handler) GetWellKnownVerificationInfo(c *gin.Context) {
574628
return
575629
}
576630

631+
// Get verification composite evidence media types
632+
compositeEvidenceMediaTypes, err := o.getSupportedCompositeEvidenceMediaTypes()
633+
if err != nil {
634+
ReportProblem(c,
635+
http.StatusInternalServerError,
636+
err.Error(),
637+
)
638+
return
639+
}
640+
577641
// Get verification server version and state
578642
version, state, err := o.getVerificationServerVersionAndState()
579643
if err != nil {
@@ -588,7 +652,7 @@ func (o *Handler) GetWellKnownVerificationInfo(c *gin.Context) {
588652
endpoints := getVerificationEndpoints()
589653

590654
// Get final object with well known information
591-
obj, err := capability.NewWellKnownInfoObj(key, mediaTypes, nil, version, state, endpoints)
655+
obj, err := capability.NewWellKnownInfoObj(key, mediaTypes, compositeEvidenceMediaTypes, nil, version, state, endpoints)
592656
if err != nil {
593657
ReportProblem(c,
594658
http.StatusInternalServerError,

0 commit comments

Comments
 (0)