veyron2/ipc: Support for granting credentials to servers in the form of blessings.

This change makes it possible for a client to provide additional credentials,
bound to the identity of the server, in the form of a blessed identity to
a server when making the request.

The server can access this credential via ipc.Context.Blessing.

Change-Id: I67dde80b7038b0ebb9b27f4917ae218b62ec13f0
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 4b53246..89af1cd 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -63,6 +63,10 @@
 	return fmt.Sprintf("%v", call.LocalID()), fmt.Sprintf("%v", call.RemoteID())
 }
 
+func (*testServer) EchoBlessing(call ipc.ServerCall, arg string) (result, blessing string) {
+	return arg, fmt.Sprintf("%v", call.Blessing())
+}
+
 func (*testServer) EchoAndError(call ipc.ServerCall, arg string) (string, error) {
 	result := fmt.Sprintf("method:%q,suffix:%q,arg:%q", call.Method(), call.Suffix(), arg)
 	if arg == "error" {
@@ -278,16 +282,20 @@
 	return
 }
 
+func bless(blessor security.PrivateID, blessee security.PublicID, name string, caveats ...security.ServiceCaveat) security.PublicID {
+	blessed, err := blessor.Bless(blessee, name, 24*time.Hour, caveats)
+	if err != nil {
+		panic(err)
+	}
+	return blessed
+}
+
 func derive(blessor security.PrivateID, name string, caveats ...security.ServiceCaveat) security.PrivateID {
 	id, err := isecurity.NewPrivateID("irrelevant")
 	if err != nil {
 		panic(err)
 	}
-	blessedID, err := blessor.Bless(id.PublicID(), name, 5*time.Minute, caveats)
-	if err != nil {
-		panic(err)
-	}
-	derivedID, err := id.Derive(blessedID)
+	derivedID, err := id.Derive(bless(blessor, id.PublicID(), name, caveats...))
 	if err != nil {
 		panic(err)
 	}
@@ -302,8 +310,8 @@
 }
 
 func TestStartCall(t *testing.T) {
-	authorizeErr := "has one or more invalid caveats"
-	nameErr := "does not have a name matching the provided pattern"
+	authorizeErr := "not authorized because"
+	nameErr := "does not match the provided pattern"
 
 	cavOnlyV1 := security.UniversalCaveat(caveat.PeerIdentity{"client/v1"})
 	now := time.Now()
@@ -435,6 +443,49 @@
 	}
 }
 
+// granter implements ipc.Granter, returning a fixed (security.PublicID, error) pair.
+type granter struct {
+	ipc.CallOpt
+	id  security.PublicID
+	err error
+}
+
+func (g granter) Grant(id security.PublicID) (security.PublicID, error) { return g.id, g.err }
+
+func TestBlessing(t *testing.T) {
+	b := createBundle(t, clientID, serverID, &testServer{})
+	defer b.cleanup(t)
+
+	tests := []struct {
+		granter                       ipc.CallOpt
+		blessing, starterr, finisherr string
+	}{
+		{blessing: "<nil>"},
+		{granter: granter{id: bless(clientID, serverID.PublicID(), "blessed")}, blessing: "client/blessed"},
+		{granter: granter{err: errors.New("hell no")}, starterr: "hell no"},
+		{granter: granter{id: clientID.PublicID()}, finisherr: "blessing provided not bound to this server"},
+	}
+	for _, test := range tests {
+		call, err := b.client.StartCall(&fakeContext{}, "mountpoint/server/suffix", "EchoBlessing", []interface{}{"argument"}, test.granter)
+		if !matchesErrorPattern(err, test.starterr) {
+			t.Errorf("%+v: StartCall returned error %v", test, err)
+		}
+		if err != nil {
+			continue
+		}
+		var result, blessing string
+		if err = call.Finish(&result, &blessing); !matchesErrorPattern(err, test.finisherr) {
+			t.Errorf("%+v: Finish returned error %v", test, err)
+		}
+		if err != nil {
+			continue
+		}
+		if result != "argument" || blessing != test.blessing {
+			t.Errorf("%+v: Got (%q, %q)", test, result, blessing)
+		}
+	}
+}
+
 func TestRPCAuthorization(t *testing.T) {
 	cavOnlyEcho := security.ServiceCaveat{
 		Service: security.AllPrincipals,