This is a short tutorial on how to get started with OMEMO. This is not to replace the XEP but to extend it and give you some clear steps to follow instead of a having to read through a formal specification.
Until OMEMO becomes an official XEP all current implemenations use the namespace eu.siacs.conversations.axolotl
instead of urn:xmpp:omemo:0
. Sub-namespaces are seperated by a .
instead of a :
. The device id however is sperated by :
. So the namespace for a PEP device bundle for example will look like this: eu.siacs.conversations.axolotl.bundles:1234
. You might want to define some constants in your code to have a central place to configure them later. Compare that to how Conversations does this.
The official XEP will also be based on Olm instead of Axolotl which means the different namespace will also indicate the use of a different crypto library. When implementing OMEMO now keep in mind that we later will coordinate a switch to Olm so you should keep the dependecy on Axolotl somewhat modular.
- Add
eu.siacs.conversations.axolotl.devicelist+notify
to your disco features. That will subscribe you to the device list updates of your contacts. - On every login publish your bundle information. (Your publickey and pre keys.) Keep the used device id consistant. You have to republish this because you don't know if the server was restarted or might have otherwise lost the information.
- After publishing the information and getting an IQ-result back retrieve your own devicelist. (You might also get this automatically due to the subscription in step one but that might fail if you don't have one yet. Retrieving the list manually makes you know for sure.) If the device list does not contain your own device id publish the device list with your device id added. (Also deduplicate device ids in the list just for good measure and to counter act potential errors in other implemenations)
- Since you subscribed to the device list you will now be receiving device ids from your contacts. Save the jid-device id tuples for later use. Each tuple will have an active flag. If a device id is no longer in the list you set it to inactive. If it re-appears later you set it to active again.
- Treat the devie ids of your other devices the same.
- Due to bugs (or weird behaviour) in ejabberd you might not always get the device list from offline contacts. So before login you should restore the tuples from your own database. But incoming PEP events will always override the database. The restore from your database is only to have a fallback in case you don't get the PEP list.
- When you first write a message to someone look up all active device tuples and create sessions with them by retrieving the corresponding bundles. (Explictitly query the nodes
eu.siacs.conversations.bundles:$id
.) - On subsequent messages you have to check if you already have sessions for all device tuples and only query the bundle for missing sessions.
- Retrieving a message from a device id will set that device id to active again.
Every session has a fingerprint. (The SHA sum of the identiy key.) Offer the user the abiltiy to decide wether to trust each fingerprint. You only send messages to trusted fingerprints where the device id is active. If there are no trusted fingerprints display a dialog offering the user to trust them. If there are new fingerprints (from new devices) offer the user to trust them. So essentially every jid-deviceid-fingerprint tuple has two values (inactive/active and undecided/trusted/untrusted)