From 4ebb5ddc45b5b621364b6022f38bafca5834076a Mon Sep 17 00:00:00 2001 From: Sergei Trofimov Date: Thu, 12 Oct 2023 17:02:11 +0100 Subject: [PATCH] WIP BORKED --- comid/measurement.go | 219 ++++++++++++------------------------- comid/psareferencevalue.go | 40 +++++-- 2 files changed, 100 insertions(+), 159 deletions(-) diff --git a/comid/measurement.go b/comid/measurement.go index b1909d87..c72d35f5 100644 --- a/comid/measurement.go +++ b/comid/measurement.go @@ -5,6 +5,7 @@ package comid import ( "encoding/json" + "errors" "fmt" "net" @@ -23,191 +24,107 @@ type Measurement struct { AuthorizedBy *CryptoKey `cbor:"2,keyasint,omitempty" json:"authorized-by,omitempty"` } +type IMKeyValue interface { + extensions.ITypeChoiceValue +} + // Mkey stores a $measured-element-type-choice. // The supported types are UUID, PSA refval-id, CCA platform-config-id and unsigned integer // TO DO Add tagged OID: see https://github.com/veraison/corim/issues/35 type Mkey struct { - val interface{} + Value IMKeyValue } func (o Mkey) IsSet() bool { - return o.val != nil + return o.Value != nil } func (o Mkey) Valid() error { - switch t := o.val.(type) { - case TaggedUUID: - if UUID(t).Empty() { - return fmt.Errorf("empty UUID") - } - return nil - case TaggedPSARefValID: - return PSARefValID(t).Valid() - case TaggedCCAPlatformConfigID: - if CCAPlatformConfigID(t).Empty() { - return fmt.Errorf("empty CCAPlatformConfigID") - } - case uint64: - if o.val == nil { - return fmt.Errorf("empty uint Mkey") - } - return nil - default: - return fmt.Errorf("unknown measurement key type: %T", t) - } - return nil -} - -func (o Mkey) IsPSARefValID() bool { - _, ok := o.val.(TaggedPSARefValID) - return ok -} - -func (o Mkey) IsCCAPlatformConfigID() bool { - _, ok := o.val.(TaggedCCAPlatformConfigID) - return ok -} + return o.Value.Valid() + //switch t := o.val.(type) { + //case TaggedUUID: + //if UUID(t).Empty() { + //return fmt.Errorf("empty UUID") + //} + //return nil + //case TaggedPSARefValID: + //return PSARefValID(t).Valid() + //case TaggedCCAPlatformConfigID: + //if CCAPlatformConfigID(t).Empty() { + //return fmt.Errorf("empty CCAPlatformConfigID") + //} + //case uint64: + //if o.val == nil { + //return fmt.Errorf("empty uint Mkey") + //} + //return nil + //default: + //return fmt.Errorf("unknown measurement key type: %T", t) + //} + //return nil +} + +// UnmarshalJSON deserializes the supplied JSON object into the target MKey +// The key object must have the following shape: +// +// { +// "type": "", +// "value": "" +// } +// +// where must be one of the known IMKeyValue implementation +// type names (available in the base implementation: "uuid", "oid", +// "psa.impl-id"), and is the class id value encoded as +// a string. The exact encoding is depenent. For the base +// implmentation types it is +// +// oid: dot-seprated integers, e.g. "1.2.3.4" +// psa.ref-val: base64-encoded bytes, e.g. "YWNtZS1pbXBsZW1lbnRhdGlvbi1pZC0wMDAwMDAwMDE=" +// uuid: standard UUID string representation, e.g. "550e8400-e29b-41d4-a716-446655440000" +func (o *Mkey) UnmarshalJSON(data []byte) error { + var value encoding.TypeAndValue -func (o Mkey) GetPSARefValID() (PSARefValID, error) { - switch t := o.val.(type) { - case TaggedPSARefValID: - return PSARefValID(t), nil - default: - return PSARefValID{}, fmt.Errorf("measurement-key type is: %T", t) + if err := json.Unmarshal(data, &value); err != nil { + return err } -} -func (o Mkey) GetCCAPlatformConfigID() (CCAPlatformConfigID, error) { - switch t := o.val.(type) { - case TaggedCCAPlatformConfigID: - return CCAPlatformConfigID(t), nil - default: - return CCAPlatformConfigID(""), fmt.Errorf("measurement-key type is: %T", t) + if value.Type == "" { + return errors.New("measurement type not set") } -} -func (o Mkey) GetKeyUint() (uint64, error) { - switch t := o.val.(type) { - case uint64: - return t, nil - default: - return MaxUint64, fmt.Errorf("measurement-key type is: %T", t) + factory, ok := classIDValueRegister[value.Type] + if !ok { + return fmt.Errorf("unknown measurement type: %q", value.Type) } -} -// UnmarshalJSON deserializes the type'n'value JSON object into the target Mkey -func (o *Mkey) UnmarshalJSON(data []byte) error { - var v tnv - - if err := json.Unmarshal(data, &v); err != nil { + v, err := factory(value.Value) + if err != nil { return err } - switch v.Type { - case "uuid": - var x UUID - if err := x.UnmarshalJSON(v.Value); err != nil { - return fmt.Errorf( - "cannot unmarshal $measured-element-type-choice of type UUID: %w", - err, - ) - } - o.val = TaggedUUID(x) - case "psa.refval-id": - var x PSARefValID - if err := json.Unmarshal(v.Value, &x); err != nil { - return fmt.Errorf( - "cannot unmarshal $measured-element-type-choice of type PSARefValID: %w", - err, - ) - } - if err := x.Valid(); err != nil { - return fmt.Errorf( - "cannot unmarshal $measured-element-type-choice of type PSARefValID: %w", - err, - ) - } - o.val = TaggedPSARefValID(x) - case "cca.platform-config-id": - var x CCAPlatformConfigID - if err := json.Unmarshal(v.Value, &x); err != nil { - return fmt.Errorf( - "cannot unmarshal $measured-element-type-choice of type CCAPlatformConfigID: %w", - err, - ) - } - if x.Empty() { - return fmt.Errorf( - "cannot unmarshal $measured-element-type-choice of type CCAPlatformConfigID: empty label", - ) - } - o.val = TaggedCCAPlatformConfigID(x) - case "uint": - var x uint64 - if err := json.Unmarshal(v.Value, &x); err != nil { - return fmt.Errorf( - "cannot unmarshal $measured-element-type-choice of type uint: %w", - err, - ) - } - o.val = x - default: - return fmt.Errorf("unknown type %s for $measured-element-type-choice", v.Type) - } + o.Value = v.Value + + return o.Valid() return nil } // MarshalJSON serializes the target Mkey into the type'n'value JSON object -// Supported types are: uuid, psa.refval-id and unsigned integer func (o Mkey) MarshalJSON() ([]byte, error) { - var ( - v tnv - b []byte - err error - ) - - switch t := o.val.(type) { - case TaggedUUID: - uuidString := UUID(t).String() - b, err = json.Marshal(uuidString) - if err != nil { - return nil, err - } - v = tnv{Type: "uuid", Value: b} - case TaggedPSARefValID: - b, err = json.Marshal(t) - if err != nil { - return nil, err - } - v = tnv{Type: "psa.refval-id", Value: b} - case TaggedCCAPlatformConfigID: - b, err = json.Marshal(t) - if err != nil { - return nil, err - } - v = tnv{Type: "cca.platform-config-id", Value: b} - - case uint64: - b, err = json.Marshal(t) - if err != nil { - return nil, err - } - v = tnv{Type: "uint", Value: b} - - default: - return nil, fmt.Errorf("unknown type %T for mkey", t) + value := encoding.TypeAndValue{ + Type: o.Value.Type(), + Value: o.Value.String(), } - return json.Marshal(v) + return json.Marshal(value) } func (o Mkey) MarshalCBOR() ([]byte, error) { - return em.Marshal(o.val) + return em.Marshal(o.Value) } func (o *Mkey) UnmarshalCBOR(data []byte) error { - return dm.Unmarshal(data, &o.val) + return dm.Unmarshal(data, &o.Value) } // Mval stores a measurement-values-map with JSON and CBOR serializations. diff --git a/comid/psareferencevalue.go b/comid/psareferencevalue.go index cde3304b..8923c2ef 100644 --- a/comid/psareferencevalue.go +++ b/comid/psareferencevalue.go @@ -4,6 +4,7 @@ package comid import ( + "encoding/json" "fmt" ) @@ -30,18 +31,26 @@ func (o PSARefValID) Valid() error { return nil } -type TaggedPSARefValID PSARefValID +func NewPSARefValID(val any) (*PSARefValID, error) { + var ret PSARefValID -func NewPSARefValID(signerID []byte) *PSARefValID { - switch len(signerID) { - case 32, 48, 64: - default: - return nil + if val == nil { + return &ret, nil } - return &PSARefValID{ - SignerID: signerID, + switch t := val.(type) { + case []byte: + switch len(t) { + case 32, 48, 64: + ret.SignerID = t + default: + return nil, fmt.Errorf("", len(t)) + } + default: + return nil, fmt.Errorf("unexpected type for PSA RefVal ID: %T", t) } + + return &ret, nil } func (o *PSARefValID) SetLabel(label string) *PSARefValID { @@ -57,3 +66,18 @@ func (o *PSARefValID) SetVersion(version string) *PSARefValID { } return o } + +type TaggedPSARefValID PSARefValID + +func (o TaggedPSARefValID) Valid() error { + return PSARefValID(o).Valid() +} + +func (o TaggedPSARefValID) String() string { + ret, err := json.Marshal(o) + if err != nil { + return "" + } + + return string(ret) +}