zlacker

[parent] [thread] 2 comments
1. codeth+(OP)[view] [source] 2021-04-08 20:28:45
Addendum to the addendum: Whether there's a fixed hash inside the Signal app or not, here's one thing that crossed my mind last night that I have yet to understand:

Let's say we have a Signal-Android client C, and the Signal developers are running two Signal servers A and a B.

Suppose server A is running a publicly verified version of Signal-Server inside an SGX enclave, i.e. the source code is available on GitHub and has been audited, and server B is a rogue server, running a version of Signal-Server that comes with a backdoor. Server B is not running inside an SGX enclave but since it was set up by the Signal developers (or they were forced to do so) it does have the Signal TLS certificates needed to impersonate a legitimate Signal server (leaving aside SGX for a second). To simplify things, let's assume both servers' IPs are hard-coded in the Signal app and the client simply picks one at random.

Now suppose C connects to B to store its c2 value[0] and expects the server to return a remote attestation signature along with the response. What is stopping server B then from forwarding the client's request to A (in its original, encrypted and signed form), taking A's response (including the remote attestation signature) and sending it back to C? That way, server B could get its hands on the crucial secret value c2 and, as a consequence, later on brute-force the client's Signal PIN, without C ever noticing that B is not running the verified version of Signal-Server.

What am I missing here?

Obviously, Signal's cloud infrastructure is much more complicated than that, see [0], so the above example has to be adapted accordingly. In particular, according to the blog post, clients do remote attestation with certain "frontend servers" and behind the frontend servers there are a number of Raft nodes and they all do remote attestation with one another. So the real-life scenario would be a bit more complicated but I wanted to keep it simple. The point, in any case, is this: Since the Signal developers are in possession of all relevant TLS certificates and are also in control of the infrastructure, they can always MITM any of their legitimate endpoints (where the incoming TLS requests from clients get decrypted) and put a rogue server in between.

One possible way out might be to generate the TLS keys inside the SGX enclave, extract the public key through some public interface while keeping the private key in the encrypted RAM. This way, the public key can still be baked into the client apps but the private key cannot be used for attacks like the one above. However, for this the clients would once again need to know the code running on the servers and do remote attestation, which brings us back to my previous question – where in Signal-Android is that hash of the server code[1]?

[0]: https://signal.org/blog/secure-value-recovery/

[1]: More precisely, the code of the frontend enclave, since the blog post[0] states that its the frontend servers that clients do the TLS handshake with:

> We also wanted to offload the client handshake and request validation process to stateless frontend enclaves that are designed to be disposable.

replies(1): >>kijiki+S7
2. kijiki+S7[view] [source] 2021-04-08 21:15:34
>>codeth+(OP)
TLS is used, but there is another layer of encryption e2e from the client to inside the enclave. Your MITM server B can decrypt the TLS layer, but still can't see the actual traffic.
replies(1): >>codeth+N8
◧◩
3. codeth+N8[view] [source] [discussion] 2021-04-08 21:22:02
>>kijiki+S7
Just came back to post this but you beat me to it haha. Thank you! :) I just looked at the SGX 101 book and found the relevant piece: Client and enclave are basically doing a DH key exchange. https://sgx101.gitbook.io/sgx101/sgx-bootstrap/attestation#s...
[go to top]