Skip to content

Commit

Permalink
[WIP] Cascade Plugin Prototype: Working
Browse files Browse the repository at this point in the history
Signed-off-by: Yogesh Deshpande <[email protected]>
  • Loading branch information
yogeshbdeshpande committed Nov 30, 2023
1 parent d96da31 commit 114fc8d
Show file tree
Hide file tree
Showing 18 changed files with 467 additions and 7 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ require (
github.com/veraison/cmw v0.1.0
github.com/veraison/corim v1.1.2-0.20230912171018-eeb7bd486d3c
github.com/veraison/dice v0.0.1
github.com/veraison/ear v1.1.2
github.com/veraison/ear v1.1.3-0.20231130183426-c7759f6f0da6
github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53
github.com/veraison/parsec v0.1.1-0.20230915122508-f31e6c9be40e
github.com/veraison/psatoken v1.2.0
Expand Down
7 changes: 5 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9
github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
Expand Down Expand Up @@ -1070,8 +1071,10 @@ github.com/veraison/corim v1.1.2-0.20230912171018-eeb7bd486d3c h1:do1Yj0d4uq+Sd4
github.com/veraison/corim v1.1.2-0.20230912171018-eeb7bd486d3c/go.mod h1:Vn9+tCyN2ljpQxYvM6rwu3hNqdVbWrdQ9hqMa1Jfxb0=
github.com/veraison/dice v0.0.1 h1:dOm7ByDN/r4WlDsGkEUXzdPMXgTvAPTAksQ8+BwBrD4=
github.com/veraison/dice v0.0.1/go.mod h1:QPMLc5LVMj08VZ+HNMYk4XxWoVYGAUBVm8Rd5V1hzxs=
github.com/veraison/ear v1.1.2 h1:Xs41FqAG8IyJaceqNFcX2+nf51Et1uyhmCJV8SZqw/8=
github.com/veraison/ear v1.1.2/go.mod h1:O3yKgZR04DWKHHiNxfXCMX9ky0cLVoC67TFks6JwEhI=
github.com/veraison/ear v1.1.3-0.20231130164136-ea589b65f3bf h1:hZUe1o0rpGQz67rQyMsXp4SneKQUhveKXDNlkZ461nQ=
github.com/veraison/ear v1.1.3-0.20231130164136-ea589b65f3bf/go.mod h1:O3yKgZR04DWKHHiNxfXCMX9ky0cLVoC67TFks6JwEhI=
github.com/veraison/ear v1.1.3-0.20231130183426-c7759f6f0da6 h1:GV2FS9DBAR6J+wi3OKGde+D6WuPUL+YKnoCIVpF1xu0=
github.com/veraison/ear v1.1.3-0.20231130183426-c7759f6f0da6/go.mod h1:O3yKgZR04DWKHHiNxfXCMX9ky0cLVoC67TFks6JwEhI=
github.com/veraison/eat v0.0.0-20210331113810-3da8a4dd42ff/go.mod h1:+kxt8iuFiVvKRs2VQ1Ho7bbAScXAB/kHFFuP5Biw19I=
github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53 h1:5gnX2TrGd/Xz8DOp2OaLtg/jLoIubSUTrgz6iZ58pJ4=
github.com/veraison/eat v0.0.0-20220117140849-ddaf59d69f53/go.mod h1:+kxt8iuFiVvKRs2VQ1Ho7bbAScXAB/kHFFuP5Biw19I=
Expand Down
1 change: 1 addition & 0 deletions scheme/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ SUBDIR += psa-iot
SUBDIR += tpm-enacttrust
SUBDIR += parsec-tpm
SUBDIR += parsec-cca
SUBDIR += cca-realm

clean: ; $(RM) -rf ./bin

Expand Down
15 changes: 15 additions & 0 deletions scheme/cca-realm/Makefile
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
32 changes: 32 additions & 0 deletions scheme/cca-realm/README.md
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="
}
]
}
}
```
33 changes: 33 additions & 0 deletions scheme/cca-realm/endorsement_handler.go
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
}
65 changes: 65 additions & 0 deletions scheme/cca-realm/endorsement_handler_test.go
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)
}
190 changes: 190 additions & 0 deletions scheme/cca-realm/evidence_handler.go
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
}
12 changes: 12 additions & 0 deletions scheme/cca-realm/plugin/Makefile
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
Loading

0 comments on commit 114fc8d

Please sign in to comment.