-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WIP] Cascade Plugin Prototype: Working
Signed-off-by: Yogesh Deshpande <[email protected]>
- Loading branch information
1 parent
d96da31
commit 114fc8d
Showing
18 changed files
with
467 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright 2023 Contributors to the Veraison project. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
.DEFAULT_GOAL := test | ||
|
||
GOPKG := github.com/veraison/services/scheme/cca-realm | ||
SRCS := $(wildcard *.go) | ||
|
||
SUBDIR += plugin | ||
|
||
include ../../mk/common.mk | ||
include ../../mk/lint.mk | ||
include ../../mk/pkg.mk | ||
include ../../mk/subdir.mk | ||
include ../../mk/test.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Endorsement Store Interface | ||
|
||
## Reference Value | ||
|
||
```json | ||
{ | ||
"scheme": "CCA_REALM", | ||
"type": "REFERENCE_VALUE", | ||
"attributes": { | ||
"cca_realm.vendor": "Worload Client Ltd", | ||
"cca_realm.id": "CD1F0E55-26F9-460D-B9D8-F7FDE171787C", | ||
"cca_realm.alg-id": "sha-256", | ||
"cca_realm.measurement-array": [ | ||
{ | ||
"measurement-value": "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" | ||
}, | ||
{ | ||
"measurement-value": "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" | ||
}, | ||
{ | ||
"measurement-value": "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" | ||
}, | ||
{ | ||
"measurement-value": "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" | ||
}, | ||
{ | ||
"measurement-value": "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc=" | ||
} | ||
] | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright 2022-2023 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
package cca_realm | ||
|
||
import ( | ||
"github.com/veraison/services/handler" | ||
) | ||
|
||
type EndorsementHandler struct{} | ||
|
||
func (o EndorsementHandler) Init(params handler.EndorsementHandlerParams) error { | ||
return nil // no-op | ||
} | ||
|
||
func (o EndorsementHandler) Close() error { | ||
return nil // no-op | ||
} | ||
|
||
func (o EndorsementHandler) GetName() string { | ||
return "unsigned-corim (CCA realm profile)" | ||
} | ||
|
||
func (o EndorsementHandler) GetAttestationScheme() string { | ||
return SchemeName | ||
} | ||
|
||
func (o EndorsementHandler) GetSupportedMediaTypes() []string { | ||
return EndorsementMediaTypes | ||
} | ||
|
||
func (o EndorsementHandler) Decode(data []byte) (*handler.EndorsementHandlerResponse, error) { | ||
return nil, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2022-2023 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
package cca_realm | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestDecoder_GetAttestationScheme(t *testing.T) { | ||
d := &EndorsementHandler{} | ||
|
||
expected := SchemeName | ||
|
||
actual := d.GetAttestationScheme() | ||
|
||
assert.Equal(t, expected, actual) | ||
} | ||
|
||
func TestDecoder_GetSupportedMediaTypes(t *testing.T) { | ||
d := &EndorsementHandler{} | ||
|
||
expected := EndorsementMediaTypes | ||
|
||
actual := d.GetSupportedMediaTypes() | ||
|
||
assert.Equal(t, expected, actual) | ||
} | ||
|
||
func TestDecoder_Init(t *testing.T) { | ||
d := &EndorsementHandler{} | ||
|
||
assert.Nil(t, d.Init(nil)) | ||
} | ||
|
||
func TestDecoder_Close(t *testing.T) { | ||
d := &EndorsementHandler{} | ||
|
||
assert.Nil(t, d.Close()) | ||
} | ||
|
||
func TestDecoder_Decode_empty_data(t *testing.T) { | ||
d := &EndorsementHandler{} | ||
|
||
emptyData := []byte{} | ||
|
||
expectedErr := `empty data` | ||
|
||
_, err := d.Decode(emptyData) | ||
|
||
assert.EqualError(t, err, expectedErr) | ||
} | ||
|
||
func TestDecoder_Decode_invalid_data(t *testing.T) { | ||
d := &EndorsementHandler{} | ||
|
||
invalidCbor := []byte("invalid CBOR") | ||
|
||
expectedErr := `CBOR decoding failed: cbor: cannot unmarshal UTF-8 text string into Go value of type corim.UnsignedCorim` | ||
|
||
_, err := d.Decode(invalidCbor) | ||
|
||
assert.EqualError(t, err, expectedErr) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
// Copyright 2021-2023 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package cca_realm | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/veraison/ccatoken" | ||
"github.com/veraison/ear" | ||
"github.com/veraison/psatoken" | ||
"github.com/veraison/services/handler" | ||
"github.com/veraison/services/log" | ||
"github.com/veraison/services/proto" | ||
"github.com/veraison/services/scheme/common" | ||
"github.com/veraison/services/scheme/common/arm" | ||
) | ||
|
||
type EvidenceHandler struct{} | ||
|
||
func (s EvidenceHandler) GetName() string { | ||
return "cca-realm-evidence-handler" | ||
} | ||
|
||
func (s EvidenceHandler) GetAttestationScheme() string { | ||
return SchemeName | ||
} | ||
|
||
func (s EvidenceHandler) GetSupportedMediaTypes() []string { | ||
return EvidenceMediaTypes | ||
} | ||
|
||
func (s EvidenceHandler) SynthKeysFromRefValue( | ||
tenantID string, | ||
refVal *handler.Endorsement, | ||
) ([]string, error) { | ||
return arm.SynthKeysFromRefValue(SchemeName, tenantID, refVal) | ||
|
||
} | ||
|
||
func (s EvidenceHandler) SynthKeysFromTrustAnchor(tenantID string, ta *handler.Endorsement) ([]string, error) { | ||
|
||
return nil, fmt.Errorf("unsupported method SynthKeysFromTrustAnchor() for realm verification plugin") | ||
} | ||
|
||
func (s EvidenceHandler) GetTrustAnchorID(token *proto.AttestationToken) (string, error) { | ||
log.Debug("Yogesh: REALM: GetTrustAnchorID invoked") | ||
return "", nil | ||
} | ||
|
||
func (s EvidenceHandler) ExtractClaims( | ||
token *proto.AttestationToken, | ||
trustAnchor string, | ||
) (*handler.ExtractedClaims, error) { | ||
|
||
var ccaToken ccatoken.Evidence | ||
log.Debug("Yogesh: REALM: ExtractClaims invoked") | ||
if err := ccaToken.FromCBOR(token.Data); err != nil { | ||
return nil, handler.BadEvidence(err) | ||
} | ||
|
||
var extracted handler.ExtractedClaims | ||
|
||
platformClaimsSet, err := common.ClaimsToMap(ccaToken.PlatformClaims) | ||
if err != nil { | ||
return nil, handler.BadEvidence(fmt.Errorf( | ||
"could not convert platform claims: %w", err)) | ||
} | ||
|
||
realmClaimsSet, err := common.ClaimsToMap(ccaToken.RealmClaims) | ||
if err != nil { | ||
return nil, handler.BadEvidence(fmt.Errorf( | ||
"could not convert realm claims: %w", err)) | ||
} | ||
|
||
extracted.ClaimsSet = map[string]interface{}{ | ||
"platform": platformClaimsSet, | ||
"realm": realmClaimsSet, | ||
} | ||
|
||
extracted.ReferenceID = arm.RefValLookupKey( | ||
SchemeName, | ||
token.TenantId, | ||
arm.MustImplIDString(ccaToken.PlatformClaims), | ||
) | ||
log.Debugf("extracted Reference ID Key = %s", extracted.ReferenceID) | ||
return &extracted, nil | ||
} | ||
|
||
// ValidateEvidenceIntegrity, decodes CCA collection and then invokes Verify API of ccatoken library | ||
// which verifies the signature on the platform part of CCA collection, using supplied trust anchor | ||
// and internally verifies the realm part of CCA token using realm public key extracted from | ||
// realm token. | ||
func (s EvidenceHandler) ValidateEvidenceIntegrity( | ||
token *proto.AttestationToken, | ||
trustAnchor string, | ||
endorsementsStrings []string, | ||
) error { | ||
log.Debug(" Yogesh: Realm: ValidateEvidence Integrity invoked") | ||
// Please note this part of Evidence Validation is already done in the Platform part | ||
log.Debug("CCA platform token signature, realm token signature and cryptographic binding verified") | ||
return nil | ||
} | ||
|
||
func (s EvidenceHandler) AppraiseEvidence( | ||
ec *proto.EvidenceContext, endorsementsStrings []string, | ||
) (*ear.AttestationResult, error) { | ||
var endorsements []handler.Endorsement // nolint:prealloc | ||
log.Debug(" Yogesh: Realm: AppraiseEvidence invoked") | ||
result := handler.CreateAttestationResult(SchemeName) | ||
|
||
for i, e := range endorsementsStrings { | ||
var endorsement handler.Endorsement | ||
|
||
if err := json.Unmarshal([]byte(e), &endorsement); err != nil { | ||
return nil, fmt.Errorf("could not decode endorsement at index %d: %w", i, err) | ||
} | ||
|
||
endorsements = append(endorsements, endorsement) | ||
} | ||
|
||
err := populateAttestationResult(result, ec.Evidence.AsMap(), endorsements) | ||
|
||
// TO DO: Handle Unprocessed evidence when new Attestation Result interface | ||
// is ready. Please see issue #105 | ||
return result, err | ||
} | ||
|
||
func populateAttestationResult( | ||
result *ear.AttestationResult, | ||
evidence map[string]interface{}, | ||
endorsements []handler.Endorsement, | ||
) error { | ||
claims, err := common.MapToClaims(evidence["platform"].(map[string]interface{})) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
appraisal := result.Submods[SchemeName] | ||
|
||
// once the signature on the token is verified, we can claim the HW is | ||
// authentic | ||
appraisal.TrustVector.Hardware = ear.GenuineHardwareClaim | ||
|
||
rawLifeCycle, err := claims.GetSecurityLifeCycle() | ||
if err != nil { | ||
return handler.BadEvidence(err) | ||
} | ||
|
||
lifeCycle := psatoken.CcaLifeCycleToState(rawLifeCycle) | ||
if lifeCycle == psatoken.CcaStateSecured || | ||
lifeCycle == psatoken.CcaStateNonCcaPlatformDebug { | ||
appraisal.TrustVector.InstanceIdentity = ear.TrustworthyInstanceClaim | ||
appraisal.TrustVector.RuntimeOpaque = ear.ApprovedRuntimeClaim | ||
appraisal.TrustVector.StorageOpaque = ear.HwKeysEncryptedSecretsClaim | ||
} else { | ||
appraisal.TrustVector.InstanceIdentity = ear.UntrustworthyInstanceClaim | ||
appraisal.TrustVector.RuntimeOpaque = ear.VisibleMemoryRuntimeClaim | ||
appraisal.TrustVector.StorageOpaque = ear.UnencryptedSecretsClaim | ||
} | ||
|
||
swComps := arm.FilterRefVal(endorsements, "CCA_SSD_PLATFORM.sw-component") | ||
match := arm.MatchSoftware(SchemeName, claims, swComps) | ||
if match { | ||
appraisal.TrustVector.Executables = ear.ApprovedRuntimeClaim | ||
log.Debug("matchSoftware Success") | ||
|
||
} else { | ||
appraisal.TrustVector.Executables = ear.UnrecognizedRuntimeClaim | ||
log.Debug("matchSoftware Failed") | ||
} | ||
|
||
platformConfig := arm.FilterRefVal(endorsements, "CCA_SSD_PLATFORM.platform-config") | ||
match = arm.MatchPlatformConfig(SchemeName, claims, platformConfig) | ||
|
||
if match { | ||
appraisal.TrustVector.Configuration = ear.ApprovedConfigClaim | ||
log.Debug("matchPlatformConfig Success") | ||
|
||
} else { | ||
appraisal.TrustVector.Configuration = ear.UnsafeConfigClaim | ||
log.Debug("matchPlatformConfig Failed") | ||
} | ||
appraisal.UpdateStatusFromTrustVector() | ||
|
||
appraisal.VeraisonAnnotatedEvidence = &evidence | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Copyright 2023 Contributors to the Veraison project. | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
ifndef COMBINED_PLUGINS | ||
SUBDIR += endorsement-handler | ||
SUBDIR += evidence-handler | ||
else | ||
SUBDIR += combined | ||
endif | ||
|
||
include ../../../mk/common.mk | ||
include ../../../mk/subdir.mk |
Oops, something went wrong.