rpc/discovery: support permission

  Support discovery permission using identity-based encryption.
  For now, a fake identity-based encryption is used.

  Fixed a bug where only the first instance of the same service
  can be discovered.

  Changed to pass Advertisement value instead of pointer
  to avoid any possible interference from local caching of plugins.

  Added marshalling utilities for addresses and ibe keys
  so that we can use in all plugins.

MultiPart: 2/3
Change-Id: I3e260a451e29571956184226b20a83a2870b1fe5
diff --git a/lib/discovery/advertise.go b/lib/discovery/advertise.go
index 0cf4018..3930f63 100644
--- a/lib/discovery/advertise.go
+++ b/lib/discovery/advertise.go
@@ -7,33 +7,45 @@
 import (
 	"v.io/v23/context"
 	"v.io/v23/discovery"
-	"v.io/v23/security/access"
+	"v.io/v23/security"
 	"v.io/v23/verror"
 )
 
 var (
-	errNoInterfaceName = verror.Register(pkgPath+".errNoInterfaceName", verror.NoRetry, "{1:}{2:} interface name not provided")
-	errNoAddresses     = verror.Register(pkgPath+".errNoAddress", verror.NoRetry, "{1:}{2:} address not provided")
+	errNoInterfaceName       = verror.Register(pkgPath+".errNoInterfaceName", verror.NoRetry, "{1:}{2:} interface name not provided")
+	errNotPackableAttributes = verror.Register(pkgPath+".errNotPackableAttributes", verror.NoRetry, "{1:}{2:} attribute not packable")
+	errNoAddresses           = verror.Register(pkgPath+".errNoAddress", verror.NoRetry, "{1:}{2:} address not provided")
+	errNotPackableAddresses  = verror.Register(pkgPath+".errNotPackableAddresses", verror.NoRetry, "{1:}{2:} address not packable")
 )
 
 // Advertise implements discovery.Advertiser.
 //
 // TODO(jhahn): Handle ACL.
-func (ds *ds) Advertise(ctx *context.T, service discovery.Service, perms access.Permissions) error {
+func (ds *ds) Advertise(ctx *context.T, service discovery.Service, perms []security.BlessingPattern) error {
 	if len(service.InterfaceName) == 0 {
 		return verror.New(errNoInterfaceName, ctx)
 	}
+	if !IsAttributePackable(service.Attrs) {
+		return verror.New(errNotPackableAttributes, ctx)
+	}
 	if len(service.Addrs) == 0 {
 		return verror.New(errNoAddresses, ctx)
 	}
-
+	if !IsAddressPackable(service.Addrs) {
+		return verror.New(errNotPackableAddresses, ctx)
+	}
 	if len(service.InstanceUuid) == 0 {
 		service.InstanceUuid = NewInstanceUUID()
 	}
-	ad := &Advertisement{
+
+	ad := Advertisement{
 		ServiceUuid: NewServiceUUID(service.InterfaceName),
 		Service:     service,
 	}
+	if err := encrypt(&ad, perms); err != nil {
+		return err
+	}
+
 	ctx, cancel := context.WithCancel(ctx)
 	for _, plugin := range ds.plugins {
 		err := plugin.Advertise(ctx, ad)