Merge ""veyron2/security": No direct vom encoding of blessings"
diff --git a/runtimes/google/ipc/stream/vc/auth.go b/runtimes/google/ipc/stream/vc/auth.go
index cc27b09..cf83fff 100644
--- a/runtimes/google/ipc/stream/vc/auth.go
+++ b/runtimes/google/ipc/stream/vc/auth.go
@@ -97,7 +97,7 @@
 	if err := enc.Encode(signature); err != nil {
 		return err
 	}
-	if err := enc.Encode(b); err != nil {
+	if err := enc.Encode(security.MarshalBlessings(b)); err != nil {
 		return err
 	}
 	if v >= version.IPCVersion5 {
diff --git a/security/blessingstore.go b/security/blessingstore.go
index 2a03456..1a7540d 100644
--- a/security/blessingstore.go
+++ b/security/blessingstore.go
@@ -15,24 +15,48 @@
 
 var errStoreAddMismatch = errors.New("blessing's public key does not match store's public key")
 
-type persistentState struct {
+type blessings struct {
+	Value       security.WireBlessings
+	unmarshaled security.Blessings
+}
+
+func (w *blessings) Blessings() security.Blessings {
+	if w == nil {
+		return nil
+	}
+	return w.unmarshaled
+}
+
+func (w *blessings) Verify() error {
+	var err error
+	if w.unmarshaled == nil {
+		w.unmarshaled, err = security.NewBlessings(w.Value)
+	}
+	return err
+}
+
+func newWireBlessings(b security.Blessings) *blessings {
+	return &blessings{Value: security.MarshalBlessings(b), unmarshaled: b}
+}
+
+type state struct {
 	// Store maps BlessingPatterns to the Blessings object that is to be shared
 	// with peers which present blessings of their own that match the pattern.
 	//
 	// All blessings bind to the same public key.
-	Store map[security.BlessingPattern]security.Blessings
+	Store map[security.BlessingPattern]*blessings
 	// Default is the default Blessings to be shared with peers for which
 	// no other information is available to select blessings.
-	Default security.Blessings
+	Default *blessings
 }
 
 // blessingStore implements security.BlessingStore.
 type blessingStore struct {
-	publicKey     security.PublicKey
-	persistedData SerializerReaderWriter
-	signer        serialization.Signer
-	mu            sync.RWMutex
-	state         persistentState // GUARDED_BY(mu)
+	publicKey  security.PublicKey
+	serializer SerializerReaderWriter
+	signer     serialization.Signer
+	mu         sync.RWMutex
+	state      state // GUARDED_BY(mu)
 }
 
 func (bs *blessingStore) Set(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) {
@@ -46,7 +70,7 @@
 	defer bs.mu.Unlock()
 	old, hadold := bs.state.Store[forPeers]
 	if blessings != nil {
-		bs.state.Store[forPeers] = blessings
+		bs.state.Store[forPeers] = newWireBlessings(blessings)
 	} else {
 		delete(bs.state.Store, forPeers)
 	}
@@ -58,7 +82,7 @@
 		}
 		return nil, err
 	}
-	return old, nil
+	return old.Blessings(), nil
 }
 
 func (bs *blessingStore) ForPeer(peerBlessings ...string) security.Blessings {
@@ -66,10 +90,11 @@
 	defer bs.mu.RUnlock()
 
 	var ret security.Blessings
-	for pattern, blessings := range bs.state.Store {
+	for pattern, wb := range bs.state.Store {
 		if pattern.MatchedBy(peerBlessings...) {
-			if union, err := security.UnionOfBlessings(ret, blessings); err != nil {
-				vlog.Errorf("UnionOfBlessings(%v, %v) failed: %v, dropping the latter from BlessingStore.ForPeers(%v)", ret, blessings, err, peerBlessings)
+			b := wb.Blessings()
+			if union, err := security.UnionOfBlessings(ret, b); err != nil {
+				vlog.Errorf("UnionOfBlessings(%v, %v) failed: %v, dropping the latter from BlessingStore.ForPeers(%v)", ret, b, err, peerBlessings)
 			} else {
 				ret = union
 			}
@@ -82,7 +107,7 @@
 	bs.mu.RLock()
 	defer bs.mu.RUnlock()
 	if bs.state.Default != nil {
-		return bs.state.Default
+		return bs.state.Default.Blessings()
 	}
 	return bs.ForPeer()
 }
@@ -94,7 +119,7 @@
 		return errStoreAddMismatch
 	}
 	oldDefault := bs.state.Default
-	bs.state.Default = blessings
+	bs.state.Default = newWireBlessings(blessings)
 	if err := bs.save(); err != nil {
 		bs.state.Default = oldDefault
 	}
@@ -119,20 +144,20 @@
 // <pattern>    : <blessings>
 func (bs *blessingStore) DebugString() string {
 	const format = "%-30s : %s\n"
-	b := bytes.NewBufferString(fmt.Sprintf("Default blessings: %v\n", bs.state.Default))
+	b := bytes.NewBufferString(fmt.Sprintf("Default blessings: %v\n", bs.state.Default.Blessings()))
 
 	b.WriteString(fmt.Sprintf(format, "Peer pattern", "Blessings"))
-	for pattern, blessings := range bs.state.Store {
-		b.WriteString(fmt.Sprintf(format, pattern, blessings))
+	for pattern, wb := range bs.state.Store {
+		b.WriteString(fmt.Sprintf(format, pattern, wb.Blessings()))
 	}
 	return b.String()
 }
 
 func (bs *blessingStore) save() error {
-	if (bs.signer == nil) && (bs.persistedData == nil) {
+	if (bs.signer == nil) && (bs.serializer == nil) {
 		return nil
 	}
-	data, signature, err := bs.persistedData.Writers()
+	data, signature, err := bs.serializer.Writers()
 	if err != nil {
 		return err
 	}
@@ -146,24 +171,36 @@
 func newInMemoryBlessingStore(publicKey security.PublicKey) security.BlessingStore {
 	return &blessingStore{
 		publicKey: publicKey,
-		state:     persistentState{Store: make(map[security.BlessingPattern]security.Blessings)},
+		state:     state{Store: make(map[security.BlessingPattern]*blessings)},
 	}
 }
 
 // newPersistingBlessingStore returns a security.BlessingStore for a principal
 // that is initialized with the persisted data. The returned security.BlessingStore
 // also persists any updates to its state.
-func newPersistingBlessingStore(persistedData SerializerReaderWriter, signer serialization.Signer) (security.BlessingStore, error) {
-	if persistedData == nil || signer == nil {
+func newPersistingBlessingStore(serializer SerializerReaderWriter, signer serialization.Signer) (security.BlessingStore, error) {
+	verifyBlessings := func(wb *blessings, key security.PublicKey) error {
+		if wb == nil {
+			return nil
+		}
+		if err := wb.Verify(); err != nil {
+			return err
+		}
+		if b := wb.Blessings(); !reflect.DeepEqual(b.PublicKey(), key) {
+			return fmt.Errorf("read Blessings: %v that are not for provided PublicKey: %v", b, key)
+		}
+		return nil
+	}
+	if serializer == nil || signer == nil {
 		return nil, errors.New("persisted data or signer is not specified")
 	}
 	bs := &blessingStore{
-		publicKey:     signer.PublicKey(),
-		state:         persistentState{Store: make(map[security.BlessingPattern]security.Blessings)},
-		persistedData: persistedData,
-		signer:        signer,
+		publicKey:  signer.PublicKey(),
+		state:      state{Store: make(map[security.BlessingPattern]*blessings)},
+		serializer: serializer,
+		signer:     signer,
 	}
-	data, signature, err := bs.persistedData.Readers()
+	data, signature, err := bs.serializer.Readers()
 	if err != nil {
 		return nil, err
 	}
@@ -172,10 +209,13 @@
 			return nil, err
 		}
 	}
-	for _, b := range bs.state.Store {
-		if !reflect.DeepEqual(b.PublicKey(), bs.publicKey) {
-			return nil, fmt.Errorf("directory contains Blessings: %v that are not for the provided PublicKey: %v", b, bs.publicKey)
+	for _, wb := range bs.state.Store {
+		if err := verifyBlessings(wb, bs.publicKey); err != nil {
+			return nil, err
 		}
 	}
+	if err := verifyBlessings(bs.state.Default, bs.publicKey); err != nil {
+		return nil, err
+	}
 	return bs, nil
 }
diff --git a/security/principal_test.go b/security/principal_test.go
index 06de1ea..eb72f43 100644
--- a/security/principal_test.go
+++ b/security/principal_test.go
@@ -41,6 +41,18 @@
 	os.RemoveAll(dir)
 }
 
+// This Test checks that the all changes made to the principal's serialization
+// format stay backwards compatible.
+//
+// The 'testdata' directory used by this test was generated using the
+// principal tool as part of CL #6820.
+// $VEYRON_BIN/principal create testdata test
+func TestLoadPersistentPrincipalBackwardsCompatibility(t *testing.T) {
+	if _, err := LoadPersistentPrincipal("./testdata", nil); err != nil {
+		t.Fatal("LoadPersistentPrincipal is not backwards compatible: failed to read serialized principal data from CL #6820")
+	}
+}
+
 func TestCreatePersistentPrincipal(t *testing.T) {
 	tests := []struct {
 		Message, Passphrase []byte
diff --git a/security/testdata/blessingroots.data b/security/testdata/blessingroots.data
new file mode 100644
index 0000000..946e9c6
--- /dev/null
+++ b/security/testdata/blessingroots.data
Binary files differ
diff --git a/security/testdata/blessingroots.sig b/security/testdata/blessingroots.sig
new file mode 100644
index 0000000..18d71ca
--- /dev/null
+++ b/security/testdata/blessingroots.sig
Binary files differ
diff --git a/security/testdata/blessingstore.data b/security/testdata/blessingstore.data
new file mode 100644
index 0000000..7ea60e0
--- /dev/null
+++ b/security/testdata/blessingstore.data
Binary files differ
diff --git a/security/testdata/blessingstore.sig b/security/testdata/blessingstore.sig
new file mode 100644
index 0000000..0256a55
--- /dev/null
+++ b/security/testdata/blessingstore.sig
Binary files differ
diff --git a/security/testdata/privatekey.pem b/security/testdata/privatekey.pem
new file mode 100644
index 0000000..d4d86c2
--- /dev/null
+++ b/security/testdata/privatekey.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIMDHoqu5AjNuR3ilzSCOC5xoPR5e9PdC8xInEGstOFA3oAoGCCqGSM49
+AwEHoUQDQgAEVsRxZ6oITmKHVzGBJDxcc3UsyqDIYMNR7x0NybORlwvXYkyhESHv
+qlbyFZo79LPzJlDstYrJNcQno+FiHt2y+Q==
+-----END EC PRIVATE KEY-----
diff --git a/tools/principal/main.go b/tools/principal/main.go
index 15e1121..5112eef 100644
--- a/tools/principal/main.go
+++ b/tools/principal/main.go
@@ -606,7 +606,7 @@
 	if blessings == nil {
 		return errors.New("no blessings found")
 	}
-	str, err := base64VomEncode(blessings)
+	str, err := base64VomEncode(security.MarshalBlessings(blessings))
 	if err != nil {
 		return fmt.Errorf("base64-VOM encoding failed: %v", err)
 	}