This page expands on the ideas of the forthcoming friend-to-friend system Murmeli, by listing possible threats which an attacker might choose to mount against a Murmeli user, and the measures to protect against them. If you have comments or suggestions on these ideas, please send them in by email.
So let's list what an attacker might try to do:
Regular messages are encrypted and signed, so even if an attacker manages to capture a message in transit, the contents cannot be read by anybody who doesn't have the private key of the recipient. Unlike with encrypted emails, Murmeli's messages don't give away the sender and recipient in plaintext.
Special case: the contact request messages are unencrypted and so could potentially be eavesdropped (either side of the Tor network). But contact can be established first by another channel (for example, using encrypted email) so that the information in the Murmeli contact request message can be limited. Plus there is now an alternative contact mechanism using encrypted contact referral messages as well, to refer one trusted contact to another in a secure way.
Sender, recipient and subject fields are not readable without decryption. The Tor network makes it extremely difficult to ascertain both sender and recipient.
It's obvious that you're using Tor, and furthermore it would be obvious to a listener that you're sending or receiving Murmeli communications. So they can tell you're using Murmeli but not necessarily with whom.
If somebody is eavesdropping on both you and on the person you're communicating with, then the timing of packets could reveal that you're probably connected to each other. But you might be just relaying messages for a third party.
Just like all your other internet traffic, if someone is eavesdropping on your network connection then they can determine when you're using the network and when you're not. But in addition, your Murmeli client accepts socket connections when it's running, and does not accept them when it's not. So in theory, if somebody knew your Murmeli id, they could 'poll' your hidden service and find out whether you're currently running Murmeli or not.
Regular messages are only accepted if they've been signed by a recognised key. So any manipulation of messages would just lead to them being rejected.
Special case: an attacker could intercept a contact request message, and construct a fake reply. The sender of the request would not be able to tell whether this fake reply came from the intended contact or an attacker. In the case of a refusal, the requester would falsely presume that the intended contact refused the request- but the two parties could presumably find another way to establish contact. In the case of a contact acceptance, where an attacker provides their own public key, then we have the potential for a man-in-the-middle attack (see MITM attack below).
It might be technically possible to filter the messages and stop them from getting through, perhaps by controlling the Tor exit nodes or by trapping them at the recipient's ISP. Such a denial of service would be a flattering last resort.
There is no server, and there are no passwords. The relay does store messages but only in encrypted form. Disabling the server would degrade the service, but there isn't a single point of failure to stop delivery completely.
Your Murmeli id is not really a secret, and can be sent in plain text in the contact request message. You may even decide to publish it to help people get in contact with you. It would then be possible for an attacker to just send malformed data to this id, and hope that your client gets overwhelmed and unable to receive real messages. Your client will reject the bad messages because they don't have valid signatures (or because they're replays of messages previously received), but it could still choke the client. And such attacks would be difficult to trace, having come through Tor.
Regular messages need to be signed, and messages which aren't signed by a recognised contact are automatically rejected. If a recognised contact starts to send unwelcome messages then you can simply cancel their key.
The only messages which aren't signed are the "contact request" messages, sent to initiate contact with a new id. These messages can't be encrypted or signed because the encryption keys haven't been exchanged yet, that's the point of requesting contact. So it would be possible to send spam in the form of contact request messages, and again it would be difficult to trace. If this became a real problem, one could choose to not even process any more contact request messages, and just tell Murmeli to ignore all such messages in future (this is available in the Settings page). Then the only way for people to initiate contact with you would be using an introduction from a trusted friend of yours (a signed and encrypted contact referral), or persuading you to initiate a contact request to them.
Person A sends their public key to person B, and must send this unencrypted because A doesn't have B's public key yet, and we don't use any trusted third party to serve the keys. So it would be possible for an attacker M to intercept this message, and replace A's key with M's public key instead. Person B would believe that this is A's key and would encrypt messages with it, which M could then decrypt, read, perhaps modify, and then re-encrypt for A. Similarly, M would give M's key to A, and A would believe that it is the key of B. If this could be consistently done, A and B would be convinced that they had secure encrypted communications, but M could read and modify everything. This is known as a Man-in-the-middle attack.
Murmeli cannot prevent this, but it does provide a key verification step. Until the keys are verified, using a completely separate communication channel such as telephone, the contacts are shown in Murmeli as "untrusted", and certain functions are restricted. Regular messages can be exchanged, but Murmeli encourages you to do the offline key verification.
The verification works by taking the fingerprints of the two keys A and B. Anyone can generate these fingerprints using the public keys, but in order to fool both A and B, the attacker would also need to have complete control over the independent non-Murmeli channel as well as complete control over the Murmeli channel. Both Murmeli clients generate a sequence of words using the combination of A's key and B's key. If A hasn't really got B's key but M's key instead, then the words which A generates (A+M) will not match the words which B generates (B+M). So when they telephone each other and compare words, they will not match and they will realise that they do not have the keys they think they have. They can then delete their contacts and re-exchange keys more securely.
If A really does have B's key and B has A's key, then the words they generate will match, and they can tell their Murmeli clients that they have successfully verified the keys offline. Note that it's not a problem to exchange their words over an insecure phone line, as the words are not secret. It just needs to be difficult for M to substitute A's and B's words, which assuming that they can recognise each other's voices on the telephone would be extremely challenging. M's only hope of fooling this technique is to be able to generate a special keypair such that A+M generates the same words as A+B and B+M generates the same words as B+A.
Murmeli stores the messages locally in a file-based database, and both sent and received messages are stored unencrypted. To prevent an attacker accessing these messages, you can store the Murmeli folder inside an encrypted partition, for example, and then the regular precautions apply just like any other files on the same machine.
Malware such as keyloggers can of course always compromise what you do with the machine, in which case Murmeli will not give you any protection.
We no longer have to worry about a compromised connection to the mongod daemon (now that a mongod daemon isn't used any more), but instead just interference with the currently running python processes of Murmeli. We're then left with the threats of secretly-installed key loggers or other system-wide attacks which are really outside the scope of what Murmeli can deal with.
Each message for person A is encrypted with A's public key, which normally does not change. If an attacker managed to store a message, perhaps at the ISP, and at some future time managed to break into the recipient's PC and steal the private key, then the attacker can decrypt and read the old message, even if the recipient has deleted their copy of the message. This means that Murmeli does not have the desirable property of forward secrecy, as the same key can be used to decrypt different messages. Even for the messages encrypted with a random, one-time symmetric key, this key must be sent to the recipient too and the same argument applies - the attacker can later obtain the private key, use this to find the symmetric key, and use that to decrypt the message.
It is possible that this could be addressed by using some kind of key exchange protocol, but this would add significantly to the complexity and require a series of ping-pong handshaking messages to be exchanged for each new key. Perhaps this can be considered as an extension to Murmeli in the future, with an appropriate lifetime of these temporary symmetric keys. This would also require each client to store a set of temporary keys and their lifetimes (one for each conversation partner) and to handle the case when one partner considers a key update necessary. Maybe these "session keys" are invalidated each time a transmission fails.
If the key can be stolen without detection, then yes. Murmeli could have a kind of alarm mechanism to revoke keys, but there isn't one yet.
Note that stealing the private encryption key would make it possible to convincingly sign messages as though they came from another person. If the victim's contacts' details could also be stolen, and the victim could be prevented from using Murmeli, then one could convincingly assume the victim's identity and communicate with their contacts as them. This situation is similar to a password being compromised on a conventional server-based system.
If the attacker can impersonate a trusted friend (or if a trusted friend sends an infected file by accident), and if the recipient accepts the attachment then it's just the same as viruses delivered by any other mechanism. The recipient needs to exercise caution and use some kind of virus scanner on the received files. But Murmeli (unfortunately) isn't able to send attachments yet so it's not yet a problem.
It would be possible to allow Murmeli to refuse certain file types as attachments, for example to prevent users from attaching a .exe file. But then the user is almost guaranteed to just rename the .exe as .jpg and send it again, instructing the recipient to rename it after receipt. Perhaps better would be to allow any filename to be attached, but to warn the recipient for certain file extensions.