veyron2/security,veyron/security: Get rid of "Caveat.Bytes" and simplify some
helper functions.
Change-Id: I26f771cebd6e512b89e98bec1fadfa1cb2aad6e8
diff --git a/runtimes/google/security/identity_chain.go b/runtimes/google/security/identity_chain.go
index 076b715..0987af3 100644
--- a/runtimes/google/security/identity_chain.go
+++ b/runtimes/google/security/identity_chain.go
@@ -91,18 +91,26 @@
return err
}
+func caveatsFromWire(bytes []wire.Caveat) []security.Caveat {
+ caveats := make([]security.Caveat, len(bytes))
+ for idx, b := range bytes {
+ caveats[idx].ValidatorVOM = b.Bytes
+ }
+ return caveats
+}
+
// Authorize checks if all caveats on the PublicID validate with respect to the
// provided context and if so returns the original PublicID. This method assumes that
// the existing PublicID was obtained after successfully decoding a serialized
// PublicID and hence has integrity.
func (id *chainPublicID) Authorize(context security.Context) (security.PublicID, error) {
for _, c := range id.certificates {
- for _, cav := range c.Caveats {
- v, err := vsecurity.CaveatValidators(cav.Bytes)
- if err != nil {
- return nil, errAuthorize(err)
- }
- if err := v[0].Validate(context); err != nil {
+ validators, err := vsecurity.CaveatValidators(caveatsFromWire(c.Caveats)...)
+ if err != nil {
+ return nil, errAuthorize(err)
+ }
+ for _, v := range validators {
+ if err := v.Validate(context); err != nil {
return nil, errAuthorize(err)
}
}
@@ -113,9 +121,7 @@
func (id *chainPublicID) ThirdPartyCaveats() []security.ThirdPartyCaveat {
var tpCaveats []security.ThirdPartyCaveat
for _, c := range id.certificates {
- for _, cav := range c.Caveats {
- tpCaveats = append(tpCaveats, vsecurity.ThirdPartyCaveats(cav.Bytes)...)
- }
+ tpCaveats = append(tpCaveats, vsecurity.ThirdPartyCaveats(caveatsFromWire(c.Caveats)...)...)
}
return tpCaveats
}
@@ -180,7 +186,7 @@
cert.Caveats = make([]wire.Caveat, len(caveats))
for i, c := range caveats {
- cert.Caveats[i] = wire.Caveat{Bytes: vsecurity.CaveatBytes(c)[0]}
+ cert.Caveats[i] = wire.Caveat{Bytes: c.ValidatorVOM}
}
vomPubID, err := id.publicID.VomEncode()
diff --git a/security/caveat/public_key_caveat.go b/security/caveat/public_key_caveat.go
index d07060b..6f3183e 100644
--- a/security/caveat/public_key_caveat.go
+++ b/security/caveat/public_key_caveat.go
@@ -27,13 +27,15 @@
// a validation key and the location (object name) of the third-party responsible
// for discharging the caveat. A discharge for this caveat is a signed assertion whose
// signature can be verified using the validation key.
+//
+// TODO(ataly): This should be a VDL defined type.
type publicKeyCaveat struct {
// RandNonce specifies a cryptographically random nonce (of fixed length) that
// uniquely identifies the caveat.
RandNonce []uint8
// DischargeMintingCaveat specifies the caveat that has to be validated
// before minting a discharge for a publicKeyCaveat.
- DischargeMintingCaveat []byte
+ DischargeMintingCaveat security.Caveat
// ValidationKey specifies the public key of the discharging-party.
ValidationKey wire.PublicKey
// ThirdPartyLocation specifies the object name of the discharging-party.
@@ -48,7 +50,7 @@
// TODO(ataly, ashankar): A 256bit hash is probably much stronger that what we need
// here. Can we truncate the hash to 96bits?
func (c *publicKeyCaveat) ID() string {
- return id(c.RandNonce, c.DischargeMintingCaveat)
+ return id(c.RandNonce, c.DischargeMintingCaveat.ValidatorVOM)
}
func (c *publicKeyCaveat) Location() string {
@@ -56,7 +58,7 @@
}
func (c *publicKeyCaveat) String() string {
- return fmt.Sprintf("publicKeyCaveat{DischargeMintingCaveat: (%v bytes), ThirdPartyLocation: %q}", len(c.DischargeMintingCaveat), c.ThirdPartyLocation)
+ return fmt.Sprintf("publicKeyCaveat{DischargeMintingCaveat: (%v bytes), ThirdPartyLocation: %q}", len(c.DischargeMintingCaveat.ValidatorVOM), c.ThirdPartyLocation)
}
func (c *publicKeyCaveat) Requirements() security.ThirdPartyRequirements {
@@ -102,12 +104,14 @@
// the validation key of the publicKeyCaveat. Additionally, the discharge may
// also include caveats which must all validate in order for the discharge to
// be considered valid.
+//
+// TODO(ataly): This should be a VDL-defined type?
type publicKeyDischarge struct {
// CaveatID is used to match this Discharge to the the ThirdPartyCaveat it is for.
CaveatID string
// Caveats under which this Discharge is valid.
- Caveats [][]byte
+ Caveats []security.Caveat
// Signature on the contents of the discharge that can be verified using the
// validaton key in the publicKeycaveat this discharge is for.
@@ -133,7 +137,7 @@
wire.WriteString(h, tmp, d.CaveatID)
for _, cav := range d.Caveats {
- wire.WriteBytes(h, tmp, cav)
+ wire.WriteBytes(h, tmp, cav.ValidatorVOM)
}
return h.Sum(nil)
}
@@ -155,7 +159,7 @@
return &publicKeyCaveat{
RandNonce: nonce,
- DischargeMintingCaveat: caveat.Bytes(),
+ DischargeMintingCaveat: caveat,
ValidationKey: validationKey,
ThirdPartyLocation: location,
ThirdPartyRequirements: requirements,
@@ -191,10 +195,7 @@
}
caveats = append(caveats, expiryCaveat)
- discharge := &publicKeyDischarge{
- CaveatID: tp.ID(),
- Caveats: vsecurity.CaveatBytes(caveats...),
- }
+ discharge := &publicKeyDischarge{CaveatID: tp.ID(), Caveats: caveats}
// TODO(ashankar,ataly): Should signer necessarily be the same as ctx.LocalID()?
// If so, need the PrivateID object corresponding to ctx.LocalID.
diff --git a/security/util.go b/security/util.go
index 31987a0..e2c37dc 100644
--- a/security/util.go
+++ b/security/util.go
@@ -58,28 +58,19 @@
return json.NewEncoder(w).Encode(acl)
}
-// CaveatBytes returns a slice containing the Bytes of the provided 'caveats'.
-func CaveatBytes(caveats ...security.Caveat) [][]byte {
- b := make([][]byte, len(caveats))
- for i, c := range caveats {
- b[i] = c.Bytes()
- }
- return b
-}
-
// CaveatValidators returns the set of security.CaveatValidators
// obtained by decoding the provided caveat bytes.
//
// It is an error if any of the provided caveat bytes cannot
// be decoded into a security.CaveatValidator.
-func CaveatValidators(caveats ...[]byte) ([]security.CaveatValidator, error) {
+func CaveatValidators(caveats ...security.Caveat) ([]security.CaveatValidator, error) {
if len(caveats) == 0 {
return nil, nil
}
validators := make([]security.CaveatValidator, len(caveats))
for i, c := range caveats {
var v security.CaveatValidator
- if err := vom.NewDecoder(bytes.NewReader(c)).Decode(&v); err != nil {
+ if err := vom.NewDecoder(bytes.NewReader(c.ValidatorVOM)).Decode(&v); err != nil {
return nil, fmt.Errorf("caveat bytes could not be VOM-decoded: %s", err)
}
validators[i] = v
@@ -89,11 +80,11 @@
// ThirdPartyCaveats returns the set of security.ThirdPartyCaveats
// that could be successfully decoded from the provided caveat bytes.
-func ThirdPartyCaveats(caveats ...[]byte) []security.ThirdPartyCaveat {
+func ThirdPartyCaveats(caveats ...security.Caveat) []security.ThirdPartyCaveat {
var tpCaveats []security.ThirdPartyCaveat
for _, c := range caveats {
var t security.ThirdPartyCaveat
- if err := vom.NewDecoder(bytes.NewReader(c)).Decode(&t); err != nil {
+ if err := vom.NewDecoder(bytes.NewReader(c.ValidatorVOM)).Decode(&t); err != nil {
continue
}
tpCaveats = append(tpCaveats, t)
diff --git a/security/util_test.go b/security/util_test.go
index 2cf2da4..c462991 100644
--- a/security/util_test.go
+++ b/security/util_test.go
@@ -66,31 +66,32 @@
func (tpCaveat) Requirements() (r security.ThirdPartyRequirements) { return }
func TestCaveatUtil(t *testing.T) {
- type b [][]byte
- type v []security.CaveatValidator
- type tp []security.ThirdPartyCaveat
+ type C []security.Caveat
+ type V []security.CaveatValidator
+ type TP []security.ThirdPartyCaveat
- newCaveatBytes := func(v security.CaveatValidator) []byte {
- cav, err := security.NewCaveat(v)
+ newCaveat := func(v security.CaveatValidator) security.Caveat {
+ c, err := security.NewCaveat(v)
if err != nil {
- t.Fatalf("NewCaveat failed: %s", err)
+ t.Fatalf("failed to create Caveat from validator %T: %v", v, c)
}
- return cav.Bytes()
+ return c
}
+
var (
- fpCavBytes = newCaveatBytes(fpCaveat{})
- tpCavBytes = newCaveatBytes(tpCaveat{})
- invalid = []byte("fake")
+ fp fpCaveat
+ tp tpCaveat
+ invalid = security.Caveat{ValidatorVOM: []byte("invalid")}
)
testdata := []struct {
- caveats [][]byte
+ caveats []security.Caveat
validators []security.CaveatValidator
tpCaveats []security.ThirdPartyCaveat
}{
{nil, nil, nil},
- {b{fpCavBytes}, v{fpCaveat{}}, nil},
- {b{tpCavBytes}, v{tpCaveat{}}, tp{tpCaveat{}}},
- {b{fpCavBytes, tpCavBytes}, v{fpCaveat{}, tpCaveat{}}, tp{tpCaveat{}}},
+ {C{newCaveat(fp)}, V{fp}, nil},
+ {C{newCaveat(tp)}, V{tp}, TP{tp}},
+ {C{newCaveat(fp), newCaveat(tp)}, V{fp, tp}, TP{tp}},
}
for i, d := range testdata {
// Test CaveatValidators.
diff --git a/services/identity/revocation/bless.go b/services/identity/revocation/bless.go
index bfacb4b..d2720e6 100644
--- a/services/identity/revocation/bless.go
+++ b/services/identity/revocation/bless.go
@@ -46,7 +46,7 @@
blessEntry.Blessed, _ = entry.Results[0].(security.PublicID)
caveats, _ := entry.Arguments[3].([]security.Caveat)
if len(caveats) > 0 {
- revocationCaveat, err := vsecurity.CaveatValidators(caveats[0].Bytes())
+ revocationCaveat, err := vsecurity.CaveatValidators(caveats[0])
if err != nil {
return blessEntry, err
}