Hi,
I'm creating a new thread to focus on the transport layer which Tommi listed as the first roadblock.
When I saw Docker's libchan [1] I thought it might be a candidate to use as, citing Tommi, "A good bidirectional protocol / messaging system that will survive in the greater Internet" for Bazil.
They call it "like Go channels over the network". It supports stream multiplexing via SPDY and uses msgpack for message encoding, and somehow also supports attaching unencoded streams to messages, although I haven't yet fully understood them.
I wrote an example using libchan with a TLS-connection authenticated via previously exchanged TLS-certificate signatures signed by NaCl keys. It's based on libchans's rexec example, I extended it to authenticate the connection. I wrote a bit more about how it in its README. You can find it on GitHub:
https://github.com/meeee/bazil-transport-experiments
I did a quick benchmark using dd for passing data through stdin from the client to the server also executing dd, just passing everything to /dev/null:
> $ dd if=/dev/zero bs=1m count=1024 | client/client dd of=/dev/null bs=1m
> [...]
> 1024+0 records in
> 1024+0 records out
> 1073741824 bytes transferred in 23.235042 secs (46212175 bytes/sec)
> 0+31336 records in
> 0+31336 records out
> 1073741824 bytes transferred in 22.849982 secs (46990926 bytes/sec)
I ran this locally on a 2010 MacBook Pro with a 2.4 GHz i5. This doesn't seem to be too fast, although I didn't yet optimize anything. I can imagine this might be fast enough for WAN access for the beginning.
Regarding another approach for authenticating a TLS connection, Tommi wrote:
> Has anyone figured out how to use the go.crypto libraries to make TLS certs with these custom fields? That's what I have not yet had the chance to figure out, and why I prototyped with the NaCl signatures in-band.
This seems to be pretty easy, you can add `ExtraExtensions` to a crypto/x509 Certificate via a pkix.Extension object:
> extensions := []pkix.Extension{pkix.Extension{
> Id: asn1.ObjectIdentifier{1, 2, 3},
> Critical: true,
> Value: []byte(":)"),
> }}
When only signing the certificate's public key (we can't sign the rest if we put our NaCl signature in the certificate itself), we'd have to make sure to not rely on anything else (like expiration date or common name) in that certificate besides its public key. We'd have to encode these things ourselve in a X.509 extension then, and sign them with NaCl. I'm not quite sure whether I like the additional HTTP request or a custom implementation of storing and verifying certificate values more.
I also began implementing NaCl-signed-public key-in-the-certificate approach, but got stuck when I noticed that go.crypto's NaCl implementation doesn't support signing (without encryption) yet. I might look into that a bit more some time.
Overall, I think libchan could do a lot of work for us and looks very promising to me.
What do you think?
Tommi: I'm in Germany, we could do a Skype/Hangout session if you want to talk about the architecture. I have some general knowledge about distributed systems and know a bit about version vectors and merkle trees, but have no experience with implementation regarding the last two.
Cheers,
Michael
[1]
https://github.com/docker/libchan