[nanomsg] Re: end-to-end security

  • From: Garrett D'Amore <garrett@xxxxxxxxxx>
  • To: Drew Crawford <drew@xxxxxxxxxxxxxxxxxx>, nanomsg@xxxxxxxxxxxxx
  • Date: Tue, 11 Mar 2014 06:56:34 -0700

I have an interest in security as well, and some background.  I had been 
contemplating a different approach, using a TLS approach.  That’s not exactly 
end-to-end, but I had also been considering the use of “tunneling” Nanomsg over 
Nanomsg as a way to achieve end-to-end-security, when combined with a TLS-like 

My biggest fear about trying to develop this without using TLS or another well 
understood *protocol* is that security protocols are notoriously hard to get 
right.  The roadside is littered with failed attempts to create new security 
protocols, by well-meaning but less than well-trained professionals.   (In 
particular, folks who’ve not got the training *as crypto protocols people*.)  
To get this right, you need something that is both designed by, and audited by, 
people with a solid background in security.

Which is why using a protocol that has already been through this — like TLS — 
is so attractive.

I would like to make sure that if we’re going to land new protocol support (not 
just API!) in nanomsg, that it is one that can be reasonably implemented by 
other parties.  (I’m in the process of implementing — from scratch — a new 
implementation of nanomsg in “pure” Go.  I think it won’t be many more days 
before I make my work public.)

I would also like to make sure that any new protocol support is designed in a 
way that makes it possible to support the other protocol topologies (bus, 
pub/sub, etc.)  I think that’s a bit non-trivial, as you then are talking about 
multicast topologies.

The challenges of this is one reason why I think end-to-end might be difficult 
in the general case.    Compared with layering on top of secure transport, 
using a secure transport seems *lots* easier.

You’d also have to figure out some questions such as — devices — if you’re 
going to route requests, you need to be able to look at least at the envelope.  
That requires that at least envelopes are unencrypted.   

Anyway, I’m happy to help review anything you do, prior to integration, but I’m 
still pretty new around here myself. :-)

Garrett D'Amore
Sent with Airmail

On March 11, 2014 at 6:08:46 AM, Drew Crawford (drew@xxxxxxxxxxxxxxxxxx) wrote:

Hello folks,

I’ve written before to gauge the interest level on landing encryption support 
to nanomsg.

After my last post, I tentatively decided to go with a libzmq-based solution.  
However, for reasons outside the scope of this list, that hasn’t gone as well 
as I’d liked, and I’m now thinking about nanomsg once again.

The problem is important enough that I actually have time to work on it, and 
due to time constraints I’m going to settle on some solution in the next few 
days.  The only open question at this point is whether I’m going to land 
patches in nanomsg, or whether I’m going to be doing some kind of private 
solution, like a private fork or wrap of some library.  I’d prefer the former 
if possible.

I’d like to make a concrete proposal for comment.  As far as I can tell, there 
hasn’t been further discussion on the subject of encryption since my last post. 
 Here is what I’m thinking on design decisions:

End-to-end, “well-above-transport-layer” security.  Don’t get me wrong, there 
is a good case for transport-layer security.  Zeromq has used it with some 
success.  I use it right now.  The thing is, I’ve become convinced it’s the 
wrong approach for **my** set of problems.
Zeromq's support gets poor when you move out of TCP transport.  It would be a 
lot of work for them to support IPC, for example, which I’m mildly interested 
in.  I suspect that UDP is somewhat challenging as well, which is a long-term 
goal.  Doing security work near the surface means it’s completely decoupled 
from adding new transports, which is good if you want new transports, and also 
good if you want security to work with them.
Patches to the cryptography require deep knowledge of zeromq internals, and the 
people with the right knowledge are often busy.  When minor features to 
security are needed it creates major delays.  If security sits near the surface 
it requires knowledge of mostly public APIs and so cryptography work can 
proceed without scheduling meetings with core committers to understand the 
obscure internal design of the day.
Focus on REQ/REP, and maybe DEVICE, which are the sockets I’m interested in.  
The other socket types can wait until somebody is sufficiently motivated to 
make security work for those socket types.
Stick close to CurveCP where sensible, but allow for some experimentation.  
Maybe the user can choose from several competing security mechanisms.

Here are some concrete API proposals:

New values for nn_getsockopt, nn_setsockopt:
Setting/getting various public and private keys
Applications would rely on these values for security, so it is important that a 
remote attacker cannot set arbitrary socket options
Switching between authentication mechanisms, if several are supported, or using 
no authentication.
Reporting authentication errors.  A logical place to do this would be from 
nn_connect, however, my understanding is that the transport connection isn’t 
established at that time.  One possibility is to introduce a separate 
nn_authenticate function, called after nn_connect and before send/receive.  
Another possibility is to report errors from send/receive themselves.
On a socket that has opted in to security, nn_send and nn_recv encrypt, 
decrypt, and verify messages as appropriate. Sockets not opted in are 
New APIs nn_send_raw and nn_recv_raw allow unencrypted reads/writes on sockets 
that have opted into security
The entire enterprise should be documented for the forseeable future as 
experimental, unstable and not for use on nukes

Again, I’m volunteering to land all of this, pretty soonish, if this is 
basically sounding like a patch you want to merge.  And I am happy to collect 
feedback and refine some of these details as appropriate.  

However, I’d rather not bikeshed on this, as I have done enough bikeshedding 
about encryption features for message-queue projects to last many lifetimes ;)  
So if this work overall isn’t feeling right for core, I am completely happy to 
find a place to do it that isn’t in core.  My feelings won’t be hurt.


Other related posts: