diff --git a/corim/entity.go b/corim/entity.go index 49aa1468..13058f77 100644 --- a/corim/entity.go +++ b/corim/entity.go @@ -4,16 +4,21 @@ package corim import ( + "errors" "fmt" - "github.com/veraison/corim/comid" ) +type IExtension interface { + Valid() error +} + // Entity stores an entity-map capable of CBOR and JSON serializations. type Entity struct { EntityName string `cbor:"0,keyasint" json:"name"` RegID *comid.TaggedURI `cbor:"1,keyasint,omitempty" json:"regid,omitempty"` Roles Roles `cbor:"2,keyasint" json:"roles"` + Extension IExtension `cbor:"3,keyasint" json:"extensions"` } func NewEntity() *Entity { @@ -58,6 +63,45 @@ func (o *Entity) SetRoles(roles ...Role) *Entity { return o } +// SetExtension adds the profile specific extension. +func (o *Entity) SetExtension(extension IExtension) *Entity { + if o != nil { + o.Extension = extension + } + return o +} + +// GetExtension gets the profile specific extension. +func (o *Entity) GetExtension() (IExtension, error) { + if o != nil { + return o.Extension, nil + } + return nil, errors.New("no Entity present") +} + +func (o *Entity) FromCBOR(data []byte) error { + if o != nil { + err := dm.Unmarshal(data, o) + if err != nil { + return err + } + } + return nil +} + +func (o *Entity) ToCBOR() ([]byte, error) { + if o != nil { + data, err := em.Marshal(o) + if err != nil { + return nil, err + } else { + return data, nil + } + } else { + return nil, fmt.Errorf("no entity to serialize") + } +} + // Valid checks for validity of the fields within each Entity func (o Entity) Valid() error { if o.EntityName == "" { @@ -72,6 +116,13 @@ func (o Entity) Valid() error { return fmt.Errorf("invalid entity: %w", err) } + // Check for user supplied Extensions + if o.Extension != nil { + if err := o.Extension.Valid(); err != nil { + return fmt.Errorf("invalid entity extensions: %w", err) + } + } + return nil } diff --git a/corim/entity_extension.go b/corim/entity_extension.go new file mode 100644 index 00000000..1e993058 --- /dev/null +++ b/corim/entity_extension.go @@ -0,0 +1,47 @@ +// Copyright 2021 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package corim + +import ( + "fmt" +) + +type EntityExtension struct { + Param1 string `cbor:"0,keyasint" json:"param1"` + Param2 byte `cbor:"1,keyasint,omitempty" json:"param2,omitempty"` +} + +func (o EntityExtension) Valid() error { + if o.Param1 == "" { + return fmt.Errorf("mandatory Parameter Param1 missing") + } + if o.Param2 == 0x40 { + return fmt.Errorf("mandatory Parameter Param2 cannot be 0x40") + } + + return nil +} + +func (o *EntityExtension) FromCBOR(data []byte) error { + if o != nil { + err := dm.Unmarshal(data, o) + if err != nil { + return err + } + } + return nil +} + +func (o *EntityExtension) ToCBOR() ([]byte, error) { + if o != nil { + data, err := em.Marshal(o) + if err != nil { + return nil, err + } else { + return data, nil + } + } else { + return nil, fmt.Errorf("no entity to serialize") + } +} diff --git a/corim/entity_extension_test.go b/corim/entity_extension_test.go new file mode 100644 index 00000000..6fefc1e9 --- /dev/null +++ b/corim/entity_extension_test.go @@ -0,0 +1,79 @@ +// Copyright 2021 Contributors to the Veraison project. +// SPDX-License-Identifier: Apache-2.0 + +package corim + +import ( + "testing" + + "fmt" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEntities_Extensions_Valid_ok(t *testing.T) { + ext := &EntityExtension{"my profile", 0x56} + + e := NewEntity(). + SetEntityName("ACME Ltd."). + SetRegID("http://acme.example"). + SetRoles(RoleManifestCreator). + SetExtension(ext) + require.NotNil(t, e) + + es := NewEntities().AddEntity(*e) + require.NotNil(t, es) + + err := es.Valid() + assert.Nil(t, err) +} + +func TestEntities_Extensions_ToCBOR_ok(t *testing.T) { + ext := &EntityExtension{"my profile", 0x56} + + e := NewEntity(). + SetEntityName("ACME Ltd."). + SetRegID("http://acme.example"). + SetRoles(RoleManifestCreator). + SetExtension(ext) + require.NotNil(t, e) + data, err := e.ToCBOR() + + require.Nil(t, err) + fmt.Printf("to CBOR Entity = %x", data) + +} + +func TestEntities_Extensions_FromCBOR_ok(t *testing.T) { + data := []byte{0xa4, 0x00, 0x69, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x01, 0xd8, 0x20, 0x73, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x02, 0x81, 0x01, 0x03, 0xa2, 0x00, 0x6a, 0x6d, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x01, 0x18, 0x56} + //var ext1 EntityExtension + e := &Entity{Extension: &EntityExtension{}} + + err := e.FromCBOR(data) + require.Nil(t, err) + ext, err := e.GetExtension() + require.Nil(t, err) + require.NotNil(t, ext) +} + +func TestEntities_NoExtensions_ToCBOR_ok(t *testing.T) { + e := NewEntity(). + SetEntityName("ACME Ltd."). + SetRegID("http://acme.example"). + SetRoles(RoleManifestCreator) + require.NotNil(t, e) + data, err := e.ToCBOR() + + require.Nil(t, err) + fmt.Printf("to CBOR Entity = %x", data) + +} + +func TestEntities_NoExtensions_FromCBOR_ok(t *testing.T) { + data := []byte{0xa4, 0x00, 0x69, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x01, 0xd8, 0x20, 0x73, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x02, 0x81, 0x01, 0x03, 0x0F6} + e := &Entity{} + err := e.FromCBOR(data) + require.Nil(t, err) + require.Nil(t, err) + +}