When the server signs user's public keys on user creation or new key generation, include the version and username as part of the signature to avoid initial-invite-exchange MITM as described in #2
Also sign the new key pair with the client's previous private key to create a verifiable trust chain going back to initial key creation.
This would definitely be a good improvement. I have not reviewed the source, rather only the threat model and description, and was going to file a query regarding this myself.
The current "big" attack vector would be for a government or court to compel surespot to sign a particular key (or just sign it themselves by registering!), then carry out MITM attacks on users via the fact SSL certificate authorities are not themselves protected from legal coercion.
Including the username in the signature would make sense, and prevent re-use of that certificate while purporting to be another user. It does leave open attacks where the server is compromised, and the server "lies" about the authenticity of a key, by saying "Oh yes, user 'surespot' has changed his key, here's his new one". Signing the new key with the old key would be good, so long as that is done on the client-side.
One way I feel surespot may be underselling itself, if I understand correctly, is that your private key REMAINS private. It's not "escrowed" on your servers from my reading of the documentation. If this is the case, this is a major plus-point of this application, as opposed to alternatives which "store" your encrypted key, just waiting on a court order to log the password used on that key...
Last thing so far - is the end user alerted if a recipient has a change of key? Otherwise, an active "MITM replacement" attack wouldn't notify me, so I could be corresponding with an imposter unless I manually check fingerprint every time. While surespot signing the public key helps, it doesn't guarantee anything, even if username is included, in case your private key is silently compromised. If the user was warned though, it would let them confirm out-of-band if the user reset their device or whatever.
It's maybe a little related to this, so thought I'd drop it in here.
You are correct in that the private keys remain on the device (unless you backup your identity to the cloud obviously), but yes they are never uploaded to any surespot server.
Currently the end user is not alerted when they receive a new key. We have plans to add this in a future version (or expose which key versions are being used to generate the shared secret alongside the message - or both). For now if you are super paranoid you could run the client with "message debug mode" enabled (available in the settings). This would reveal the key versions used to generate the shared secret for the message.
Thanks! Yup that's a brilliant feature actually. A user could, in theory, say "how is this better than iMessage". And you've pretty much answered that, given these articles:
Where the author demonstrates how Apple is at least capable of replicating and reproducing your keys. I suggest they are stored. And since they can be recovered even if you forget your password, I suggest they must be held unencrypted, or encrypted with a key apple itself holds at all times by-design (making them effectively unencrypted)
I will have a play with that option and have a look. In future, I could perhaps envisage an option where the end user could approve certain keys, and these would be marked with an icon indicating trust. Key fingerprints are not ideal for the end user though (thought I do like how the fingerprint is displayed in a more friendly way that is broken up) so perhaps you might want to consider something along the lines of:
i) take a large English word list, with 65535 entries in it.
ii) Map these in a 1:1 relationship with 4 hex digits. That way, the user's 32-hex-digit fingerprint is 8 relatively simple words
This would be easily conveyed across a channel like the phone. While surespot has the QR code, it only uses the username to do the connection, and doesn't confirm the fingerprint. Alternatively, perhaps the fingerprint could also be added to this QR-code?
In android v62 and iOS v10 we have made changes to the signing mechanisms. The server now signs the username, version, and public keys. The client now signs the username, version, and public keys with the previous version of the signing key. When receiving new public keys the client checks both signatures. This means there is now a chain of trust going back to the initial key pair and user creation.