Skip to content

Commit

Permalink
refactor: align realm claims with profiles
Browse files Browse the repository at this point in the history
Refactor realm claims to align with PSA token profile definitions and to
allow them to be potentially extended in an analogous way via CCA
profiles.

- Use psatoken.IClaimsBase to define realm.IClaims. This exposes
  operations common to all claims objects, namely marshalling and
  validation.
- Expose previously internal realm.validate() as realm.ValidateClaims().
  This will help with implementing profiles that do not embed the
  original claims structure.
- Expose individual claim field validators and rename them from
  isValidXXX (which implies a boolean return) to ValidateXXX. This will
  be useful if, e.g., client code wants to make sure a hash is a valid
  realm challenge without needing a claims structure.
- Reuse errors defined inside psatoken, rather then re-defining them for
  realm claims. Errors such as "syntax error" or "missing mandatory
  claims" are in effect part of the generic IClaimsBase interface (i.e.
  common to all profile-able claims objects).
- Do not use json tags inside error messages, as they may be different
  for profiles that implement their own claims without embedding
  existing ones.
- Some minor stylistic tidying (consistent spacing, etc).

Signed-off-by: Sergei Trofimov <[email protected]>
  • Loading branch information
setrofim committed Jul 3, 2024
1 parent 9849f1f commit 18b4708
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 127 deletions.
2 changes: 1 addition & 1 deletion evidence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func TestEvidence_SetClaims_invalid_realm(t *testing.T) {
err = incompleteRealmClaims.SetPubKeyHashAlgID("sha-256")
require.NoError(t, err)

expectedErr := "validation of cca-realm-claims failed: validating cca-realm-challenge claim: missing mandatory claim"
expectedErr := "validation of cca-realm-claims failed: validating realm challenge claim: missing mandatory claim"

var e Evidence

Expand Down
68 changes: 35 additions & 33 deletions realm/claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"

"github.com/veraison/eat"
"github.com/veraison/psatoken"
)

type Claims struct {
Expand All @@ -21,7 +22,7 @@ type Claims struct {
// Setters

func (c *Claims) SetChallenge(v []byte) error {
if err := isValidChallenge(v); err != nil {
if err := ValidateChallenge(v); err != nil {
return err
}

Expand All @@ -35,7 +36,7 @@ func (c *Claims) SetChallenge(v []byte) error {
}

func (c *Claims) SetPersonalizationValue(v []byte) error {
if err := isValidPersonalizationValue(v); err != nil {
if err := ValidatePersonalizationValue(v); err != nil {
return err
}

Expand All @@ -44,7 +45,7 @@ func (c *Claims) SetPersonalizationValue(v []byte) error {
}

func (c *Claims) SetInitialMeasurement(v []byte) error {
if err := isValidRealmMeas(v); err != nil {
if err := ValidateRealmMeas(v); err != nil {
return err
}

Expand All @@ -53,7 +54,7 @@ func (c *Claims) SetInitialMeasurement(v []byte) error {
}

func (c *Claims) SetExtensibleMeasurements(v [][]byte) error {
if err := isValidExtensibleMeas(v); err != nil {
if err := ValidateExtensibleMeas(v); err != nil {
return err
}

Expand All @@ -62,7 +63,7 @@ func (c *Claims) SetExtensibleMeasurements(v [][]byte) error {
}

func (c *Claims) SetHashAlgID(v string) error {
if err := isValidHashAlgID(v); err != nil {
if err := ValidateHashAlgID(v); err != nil {
return err
}

Expand All @@ -71,7 +72,7 @@ func (c *Claims) SetHashAlgID(v string) error {
}

func (c *Claims) SetPubKey(v []byte) error {
if err := isValidRealmPubKey(v); err != nil {
if err := ValidateRealmPubKey(v); err != nil {
return err
}

Expand All @@ -81,7 +82,7 @@ func (c *Claims) SetPubKey(v []byte) error {

func (c *Claims) SetPubKeyHashAlgID(v string) error {
if v == "" {
return fmt.Errorf("invalid null string set for cca-realm-pubkey-hash-algo-id")
return fmt.Errorf("invalid null string set for realm pubkey hash alg ID")
}

c.PublicKeyHashAlgID = &v
Expand All @@ -91,65 +92,69 @@ func (c *Claims) SetPubKeyHashAlgID(v string) error {
// Getters
func (c Claims) GetChallenge() ([]byte, error) {
v := c.Challenge

if v == nil {
return nil, ErrMandatoryClaimMissing
return nil, psatoken.ErrMandatoryClaimMissing
}

l := v.Len()

if l != 1 {
return nil, fmt.Errorf("%w: got %d nonces, want 1", ErrWrongClaimSyntax, l)
return nil, fmt.Errorf("%w: got %d nonces, want 1", psatoken.ErrWrongSyntax, l)
}

n := v.GetI(0)
if err := isValidChallenge(n); err != nil {
if err := ValidateChallenge(n); err != nil {
return nil, err
}

return n, nil
}

func (c Claims) GetPersonalizationValue() ([]byte, error) {
v := c.PersonalizationValue

if v == nil {
return nil, ErrMandatoryClaimMissing
return nil, psatoken.ErrMandatoryClaimMissing
}
if err := isValidPersonalizationValue(*v); err != nil {

if err := ValidatePersonalizationValue(*v); err != nil {
return nil, err
}

return *v, nil
}

func (c Claims) GetInitialMeasurement() ([]byte, error) {

v := c.InitialMeasurement
if v == nil {
return nil, ErrMandatoryClaimMissing
return nil, psatoken.ErrMandatoryClaimMissing
}
if err := isValidRealmMeas(*v); err != nil {

if err := ValidateRealmMeas(*v); err != nil {
return nil, err
}

return *v, nil
}

func (c Claims) GetExtensibleMeasurements() ([][]byte, error) {
v := c.ExtensibleMeasurements
if v == nil {
return nil, ErrMandatoryClaimMissing
return nil, psatoken.ErrMandatoryClaimMissing
}
if err := isValidExtensibleMeas(*v); err != nil {

if err := ValidateExtensibleMeas(*v); err != nil {
return nil, err
}

return *v, nil
}

func (c Claims) GetHashAlgID() (string, error) {
v := c.HashAlgID
if v == nil {
return "", ErrMandatoryClaimMissing
return "", psatoken.ErrMandatoryClaimMissing
}
if err := isValidHashAlgID(*v); err != nil {
if err := ValidateHashAlgID(*v); err != nil {
return "", err
}
return *v, nil
Expand All @@ -159,10 +164,10 @@ func (c Claims) GetPubKey() ([]byte, error) {
v := c.PublicKey

if v == nil {
return nil, ErrMandatoryClaimMissing
return nil, psatoken.ErrMandatoryClaimMissing
}

if err := isValidRealmPubKey(*v); err != nil {
if err := ValidateRealmPubKey(*v); err != nil {
return nil, err
}

Expand All @@ -173,14 +178,15 @@ func (c Claims) GetPubKeyHashAlgID() (string, error) {
v := c.PublicKeyHashAlgID

if v == nil {
return "", ErrMandatoryClaimMissing
return "", psatoken.ErrMandatoryClaimMissing
}

return *v, nil
}

// Semantic validation
func (c Claims) Validate() error {
return validate(&c)
return ValidateClaims(&c)
}

// Codecs
Expand Down Expand Up @@ -227,31 +233,27 @@ func (c Claims) ToUnvalidatedCBOR() ([]byte, error) {
}

func (c *Claims) FromJSON(buf []byte) error {
err := c.FromUnvalidatedJSON(buf)
if err != nil {
if err := c.FromUnvalidatedJSON(buf); err != nil {
return err
}

err = c.Validate()
if err != nil {
if err := c.Validate(); err != nil {
return fmt.Errorf("validation of CCA realm claims failed: %w", err)
}

return nil
}

func (c *Claims) FromUnvalidatedJSON(buf []byte) error {
err := json.Unmarshal(buf, c)
if err != nil {
if err := json.Unmarshal(buf, c); err != nil {
return fmt.Errorf("JSON decoding of CCA realm claims failed: %w", err)
}

return nil
}

func (c Claims) ToJSON() ([]byte, error) {
err := c.Validate()
if err != nil {
if err := c.Validate(); err != nil {
return nil, fmt.Errorf("validation of CCA realm claims failed: %w", err)
}

Expand Down
28 changes: 14 additions & 14 deletions realm/claims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,27 @@ func Test_CcaRealmClaims_Set_nok(t *testing.T) {
c := NewClaims()

err := c.SetChallenge([]byte("123"))
expectedErr := "wrong syntax for claim: length 3 (cca-hash-type MUST be 64 bytes)"
expectedErr := "wrong syntax: length 3 (hash MUST be 64 bytes)"
assert.EqualError(t, err, expectedErr)

err = c.SetPersonalizationValue([]byte("personalizationVal"))
expectedErr = "wrong syntax for claim: length 18 (cca-personalization-value MUST be 64 bytes)"
expectedErr = "wrong syntax: length 18 (personalization value MUST be 64 bytes)"
assert.EqualError(t, err, expectedErr)

err = c.SetInitialMeasurement([]byte("random"))
expectedErr = "wrong syntax for claim: length 6 (cca-realm-measurement MUST be 32, 48 or 64 bytes)"
expectedErr = "wrong syntax: length 6 (realm measurement MUST be 32, 48 or 64 bytes)"
assert.EqualError(t, err, expectedErr)

err = c.SetExtensibleMeasurements([][]byte{})
expectedErr = "missing mandatory claim cca-realm-extended-measurements"
expectedErr = "missing mandatory claim realm extended measurements"
assert.EqualError(t, err, expectedErr)

err = c.SetHashAlgID("")
expectedErr = "wrong syntax for claim: empty string"
expectedErr = "wrong syntax: empty string"
assert.EqualError(t, err, expectedErr)

err = c.SetPubKey([]byte("not-a-valid-point"))
expectedErr = "wrong syntax for claim: length 17 (cca-realm-public-key MUST be 97 bytes)"
expectedErr = "wrong syntax: length 17 (realm public key MUST be 97 bytes)"
assert.EqualError(t, err, expectedErr)

err = c.SetPubKey([]byte{
Expand All @@ -80,19 +80,19 @@ func Test_CcaRealmClaims_Set_nok(t *testing.T) {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff,
})
expectedErr = "wrong syntax for claim: checking raw public key coordinates are on curve P-384: failed to unmarshal elliptic curve point"
expectedErr = "wrong syntax: checking raw public key coordinates are on curve P-384: failed to unmarshal elliptic curve point"
assert.EqualError(t, err, expectedErr)

err = c.SetPubKeyHashAlgID("")
expectedErr = "invalid null string set for cca-realm-pubkey-hash-algo-id"
expectedErr = "invalid null string set for realm pubkey hash alg ID"
assert.EqualError(t, err, expectedErr)
}

func Test_CcaRealmClaims_ToCBOR_invalid(t *testing.T) {
c := NewClaims()

_, err := c.ToCBOR()
expectedErr := `validation of CCA realm claims failed: validating cca-realm-challenge claim: missing mandatory claim`
expectedErr := `validation of CCA realm claims failed: validating realm challenge claim: missing mandatory claim`
assert.EqualError(t, err, expectedErr)
}

Expand Down Expand Up @@ -160,36 +160,36 @@ func Test_CcaRealmClaims_FromCBOR_bad_input(t *testing.T) {
func Test_CcaRealmClaims_FromCBOR_missing_mandatory_claims(t *testing.T) {
buf := mustHexDecode(t, testEncodedCcaRealmClaimsMissingMandNonce)

expectedErr := "validation of CCA realm claims failed: validating cca-realm-challenge claim: missing mandatory claim"
expectedErr := "validation of CCA realm claims failed: validating realm challenge claim: missing mandatory claim"

var c Claims
err := c.FromCBOR(buf)
assert.EqualError(t, err, expectedErr)

buf = mustHexDecode(t, testEncodedCcaClaimsMissingMandInitialMeas)

expectedErr = "validation of CCA realm claims failed: validating cca-realm-initial-measurements claim: missing mandatory claim"
expectedErr = "validation of CCA realm claims failed: validating realm initial measurements claim: missing mandatory claim"
c = Claims{}
err = c.FromCBOR(buf)
assert.EqualError(t, err, expectedErr)

buf = mustHexDecode(t, testEncodedCcaClaimsMissingMandHashAlgID)

expectedErr = "validation of CCA realm claims failed: validating cca-realm-hash-alg-id claim: missing mandatory claim"
expectedErr = "validation of CCA realm claims failed: validating realm hash alg ID claim: missing mandatory claim"
c = Claims{}
err = c.FromCBOR(buf)
assert.EqualError(t, err, expectedErr)

buf = mustHexDecode(t, testEncodedCcaClaimsMissingMandPubKey)

expectedErr = "validation of CCA realm claims failed: validating cca-realm-public-key claim: missing mandatory claim"
expectedErr = "validation of CCA realm claims failed: validating realm public key claim: missing mandatory claim"
c = Claims{}
err = c.FromCBOR(buf)
assert.EqualError(t, err, expectedErr)

buf = mustHexDecode(t, testEncodedCcaClaimsMissingMandExtendedMeas)

expectedErr = "validation of CCA realm claims failed: validating cca-realm-extended-measurements claim: missing mandatory claim"
expectedErr = "validation of CCA realm claims failed: validating realm extended measurements claim: missing mandatory claim"
c = Claims{}
err = c.FromCBOR(buf)
assert.EqualError(t, err, expectedErr)
Expand Down
Loading

0 comments on commit 18b4708

Please sign in to comment.