veraison / corim

CoRIM and CoMID manipulation library and CLI
Apache License 2.0
9 stars 7 forks source link

measurement-values-map profile extension #119

Closed jraman567 closed 3 months ago

jraman567 commented 4 months ago

I'm figuring out how to configure the corim to load measurement-values-map as a profile extension.

comid.ValueTriple doesn't have an extension point, so the external "ReferenceValues" don't appear to attach to any defined extension point. Please see the attached output, which adds "Address" as an external reference value.

I noticed an alternative approach of using comid.ExtMval to add refvals on a per-instance basis instead of a profile. Is that the recommended approach for measurement-values-map?

Thank you!

(*comid.Comid)(0xc00011a540)({
 Language: (*string)(0xc0000a0330)((len=5) "en-GB"),
 TagIdentity: (comid.TagIdentity) {
  TagID: (swid.TagID) example,
  TagVersion: (uint) 0
 },
 Entities: (*comid.Entities)(0xc0000e09c0)({
  Collection: (extensions.Collection[github.com/veraison/corim/comid.Entity,*github.com/veraison/corim/comid.Entity]) {
   Values: ([]comid.Entity) (len=1 cap=1) {
    (comid.Entity) {
     Name: (*comid.EntityName)(0xc0000a0390)(ACME Ltd.),
     RegID: (*comid.TaggedURI)(0xc0000a0360)((len=20) "https://acme.example"),
     Roles: (comid.Roles) (len=1 cap=1) {
      (comid.Role) creator
     },
     Extensions: (comid.Extensions) {
      Extensions: (extensions.Extensions) {
       IMapValue: (extensions.IMapValue) <nil>
      }
     }
    }
   },
   valueExtensions: (extensions.cache) {
    extensions: (extensions.Map) <nil>
   }
  }
 }),
 LinkedTags: (*comid.LinkedTags)(<nil>),
 Triples: (comid.Triples) {
  ReferenceValues: (*comid.ValueTriples)(0xc0000e09a0)({
   Values: ([]comid.ValueTriple) (len=1 cap=1) {
    (comid.ValueTriple) {
     _: (struct {}) {
     },
     Environment: (comid.Environment) {
      Class: (*comid.Class)(0xc0000a5da0)({
       ClassID: (*comid.ClassID)(0xc0000a03c0)(YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE=),
       Vendor: (*string)(0xc0000a03b0)((len=9) "ACME Ltd."),
       Model: (*string)(0xc0000a03a0)((len=14) "RoadRunner 2.0"),
       Layer: (*uint64)(<nil>),
       Index: (*uint64)(<nil>)
      }),
      Instance: (*comid.Instance)(<nil>),
      Group: (*comid.Group)(<nil>)
     },
     Measurements: (comid.Measurements) {
      Values: ([]comid.Measurement) (len=1 cap=1) {
       (comid.Measurement) {
        Key: (*comid.Mkey)(0xc0000a03f0)({
         Value: (*comid.TaggedPSARefValID)(0xc0000a5e30)({"label":"BL","version":"5.0.5","signer-id":"rLsRx+TaIXIFUjzkzhokWuGiOa48a/2eeHH35di66Gs="})
        }),
        Val: (comid.Mval) {
         Ver: (*comid.Version)(<nil>),
         SVN: (*comid.SVN)(<nil>),
         Digests: (*comid.Digests)(0xc0000ae120)((len=1 cap=1) {
          (swid.HashEntry) sha-256-32;q83vAA==
         }),
         Flags: (*comid.FlagsMap)(<nil>),
         RawValue: (*comid.RawValue)(<nil>),
         RawValueMask: (*[]uint8)(<nil>),
         MACAddr: (*comid.MACaddr)(<nil>),
         IPAddr: (*net.IP)(<nil>),
         SerialNumber: (*string)(<nil>),
         UEID: (*eat.UEID)(<nil>),
         UUID: (*comid.UUID)(<nil>),
         IntegrityRegisters: (*comid.IntegrityRegisters)(<nil>),
         Extensions: (comid.Extensions) {
          Extensions: (extensions.Extensions) {
           IMapValue: (extensions.IMapValue) <nil>
          }
         }
        },
        AuthorizedBy: (*comid.CryptoKey)(<nil>)
       }
      },
      valueExtensions: (extensions.cache) {
       extensions: (extensions.Map) {
       }
      }
     }
    }
   },
   valueExtensions: (extensions.cache) {
    extensions: (extensions.Map) (len=1) {
     (extensions.Point) (len=4) "Mval": (*main.RefValExtensions)(0xc0000a20a8)({
      Address: (*string)(<nil>)
     })
    }
   }
  }),
  EndorsedValues: (*comid.ValueTriples)(<nil>),
  DevIdentityKeys: (*comid.KeyTriples)(<nil>),
  AttestVerifKeys: (*comid.KeyTriples)(<nil>),
  Extensions: (comid.Extensions) {
   Extensions: (extensions.Extensions) {
    IMapValue: (extensions.IMapValue) <nil>
   }
  }
 },
 Extensions: (comid.Extensions) {
  Extensions: (extensions.Extensions) {
   IMapValue: (extensions.IMapValue) <nil>
  }
 }
})
setrofim commented 3 months ago

The extension point for reference values is comid.ExtReferenceValue. It can be specified via a profile.

Please see corim/example_profile_test.go which has an example of registering a profile with a refval extension.

If you're still having trouble, please could you share the code that shows how you're registering the extension, and how you are then attempting to use it.

jraman567 commented 3 months ago

corim/example_profile_test.go shows how to use comid.ExtEntity. I'm able to use this extension successfully.

Whereas, with comid.ExtReferenceValue, I need help accessing the extensions. Unlike comid.Entity, comid.ValueTriples (the type of comid.Triples.ReferenceValues[0]) doesn't have an "Extensions" member. So, it needs to be clarified where the extensions are attached to.

Please see the example below:

package main

import (
    "encoding/hex"
    "fmt"
    "log"

    "github.com/veraison/corim/comid"
    "github.com/veraison/corim/corim"
    "github.com/veraison/corim/extensions"
    "github.com/veraison/eat"
    "github.com/veraison/swid"

    "github.com/davecgh/go-spew/spew"
)

type RefValExtensions struct {
    Address *string `cbor:"-1,keyasint,omitempty" json:"address,omitempty"`
}

func init() {
    profileID, err := eat.NewProfile("http://example.com/example-profile")
    if err != nil {
        panic(err) // will not error, as the hard-coded string above is valid
    }

    extMap := extensions.NewMap().
        Add(comid.ExtEntity, &RefValExtensions{}).
        Add(comid.ExtReferenceValue, &RefValExtensions{})

    if err := corim.RegisterProfile(profileID, extMap); err != nil {
        // will not error, assuming our profile ID is unique, and we've
        // correctly set up the extensions Map above
        panic(err)
    }
}

func main() {
    profileID, err := eat.NewProfile("http://example.com/example-profile")
    if err != nil {
        panic(err)
    }

    profile, ok := corim.GetProfile(profileID)
    if !ok {
        log.Fatalf("profile %v not found", profileID)
    }

    myCorim := profile.GetUnsignedCorim()
    myComid := profile.GetComid().
        SetLanguage("en-GB").
        SetTagIdentity("example", 0).
        // Adding an entity to the Entities collection also registers
        // profile's extensions
        AddEntity("ACME Ltd.", &comid.TestRegID, comid.RoleCreator)

    refVal := comid.ValueTriple{
        Environment: comid.Environment{
            Class: comid.NewClassImplID(comid.TestImplID).
                SetVendor("ACME Ltd.").
                SetModel("RoadRunner 2.0"),
        },
        Measurements: *comid.NewMeasurements(),
    }

    measurement := comid.MustNewPSAMeasurement(
        comid.MustCreatePSARefValID(
            comid.TestSignerID, "BL", "5.0.5",
        )).AddDigest(swid.Sha256_32, []byte{0xab, 0xcd, 0xef, 0x00})

    refVal.Measurements.Add(measurement)
    myComid.Triples.AddReferenceValue(refVal)

    /* This works as explained in the example */
    address := "123 Fake Street"
    err = myComid.Entities.Values[0].Extensions.Set("Address", &address)
    if err != nil {
        log.Fatalf("could not set entity Address: %v", err)
    }

    /* This one does not */
    /*
    address2 := "456 Fake Street"
    err = myComid.Triples.ReferenceValues.Values[0].Extensions.Set("Address", &address2)
    if err != nil {
        log.Fatalf("could not set entity Address: %v", err)
    }
    */

    spew.Dump(myComid)

    err = myComid.Valid()
    if err != nil {
        log.Fatalf("comid validity: %v", err)
    }

    myCorim.AddComid(*myComid)

    buf, err := myCorim.ToCBOR()
    if err != nil {
        log.Fatalf("could not encode CoRIM: %v", err)
    }

    fmt.Printf("corim: %v", hex.EncodeToString(buf))
}
setrofim commented 3 months ago

Thanks for posting the example. I was able to reproduce the issue. It is due to a couple of subtle bugs in extensions.Collection implementation that should be fixed here: https://github.com/veraison/corim/pull/120

There is also a slight issue with your code -- you need to be accessing Extension at the MVal instance inside Measurement, rather than inside ValueTriple:

    /* This should now work */
    address2 := "456 Fake Street"
    err = myComid.Triples.ReferenceValues.Values[0].
                  Measurements.Values[0].
                  Val.Extensions.Set("Address", &address2)
    if err != nil {
        log.Fatalf("could not set entity Address: %v", err)
    }

Please could you try updating the commented out block in your example to the above and then re-building again the top commit in the pull request.

jraman567 commented 3 months ago

Thank you! I can access I can access comid.ExtReferenceValue with this pull request #120 and the fix above.