First-class TLS support for capnp

233 views
Skip to first unread message

Tony Arcieri

unread,
Mar 9, 2017, 1:35:05 PM3/9/17
to capnproto
I've been deliberating switching one of my projects over from protobufs/gRPC to capnp. My initial use case is mmaped struct-like data, which capnp excels at, but I would also like to be able to serve that same data to the wire, so I more or less want the full capnp-rpc package.

Unfortunately, I'm back to the same sticking point which has prevented me from using capnp in the past: TLS support. Has there been any movement on first-class TLS support in capnp-rpc implementations? It's really a showstopper for my use cases and I would like to avoid having to deal with bespoke TLS support in every language I want to make a client library for.

I know that TLS hasn't been very amenable to capnp-style flows (and talked with Kenton about that a bit) but I think TLS 1.3 will address a lot of these problems with 0-RTT support, and until then TLS will just add additional roundtrips, something I'm fine with.

Alternatively there's the Noise protocol, which may be a better fit for capnp's messaging semantics:


Either way, I need encryption 😉

--
Tony Arcieri

Ian Denhardt

unread,
Mar 9, 2017, 3:14:11 PM3/9/17
to Tony Arcieri, capnproto
What constitutes "first class" support? I agree it would be nice to have
a more off-the-shelf approach to "this is how you do encrypted capnp."
But it might be useful to know more precisely what "open a tls
connection and start a two-party rpc session" lacks.

Quoting Tony Arcieri (2017-03-09 13:34:43)
> [1]http://noiseprotocol.org/
> Either way, I need encryption� �
> --
> Tony Arcieri
>
> --
> You received this message because you are subscribed to the Google
> Groups "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [2]capnproto+...@googlegroups.com.
> Visit this group at [3]https://groups.google.com/group/capnproto.
>
> Verweise
>
> 1. http://noiseprotocol.org/
> 2. mailto:capnproto+...@googlegroups.com
> 3. https://groups.google.com/group/capnproto
signature.asc

Kenton Varda

unread,
Mar 9, 2017, 4:09:14 PM3/9/17
to Tony Arcieri, capnproto
Hi Tony

FWIW I wrote some KJ TLS bindings a while back (but hesitate to merge them without a review by someone who knows OpenSSL):


As Ian says, it's straightforward to layer Cap'n Proto's "two-party" RPC (which is the only thing that anyone uses currently) on top of TLS, since it accepts an arbitrary abstract I/O stream. This should only take a few lines of code. So I, too, wonder what "first-class" support would mean.

I am very interested in building a better crypto transport leveraging libsodium and probably Noise, but that is, of course, a much more complicated project. :)

-Kenton

--
You received this message because you are subscribed to the Google Groups "Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/capnproto.

Tony Arcieri

unread,
Mar 9, 2017, 4:12:55 PM3/9/17
to Kenton Varda, capnproto
On Thu, Mar 9, 2017 at 1:08 PM, Kenton Varda <ken...@sandstorm.io> wrote:
As Ian says, it's straightforward to layer Cap'n Proto's "two-party" RPC (which is the only thing that anyone uses currently) on top of TLS, since it accepts an arbitrary abstract I/O stream. This should only take a few lines of code. So I, too, wonder what "first-class" support would mean.

As an example of where things aren't straightforward: the Node.js RPC client:


    // connect() accepts the same address string format as kj::Network.
    var conn = capnp.connect("localhost:1234");

How do I use TLS here? It's abstracting over the socket. Is there a separate API I can use to pass in a TLS socket?

To me first class support would entail at least the following:

- Ensuring there is a strategy for using TLS with all of the extant capnp RPC implementations in every language
- Documenting how to use TLS for each implementation

--
Tony Arcieri

Nathan Hourt

unread,
Mar 9, 2017, 11:04:59 PM3/9/17
to Cap'n Proto
I've implemented Capnp RPC over TLS-PSK, using Botan's TLS implementation. My solution is somewhat purpose specific, as it uses a blockchain instead of CAs, but it may be useful for referencing if anyone's interested. I make no promises as to the quality or correctness, but it does appear to work correctly.

It works using primarily two classes. The stream is the TlsPskAdaptor class, which implements kj::AsyncIoStream. These aren't instantiated directly, but are rather created by the TlsPskAdaptorFactory class, which helps with the PSK calculation, object lifetime management, and configuring Botan. This architecture could probably be simplified (especially if you're not allergic to CAs like I am), but it's what I came up with as an initial effort and it works well enough for now. :)

I'm happy to answer questions if anyone has them. The code is available here: https://github.com/FollowMyVote/StakeWeightedVoting/tree/master/shared/BotanIntegration

Kenton Varda

unread,
Mar 11, 2017, 11:39:34 PM3/11/17
to Tony Arcieri, capnproto
Hmm. Arguably the bug is that the v8 capnp bindings don't accept an arbitrary stream here.

I hesitate to make TLS something that is "built in" to the library, since we'd then be stuck with it even after we have a better transport -- and we'd be bloating all the people who don't actually want it. I think we need to keep it as a separable dependency.

-Kenton

--
Reply all
Reply to author
Forward
0 new messages