Here is an update on what I’ve been working on.
1. Connection information of a TLS connection made with ocaml-conduit
When a TLS connection has been successfully established, we need to be able to find out information about the connection. In particular we need to know the public key with which the remote node identified itself, which is crucial for UPSYCLE’s public key addressing. (Formerly, I was using an insecure workaround to deal with this, because I didn’t want to be blocked on this at that stage).
I’ve confirmed that this is not possible with ocaml-conduit
. (See the issues I’ve created there). There have been people asking about this in the past, and the authors have provided tips and so on, but none of them work any more because the API changes a lot between releases, the documentation is very sparse, and even their own examples don’t seem to work. (Probably ocaml-conduit
is not the right thing to use going forward, but we’re sticking with it now because changing now would be worse.)
So I forked ocaml-conduit
and added the missing functionality. It works. I’ll be committing this to the DREAM repo shortly. This is not a good long-term solution because it’ll be annoying to keep merging changes that authors make to the main (upstream) ocaml-conduit
repo. But that’s something for after the demo or for DREAM 2.0. If we’re not working on DREAM any more at that time I’ll still be happy to help consult on this issue.
2. Client authentication with ocaml-conduit
After completing the above, I kept finding that the information about the client was missing. No certificates, public key etc. After a lot of debugging and scratching my head I think I found a bug in ocaml-conduit
. Fixed it (in the fork), reported it and got no answer. Kinda strange. Anyway it seems that client authentication was broken – even when you try to turn it on, it gets skipped.
3. Self-signed certificates
@tg-x please correct if anything here is wrong:
UPSYCLE doesn’t use certificate authorities. Therefore also no certificate chains. Each node must have a valid certificate, which it creates by itself and signs by itself. A TLS connection which has been established between two nodes, using client auth, whereby both nodes presented self-signed certificates, is perfectly secure and the communication is guaranteed to be encrypted. The only thing you don’t have is an assurance that the remote node really is the node which it claims to be (and vice-versa). However, this is not a problem, because the message routers contain a list of public keys in their configuration, and they learn about new ones through the P2P system (P2Pcollab, WIP). And nodes which connect to the message router have its public key in their configuration, so if it checks out with what the remote node presents then all is good.
ocaml-conduit
(and tls
which does the real work underneath) allow you to pass a tls_authenticator
callback in both client and server mode. So to make self-signed certificates work, we’re using a very simple ‘null’ authenticator (gleaned from the source code of another mirage repo, x509
, and also used in the tls
examples). The question is whether this is the right way to do this and whether there are other security repercussions. I’ve opened an issue about it and may post a bit more over there to ask some specific questions.
4. ED25519 keys
Still need to figure out how to use these in certificates which tls
and/or openssl
accept. Initial attempts haven’t been successful.
1 - does anyone have experience with this and want to share some tips?
2 - @tg-x if this becomes too time-consuming, can we just stick with RSA keys? What would be the consequences of that?