Skip to content

Commit

Permalink
Add methods to directly add Reference Values and Endorsed Values
Browse files Browse the repository at this point in the history
Signed-off-by: Priyanshu Thapliyal <[email protected]>
  • Loading branch information
Priyanshuthapliyal2005 committed Dec 25, 2024
1 parent b690f86 commit 00c59d3
Show file tree
Hide file tree
Showing 6 changed files with 398 additions and 53 deletions.
142 changes: 121 additions & 21 deletions comid/comid.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,27 +243,27 @@ func (o *Comid) AddDevIdentityKey(val KeyTriple) *Comid {
}

func (o Comid) Valid() error {
if err := o.TagIdentity.Valid(); err != nil {
return fmt.Errorf("tag-identity validation failed: %w", err)
}

if o.Entities != nil {
if err := o.Entities.Valid(); err != nil {
return fmt.Errorf("entities validation failed: %w", err)
}
}

if o.LinkedTags != nil {
if err := o.LinkedTags.Valid(); err != nil {
return fmt.Errorf("linked-tags validation failed: %w", err)
}
}

if err := o.Triples.Valid(); err != nil {
return fmt.Errorf("triples validation failed: %w", err)
}

return o.Extensions.validComid(&o)
if err := o.TagIdentity.Valid(); err != nil {
return fmt.Errorf("tag-identity validation failed: %v", err) // Changed %w to %v
}

if o.Entities != nil {
if err := o.Entities.Valid(); err != nil {
return fmt.Errorf("entities validation failed: %v", err) // Changed %w to %v
}
}

if o.LinkedTags != nil {
if err := o.LinkedTags.Valid(); err != nil {
return fmt.Errorf("linked-tags validation failed: %v", err) // Changed %w to %v
}
}

if err := o.Triples.Valid(); err != nil {
return fmt.Errorf("triples validation failed: %v", err) // Changed %w to %v
}

return o.Extensions.validComid(&o)
}

// ToCBOR serializes the target Comid to CBOR
Expand Down Expand Up @@ -321,3 +321,103 @@ func (o Comid) ToJSONPretty(indent string) ([]byte, error) {

return json.MarshalIndent(&o, "", indent)
}

// AddSimpleReferenceValue adds a reference value with a single measurement
func (o *Comid) AddSimpleReferenceValue(env Environment, measurement *Measurement) error {
if err := env.Valid(); err != nil {
return fmt.Errorf("invalid environment: %w", err)
}

if measurement == nil {
return fmt.Errorf("measurement cannot be nil")
}

if o.Triples.ReferenceValues == nil {
o.Triples.ReferenceValues = NewValueTriples()
}

builder := NewReferenceValueBuilder().
WithEnvironment(env).
WithMeasurement(measurement)

triple, err := builder.Build()
if err != nil {
return fmt.Errorf("building reference value: %w", err)
}

if res := o.AddReferenceValue(*triple); res == nil {
return fmt.Errorf("failed to add reference value")
}

return nil
}

func (o *Comid) AddDigestReferenceValue(env Environment, alg string, digest []byte) error {
if len(digest) == 0 {
return fmt.Errorf("digest cannot be empty")
}
hashAlg := HashAlgFromString(alg)
if !hashAlg.Valid() {
return fmt.Errorf("unrecognized algorithm %q", alg)
}
m := &Measurement{
Val: Mval{
Digests: NewDigests(),
},
}
if m.Val.Digests.AddDigest(hashAlg.ToUint64(), digest) == nil {
return fmt.Errorf("failed to create hash entry")
}
return o.AddSimpleReferenceValue(env, m)
}

// AddRawReferenceValue adds a reference value with raw measurement data
func (o *Comid) AddRawReferenceValue(env Environment, raw []byte) error {
if len(raw) == 0 {
return fmt.Errorf("raw value cannot be empty")
}

m := &Measurement{
Val: Mval{
RawValue: NewRawValue().SetBytes(raw),
},
}

return o.AddSimpleReferenceValue(env, m)
}

// AddReferenceValueDirect adds a reference value directly to the reference-triples list without creating instances for Measurement and ValueTriples.
func (o *Comid) AddReferenceValueDirect(environment Environment, measurements Measurements) *Comid {
if o != nil {
val := ValueTriple{
Environment: environment,
Measurements: measurements,
}
if o.Triples.ReferenceValues == nil {
o.Triples.ReferenceValues = NewValueTriples()
}

if o.Triples.AddReferenceValue(val) == nil {
return nil
}
}
return o
}

// AddEndorsedValueDirect adds an endorsed value directly to the endorsed-triples list without creating instances for Measurement and ValueTriples.
func (o *Comid) AddEndorsedValueDirect(environment Environment, measurements Measurements) *Comid {
if o != nil {
val := ValueTriple{
Environment: environment,
Measurements: measurements,
}
if o.Triples.EndorsedValues == nil {
o.Triples.EndorsedValues = NewValueTriples()
}

if o.Triples.AddEndorsedValue(val) == nil {
return nil
}
}
return o
}
30 changes: 30 additions & 0 deletions comid/comid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,33 @@ func Test_String2URI_nok(t *testing.T) {
_, err := String2URI(&s)
assert.EqualError(t, err, `expecting an absolute URI: "@@@" is not an absolute URI`)
}


func Test_Comid_SimpleReferenceValue(t *testing.T) {
c := NewComid()
env := Environment{
Instance: MustNewUUIDInstance(TestUUID),
}

// Test digest reference value
err := c.AddDigestReferenceValue(env, "sha-256", []byte{
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f,
})
require.NoError(t, err)

// Verify values were added
require.NotNil(t, c.Triples.ReferenceValues)
require.Len(t, c.Triples.ReferenceValues.Values, 1)

// Verify digest value
rv := c.Triples.ReferenceValues.Values[0]
require.NotNil(t, rv.Measurements.Values[0].Val.Digests)
require.Equal(t, HashAlgSHA256.ToUint64(), (*rv.Measurements.Values[0].Val.Digests)[0].HashAlgID)
}
63 changes: 31 additions & 32 deletions comid/digests.go
Original file line number Diff line number Diff line change
@@ -1,53 +1,52 @@
// Copyright 2021 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0

package comid

import (
"fmt"

"github.com/veraison/swid"
"fmt"
"github.com/veraison/swid"
)

// Digests is an alias for an array of SWID HashEntry
// Digests is an array of SWID HashEntry
type Digests []swid.HashEntry

// NewDigests instantiates an empty array of Digests
func NewDigests() *Digests {
return new(Digests)
return new(Digests)
}

// AddDigest create a new digest from the supplied arguments and appends it to
// the (already instantiated) Digests target. The method is a no-op if it is
// invoked on a nil target and will refuse to add inconsistent algo/value
// combinations.
// AddDigest create a new digest from the supplied arguments and appends it to the (already instantiated) Digests target.
// The method is a no-op if it is invoked on a nil target and will refuse to add inconsistent algo/value combinations.
func (o *Digests) AddDigest(algID uint64, value []byte) *Digests {
if o != nil {
he := NewHashEntry(algID, value)
if he == nil {
return nil
}
*o = append(*o, *he)
}
return o
if o != nil {
he := NewHashEntry(algID, value)
if he == nil {
return nil
}
*o = append(*o, *he)
}
return o
}

func (o Digests) Valid() error {
for i, m := range o {
if err := swid.ValidHashEntry(m.HashAlgID, m.HashValue); err != nil {
return fmt.Errorf("digest at index %d: %w", i, err)
}
}
return nil
if len(o) == 0 {
return fmt.Errorf("digests must not be empty")
}

for i, m := range o {
if err := swid.ValidHashEntry(m.HashAlgID, m.HashValue); err != nil {
return fmt.Errorf("digest at index %d: %w", i, err)
}
}
return nil
}


func NewHashEntry(algID uint64, value []byte) *swid.HashEntry {
var he swid.HashEntry
var he swid.HashEntry

err := he.Set(algID, value)
if err != nil {
return nil
}
err := he.Set(algID, value)
if err != nil {
return nil
}

return &he
return &he
}
77 changes: 77 additions & 0 deletions comid/hashalg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package comid

import (
"fmt"
"strings"
"encoding/json"
)

type HashAlg uint64

const (
HashAlgSHA256 HashAlg = 1
HashAlgSHA384 HashAlg = 2
HashAlgSHA512 HashAlg = 3
)

func (h HashAlg) Valid() bool {
return h >= HashAlgSHA256 && h <= HashAlgSHA512
}

func HashAlgFromString(s string) HashAlg {
switch strings.ToLower(s) {
case "sha-256":
return HashAlgSHA256
case "sha-384":
return HashAlgSHA384
case "sha-512":
return HashAlgSHA512
default:
return 0
}
}

func (h HashAlg) String() string {
switch h {
case HashAlgSHA256:
return "sha-256"
case HashAlgSHA384:
return "sha-384"
case HashAlgSHA512:
return "sha-512"
default:
return fmt.Sprintf("unknown(%d)", h)
}
}

func (h HashAlg) MarshalJSON() ([]byte, error) {
return json.Marshal(h.String())
}
func (h *HashAlg) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
*h = HashAlgFromString(s)
if !h.Valid() {
return fmt.Errorf("invalid hash algorithm: %s", s)
}
return nil
}

// ToUint64 returns 0 if invalid, otherwise the numeric value.
func (h HashAlg) ToUint64() uint64 {
if !h.Valid() {
return 0
}
return uint64(h)
}

// HashAlgFromUint64 returns 0 if v is invalid, otherwise the matching HashAlg.
func HashAlgFromUint64(v uint64) HashAlg {
h := HashAlg(v)
if !h.Valid() {
return 0
}
return h
}
Loading

0 comments on commit 00c59d3

Please sign in to comment.