rippled: peer handshake violates TLS transparency

Current design of the peer protocol handshake limits alternative implementations in languages other than C/C++ as described in this article. Indeed, src/ripple/overlay/README.md refers to the current implementation rather than describing the protocol:

* `Session-Signature`

    This field must be present. It contains a cryptographic token formed
    from the SHA512 hash of the shared data exchanged during SSL handshaking.
    For more details see the corresponding source code.

apparently referring to lines 31-93 in src/ripple/overlay/impl/TMHello.cpp.

OpenSSL routines SSL_get_finished and SSL_get_peer_finished are being used to access Finished messages sent over the socket which violates TLS socket transparency. These low-lever routines are only available in C/C++ for a reason.

Requesting protocol upgrade to RTXP/1.3 with Session-Signature (HTTP header) and nodeproof (the corresponding field of the Hello message in protobuf protocol) replaced by a more portable mechanism which would not be language-specific and could be implemented in other programming languages, for example using Node.js.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 22 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Node.js v9.9.0 has been released with Finished messages exposed. It should now be possible to develop a Node.js-based client for the Ripple peer network, for example starting from this skeleton.

If somebody interested in handshake on Rust, I made small dirty PoC: https://github.com/fanatid/rust-ripple-p2p

Maybe I’m missing something, but how is using “tls-unique” any different from using the SSL_get_finished/SSL_get_peer_finished? And wouldn’t using “tls-unique” also violate TLS transparency?

In any event, if this is an actual issue for anyone, they’re welcome to submit a pull request. The simplest way to do it is to add support for some new form of MITM rejection while still supporting the existing scheme for a few more versions.

As far as I understand the issue, it is necessary (or at least desirable) to protect rippled <–> rippled TLS connections against active MITMs. They way this is currently done relies on signing messages that are hard to obtain with some TLS implementations (since in many cases the actual messages sent/received when establishing a connection are not that interesting to people who just want to create a TLS secured connection).

A different option might be to communicate node keys out of band (difficult, maybe centralized, does it really scale…?) or to introduce trusted third parties (signed certificates instead of just random raw keys).

Maybe a possible solution could be the second one, Let’s Encrypt certificates are free and while it would be a hassle to buy a domain(!) just to run a server, it would be at least a second option to ensure MITM protection while enabling more diverse server implementations that don’t have to be able to access protocol messages just for an initial handshake.

This might also improve clustering, currently one has to add nodes explicitly one by one in there, it would be nice to dynamically add any peer with a key signed by an internal CA for example.