Here is an update on what I’ve been working on.
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.
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.
@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.
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.
Still need to figure out how to use these in certificates which
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?