[zeromq-dev] zyre and curve key exchange

Justin Azoff justin.azoff at gmail.com
Sat Jul 15 23:45:41 CEST 2017

On Sat, Jul 15, 2017 at 5:38 AM, Luca Boccassi <luca.boccassi at gmail.com> wrote:

> Looks very interesting!
> I would recommend using actor calls rather than overloading.
> The endpoint format is already very overloaded and a bit confusing as
> it is, having clear API calls is much cleaner and understandable for
> users and developers IMHO.

Hi!  I've been working with Wes on the zyre/curve bits.  One of the
reasons I was thinking about overloading the endpoints is that for the
actor messages we can easily implement things like

'CONNECT' 'endpoint'

'CONNECT CURVE' 'endpoint' 'public_key'

or if someone wanted to use PLAIN auth

'CONNECT PLAIN' 'endpoint' 'username' 'password'

The code to implement all that on the other end and all the api calls
is simple and easy to understand, but a bit verbose, and needs to be
implemented in every actor.

The problems start with the service discovery.  Gossip only supports
key/value pairs, and I'm working on a simpler service discovery
library that will have the same issue

I have a branch of zyre that enables arbitrary external discovery:

this adds a "REQUIRE PEER" actor message along with the corresponding
zyre_require_peer (zyre_t *self, const char *uuid, const char
*endpoint) api method.

For now we have things working by PUBLISH'ing into gossip

'UUID=endpoint' for regular connections, or

'UUID=endpoint|publickey' for curve connections and then splitting
things back out inside zyre.

but this 'endpoint|key' thing feels hackish.  If there was a function
for parsing uris, we could just use endpoints like

tcp://endpoint:port?public-key=key or

The only other idea I had was to use zhash_pack or something similar
to advertise the values as
"endpoint=tcp://endpoint:port,public-key=key"  and then a function
that could take a string like that and setup the socket appropriately.

If such a function was part of czmq that could remove the need for
separate CONNECT/CONNECT CURVE/CONNECT PLAIN methods everywhere.

So I guess what I am saying is we can build the api for

zyre_require_peer (zyre_t *self, const char *uuid, const char *endpoint)
zyre_require_peer_curve (zyre_t *self, const char *uuid, const char
*endpoint, const char *publickey)

but haven't quite worked out how to encode/serialize the information
needed to call the appropriate method when using service discovery.

It's possible we are going about this all wrong.  Wes mentioned that
some people have just ran a 2nd REP service that just responds with
the nodes public key.  This would remove the need for the public key
to be published as part of the service discovery process.  As long as
the key is a present in a local zcertstore that would still be secure.
If there was a way to connect to a remove curve server without needing
to use zsock_set_curve_serverkey but instead auto negotiate based on a
zcertstore, that would also work.

- Justin

More information about the zeromq-dev mailing list