I did developp a mechanism for libzmq (not published), I came to the conclusion that adding a security mechanism inside libzmq is not a good solution for the following reasons:
1. it complexify the library internals drastically, what is bad for quality of its primer objectives. 2. The library was not designed for security at the beginning, so it has lead to bad design and hard-to-maintain code. 3. In the case of libzmq, mechanisms are processed in the I/O threads, which is not what I wanted. 4. Still with libzmq, I could not easily proxy security mechanisms, i.e. end-to-end with intermediate untrusted nodes: I had to stack three protocol layers: ZMTP + my security mechanism + ZMTP again, to succeed. The result works, but is heavy to maintain.That made me redevelop my security stack in a separate library, independent from libzmq. So now, I can choose libzmq or nanomsg or whatever. I have a simple API that do not require integration with the messaging library, and that work only on buffers :
1. receive_handcheck_message 2. send_handcheck_message 3. is_handcheck_finished 4. encode 5. decode The big advantages are: 1. messaging library independence. 2. usable for any SP or transportThe only thing I will add is a structure mapping to the buffers to obtain zero copy.
Just my humble thoughts worthing no more than 2 cts, but I have wasted three months to come out to that. I hope you will save your time and efforts.
Laurent. Le 11/03/2014 13:59, Drew Crawford a écrit :
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. o 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. o 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: o 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 o 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 unaffected. o 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 nukesAgain, 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.Drew