-
Notifications
You must be signed in to change notification settings - Fork 17
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 methods to directly add Reference Values and Endorsed Values #142
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think "simple" is the right term for this. Perhaps something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not address #136, as this does not handle extensions, which is the intent of adding the helper methods. Note that the issue says "without creating instances of measurements" -- where as this still requres a measurement instance. The reason is that extensions are registred with the collection, and are not propagated to the reference values (and then, through measurement, down to the Mval and the Flags) until the values are added to the collection, so its not possible to specify values for the extension fields until the reference value is in the collection. The goal of #136 is to address that by adding a method that adds a reference/endorsement value from all raw inputs in asingle operation. Another issue that, as of the latest CoRIM spec update, a reference value can contain multiple measurements, so the mothod would need to accomodate that as well.... |
||
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 | ||
} |
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 | ||
} |
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 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
(also, remove the comments -- they don't make sense without historical context)