Daniel Gultsch

The rocky road to OMEMO by default

Why it took us more than two years to enable End-to-End encryption by default: The first in a series of essays leading up to the release of Conversations 2.0

When Andreas Straub first introduced OMEMO into Conversations he was trying to make it work with existing server infrastructure by utilizing a general purpose storage mechanism called PEP to store the public key material. PEP, at that point, was primarily being used to distribute the user’s avatar. At least on paper it was also capable of storing group chat bookmarks and all kind of other information. By default only the contacts of a user are allowed to access the information stored in PEP. This default is perfectly reasonable for avatars and still gets you a long way when trying to use OMEMO - After all, most of the time you will be chatting with your contacts. Most of the time, but not always…
There are two primary exceptions to that rule: Group chats, and the first few messages you exchange before adding each other to your contact lists. This was a big hurdle we had to overcome before being able to make OMEMO default for all outgoing messages. Unfortunately, efficiently changing the access model of a PEP node was, despite being standardized, not implemented in any of the major servers.
Ejabberd, one of the major XMPP servers, got support for that in its 17.12 release. Prosody, another widely used XMPP server, is still working on that feature, but has a module called omemo_all_access that essentially disables access control for all OMEMO nodes and thus achieves the same effect.

The other big hurdle we had to overcome was the adoption rate in clients. If you send OMEMO encrypted messages by default you should have a reasonable expectation that your contact will be able to decrypt the message. Reasonable expectation doesn’t mean that every single client out there has to support it—In an ecosystem with hundreds of small, badly maintained clients that’s just not feasible—but the major clients should at least have a plugin available.
In March 2018 we finally reached the point where every plattform has one or more clients with OMEMO support. Conversations and Zom on Android, ChatSecure on iOS, Psi and Gajim on the desktop. The up and coming desktop client Dino—despite not having had an initial release—already has support for OMEMO as well. And even the webclient JSXC has a plugin available.
Considering the complexity of OMEMO and the fact that most of these clients are developed by people in their spare time, this is actually quite an impressive adoption rate.

More of an UX issue, that stood between us and enabling OMEMO by default, was the rather aggressive Man-in-the-Middle protection that would prompt the user whenever an encryption key had changed. This approach, while arguably being more secure than the approaches taken by our competition, can create a barrier for the casual user and was replaced by a more flexible one called Blind Trust Before Verification.

All of the discussed changes took their time. But they were necessary to maintain a good user experience.

Moxie Marlinspike, in his 2016 propaganda piece ignorantly bashing XMPP, had one valid point: Enabling end-to-end encryption in a homogenous environment is easier than introducing it in a heterogenous one like Jabber. Nobody is denying that. However, if something is hard to achieve there are two possible approaches: Either try your best and don’t give up, or put your head in the sand and create yet another walled garden that is no different from other proprietary solutions.
Admittedly it has taken us a while to get to a point where we can enable end-to-end encryption by default, but it was worth the effort in that we ended up with something that is different from WhatsApp in more than just marketing.