Skip to content

Commit

Permalink
Add Integrity Registers
Browse files Browse the repository at this point in the history
Signed-off-by: Yogesh Deshpande <[email protected]>
  • Loading branch information
yogeshbdeshpande committed Feb 1, 2024
1 parent da24191 commit adc5ab9
Show file tree
Hide file tree
Showing 3 changed files with 334 additions and 1 deletion.
149 changes: 149 additions & 0 deletions comid/integregisters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright 2024 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package comid

import (
"encoding/json"
"fmt"

"github.com/veraison/swid"
)

// IRegisterIndex is the interface to hold register index
type IRegisterIndex interface{}

type IntegReg struct {
Register map[IRegisterIndex]Digests
}

func NewIntegRegister() (*IntegReg, error) {
reg := make(map[IRegisterIndex]Digests)
return &IntegReg{Register: reg}, nil
}

// AddDigests allows inserting a series of Digests at a specific RegisterIndex
func (i *IntegReg) AddDigests(index IRegisterIndex, digests Digests) error {
if len(digests) == 0 {
return fmt.Errorf("no digests to add")
}
for _, digest := range digests {
if err := i.AddDigest(index, digest); err != nil {
return fmt.Errorf("unable to add Digest %v", err)
}
}
return nil
}

// AddDigest allows inserting a Digest at a specific RegisterIndex
func (i *IntegReg) AddDigest(index IRegisterIndex, digest swid.HashEntry) error {
switch t := index.(type) {
case string, uint, uint64:
digests := append(i.Register[t], digest)

Check failure on line 41 in comid/integregisters.go

View workflow job for this annotation

GitHub Actions / Lint

appendAssign: append result not assigned to the same slice (gocritic)

Check failure on line 41 in comid/integregisters.go

View workflow job for this annotation

GitHub Actions / Lint

appendAssign: append result not assigned to the same slice (gocritic)
i.Register[t] = digests

default:
return fmt.Errorf("unexpected type for index: %T", t)
}
return nil
}

// RemoveIndex removes an Index from the Register
func (i *IntegReg) RemoveIndex(index IRegisterIndex) error {
if i.Register == nil {
return fmt.Errorf("cannot remove index, non existent register")
}
switch t := index.(type) {
case uint, uint64, string:
delete(i.Register, index)
default:
return fmt.Errorf("unknown type %T for index-type-choice", t)
}
return nil
}

func (i IntegReg) MarshalCBOR() ([]byte, error) {
return em.Marshal(i.Register)
}

func (i *IntegReg) UnMarshalCBOR(data []byte) error {
return dm.Unmarshal(data, &i.Register)
}

func (i IntegReg) ToJSON() ([]byte, error) {
jmap := make(map[string]json.RawMessage)
for key, val := range i.Register {
var v tnv
switch t := key.(type) {
case uint, uint64:
b, err := json.Marshal(key)
v = tnv{Type: "uint", Value: b}
if err != nil {
return nil, err
}
case string:
b, err := json.Marshal(key)
v = tnv{Type: "text", Value: b}
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unknown type %T for index-type-choice", t)
}
newk, err := json.Marshal(v)
if err != nil {
return nil, err
}
newkey := string(newk)
newval, err := json.Marshal(val)
if err != nil {
return nil, err
}
jmap[newkey] = newval
}
return json.Marshal(jmap)
}

func (i *IntegReg) FromJSON(data []byte) error {
jmap := make(map[string]json.RawMessage)
if err := json.Unmarshal(data, &jmap); err != nil {
return fmt.Errorf("register map decoding failure: %w", err)
}
for key, val := range jmap {
index, err := UnMarshalIndex(key)
if err != nil {
return fmt.Errorf("unable to UnMarshal Index: %v", err)
}
var d Digests

if err = json.Unmarshal(val, &d); err != nil {
return fmt.Errorf("unable to UnMarshal Digests: %v", err)
}
if err = i.AddDigests(index, d); err != nil {
return fmt.Errorf("unable to insert register into register set %v", err)
}
}
return nil
}

func UnMarshalIndex(key string) (IRegisterIndex, error) {
var v tnv
if err := json.Unmarshal([]byte(key), &v); err != nil {
return nil, fmt.Errorf("unable to UnMarshal key: %v", err)
}
switch v.Type {
case "uint":
var key uint
if err := json.Unmarshal(v.Value, &key); err != nil {
return nil, fmt.Errorf("unable to UnMarshal uint key %v", err)
}
return key, nil
case "text":
var key string
if err := json.Unmarshal(v.Value, &key); err != nil {
return nil, fmt.Errorf("unable to UnMarshal uint key %v", err)
}
return key, nil
default:
return nil, fmt.Errorf("invalid type %s", v.Type)
}
}
184 changes: 184 additions & 0 deletions comid/integregisters_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Copyright 2024 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0

package comid

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/veraison/swid"
)

func prepareRegister(iType string) (*IntegReg, error) {
tv := "12435465869790801243546586979080124354658697908"
reg, err := NewIntegRegister()
if err != nil {
return nil, err
}

for index := 0; index < 5; index++ {
entry := &swid.HashEntry{}
d := tv + fmt.Sprint(index)
fmt.Printf("test bytes = %s", tv)
hash := []byte(d)
err = entry.Set(swid.Sha384, hash)
if err != nil {
return nil, err
}
switch iType {
case "uint":
err = reg.AddDigest(uint(index), *entry)
case "text":
i := fmt.Sprint(index)
err = reg.AddDigest(i, *entry)
default:
err = fmt.Errorf("invalid iType = %s", iType)
}
if err != nil {
return nil, err
}
}

return reg, nil
}

func TestIntegRegister_AddDigest_OK(t *testing.T) {
_, err := prepareRegister("uint")
require.NoError(t, err)
}

func TestIntegRegister_AddDigest_NOK(t *testing.T) {
expectedErr := `unexpected type for index: bool`
var k bool
reg, err := prepareRegister("uint")
require.NoError(t, err)
err = reg.AddDigest(k, swid.HashEntry{})
assert.EqualError(t, err, expectedErr)
}

func TestIntegRegister_UInt_MarshalCBOR_OK(t *testing.T) {
reg, err := prepareRegister("uint")
require.NoError(t, err)
bytes, err := reg.MarshalCBOR()
require.NoError(t, err)
fmt.Printf("CBOR Payload = %x", bytes)

}

func TestIntegRegister_UInt_UnMarshalCBOR_OK(t *testing.T) {
bstr := MustHexDecode(nil, `a302818207583031323433353436353836393739303830313234333534363538363937393038303132343335343635383639373930383000828207583031323433353436353836393739303830313234333534363538363937393038303132343335343635383639373930383082075830313234333534363538363937393038303132343335343635383639373930383031323433353436353836393739303930018182075830313234333534363538363937393038303132343335343635383639373930383031323433353436353836393739303830`)
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.UnMarshalCBOR(bstr)
require.NoError(t, err)

}

func TestIntegRegister_UInt_ToJSON_OK(t *testing.T) {
reg, err := prepareRegister("uint")
require.NoError(t, err)
bytes, err := reg.ToJSON()
require.NoError(t, err)
fmt.Printf("JSON Payload = %s", bytes)
}

func TestIntegRegister_Text_MarshalCBOR_OK(t *testing.T) {
reg, err := prepareRegister("text")
require.NoError(t, err)
bytes, err := reg.MarshalCBOR()
require.NoError(t, err)
fmt.Printf("CBOR Payload = %x", bytes)

}

func TestIntegRegister_Text_UnMarshalCBOR_OK(t *testing.T) {
bstr := MustHexDecode(nil, `a3613281820758303132343335343635383639373930383031323433353436353836393739303830313234333534363538363937393038306133818207583031323433353436353836393739303830313234333534363538363937393038303132343335343635383639373930383061318182075830313234333534363538363937393038303132343335343635383639373930383031323433353436353836393739303830`)
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.UnMarshalCBOR(bstr)
require.NoError(t, err)
}

func TestIntegRegister_Text_ToJSON_OK(t *testing.T) {
reg, err := prepareRegister("text")
require.NoError(t, err)
bytes, err := reg.ToJSON()
require.NoError(t, err)
fmt.Printf("JSON Payload = %s", bytes)
}

func TestIntegRegister_Text_FromJSON_OK(t *testing.T) {
j := `{"{\"type\":\"text\",\"value\":\"a\"}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],"{\"type\":\"text\",\"value\":\"b\"}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],"{\"type\":\"text\",\"value\":\"c\"}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],"{\"type\":\"text\",\"value\":\"d\"}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDkw"]}`
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.FromJSON([]byte(j))
require.NoError(t, err)
}

func TestIntegRegister_UInt_FromJSON_OK(t *testing.T) {
j := `{
"{\"type\":\"uint\",\"value\":0}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],
"{\"type\":\"uint\",\"value\":1}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],
"{\"type\":\"uint\",\"value\":2}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],
"{\"type\":\"uint\",\"value\":5}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDkw"]
}`
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.FromJSON([]byte(j))
require.NoError(t, err)
}

func TestIntegRegister_UInt_Text_FromJSON_OK(t *testing.T) {
j := `{
"{\"type\":\"uint\",\"value\":0}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],
"{\"type\":\"uint\",\"value\":1}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],
"{\"type\":\"uint\",\"value\":2}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"],
"{\"type\":\"text\",\"value\":\"five\"}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDkw"]
}`
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.FromJSON([]byte(j))
require.NoError(t, err)
}

func TestIntegRegister_UInt_FromJSON_NOK(t *testing.T) {
expectedErr := `unable to UnMarshal Index: invalid type int`
j := `{
"{\"type\":\"int\",\"value\":0}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"]
}`
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.FromJSON([]byte(j))
assert.EqualError(t, err, expectedErr)
}

func TestIntegRegister_UIntFromJSON_NOK1(t *testing.T) {
expectedErr := `unable to UnMarshal Index: unable to UnMarshal key: invalid character 'a' looking for beginning of object key string`
j := `{
"{abcd}":["sha-384;MTI0MzU0NjU4Njk3OTA4MDEyNDM1NDY1ODY5NzkwODAxMjQzNTQ2NTg2OTc5MDgw"]
}`
reg, err := NewIntegRegister()
require.NoError(t, err)
err = reg.FromJSON([]byte(j))
assert.EqualError(t, err, expectedErr)
}

func TestIntegRegister_RemoveIndex_OK(t *testing.T) {
reg, err := prepareRegister("uint")
require.NoError(t, err)
err = reg.RemoveIndex(uint(0))
require.NoError(t, err)

}

func TestIntegRegister_RemoveIndex_NOK(t *testing.T) {
expectedErr := `unknown type int for index-type-choice`
reg, err := prepareRegister("uint")
require.NoError(t, err)
err = reg.RemoveIndex(0)
assert.EqualError(t, err, expectedErr)

}
2 changes: 1 addition & 1 deletion comid/measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ type Mval struct {
SerialNumber *string `cbor:"8,keyasint,omitempty" json:"serial-number,omitempty"`
UEID *eat.UEID `cbor:"9,keyasint,omitempty" json:"ueid,omitempty"`
UUID *UUID `cbor:"10,keyasint,omitempty" json:"uuid,omitempty"`

IntegReg *IntegReg `cbor:"14,keyasint,omitempty" json:"integ-reg,omitempty"`
Extensions
}

Expand Down

0 comments on commit adc5ab9

Please sign in to comment.