Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CoRIM extension mechanisms #96

Merged
merged 5 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-go-cover.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
steps:
- uses: actions/setup-go@v2
with:
go-version: "1.18"
go-version: "1.19"
- name: Checkout code
uses: actions/checkout@v2
- name: Install mockgen
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/linters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
steps:
- uses: actions/setup-go@v2
with:
go-version: "1.18"
go-version: "1.19"
- name: Checkout code
uses: actions/checkout@v2
- name: Install golangci-lint
Expand Down
12 changes: 4 additions & 8 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ linters-settings:
- octalLiteral
- paramTypeCombine
- whyNoLint
- wrapperFunc
- wrapperFunc
gofmt:
simplify: false
simplify: false
goimports:
golint:
min-confidence: 0
Expand All @@ -40,24 +40,20 @@ linters-settings:
linters:
disable-all: true
enable:
- deadcode
- errcheck
- goconst
- gocyclo
- gofmt
- goimports
- golint
- gosec
- govet
- ineffassign
- maligned
- misspell
- revive
- staticcheck
- structcheck
- typecheck
- unconvert
- unused
- varcheck


issues:
Expand All @@ -72,7 +68,7 @@ issues:
- goconst
- dupl
- gomnd
- lll
- lll
- path: doc\.go
linters:
- goimports
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ GOPKG := github.com/veraison/corim/corim
GOPKG += github.com/veraison/corim/comid
GOPKG += github.com/veraison/corim/cots
GOPKG += github.com/veraison/corim/cocli/cmd
GOPKG += github.com/veraison/corim/encoding
GOPKG += github.com/veraison/corim/extensions

MOCKGEN := $(shell go env GOPATH)/bin/mockgen
INTERFACES := cocli/cmd/isubmitter.go
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,16 @@ Before requesting a PR (and routinely during the dev/test cycle), you are encour
make presubmit
```
and check its output to make sure your code coverage figures are in line with the set target and that there are no newly introduced lint problems.

## Extending CoRIM/CoMID

The CoRIM specification provides a mechanism for adding extensions to the base
CoRIM schema. The `corim` and `comid` structs which can be extended, embed an
`Extensions` object that allows registering a wrapper structure defining
extension fields. For field types that can be extended, i.e. `type choice`,
extensions can be implemented by calling an appropriate registration function
and giving it a new type or a value (for enums).

Please see [extensions documentation](extensions/README.md) for details.


4 changes: 2 additions & 2 deletions cocli/cmd/corimCreate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func Test_CorimCreateCmd_with_a_bad_comid(t *testing.T) {
cmd.SetArgs(args)

err = cmd.Execute()
assert.EqualError(t, err, `error loading CoMID from bad-comid.cbor: cbor: unexpected "break" code`)
assert.EqualError(t, err, `error loading CoMID from bad-comid.cbor: expected map (CBOR Major Type 5), found Major Type 7`)
}

func Test_CorimCreateCmd_with_an_invalid_comid(t *testing.T) {
Expand All @@ -138,7 +138,7 @@ func Test_CorimCreateCmd_with_an_invalid_comid(t *testing.T) {
cmd.SetArgs(args)

err = cmd.Execute()
assert.EqualError(t, err, `error adding CoMID from invalid-comid.cbor (check its validity using the "comid validate" sub-command)`)
assert.EqualError(t, err, `error loading CoMID from invalid-comid.cbor: missing mandatory field "Triples" (4)`)
}

func Test_CorimCreateCmd_with_a_bad_coswid(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cocli/cmd/corimDisplay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func Test_CorimDisplayCmd_invalid_signed_corim(t *testing.T) {
require.NoError(t, err)

err = cmd.Execute()
assert.EqualError(t, err, "error decoding signed CoRIM from invalid.cbor: failed validation of unsigned CoRIM: empty id")
assert.EqualError(t, err, `error decoding signed CoRIM from invalid.cbor: failed CBOR decoding of unsigned CoRIM: unexpected EOF`)
}

func Test_CorimDisplayCmd_ok_top_level_view(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cocli/cmd/corimExtract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func Test_CorimExtractCmd_invalid_signed_corim(t *testing.T) {
require.NoError(t, err)

err = cmd.Execute()
assert.EqualError(t, err, "error decoding signed CoRIM from invalid.cbor: failed validation of unsigned CoRIM: empty id")
assert.EqualError(t, err, `error decoding signed CoRIM from invalid.cbor: failed CBOR decoding of unsigned CoRIM: unexpected EOF`)
}

func Test_CorimExtractCmd_ok_save_to_default_dir(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions cocli/cmd/corimSign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func Test_CorimSignCmd_bad_unsigned_corim(t *testing.T) {
require.NoError(t, err)

err = cmd.Execute()
assert.EqualError(t, err, "error decoding unsigned CoRIM from bad.txt: unexpected EOF")
assert.EqualError(t, err, "error decoding unsigned CoRIM from bad.txt: expected map (CBOR Major Type 5), found Major Type 3")
}

func Test_CorimSignCmd_invalid_unsigned_corim(t *testing.T) {
Expand All @@ -109,7 +109,7 @@ func Test_CorimSignCmd_invalid_unsigned_corim(t *testing.T) {
require.NoError(t, err)

err = cmd.Execute()
assert.EqualError(t, err, "error validating CoRIM: tags validation failed: no tags")
assert.EqualError(t, err, `error decoding unsigned CoRIM from invalid.cbor: missing mandatory field "Tags" (1)`)
}

func Test_CorimSignCmd_non_existent_meta_file(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions comid/attestverifkey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ func TestAttestVerifKey_Valid_empty(t *testing.T) {
testerr: "environment validation failed: environment must not be empty",
},
{
env: Environment{Instance: NewInstanceUEID(TestUEID)},
env: Environment{Instance: MustNewUEIDInstance(TestUEID)},
verifkey: CryptoKeys{},
testerr: "verification keys validation failed: no keys to validate",
},
{
env: Environment{Instance: NewInstanceUEID(TestUEID)},
env: Environment{Instance: MustNewUEIDInstance(TestUEID)},
verifkey: CryptoKeys{&invalidKey},
testerr: "verification keys validation failed: invalid key at index 0: key value not set",
},
}

for _, tv := range tvs {
av := AttestVerifKey{Environment: tv.env, VerifKeys: tv.verifkey}
err := av.Valid()
Expand Down
31 changes: 27 additions & 4 deletions comid/cbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package comid

import (
"fmt"
"reflect"

cbor "github.com/fxamacker/cbor/v2"
Expand All @@ -12,16 +13,14 @@ import (
var (
em, emError = initCBOREncMode()
dm, dmError = initCBORDecMode()
)

func comidTags() cbor.TagSet {
comidTagsMap := map[uint64]interface{}{
comidTagsMap = map[uint64]interface{}{
32: TaggedURI(""),
37: TaggedUUID{},
111: TaggedOID{},
// CoMID tags
550: TaggedUEID{},
//551: To Do see: https://github.com/veraison/corim/issues/32
551: TaggedInt(0),
552: TaggedSVN(0),
553: TaggedMinSVN(0),
554: TaggedPKIXBase64Key(""),
Expand All @@ -37,7 +36,9 @@ func comidTags() cbor.TagSet {
601: TaggedPSARefValID{},
602: TaggedCCAPlatformConfigID(""),
}
)

func comidTags() cbor.TagSet {
opts := cbor.TagOptions{
EncTag: cbor.EncTagRequired,
DecTag: cbor.DecTagRequired,
Expand Down Expand Up @@ -69,6 +70,28 @@ func initCBORDecMode() (dm cbor.DecMode, err error) {
return decOpt.DecModeWithTags(comidTags())
}

func registerCOMIDTag(tag uint64, t interface{}) error {
if _, exists := comidTagsMap[tag]; exists {
return fmt.Errorf("tag %d is already registered", tag)
}

comidTagsMap[tag] = t

var err error

em, err = initCBOREncMode()
if err != nil {
return err
}

dm, err = initCBORDecMode()
if err != nil {
return err
}

return nil
}

func init() {
if emError != nil {
panic(emError)
Expand Down
75 changes: 72 additions & 3 deletions comid/ccaplatformconfigid.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@

package comid

import "fmt"
import (
"encoding/json"
"errors"
"fmt"
"unicode/utf8"
)

type CCAPlatformConfigID string
var CCAPlatformConfigIDType = "cca.platform-config-id"
thomas-fossati marked this conversation as resolved.
Show resolved Hide resolved

type TaggedCCAPlatformConfigID CCAPlatformConfigID
type CCAPlatformConfigID string

func (o CCAPlatformConfigID) Empty() bool {
return o == ""
Expand All @@ -27,3 +32,67 @@ func (o CCAPlatformConfigID) Get() (CCAPlatformConfigID, error) {
}
return o, nil
}

type TaggedCCAPlatformConfigID CCAPlatformConfigID

func NewTaggedCCAPlatformConfigID(val any) (*TaggedCCAPlatformConfigID, error) {
var ret TaggedCCAPlatformConfigID

if val == nil {
return &ret, nil
}

switch t := val.(type) {
case TaggedCCAPlatformConfigID:
ret = t
case *TaggedCCAPlatformConfigID:
ret = *t
case CCAPlatformConfigID:
ret = TaggedCCAPlatformConfigID(t)
case *CCAPlatformConfigID:
ret = TaggedCCAPlatformConfigID(*t)
case string:
ret = TaggedCCAPlatformConfigID(t)
case []byte:
if !utf8.Valid(t) {
return nil, errors.New("bytes do not form a valid UTF-8 string")
}
ret = TaggedCCAPlatformConfigID(t)
default:
return nil, fmt.Errorf("unexpected type for CCA platform-config-id: %T", t)
}

return &ret, nil
}

func (o TaggedCCAPlatformConfigID) Valid() error {
if o == "" {
return errors.New("empty value")
}

return nil
}

func (o TaggedCCAPlatformConfigID) String() string {
return string(o)
}

func (o TaggedCCAPlatformConfigID) Type() string {
return CCAPlatformConfigIDType
}

func (o TaggedCCAPlatformConfigID) IsZero() bool {
return len(o) == 0
}

func (o *TaggedCCAPlatformConfigID) UnmarshalJSON(data []byte) error {
var temp string

if err := json.Unmarshal(data, &temp); err != nil {
return err
}

*o = TaggedCCAPlatformConfigID(temp)

return nil
}
64 changes: 64 additions & 0 deletions comid/ccaplatformconfigid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,67 @@ func TestCCAPlatformConfigID_Get_nok(t *testing.T) {
_, err := cca.Get()
assert.EqualError(t, err, expectedErr)
}

func TestNewTaggedCCAPlatformConfigID(t *testing.T) {
testID := TaggedCCAPlatformConfigID("test")
untagged := CCAPlatformConfigID("test")

for _, tv := range []struct {
Name string
Input any
Err string
Expected TaggedCCAPlatformConfigID
}{
{
Name: "TaggedCCAPlatformConfigID ok",
Input: testID,
Expected: testID,
},
{
Name: "*TaggedCCAPlatformConfigID ok",
Input: &testID,
Expected: testID,
},
{
Name: "CCAPlatformConfigID ok",
Input: untagged,
Expected: testID,
},
{
Name: "*CCAPlatformConfigID ok",
Input: &untagged,
Expected: testID,
},
{
Name: "string ok",
Input: "test",
Expected: testID,
},
{
Name: "[]byte ok",
Input: []byte{0x74, 0x65, 0x73, 0x74},
Expected: testID,
},
{
Name: "[]byte not ok",
Input: []byte{0x80, 0x65, 0x73, 0x74},
Err: "bytes do not form a valid UTF-8 string",
},
{
Name: "bad type",
Input: 7,
Err: "unexpected type for CCA platform-config-id: int",
},
} {
t.Run(tv.Name, func(t *testing.T) {
out, err := NewTaggedCCAPlatformConfigID(tv.Input)

if tv.Err != "" {
assert.Nil(t, out)
assert.EqualError(t, err, tv.Err)
} else {
assert.Equal(t, tv.Expected, *out)
}
})
}
}
Loading
Loading