Skip to content

Commit

Permalink
feat: add validation for MAC and IP addresses in Measurement.Valid me…
Browse files Browse the repository at this point in the history
…thod

Also:
* enhance validation logic in Mval.Valid()
* add and refine tests for Mval.Valid() function
* update MAC address validation to allow EUI-48 and EUI-64 formats

---------

Signed-off-by: Ravjot Singh <[email protected]>
  • Loading branch information
ravjot07 authored Jan 11, 2025
1 parent ca718d8 commit 8f38e74
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 2 deletions.
24 changes: 22 additions & 2 deletions comid/measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ func (o Mval) MarshalJSON() ([]byte, error) {
}

func (o Mval) Valid() error {
// Check if no measurement values are set
if o.Ver == nil &&
o.SVN == nil &&
o.Digests == nil &&
Expand All @@ -439,28 +440,47 @@ func (o Mval) Valid() error {
return fmt.Errorf("no measurement value set")
}

// Validate Version
if o.Ver != nil {
if err := o.Ver.Valid(); err != nil {
return err
}
}

// Validate Digests
if o.Digests != nil {
if err := o.Digests.Valid(); err != nil {
return err
}
}

// Validate Flags
if o.Flags != nil {
if err := o.Flags.Valid(); err != nil {
return err
}
}

// raw value and mask have no specific semantics
// Validate MAC Address
if o.MACAddr != nil {
macLen := len(*o.MACAddr)
if macLen != 6 && macLen != 8 { // MAC address must be either 6 or 8 bytes
return fmt.Errorf("invalid MAC address length: expected 6 or 8 bytes, got %d", macLen)
}
}

// Validate IP Address
if o.IPAddr != nil {
ip := *o.IPAddr
// Must be valid IPv4 or IPv6 (i.e., .To4() != nil or .To16() != nil)
if ip.To4() == nil && ip.To16() == nil {
return fmt.Errorf("invalid IP address: %s", ip.String())
}
}

// TODO(tho) MAC addr & friends (see https://github.com/veraison/corim/issues/18)
// raw value and raw-value-mask have no specific semantics here

// Validate extensions (custom logic implemented in validMval())
return o.Extensions.validMval(&o)
}

Expand Down
97 changes: 97 additions & 0 deletions comid/measurement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package comid
import (
"crypto"
"fmt"
"net"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -601,3 +602,99 @@ func TestMkey_UintMkey(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, 7, ret)
}

func TestMval_Valid(t *testing.T) {
t.Run("No fields set", func(t *testing.T) {
mval := Mval{}
err := mval.Valid()
assert.EqualError(t, err, "no measurement value set")
})

t.Run("All fields nil except Ver, which is valid", func(t *testing.T) {
var scheme swid.VersionScheme
_ = scheme.SetCode(swid.VersionSchemeSemVer)
mval := Mval{
Ver: &Version{
Version: "1.0",
Scheme: scheme,
},
}
err := mval.Valid()
assert.NoError(t, err)
})

// Test with valid 6-byte MAC
t.Run("MACAddr valid (6 bytes)", func(t *testing.T) {
mac := MACaddr([]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}) // EUI-48
mval := Mval{MACAddr: &mac}
err := mval.Valid()
assert.NoError(t, err, "6-byte MAC should be valid")
})

// Test with valid 8-byte MAC
t.Run("MACAddr valid (8 bytes)", func(t *testing.T) {
mac := MACaddr([]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}) // EUI-64
mval := Mval{MACAddr: &mac}
err := mval.Valid()
assert.NoError(t, err, "8-byte MAC should be valid")
})

// Test with invalid MAC length
t.Run("MACAddr invalid (too many bytes)", func(t *testing.T) {
mac := MACaddr([]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}) // 7 bytes
mval := Mval{MACAddr: &mac}
err := mval.Valid()
assert.EqualError(t, err, "invalid MAC address length: expected 6 or 8 bytes, got 7")
})

// Test with invalid MAC length
t.Run("MACAddr invalid (too few bytes)", func(t *testing.T) {
mac := MACaddr([]byte{0x01, 0x02, 0x03, 0x04}) // 4 bytes
mval := Mval{MACAddr: &mac}
err := mval.Valid()
assert.EqualError(t, err, "invalid MAC address length: expected 6 or 8 bytes, got 4")
})

t.Run("MACAddr valid (6 bytes)", func(t *testing.T) {
mac := MACaddr([]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06})
mval := Mval{MACAddr: &mac}
err := mval.Valid()
assert.NoError(t, err)
})

t.Run("IPAddr valid (IPv4)", func(t *testing.T) {
ip := net.IPv4(192, 168, 1, 100)
mval := Mval{IPAddr: &ip}
err := mval.Valid()
assert.NoError(t, err)
})

t.Run("IPAddr valid (IPv6)", func(t *testing.T) {
ip := net.ParseIP("2001:db8::1")
mval := Mval{IPAddr: &ip}
err := mval.Valid()
assert.NoError(t, err)
})

t.Run("Digests valid", func(t *testing.T) {
ds := NewDigests()
_ = ds.AddDigest(swid.Sha256, []byte{0xAA, 0xBB})
mval := Mval{
Digests: ds,
}
err := mval.Valid()
assert.NoError(t, err)
})

t.Run("Extensions valid", func(t *testing.T) {
// Suppose we have some extension data that is considered valid
ext := Extensions{}
mval := Mval{
Extensions: ext,
// Must also set one non-empty field to pass "no measurement value set"
Ver: &Version{Version: "1.0"},
}
err := mval.Valid()
assert.NoError(t, err)
})
}

0 comments on commit 8f38e74

Please sign in to comment.