From 7fbc5a79f87b8dfeb0e5f185a3c00bb1379c39ab Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 7 Mar 2020 18:13:06 +0100 Subject: [PATCH 01/49] XEP-0384: put bundles in different items of the same node --- xep-0384.xml | 76 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index d93debab..09efbb10 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -170,16 +170,16 @@

-

In order to determine whether a given contact has devices that support OMEMO, the devicelist node in PEP is consulted. Devices MUST subscribe to 'eu.siacs.conversations.axolotl.devicelist' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the devicelist.

+

In order to determine whether a given contact has devices that support OMEMO, the devicelist node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:1:devices' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the devicelist.

- + - + @@ -193,9 +193,9 @@ - + - + @@ -206,38 +206,50 @@ ]]>

NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

-

Furthermore, a device MUST announce its IdentityKey, a signed PreKey, and a list of PreKeys in a separate, per-device PEP node. The list SHOULD contain 100 PreKeys, but MUST contain no less than 20.

- +

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundle’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

+

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

+ - - - - - BASE64ENCODED... - - - BASE64ENCODED... - - - BASE64ENCODED... - + + + + BASE64ENCODED + BASE64ENCODED - - BASE64ENCODED... - - - BASE64ENCODED... - - - BASE64ENCODED... - - + BASE64ENCODED + BASE64ENCODED + + BASE64ENCODED +]]> +

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:bundle’ node to ‘open’ to give entities without presence subscription read access to the bundles and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

+

The access model can be changed efficiently by using publish-options as described in XEP-0060 §7.1.5.

+ + + + + + + + + + + + + http://jabber.org/protocol/pubsub#publish-options + + + open + + + + ]]>
@@ -248,7 +260,9 @@ to='juliet@capulet.lit' id='fetch1'> - + + + ]]>

A random preKeyPublic entry is selected, and used to build a SignalProtocol session.

From 88d58a70fd5748551767be10201ce094d3f3a2eb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 7 Mar 2020 19:13:30 +0100 Subject: [PATCH 02/49] XEP-0384: add label attribute to bundle --- xep-0384.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index 09efbb10..ce0d3ea2 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -208,12 +208,14 @@

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundle’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

+

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

- + BASE64ENCODED BASE64ENCODED From 170cc7b3ab55d2feff1c7cc78de1583e8f1b7bb9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 10:45:03 +0100 Subject: [PATCH 03/49] XEP-0384: fix s/list/devices/ --- xep-0384.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index ce0d3ea2..ad739571 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -182,7 +182,7 @@ - + @@ -195,11 +195,11 @@ - + - + From 70bdbf31ccceace788d1f9393065eb5f77fb5c92 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 10:49:00 +0100 Subject: [PATCH 04/49] XEP-0384: rename bundle node to bundles --- xep-0384.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index ad739571..bdf7b16a 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -206,13 +206,13 @@ ]]>

NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

-

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundle’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

+

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

- + @@ -229,12 +229,12 @@ ]]> -

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:bundle’ node to ‘open’ to give entities without presence subscription read access to the bundles and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

+

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:bundles’ node to ‘open’ to give entities without presence subscription read access to the bundles and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

The access model can be changed efficiently by using publish-options as described in XEP-0060 §7.1.5.

- + @@ -262,7 +262,7 @@ to='juliet@capulet.lit' id='fetch1'> - + From 5ffb1279addd0bae620f1407683aa335e81888b8 Mon Sep 17 00:00:00 2001 From: sualko Date: Sun, 8 Mar 2020 10:55:43 +0100 Subject: [PATCH 05/49] XEP-0384: add section about ending a session --- xep-0384.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xep-0384.xml b/xep-0384.xml index bdf7b16a..e7e5ef35 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -269,6 +269,15 @@ ]]>

A random preKeyPublic entry is selected, and used to build a SignalProtocol session.

+ +

In order to signal a contact that you like to terminate a session, your + device MUST send an <terminate> element to all intended recipient devices + inside an encrypted stanza. A user or client MAY tag the element with a + reason. If a device is receiving a stanza containing a <terminate> element, + it MUST show an information that the peer has ended the session. To prevent + that the user is accidentally sending plaintext messages, the client MUST + block all outgoing message until the user switched to plaintext.

+

In order to send a chat message, its <body> first has to be From efd28fd64832d6fc3072e6a13c462c430dbe8ed4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 11:08:20 +0100 Subject: [PATCH 06/49] XEP-0384: wrap key elements in keys with jid attribute --- xep-0384.html | 377 ++++++++++++++++++++++++++++++++++++++++++++++++++ xep-0384.xml | 33 +++-- 2 files changed, 396 insertions(+), 14 deletions(-) create mode 100644 xep-0384.html diff --git a/xep-0384.html b/xep-0384.html new file mode 100644 index 00000000..144ca204 --- /dev/null +++ b/xep-0384.html @@ -0,0 +1,377 @@ + +XEP-0384: OMEMO Encryption

XEP-0384: OMEMO Encryption

Abstract
This specification defines a protocol for end-to-end encryption in one-on-one chats that may have multiple clients per account.
Author
Andreas Straub
Copyright
© 1999 – 2020 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

Deferred

WARNING: This document has been automatically Deferred after 12 months of inactivity in its previous Experimental state. Implementation of the protocol described herein is not recommended for production systems. However, exploratory implementations are encouraged to resume the standards process.
Type
Standards Track
Version
0.3.0 (2018-07-31)
Document Lifecycle
  1. Experimental
  2. Deferred
  3. Proposed
  4. Draft
  5. Final

1. + Introduction

+

1.1 Motivation

+

+ There are two main end-to-end encryption schemes in common use in the XMPP + ecosystem, Off-the-Record (OTR) messaging (Current Off-the-Record Messaging Usage (XEP-0364) [1]) and OpenPGP + (Current Jabber OpenPGP Usage (XEP-0027) [2]). OTR has significant usability drawbacks for inter-client + mobility. As OTR sessions exist between exactly two clients, the chat + history will not be synchronized across other clients of the involved + parties. Furthermore, OTR chats are only possible if both participants are + currently online, due to how the rolling key agreement scheme of OTR + works. OpenPGP, while not suffering from these mobility issues, does not + provide any kind of forward secrecy and is vulnerable to replay attacks. + Additionally, PGP over XMPP uses a custom wireformat which is defined by + convention rather than standardization, and involves quite a bit of + external complexity. +

+

+ This XEP defines a protocol that leverages the SignalProtocol encryption to provide + multi-end to multi-end encryption, allowing messages to be synchronized + securely across multiple clients, even if some of them are offline. The SignalProtocol + is a cryptographic double ratched protocol based on work by Trevor Perrin + and Moxie Marlinspike first published as the Axolotl protocol. While the + protocol itself has specifications in the public domain, the + protobuf-based wire format of the signal protocol is not fully + documented. The signal protocol currently only exists in GPLv3-licensed + implementations maintained by OpenWhisperSystems. +

+
+

1.2 Overview

+

+ The general idea behind this protocol is to maintain separate, + long-standing SignalProtocol-encrypted sessions with each device of each contact + (as well as with each of our other devices), which are used as secure key + transport channels. In this scheme, each message is encrypted with a + fresh, randomly generated encryption key. An encrypted header is added to + the message for each device that is supposed to receive it. These headers + simply contain the key that the payload message is encrypted with, and + they are separately encrypted using the session corresponding to the + counterpart device. The encrypted payload is sent together with the + headers as a <message> stanza. Individual recipient devices can + decrypt the header item intended for them, and use the contained payload + key to decrypt the payload message. +

+

+ As the encrypted payload is common to all recipients, it only has to be + included once, reducing overhead. Furthermore, SignalProtocols’s transparent handling + of messages that were lost or received out of order, as well as those sent + while the recipient was offline, is maintained by this protocol. As a + result, in combination with Message Carbons (XEP-0280) [3] and Message Archive Management (XEP-0313) [4], the desired property + of inter-client history synchronization is achieved. +

+

+ OMEMO currently uses version 3 SignalProtocol. Instead of a Signal key + server, Personal Eventing Protocol (XEP-0163) [5] (PEP) is used to publish key data. +

+
+

2. + Requirements

+ +

3. + Glossary

+

3.1 General Terms

+
+
Device
A communication end point, i.e. a specific client instance
+
OMEMO element
An <encrypted> element in the eu.siacs.conversations.axolotl namespace. Can be either MessageElement or a KeyTransportElement
+
MessageElement
An OMEMO element that contains a chat message. Its <payload>, when decrypted, corresponds to a <message>'s <body>.
+
KeyTransportElement
An OMEMO element that does not have a <payload>. It contains a fresh encryption key, which can be used for purposes external to this XEP.
+
Bundle
A collection of publicly accessible data that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
+
rid
The device id of the intended recipient of the containing <key>
+
sid
The device id of the sender of the containing OMEMO element
+ +
+
+

3.2 SignalProtocol-specific

+
+
IdentityKey
Per-device public/private key pair used to authenticate communications
+
PreKey
A Diffie-Hellman public key, published in bulk and ahead of time
+
PreKeySignalMessage
An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.
+
SignalMessage
An encrypted message
+
+
+

4. + Use Cases

+

4.1 Setup

+

+ The first thing that needs to happen if a client wants to start using + OMEMO is they need to generate an IdentityKey and a Device ID. The + IdentityKey is a Curve25519 [6] public/private Key pair. The Device ID is a + randomly generated integer between 1 and 2^31 - 1. +

+
+

4.2 Discovering peer support

+

In order to determine whether a given contact has devices that support OMEMO, the devicelist node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:1:devices' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the devicelist.

+
Example 1. Devicelist update received by subscribed clients
+<message from='juliet@capulet.lit'
+         to='romeo@montague.lit'
+         type='headline'
+         id='update_01'>
+  <event xmlns='http://jabber.org/protocol/pubsub#event'>
+    <items node='urn:xmpp:omemo:1:devices'>
+      <item id='current'>
+        <devices xmlns='urn:xmpp:omemo:1'>
+          <device id='12345' />
+          <device id='4223' />
+        </devices>
+      </item>
+    </items>
+  </event>
+</message>
+
+

4.3 Announcing support

+

In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device ID to the devicelist PEP node.

+
Example 2. Adding the own device ID to the list
+<iq from='juliet@capulet.lit' type='set' id='announce1'>
+  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+    <publish node='urn:xmpp:omemo:1:devices'>
+      <item id='current'>
+        <devices xmlns='urn:xmpp:omemo:1'>
+          <device id='12345' />
+          <device id='4223' />
+          <device id='31415' />
+        </devices>
+      </item>
+    </publish>
+  </pubsub>
+</iq>
+

NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

+

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

+

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

+

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

+

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

+
Example 3. Publishing bundle information
+<iq from='juliet@capulet.lit' type='set' id='annouce2'>
+  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+    <publish node='urn:xmpp:omemo:1:bundles'>
+      <item id='31415'>
+        <bundle xmlns='urn:xmpp:omemo:1'
+                label='My desktop client'>
+          <spk id='0'>BASE64ENCODED</spk>
+          <ik>BASE64ENCODED</ik>
+          <prekeys>
+            <pk id='0'>BASE64ENCODED</pk>
+            <pk id='1'>BASE64ENCODED</pk>
+            <!-- … -->
+            <pk id='99'>BASE64ENCODED</pk>
+          </prekeys>
+        </bundle>
+      </item>
+    </publish>
+  </pubsub>
+</iq>
+

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:bundles’ node to ‘open’ to give entities without presence subscription read access to the bundles and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

+

The access model can be changed efficiently by using publish-options as described in XEP-0060 §7.1.5.

+
Example 4. Publishing bundle information with an open access model
+<iq from='juliet@capulet.lit' type='set' id='annouce2'>
+  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+    <publish node='urn:xmpp:omemo:1:bundles'>
+      <item id='31415'>
+        <bundle xmlns='urn:xmpp:omemo:1'>
+          <!-- … -->
+        </bundle>
+      </item>
+    </publish>
+    <publish-options>
+      <x xmlns='jabber:x:data' type='submit'>
+        <field var='FORM_TYPE' type='hidden'>
+          <value>http://jabber.org/protocol/pubsub#publish-options</value>
+        </field>
+        <field var='pubsub#access_model'>
+          <value>open</value>
+        </field>
+      </x>
+    </publish-options>
+  </pubsub>
+</iq>
+
+

4.4 Building a session

+

In order to build a session with a device, their bundle information is fetched.

+
Example 5. Fetching a device's bundle information
+<iq type='get'
+    from='romeo@montague.lit'
+    to='juliet@capulet.lit'
+    id='fetch1'>
+  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+    <items node='urn:xmpp:omemo:1:bundles'>
+      <item id='31415'/>
+    <items>
+  </pubsub>
+</iq>
+

A random preKeyPublic entry is selected, and used to build a SignalProtocol session.

+
+

4.5 Sending a message

+

+ In order to send a chat message, its <body> first has to be + encrypted. The client MUST use fresh, randomly generated key with + AES-256.. + The 16 bytes key and the GCM authentication tag (The tag SHOULD have at least + 128 bit) are concatenated and for each intended recipient device, + i.e. both own devices as well as devices associated with the contact, the + result of this concatenation is encrypted using the corresponding + long-standing SignalProtocol session. Each encrypted payload key/authentication tag + tuple is tagged with the recipient device's ID. The key element MUST be + tagged with a prekey attribute set to true if a PreKeySignalMessage is being + used. This is all serialized into a MessageElement, which is transmitted + in a <message> as follows: +

+
Example 6. Sending a message
+<message to='juliet@capulet.lit' from='romeo@montague.lit' id='send1'>
+  <encrypted xmlns='urn:xmpp:omemo:1'>
+    <header sid='27183'>
+      <keys jid='juliet@capulet.lit'>
+        <key rid='31415'>BASE64ENCODED...</key>
+      </keys>
+      <keys jid='remeo@montague.lit'>
+        <key rid='1337'>BASE64ENCODED...</key>
+        <key prekey="true" rid='12321'>BASE64ENCODED...</key>
+        <!-- ... -->
+      </keys>
+    </header>
+    <payload>BASE64ENCODED</payload>
+  </encrypted>
+  <store xmlns='urn:xmpp:hints'/>
+</message>
+
+

4.6 Sending a key

+

+ The client may wish to transmit keying material to the contact. This first + has to be generated. The client MUST generate a fresh, randomly generated key. + The 16 bytes key and the GCM authentication tag (The tag + SHOULD have at least 128 bit) are concatenated and for each intended + recipient device, i.e. both own devices as well as devices associated + with the contact, this key is encrypted using the corresponding + long-standing SignalProtocol session. Each encrypted payload key/authentication tag + tuple is tagged with the recipient device's ID. The key element MUST be + tagged with a prekey attribute set to true if a PreKeySignalMessage is being + used This is all serialized into a KeyTransportElement, omitting the + <payload> as follows: +

+
Example 7. Sending a key
+<encrypted xmlns='urn:xmpp:omemo:1'>
+  <header sid='27183'>
+    <keys jid='remeo@montague.lit'>
+      <key rid='31415'>BASE64ENCODED...</key>
+      <key prekey="true" rid='12321'>BASE64ENCODED...</key>
+      <!-- ... -->
+    </keys>
+  </header>
+</encrypted>
+

This KeyTransportElement can then be sent over any applicable transport mechanism.

+
+

4.7 Receiving a message

+

When an OMEMO element is received, the client MUST check whether there is a <key> element with an rid attribute matching its own device ID. If this is not the case, the element MUST be silently discarded. If such an element exists, the client checks whether the element's contents are a PreKeySignalMessage.

+

If this is the case, a new session is built from this received element. The client SHOULD then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST delete the private key belonging to the PreKey after use.

+

If the element's contents are a SignalMessage, and the client has a session with the sender's device, it tries to decrypt the SignalMessage using this session. If the decryption fails or if the element's contents are not a SignalMessage either, the OMEMO element MUST be silently discarded.

+

If the OMEMO element contains a <payload>, it is an OMEMO message element. The client tries to decrypt the base64 encoded contents using the key and the authentication tag extracted from the <key> element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the <body> of the received message.

+

If the OMEMO element does not contain a <payload>, the client has received a KeyTransportElement. The key extracted from the <key> element can then be used for other purposes (e.g. encrypted file transfer).

+
+

5. + Business Rules

+

Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

+

Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial PreKeySignalMessage later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

+

As there are no explicit error messages in this protocol, if a client does receive a PreKeySignalMessage using an invalid PreKey, they SHOULD respond with a KeyTransportElement, sent in a <message> using a PreKeySignalMessage. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

+

If a PreKeySignalMessage is received as part of a Message Archive Management (XEP-0313) [4] catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a KeyTransportMessage using a PreKeySignalMessage before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

+

As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a Message Processing Hints (XEP-0334) [7] <store /> hint in their OMEMO messages. Otherwise, server implementations of Message Archive Management (XEP-0313) [4] will generally not retain OMEMO messages, since they do not contain a <body />

+

6. + Implementation Notes

+ +

+ The SignalProtocol-library uses a trust model that doesn't work very well with + OMEMO. For this reason it may be desirable to have the library consider all + keys trusted, effectively disabling its trust management. This makes it + necessary to implement trust handling oneself. +

+

7. + Security Considerations

+

Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

+

When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user.

+

While it is RECOMMENDED that clients postpone private key deletion until after MAM catch-up and this standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to [8].

+

+ In order to be able to handle out-of-order messages, the SignalProtocol stack has to + cache the keys belonging to "skipped" messages that have not been seen yet. + It is up to the implementor to decide how long and how many of such keys to + keep around. +

+

8. + IANA Considerations

+

This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

+

9. + XMPP Registrar Considerations

+

9.1 Protocol Namespaces

+

This specification defines the following XMPP namespaces:

+
    +
  • eu.siacs.conversations.axolotl
  • +
+
+

9.2 Protocol Versioning

+

If the protocol defined in this specification undergoes a revision that is not fully backwards-compatible with an older version, the XMPP Registrar shall increment the protocol version number found at the end of the XML namespaces defined herein, as described in Section 4 of XEP-0053.

+
+

10. + XML Schema

+
+<xml version="1.0" encoding="utf8">
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="eu.siacs.conversations.axolotl"
+    xmlns="eu.siacs.conversations.axolotl">
+
+  <xs:element name="encrypted">
+    <xs:element name="header">
+      <xs:attribute name="sid" type="xs:integer"/>
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="key" type="xs:base64Binary" maxOccurs="unbounded">
+            <xs:attribute name="rid" type="xs:integer" use="required"/>
+            <xs:attribute name="prekey" type="xs:boolean"/>
+          </xs:element>
+          <xs:element name="iv" type="xs:base64Binary"/>
+      </xs:complexType>
+    </xs:element>
+    <xs:element name="payload" type="xs:base64Binary" minOccurs="0"/>
+  </xs:element>
+
+  <xs:element name="list">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="device" maxOccurs="unbounded">
+          <xs:attribute name="id" type="integer" use="required"/>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="bundle">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="signedPreKeyPublic" type="base64Binary">
+          <xs:attribute name="signedPreKeyId" type="integer"/>
+        </xs:element>
+        <xs:element name="signedPreKeySignature" type="base64Binary"/>
+        <xs:element name="identityKey" type="base64Binary"/>
+        <xs:element name="prekeys">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="preKeyPublic" type="base64Binary" maxOccurs="unbounded">
+                <xs:attribute name="preKeyId" type="integer" use="required"/>
+              </xs:element>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+</xs:schema>
+
+

11. + Acknowledgements

+

Big thanks to Daniel Gultsch for mentoring me during the development of this protocol. Thanks to Thijs Alkemade and Cornelius Aschermann for talking through some of the finer points of the protocol with me. And lastly I would also like to thank Sam Whited, Holger Weiss, and Florian Schmaus for their input on the standard.

+

Appendices

Appendix A: Document Information

Series
XEP
Number
0384
Publisher
XMPP Standards Foundation
Status
Deferred
Type
Standards Track
Version
0.3.0
Last Updated
2018-07-31
Approving Body
XMPP Council
Dependencies
XMPP Core, XEP-0163
Supersedes
None
Superseded By
None
Short Name
OMEMO
Source Control
HTML

+ This document in other formats: + XML  + PDF

Appendix B: Author Information

Andreas Straub
Email
andy@strb.org
JabberID
andy@strb.org

Copyright

This XMPP Extension Protocol is copyright © 1999 – 2020 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which can be found at <https://xmpp.org/about/xsf/ipr-policy> or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).

Visual Presentation

The HTML representation (you are looking at) is maintained by the XSF. It is based on the YAML CSS Framework, which is licensed under the terms of the CC-BY-SA 2.0 license.

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 6120) and XMPP IM (RFC 6121) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <http://xmpp.org/about/discuss.shtml> for a complete list.

Errata can be sent to <editor@xmpp.org>.

Appendix F: Requirements Conformance

The following requirements keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".

Appendix G: Notes

1. XEP-0364: Current Off-the-Record Messaging Usage <https://xmpp.org/extensions/xep-0364.html>.

2. XEP-0027: Current Jabber OpenPGP Usage <https://xmpp.org/extensions/xep-0027.html>.

3. XEP-0280: Message Carbons <https://xmpp.org/extensions/xep-0280.html>.

4. XEP-0313: Message Archive Management <https://xmpp.org/extensions/xep-0313.html>.

5. XEP-0163: Personal Eventing Protocol <https://xmpp.org/extensions/xep-0163.html>.

6. Curve25519: new Diffie-Hellman speed records <http://cr.yp.to/ecdh/curve25519-20060209.pdf>.

7. XEP-0334: Message Processing Hints <https://xmpp.org/extensions/xep-0334.html>.

8. Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158.

Appendix H: Revision History

Note: Older versions of this specification might be available at http://xmpp.org/extensions/attic/

  1. Version 0.3.0 (2018-07-31)

    Make examples show items published to the id "current", as per XEP-0060 §12.20.

    egp
  2. Version 0.2.2 (2018-11-03)
    Fix a bunch of typos, batch-style.
    pep
  3. Version 0.2.1 (2018-05-21)
    Fix attribute names in schema
    mb
  4. Version 0.2 (2017-06-02)
    +

    Depend on SignalProtocol instead of Olm.

    +

    Changed to eu.siacs.conversations.axolotl Namespace which is currently used in the wild

    +
    dg
  5. Version 0.1 (2016-12-07)

    Initial version approved by the council.

    XEP Editor: ssw
  6. Version 0.0.2 (2016-09-22)

    Depend on Olm instead of Axolotl.

    ssw, dg
  7. Version 0.0.1 (2015-10-25)

    First draft.

    as

END

diff --git a/xep-0384.xml b/xep-0384.xml index e7e5ef35..abd58cce 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -281,8 +281,8 @@

In order to send a chat message, its <body> first has to be - encrypted. The client MUST use fresh, randomly generated key/IV pairs with - AES-128 in Galois/Counter Mode (GCM). + encrypted. The client MUST use fresh, randomly generated key with + AES-256.. The 16 bytes key and the GCM authentication tag (The tag SHOULD have at least 128 bit) are concatenated and for each intended recipient device, i.e. both own devices as well as devices associated with the contact, the @@ -295,12 +295,16 @@

- +
- BASE64ENCODED... - BASE64ENCODED... - - BASE64ENCODED... + + BASE64ENCODED... + + + BASE64ENCODED... + BASE64ENCODED... + +
BASE64ENCODED
@@ -310,8 +314,8 @@

The client may wish to transmit keying material to the contact. This first - has to be generated. The client MUST generate a fresh, randomly generated - key/IV pair. The 16 bytes key and the GCM authentication tag (The tag + has to be generated. The client MUST generate a fresh, randomly generated key. + The 16 bytes key and the GCM authentication tag (The tag SHOULD have at least 128 bit) are concatenated and for each intended recipient device, i.e. both own devices as well as devices associated with the contact, this key is encrypted using the corresponding @@ -322,12 +326,13 @@ <payload> as follows:

+
- BASE64ENCODED... - BASE64ENCODED... - - BASE64ENCODED... + + BASE64ENCODED... + BASE64ENCODED... + +
]]>

This KeyTransportElement can then be sent over any applicable transport mechanism.

From 4908f44da40265087c5b1f3db1255d0a97283342 Mon Sep 17 00:00:00 2001 From: sualko Date: Sun, 8 Mar 2020 11:11:24 +0100 Subject: [PATCH 07/49] XEP-0384: add missing signed prekey signature --- xep-0384.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index abd58cce..a3d2e952 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -207,7 +207,7 @@

NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

-

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

+

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

@@ -217,6 +217,7 @@ BASE64ENCODED + BASE64ENCODED BASE64ENCODED BASE64ENCODED From 38eb801e8c87bbf7b4f5c16ef289b12174af07e3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 11:11:27 +0100 Subject: [PATCH 08/49] XEP-0384: change namespace to urn:xmpp:omemo:1 --- xep-0384.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index a3d2e952..ad80a8d8 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -142,7 +142,7 @@
Device
A communication end point, i.e. a specific client instance
-
OMEMO element
An <encrypted> element in the eu.siacs.conversations.axolotl namespace. Can be either MessageElement or a KeyTransportElement
+
OMEMO element
An <encrypted> element in the urn:xmpp:omemo:1 namespace. Can be either MessageElement or a KeyTransportElement
MessageElement
An OMEMO element that contains a chat message. Its <payload>, when decrypted, corresponds to a <message>'s <body>.
KeyTransportElement
An OMEMO element that does not have a <payload>. It contains a fresh encryption key, which can be used for purposes external to this XEP.
Bundle
A collection of publicly accessible data that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
@@ -380,7 +380,7 @@

This specification defines the following XMPP namespaces:

    -
  • eu.siacs.conversations.axolotl
  • +
  • urn:xmpp:omemo:1
From d203e84edde3d25d1622c2cae0f59673fb60b38a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 11:12:42 +0100 Subject: [PATCH 09/49] delete rendered version of XEP-0384 --- xep-0384.html | 377 -------------------------------------------------- 1 file changed, 377 deletions(-) delete mode 100644 xep-0384.html diff --git a/xep-0384.html b/xep-0384.html deleted file mode 100644 index 144ca204..00000000 --- a/xep-0384.html +++ /dev/null @@ -1,377 +0,0 @@ - -XEP-0384: OMEMO Encryption

XEP-0384: OMEMO Encryption

Abstract
This specification defines a protocol for end-to-end encryption in one-on-one chats that may have multiple clients per account.
Author
Andreas Straub
Copyright
© 1999 – 2020 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

Deferred

WARNING: This document has been automatically Deferred after 12 months of inactivity in its previous Experimental state. Implementation of the protocol described herein is not recommended for production systems. However, exploratory implementations are encouraged to resume the standards process.
Type
Standards Track
Version
0.3.0 (2018-07-31)
Document Lifecycle
  1. Experimental
  2. Deferred
  3. Proposed
  4. Draft
  5. Final

1. - Introduction

-

1.1 Motivation

-

- There are two main end-to-end encryption schemes in common use in the XMPP - ecosystem, Off-the-Record (OTR) messaging (Current Off-the-Record Messaging Usage (XEP-0364) [1]) and OpenPGP - (Current Jabber OpenPGP Usage (XEP-0027) [2]). OTR has significant usability drawbacks for inter-client - mobility. As OTR sessions exist between exactly two clients, the chat - history will not be synchronized across other clients of the involved - parties. Furthermore, OTR chats are only possible if both participants are - currently online, due to how the rolling key agreement scheme of OTR - works. OpenPGP, while not suffering from these mobility issues, does not - provide any kind of forward secrecy and is vulnerable to replay attacks. - Additionally, PGP over XMPP uses a custom wireformat which is defined by - convention rather than standardization, and involves quite a bit of - external complexity. -

-

- This XEP defines a protocol that leverages the SignalProtocol encryption to provide - multi-end to multi-end encryption, allowing messages to be synchronized - securely across multiple clients, even if some of them are offline. The SignalProtocol - is a cryptographic double ratched protocol based on work by Trevor Perrin - and Moxie Marlinspike first published as the Axolotl protocol. While the - protocol itself has specifications in the public domain, the - protobuf-based wire format of the signal protocol is not fully - documented. The signal protocol currently only exists in GPLv3-licensed - implementations maintained by OpenWhisperSystems. -

-
-

1.2 Overview

-

- The general idea behind this protocol is to maintain separate, - long-standing SignalProtocol-encrypted sessions with each device of each contact - (as well as with each of our other devices), which are used as secure key - transport channels. In this scheme, each message is encrypted with a - fresh, randomly generated encryption key. An encrypted header is added to - the message for each device that is supposed to receive it. These headers - simply contain the key that the payload message is encrypted with, and - they are separately encrypted using the session corresponding to the - counterpart device. The encrypted payload is sent together with the - headers as a <message> stanza. Individual recipient devices can - decrypt the header item intended for them, and use the contained payload - key to decrypt the payload message. -

-

- As the encrypted payload is common to all recipients, it only has to be - included once, reducing overhead. Furthermore, SignalProtocols’s transparent handling - of messages that were lost or received out of order, as well as those sent - while the recipient was offline, is maintained by this protocol. As a - result, in combination with Message Carbons (XEP-0280) [3] and Message Archive Management (XEP-0313) [4], the desired property - of inter-client history synchronization is achieved. -

-

- OMEMO currently uses version 3 SignalProtocol. Instead of a Signal key - server, Personal Eventing Protocol (XEP-0163) [5] (PEP) is used to publish key data. -

-
-

2. - Requirements

-
    -
  • Provide forward secrecy
  • -
  • Ensure chat messages can be deciphered by all (capable) clients of both parties
  • -
  • Be usable regardless of the participants' online statuses
  • -
  • Provide a method to exchange auxilliary keying material. This could for example be used to secure encrypted file transfers.
  • -
-

3. - Glossary

-

3.1 General Terms

-
-
Device
A communication end point, i.e. a specific client instance
-
OMEMO element
An <encrypted> element in the eu.siacs.conversations.axolotl namespace. Can be either MessageElement or a KeyTransportElement
-
MessageElement
An OMEMO element that contains a chat message. Its <payload>, when decrypted, corresponds to a <message>'s <body>.
-
KeyTransportElement
An OMEMO element that does not have a <payload>. It contains a fresh encryption key, which can be used for purposes external to this XEP.
-
Bundle
A collection of publicly accessible data that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
-
rid
The device id of the intended recipient of the containing <key>
-
sid
The device id of the sender of the containing OMEMO element
- -
-
-

3.2 SignalProtocol-specific

-
-
IdentityKey
Per-device public/private key pair used to authenticate communications
-
PreKey
A Diffie-Hellman public key, published in bulk and ahead of time
-
PreKeySignalMessage
An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.
-
SignalMessage
An encrypted message
-
-
-

4. - Use Cases

-

4.1 Setup

-

- The first thing that needs to happen if a client wants to start using - OMEMO is they need to generate an IdentityKey and a Device ID. The - IdentityKey is a Curve25519 [6] public/private Key pair. The Device ID is a - randomly generated integer between 1 and 2^31 - 1. -

-
-

4.2 Discovering peer support

-

In order to determine whether a given contact has devices that support OMEMO, the devicelist node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:1:devices' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the devicelist.

-
Example 1. Devicelist update received by subscribed clients
-<message from='juliet@capulet.lit'
-         to='romeo@montague.lit'
-         type='headline'
-         id='update_01'>
-  <event xmlns='http://jabber.org/protocol/pubsub#event'>
-    <items node='urn:xmpp:omemo:1:devices'>
-      <item id='current'>
-        <devices xmlns='urn:xmpp:omemo:1'>
-          <device id='12345' />
-          <device id='4223' />
-        </devices>
-      </item>
-    </items>
-  </event>
-</message>
-
-

4.3 Announcing support

-

In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device ID to the devicelist PEP node.

-
Example 2. Adding the own device ID to the list
-<iq from='juliet@capulet.lit' type='set' id='announce1'>
-  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-    <publish node='urn:xmpp:omemo:1:devices'>
-      <item id='current'>
-        <devices xmlns='urn:xmpp:omemo:1'>
-          <device id='12345' />
-          <device id='4223' />
-          <device id='31415' />
-        </devices>
-      </item>
-    </publish>
-  </pubsub>
-</iq>
-

NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

-

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

-

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

-

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

-

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

-
Example 3. Publishing bundle information
-<iq from='juliet@capulet.lit' type='set' id='annouce2'>
-  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-    <publish node='urn:xmpp:omemo:1:bundles'>
-      <item id='31415'>
-        <bundle xmlns='urn:xmpp:omemo:1'
-                label='My desktop client'>
-          <spk id='0'>BASE64ENCODED</spk>
-          <ik>BASE64ENCODED</ik>
-          <prekeys>
-            <pk id='0'>BASE64ENCODED</pk>
-            <pk id='1'>BASE64ENCODED</pk>
-            <!-- … -->
-            <pk id='99'>BASE64ENCODED</pk>
-          </prekeys>
-        </bundle>
-      </item>
-    </publish>
-  </pubsub>
-</iq>
-

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:bundles’ node to ‘open’ to give entities without presence subscription read access to the bundles and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

-

The access model can be changed efficiently by using publish-options as described in XEP-0060 §7.1.5.

-
Example 4. Publishing bundle information with an open access model
-<iq from='juliet@capulet.lit' type='set' id='annouce2'>
-  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-    <publish node='urn:xmpp:omemo:1:bundles'>
-      <item id='31415'>
-        <bundle xmlns='urn:xmpp:omemo:1'>
-          <!-- … -->
-        </bundle>
-      </item>
-    </publish>
-    <publish-options>
-      <x xmlns='jabber:x:data' type='submit'>
-        <field var='FORM_TYPE' type='hidden'>
-          <value>http://jabber.org/protocol/pubsub#publish-options</value>
-        </field>
-        <field var='pubsub#access_model'>
-          <value>open</value>
-        </field>
-      </x>
-    </publish-options>
-  </pubsub>
-</iq>
-
-

4.4 Building a session

-

In order to build a session with a device, their bundle information is fetched.

-
Example 5. Fetching a device's bundle information
-<iq type='get'
-    from='romeo@montague.lit'
-    to='juliet@capulet.lit'
-    id='fetch1'>
-  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-    <items node='urn:xmpp:omemo:1:bundles'>
-      <item id='31415'/>
-    <items>
-  </pubsub>
-</iq>
-

A random preKeyPublic entry is selected, and used to build a SignalProtocol session.

-
-

4.5 Sending a message

-

- In order to send a chat message, its <body> first has to be - encrypted. The client MUST use fresh, randomly generated key with - AES-256.. - The 16 bytes key and the GCM authentication tag (The tag SHOULD have at least - 128 bit) are concatenated and for each intended recipient device, - i.e. both own devices as well as devices associated with the contact, the - result of this concatenation is encrypted using the corresponding - long-standing SignalProtocol session. Each encrypted payload key/authentication tag - tuple is tagged with the recipient device's ID. The key element MUST be - tagged with a prekey attribute set to true if a PreKeySignalMessage is being - used. This is all serialized into a MessageElement, which is transmitted - in a <message> as follows: -

-
Example 6. Sending a message
-<message to='juliet@capulet.lit' from='romeo@montague.lit' id='send1'>
-  <encrypted xmlns='urn:xmpp:omemo:1'>
-    <header sid='27183'>
-      <keys jid='juliet@capulet.lit'>
-        <key rid='31415'>BASE64ENCODED...</key>
-      </keys>
-      <keys jid='remeo@montague.lit'>
-        <key rid='1337'>BASE64ENCODED...</key>
-        <key prekey="true" rid='12321'>BASE64ENCODED...</key>
-        <!-- ... -->
-      </keys>
-    </header>
-    <payload>BASE64ENCODED</payload>
-  </encrypted>
-  <store xmlns='urn:xmpp:hints'/>
-</message>
-
-

4.6 Sending a key

-

- The client may wish to transmit keying material to the contact. This first - has to be generated. The client MUST generate a fresh, randomly generated key. - The 16 bytes key and the GCM authentication tag (The tag - SHOULD have at least 128 bit) are concatenated and for each intended - recipient device, i.e. both own devices as well as devices associated - with the contact, this key is encrypted using the corresponding - long-standing SignalProtocol session. Each encrypted payload key/authentication tag - tuple is tagged with the recipient device's ID. The key element MUST be - tagged with a prekey attribute set to true if a PreKeySignalMessage is being - used This is all serialized into a KeyTransportElement, omitting the - <payload> as follows: -

-
Example 7. Sending a key
-<encrypted xmlns='urn:xmpp:omemo:1'>
-  <header sid='27183'>
-    <keys jid='remeo@montague.lit'>
-      <key rid='31415'>BASE64ENCODED...</key>
-      <key prekey="true" rid='12321'>BASE64ENCODED...</key>
-      <!-- ... -->
-    </keys>
-  </header>
-</encrypted>
-

This KeyTransportElement can then be sent over any applicable transport mechanism.

-
-

4.7 Receiving a message

-

When an OMEMO element is received, the client MUST check whether there is a <key> element with an rid attribute matching its own device ID. If this is not the case, the element MUST be silently discarded. If such an element exists, the client checks whether the element's contents are a PreKeySignalMessage.

-

If this is the case, a new session is built from this received element. The client SHOULD then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST delete the private key belonging to the PreKey after use.

-

If the element's contents are a SignalMessage, and the client has a session with the sender's device, it tries to decrypt the SignalMessage using this session. If the decryption fails or if the element's contents are not a SignalMessage either, the OMEMO element MUST be silently discarded.

-

If the OMEMO element contains a <payload>, it is an OMEMO message element. The client tries to decrypt the base64 encoded contents using the key and the authentication tag extracted from the <key> element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the <body> of the received message.

-

If the OMEMO element does not contain a <payload>, the client has received a KeyTransportElement. The key extracted from the <key> element can then be used for other purposes (e.g. encrypted file transfer).

-
-

5. - Business Rules

-

Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

-

Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial PreKeySignalMessage later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

-

As there are no explicit error messages in this protocol, if a client does receive a PreKeySignalMessage using an invalid PreKey, they SHOULD respond with a KeyTransportElement, sent in a <message> using a PreKeySignalMessage. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

-

If a PreKeySignalMessage is received as part of a Message Archive Management (XEP-0313) [4] catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a KeyTransportMessage using a PreKeySignalMessage before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

-

As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a Message Processing Hints (XEP-0334) [7] <store /> hint in their OMEMO messages. Otherwise, server implementations of Message Archive Management (XEP-0313) [4] will generally not retain OMEMO messages, since they do not contain a <body />

-

6. - Implementation Notes

- -

- The SignalProtocol-library uses a trust model that doesn't work very well with - OMEMO. For this reason it may be desirable to have the library consider all - keys trusted, effectively disabling its trust management. This makes it - necessary to implement trust handling oneself. -

-

7. - Security Considerations

-

Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

-

When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user.

-

While it is RECOMMENDED that clients postpone private key deletion until after MAM catch-up and this standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to [8].

-

- In order to be able to handle out-of-order messages, the SignalProtocol stack has to - cache the keys belonging to "skipped" messages that have not been seen yet. - It is up to the implementor to decide how long and how many of such keys to - keep around. -

-

8. - IANA Considerations

-

This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

-

9. - XMPP Registrar Considerations

-

9.1 Protocol Namespaces

-

This specification defines the following XMPP namespaces:

-
    -
  • eu.siacs.conversations.axolotl
  • -
-
-

9.2 Protocol Versioning

-

If the protocol defined in this specification undergoes a revision that is not fully backwards-compatible with an older version, the XMPP Registrar shall increment the protocol version number found at the end of the XML namespaces defined herein, as described in Section 4 of XEP-0053.

-
-

10. - XML Schema

-
-<xml version="1.0" encoding="utf8">
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    targetNamespace="eu.siacs.conversations.axolotl"
-    xmlns="eu.siacs.conversations.axolotl">
-
-  <xs:element name="encrypted">
-    <xs:element name="header">
-      <xs:attribute name="sid" type="xs:integer"/>
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="key" type="xs:base64Binary" maxOccurs="unbounded">
-            <xs:attribute name="rid" type="xs:integer" use="required"/>
-            <xs:attribute name="prekey" type="xs:boolean"/>
-          </xs:element>
-          <xs:element name="iv" type="xs:base64Binary"/>
-      </xs:complexType>
-    </xs:element>
-    <xs:element name="payload" type="xs:base64Binary" minOccurs="0"/>
-  </xs:element>
-
-  <xs:element name="list">
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element name="device" maxOccurs="unbounded">
-          <xs:attribute name="id" type="integer" use="required"/>
-        </xs:element>
-      </xs:sequence>
-    </xs:complexType>
-  </xs:element>
-
-  <xs:element name="bundle">
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element name="signedPreKeyPublic" type="base64Binary">
-          <xs:attribute name="signedPreKeyId" type="integer"/>
-        </xs:element>
-        <xs:element name="signedPreKeySignature" type="base64Binary"/>
-        <xs:element name="identityKey" type="base64Binary"/>
-        <xs:element name="prekeys">
-          <xs:complexType>
-            <xs:sequence>
-              <xs:element name="preKeyPublic" type="base64Binary" maxOccurs="unbounded">
-                <xs:attribute name="preKeyId" type="integer" use="required"/>
-              </xs:element>
-            </xs:sequence>
-          </xs:complexType>
-        </xs:element>
-      </xs:sequence>
-    </xs:complexType>
-  </xs:element>
-
-</xs:schema>
-
-

11. - Acknowledgements

-

Big thanks to Daniel Gultsch for mentoring me during the development of this protocol. Thanks to Thijs Alkemade and Cornelius Aschermann for talking through some of the finer points of the protocol with me. And lastly I would also like to thank Sam Whited, Holger Weiss, and Florian Schmaus for their input on the standard.

-

Appendices

Appendix A: Document Information

Series
XEP
Number
0384
Publisher
XMPP Standards Foundation
Status
Deferred
Type
Standards Track
Version
0.3.0
Last Updated
2018-07-31
Approving Body
XMPP Council
Dependencies
XMPP Core, XEP-0163
Supersedes
None
Superseded By
None
Short Name
OMEMO
Source Control
HTML

- This document in other formats: - XML  - PDF

Appendix B: Author Information

Andreas Straub
Email
andy@strb.org
JabberID
andy@strb.org

Copyright

This XMPP Extension Protocol is copyright © 1999 – 2020 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which can be found at <https://xmpp.org/about/xsf/ipr-policy> or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).

Visual Presentation

The HTML representation (you are looking at) is maintained by the XSF. It is based on the YAML CSS Framework, which is licensed under the terms of the CC-BY-SA 2.0 license.

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 6120) and XMPP IM (RFC 6121) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <http://xmpp.org/about/discuss.shtml> for a complete list.

Errata can be sent to <editor@xmpp.org>.

Appendix F: Requirements Conformance

The following requirements keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".

Appendix G: Notes

1. XEP-0364: Current Off-the-Record Messaging Usage <https://xmpp.org/extensions/xep-0364.html>.

2. XEP-0027: Current Jabber OpenPGP Usage <https://xmpp.org/extensions/xep-0027.html>.

3. XEP-0280: Message Carbons <https://xmpp.org/extensions/xep-0280.html>.

4. XEP-0313: Message Archive Management <https://xmpp.org/extensions/xep-0313.html>.

5. XEP-0163: Personal Eventing Protocol <https://xmpp.org/extensions/xep-0163.html>.

6. Curve25519: new Diffie-Hellman speed records <http://cr.yp.to/ecdh/curve25519-20060209.pdf>.

7. XEP-0334: Message Processing Hints <https://xmpp.org/extensions/xep-0334.html>.

8. Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158.

Appendix H: Revision History

Note: Older versions of this specification might be available at http://xmpp.org/extensions/attic/

  1. Version 0.3.0 (2018-07-31)

    Make examples show items published to the id "current", as per XEP-0060 §12.20.

    egp
  2. Version 0.2.2 (2018-11-03)
    Fix a bunch of typos, batch-style.
    pep
  3. Version 0.2.1 (2018-05-21)
    Fix attribute names in schema
    mb
  4. Version 0.2 (2017-06-02)
    -

    Depend on SignalProtocol instead of Olm.

    -

    Changed to eu.siacs.conversations.axolotl Namespace which is currently used in the wild

    -
    dg
  5. Version 0.1 (2016-12-07)

    Initial version approved by the council.

    XEP Editor: ssw
  6. Version 0.0.2 (2016-09-22)

    Depend on Olm instead of Axolotl.

    ssw, dg
  7. Version 0.0.1 (2015-10-25)

    First draft.

    as

END

From 8cc7ce6e46ef54ff6fbe997359e1e1d4681b240e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 12:10:05 +0100 Subject: [PATCH 10/49] XEP-0384: explain that access model should be open --- xep-0384.xml | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index ad80a8d8..7ebb148c 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -189,7 +189,10 @@ ]]>
+

In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device ID to the devicelist PEP node.

+

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:devices’ node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

+

The access model can be changed efficiently by using publish-options.

@@ -202,13 +205,26 @@ + + + + http://jabber.org/protocol/pubsub#publish-options + + + open + + + ]]>

NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

+
+

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

-

A bundle is an element called ‘bundle’ in the ‘urn:xmpp:omomo:1’ namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

+

A bundle is an element called 'bundle' in the 'urn:xmpp:omomo:1' namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

+

When publishing bundles a client MUST make sure that the 'urn:xmpp:omemo:1' node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

@@ -228,10 +244,20 @@ + + + + http://jabber.org/protocol/pubsub#publish-options + + + max + + + ]]> -

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:bundles’ node to ‘open’ to give entities without presence subscription read access to the bundles and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

-

The access model can be changed efficiently by using publish-options as described in XEP-0060 §7.1.5.

+

As with the 'urn:xmpp:omemo:1:devices' node it is RECOMMENDED to set the access model of the 'urn:xmpp:omemo:1:bundles' to open. Clients that do not adhere to the recommended access model (and for example want to stick to the default 'presence') are highly encouraged to configure the same access model for 'urn:xmpp:omemo:1:devices' and 'urn:xmpp:omemo:1:bundles', otherwise remote entities might end up in a situation where they are able to retrieve the device list but not the bundle or vice versa.

+

The access model can be changed efficiently by using publish-options.

@@ -247,6 +273,9 @@ http://jabber.org/protocol/pubsub#publish-options + + max + open @@ -254,6 +283,7 @@ ]]> +

In order to build a session with a device, their bundle information is fetched.

From 27b13072749a91b9ed75f51cb3f4d45ddb3b7d19 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 8 Mar 2020 10:58:41 +0100 Subject: [PATCH 11/49] XEP-0384: add business rule on heartbeat messages --- xep-0384.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/xep-0384.xml b/xep-0384.xml index 7ebb148c..68471ced 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -382,6 +382,7 @@

As there are no explicit error messages in this protocol, if a client does receive a PreKeySignalMessage using an invalid PreKey, they SHOULD respond with a KeyTransportElement, sent in a <message> using a PreKeySignalMessage. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

If a PreKeySignalMessage is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a KeyTransportMessage using a PreKeySignalMessage before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

+

When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

From 501317848802b2075aef134c42a65d09d9d4d0b0 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 12:26:54 +0100 Subject: [PATCH 12/49] Added technical protocol details --- xep-0384.xml | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/xep-0384.xml b/xep-0384.xml index 68471ced..929669cd 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -160,6 +160,71 @@
+ + +

+ This protocol uses the DoubleRatchet encryption mechanism in conjunction with the X3DH key exchange. The following section provides detailed technical information about the protocol that should be sufficient to build a compatible OMEMO implementation. Readers who do not intend to build an OMEMO-compatible library can safely skip this section, relevant details are repeated where needed. +

+
+ +

+ The X3DH key exchange is specified here and placed under the public domain. OMEMO uses this key exchange mechanism with the following parameters/settings: +

+
+
curve
X25519
+
hash function
SHA-256
+
info string
"OMEMO X3DH"
+
byte-encoding of the public keys
the default as used by most crypto libraries TODO
+
signed pre-key rotation period
Signed pre-keys SHOULD be rotated periodically once a week to once a month. A faster or slower rotation period should not be required.
+
time to keep the private key of the old signed pre-key after rotating it
The private key of the old signed pre-key SHOULD be kept for another rotation period as defined above, to account for delayed messages using the old signed pre-key.
+
number of pre-keys to provide in the bundle
The bundle SHOULD always contain around 100 pre-keys.
+
minimum number of pre-keys to provide in the bundle
The bundle MUST always contain at least 25 pre-keys.
+
associated data
The associated data is created by concatenating the identity keys of Alice and Bob: AD = Encode(IK_A) || Encode(IK_B)
+
XEdDSA
To reduce the amount of bytes that have to be transferred, the key exchange uses XEdDSA on curves X25519/Ed25519 (aka XEd25519) to derive signing keys from encryption keys.
+
+
+ +

NOTE: OMEMOMessage.proto and OMEMOAuthenticatedMessage.proto refer to the protobuf structures as defined here.

+

+ The DoubleRatchet protocol is specified here and placed under the public domain. OMEMO uses this protocol with the following parameters/settings: +

+
+
ratchet initialization
The double ratchet is initialized using the shared secret, ad and public keys as yielded by the X3DH key exchange, as explained in the double ratchet specification.
+
MAX_SKIP
It is RECOMMENDED to keep around 1000 skipped message keys.
+
deletion policy for skipped message keys
Skipped message keys MUST be stored until MAX_SKIP message keys are stored. At that point, keys are discarded on a LRU basis to make space for new message keys. Implementations SHOULD not keep skipped message keys around forever, but discard old keys on a different implementation-defined policy. It is RECOMMENDED to base this policy on deterministic events rather than time.
+
authentication tag truncation
Authentication tags are truncated to 16 bytes/128 bits.
+
CONCAT(ad, header)
CONCAT(ad, header) = ad || OMEMOMessage.proto(header) NOTE: the OMEMOMessage.proto is initialized without the ciphertext, which is optional. NOTE: Implementations are not strictly required to return a parseable byte array here, as the unpacked/parsed data is required later in the protocol.
+
KDF_RK(rk, dh_out)
HKDF-SHA-256 using the rk as HKDF salt, dh_out as HKDF input material and "OMEMO Root Chain" as HKDF info.
+
KDF_CK(ck)
HMAC-SHA-256 using ck as the HMAC key, a single byte constant 0x01 as HMAC input to produce the next message key and a single byte constant 0x02 as HMAC input to produce the next chain key.
+
ENCRYPT(mk, plaintext, associated_data)
+ The encryption step uses authenticated encryption consisting of AES-256-CBC with HMAC-SHA-256. +
    +
  1. Use HKDF-SHA-256 to generate 80 bytes of output from the message key by providing mk as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Message Key Material" as HKDF info.
  2. +
  3. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
  4. +
  5. Encrypt the plaintext (which is a 16 bytes key as specified here) using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
  6. +
  7. Split the associated data as returned by CONCAT into the original ad and the OMEMOMessage.proto structure.
  8. +
  9. Add the ciphertext to the OMEMOMessage.proto structure.
  10. +
  11. Serialize the ad and the OMEMOMessage.proto structure into a parseable byte array by concatenating ad and the serialized protobuf structure.
  12. +
  13. Calculate the HMAC-SHA-256 using the authentication key and the input material as derived in the steps above.
  14. +
  15. Put the OMEMOMessage.proto structure and the HMAC into a new OMEMOAuthenticatedMessage.proto structure.
  16. +
+
+
+
+ +

+ The contents are encrypted and authenticated using a combination of AES-256-CBC and HMAC-SHA-256. +

+
    +
  1. Generate 16 bytes of cryptographically secure random data, called key in the remainder of this algorithm.
  2. +
  3. Encrypt this key using the double ratchet as specified above, once for each intended recipient.
  4. +
  5. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
  6. +
  7. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
  8. +
  9. Encrypt the plaintext using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
  10. +
  11. Calculate the HMAC-SHA-256 using the authentication key and the ciphertext from the previous steps.
  12. +
+
+

@@ -474,6 +539,21 @@ ]]> + + +

Big thanks to Daniel Gultsch for mentoring me during the development of this protocol. Thanks to Thijs Alkemade and Cornelius Aschermann for talking through some of the finer points of the protocol with me. And lastly I would also like to thank Sam Whited, Holger Weiss, and Florian Schmaus for their input on the standard.

From c662094c6f7c4612bf9e07f6270acbeda5ff9830 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 8 Mar 2020 12:28:10 +0100 Subject: [PATCH 13/49] Add SCE usage and remove some Signal references --- xep-0384.xml | 67 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 929669cd..0fb7cf1f 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -1,5 +1,7 @@ + %ents; ]> @@ -90,21 +92,18 @@ external complexity.

- This XEP defines a protocol that leverages the SignalProtocol encryption to provide + This XEP defines a protocol that leverages the Double Ratchet Algorithm to provide multi-end to multi-end encryption, allowing messages to be synchronized - securely across multiple clients, even if some of them are offline. The SignalProtocol - is a cryptographic double ratched protocol based on work by Trevor Perrin - and Moxie Marlinspike first published as the Axolotl protocol. While the - protocol itself has specifications in the public domain, the - protobuf-based wire format of the signal protocol is not fully - documented. The signal protocol currently only exists in GPLv3-licensed - implementations maintained by OpenWhisperSystems. + securely across multiple clients, even if some of them are offline. + The Double Ratched protocol is based on work by Trevor Perrin + and Moxie Marlinspike and was first published as the Axolotl protocol. + The specification for the protocol is available in the public domain.

The general idea behind this protocol is to maintain separate, - long-standing SignalProtocol-encrypted sessions with each device of each contact + long-standing Double Ratchet-encrypted sessions with each device of each contact (as well as with each of our other devices), which are used as secure key transport channels. In this scheme, each message is encrypted with a fresh, randomly generated encryption key. An encrypted header is added to @@ -125,8 +124,9 @@ of inter-client history synchronization is achieved.

- OMEMO currently uses version 3 SignalProtocol. Instead of a Signal key - server, &xep0163; (PEP) is used to publish key data. + While in the future a dedicated key server component could be used to distribute + key material for session creation, the current specification relies on PEP to publish + and acquire key bundles.

@@ -376,19 +376,36 @@

- In order to send a chat message, its <body> first has to be - encrypted. The client MUST use fresh, randomly generated key with - AES-256.. - The 16 bytes key and the GCM authentication tag (The tag SHOULD have at least - 128 bit) are concatenated and for each intended recipient device, - i.e. both own devices as well as devices associated with the contact, the - result of this concatenation is encrypted using the corresponding - long-standing SignalProtocol session. Each encrypted payload key/authentication tag - tuple is tagged with the recipient device's ID. The key element MUST be - tagged with a prekey attribute set to true if a PreKeySignalMessage is being - used. This is all serialized into a MessageElement, which is transmitted - in a <message> as follows: + In order to send a chat message, extension elements that are deemed sensible first have to be + encrypted. For this purpose, extensions that are only intended to be accessible to the recipient + are placed inside a &xep0420; &content; element, which is then encrypted using a message key. + For this reason OMEMO defines its own SCE profile.

+ +

+ An OMEMO SCE &content; element +

+
    +
  • MUST contain an <rpad/> affix element. This is used to prevent an attacker from gaining insights about the content of a message based on the length of the ciphertext.
  • +
  • MAY contain a <time/> affix element. This can be used to prevent the server from modifying the order in which messages from different sending devices have been sent.
  • +
  • SHOULD contain a <from/> affix element.
  • +
  • MUST contain a <to/> affix element whenever a message is sent via a group chat (MUC/MIX). This is used to prevent the server from silently converting a group message into a private message and vice versa.
  • +
+
+

+ The ciphertext that is the encrypted &content; element is then encoded using base64 and placed as text content into the &payload; element. +

+ + + + Hello World! + + + ... + +]]> + @@ -402,7 +419,9 @@ - BASE64ENCODED + + -- MESSAGE-KEY-ENCRYPTED CONTENT ELEMENT -- + ]]> From cd73b5616ec91ad2f0b0645d2ab436cf34305fa5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 12:30:22 +0100 Subject: [PATCH 14/49] XEP-0384: mention keys wrapper in 'receiving a message' --- xep-0384.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 0fb7cf1f..6a4a5ef5 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -453,11 +453,10 @@

This KeyTransportElement can then be sent over any applicable transport mechanism.

-

When an OMEMO element is received, the client MUST check whether there is a <key> element with an rid attribute matching its own device ID. If this is not the case, the element MUST be silently discarded. If such an element exists, the client checks whether the element's contents are a PreKeySignalMessage.

+

When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device ID. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are a PreKeySignalMessage.

If this is the case, a new session is built from this received element. The client SHOULD then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST delete the private key belonging to the PreKey after use.

If the element's contents are a SignalMessage, and the client has a session with the sender's device, it tries to decrypt the SignalMessage using this session. If the decryption fails or if the element's contents are not a SignalMessage either, the OMEMO element MUST be silently discarded.

If the OMEMO element contains a <payload>, it is an OMEMO message element. The client tries to decrypt the base64 encoded contents using the key and the authentication tag extracted from the <key> element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the <body> of the received message.

-

If the OMEMO element does not contain a <payload>, the client has received a KeyTransportElement. The key extracted from the <key> element can then be used for other purposes (e.g. encrypted file transfer).

From d914cd202566d08a8414f57d5b9c96b090cf6b40 Mon Sep 17 00:00:00 2001 From: sualko Date: Sun, 8 Mar 2020 12:43:00 +0100 Subject: [PATCH 15/49] XEP-0384: remove key transport message --- xep-0384.xml | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 6a4a5ef5..04572316 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -142,9 +142,8 @@
Device
A communication end point, i.e. a specific client instance
-
OMEMO element
An <encrypted> element in the urn:xmpp:omemo:1 namespace. Can be either MessageElement or a KeyTransportElement
+
OMEMO element
An <encrypted> element in the urn:xmpp:omemo:1 namespace.
MessageElement
An OMEMO element that contains a chat message. Its <payload>, when decrypted, corresponds to a <message>'s <body>.
-
KeyTransportElement
An OMEMO element that does not have a <payload>. It contains a fresh encryption key, which can be used for purposes external to this XEP.
Bundle
A collection of publicly accessible data that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
rid
The device id of the intended recipient of the containing <key>
sid
The device id of the sender of the containing OMEMO element
@@ -426,32 +425,6 @@ ]]> - -

- The client may wish to transmit keying material to the contact. This first - has to be generated. The client MUST generate a fresh, randomly generated key. - The 16 bytes key and the GCM authentication tag (The tag - SHOULD have at least 128 bit) are concatenated and for each intended - recipient device, i.e. both own devices as well as devices associated - with the contact, this key is encrypted using the corresponding - long-standing SignalProtocol session. Each encrypted payload key/authentication tag - tuple is tagged with the recipient device's ID. The key element MUST be - tagged with a prekey attribute set to true if a PreKeySignalMessage is being - used This is all serialized into a KeyTransportElement, omitting the - <payload> as follows: -

- -
- - BASE64ENCODED... - BASE64ENCODED... - - -
-]]>
-

This KeyTransportElement can then be sent over any applicable transport mechanism.

-

When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device ID. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are a PreKeySignalMessage.

If this is the case, a new session is built from this received element. The client SHOULD then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST delete the private key belonging to the PreKey after use.

@@ -462,8 +435,8 @@

Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial PreKeySignalMessage later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

-

As there are no explicit error messages in this protocol, if a client does receive a PreKeySignalMessage using an invalid PreKey, they SHOULD respond with a KeyTransportElement, sent in a <message> using a PreKeySignalMessage. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

-

If a PreKeySignalMessage is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a KeyTransportMessage using a PreKeySignalMessage before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

+

As there are no explicit error messages in this protocol, if a client does receive a PreKeySignalMessage using an invalid PreKey, they SHOULD respond with a normal OMEMO encrypted message with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

+

If a PreKeySignalMessage is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

From 94067ef61dad9179f016a3a0bbf6a94005bab8ee Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 8 Mar 2020 13:01:21 +0100 Subject: [PATCH 16/49] OMEMO is not only 1:1 --- xep-0384.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index 04572316..6a12f8ae 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -9,7 +9,7 @@
OMEMO Encryption - This specification defines a protocol for end-to-end encryption in one-on-one chats that may have multiple clients per account. + This specification defines a protocol for end-to-end encryption in one-to-one chats, as well as group chats where each participant may have multiple clients per account. &LEGALNOTICE; 0384 Deferred From 9932fd4433b5b6b7529fcfe6bdbf2db45c1c5388 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 8 Mar 2020 13:07:09 +0100 Subject: [PATCH 17/49] Be less harsh to OTR :P --- xep-0384.xml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 6a12f8ae..d3cb2869 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -80,12 +80,13 @@

There are two main end-to-end encryption schemes in common use in the XMPP ecosystem, Off-the-Record (OTR) messaging (&xep0364;) and OpenPGP - (&xep0027;). OTR has significant usability drawbacks for inter-client - mobility. As OTR sessions exist between exactly two clients, the chat - history will not be synchronized across other clients of the involved - parties. Furthermore, OTR chats are only possible if both participants are - currently online, due to how the rolling key agreement scheme of OTR - works. OpenPGP, while not suffering from these mobility issues, does not + (&xep0027;). Older OTR versions have had significant usability drawbacks for inter-client + mobility. As OTR sessions existed between exactly two clients, the chat + history would not be synchronized across other clients of the involved + parties. Furthermore, OTR chats were only possible if both participants were + online at the same time, due to how the rolling key agreement scheme of OTR + worked. Some of those problems have been addressed in OTRv4. + OpenPGP, while not suffering from these mobility issues, does not provide any kind of forward secrecy and is vulnerable to replay attacks. Additionally, PGP over XMPP uses a custom wireformat which is defined by convention rather than standardization, and involves quite a bit of From 433b1111f552843bb86caad0fc75db1c5a18b980 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 8 Mar 2020 13:10:34 +0100 Subject: [PATCH 18/49] Mention XEP-0373 --- xep-0384.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index d3cb2869..19efc094 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -90,7 +90,7 @@ provide any kind of forward secrecy and is vulnerable to replay attacks. Additionally, PGP over XMPP uses a custom wireformat which is defined by convention rather than standardization, and involves quite a bit of - external complexity. + external complexity. The wire format issues were resolved with &xep0373;.

This XEP defines a protocol that leverages the Double Ratchet Algorithm to provide From 5e434f93346162c0cc540c15c9ae456f6ca03741 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 13:40:30 +0100 Subject: [PATCH 19/49] Added more protocol details and improved some sections --- xep-0384.xml | 72 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 19efc094..6713bc94 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -118,9 +118,9 @@

As the encrypted payload is common to all recipients, it only has to be - included once, reducing overhead. Furthermore, SignalProtocols’s transparent handling - of messages that were lost or received out of order, as well as those sent - while the recipient was offline, is maintained by this protocol. As a + included once, reducing overhead. Furthermore, the transparent handling by the + double ratchet protocol of messages that were lost or received out of order, as well + as those sent while the recipient was offline, is maintained by this protocol. As a result, in combination with &xep0280; and &xep0313;, the desired property of inter-client history synchronization is achieved.

@@ -155,8 +155,8 @@
IdentityKey
Per-device public/private key pair used to authenticate communications
PreKey
A Diffie-Hellman public key, published in bulk and ahead of time
-
PreKeySignalMessage
An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.
-
SignalMessage
An encrypted message
+
OMEMOKeyExchange
An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.
+
OMEMOAuthenticatedMessage
An encrypted and authenticated message
@@ -184,7 +184,7 @@
-

NOTE: OMEMOMessage.proto and OMEMOAuthenticatedMessage.proto refer to the protobuf structures as defined here.

+

NOTE: OMEMOMessage.proto, OMEMOAuthenticatedMessage.proto and OMEMOKeyExchange.proto refer to the protobuf structures as defined here.

The DoubleRatchet protocol is specified here and placed under the public domain. OMEMO uses this protocol with the following parameters/settings:

@@ -217,21 +217,30 @@

  1. Generate 16 bytes of cryptographically secure random data, called key in the remainder of this algorithm.
  2. -
  3. Encrypt this key using the double ratchet as specified above, once for each intended recipient.
  4. +
  5. Encrypt this key using the double ratchet as specified above, once for each intended recipient. This yields one OMEMOKeyExchange or OMEMOAuthenticatedMessage per recipient device.
  6. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
  7. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
  8. Encrypt the plaintext using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
  9. Calculate the HMAC-SHA-256 using the authentication key and the ciphertext from the previous steps.
+ +

+ The contents are decrypted by reversing the encryption steps. +

+
    +
  1. Decrypt the 16 bytes key from the OMEMOKeyExchange or OMEMOAuthenticatedMessage, encrypted using the double ratchet belonging to this device.
  2. +
  3. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
  4. +
  5. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
  6. +
  7. Verify the HMAC-SHA-256 using the authentication key derived in the previous step and the ciphertext.
  8. +
  9. Decrypt the ciphertext using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous steps.
  10. +
+

- The first thing that needs to happen if a client wants to start using - OMEMO is they need to generate an IdentityKey and a Device ID. The - IdentityKey is a &curve25519; public/private Key pair. The Device ID is a - randomly generated integer between 1 and 2^31 - 1. + To participate in OMEMO-encrypted chats, clients need to set up an OMEMO library and generate a device id, which is a randomly generated integer between 1 and 2^31 - 1. The device id must be unique for the account.

@@ -255,7 +264,7 @@ -

In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device ID to the devicelist PEP node.

+

In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devicelist PEP node.

It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:devices’ node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

The access model can be changed efficiently by using publish-options.

This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

-

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

-

A bundle is an element called 'bundle' in the 'urn:xmpp:omomo:1' namespace. It has a child element called ‘spk’ that contains the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

+

Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

+

A bundle is an element called 'bundle' in the 'urn:xmpp:omomo:1' namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

When publishing bundles a client MUST make sure that the 'urn:xmpp:omemo:1' node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

]]> -

A random preKeyPublic entry is selected, and used to build a SignalProtocol session.

+

A random pk entry is selected, and used to build an OMEMO session.

-

In order to signal a contact that you like to terminate a session, your - device MUST send an <terminate> element to all intended recipient devices +

In order to signal (TODO: english?) a contact that you like to terminate a session, your + device MUST send a <terminate> element to all intended recipient devices inside an encrypted stanza. A user or client MAY tag the element with a reason. If a device is receiving a stanza containing a <terminate> element, it MUST show an information that the peer has ended the session. To prevent @@ -392,6 +401,9 @@

  • MUST contain a <to/> affix element whenever a message is sent via a group chat (MUC/MIX). This is used to prevent the server from silently converting a group message into a private message and vice versa.
  • +

    + The &content; element is encrypted as described in the section about Message Encryption. +

    The ciphertext that is the encrypted &content; element is then encoded using base64 and placed as text content into the &payload; element.

    @@ -427,17 +439,19 @@ ]]>
    -

    When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device ID. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are a PreKeySignalMessage.

    -

    If this is the case, a new session is built from this received element. The client SHOULD then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST delete the private key belonging to the PreKey after use.

    -

    If the element's contents are a SignalMessage, and the client has a session with the sender's device, it tries to decrypt the SignalMessage using this session. If the decryption fails or if the element's contents are not a SignalMessage either, the OMEMO element MUST be silently discarded.

    -

    If the OMEMO element contains a <payload>, it is an OMEMO message element. The client tries to decrypt the base64 encoded contents using the key and the authentication tag extracted from the <key> element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the <body> of the received message.

    +

    When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device ID. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

    +

    If this is the case, a new session is built from this received element. The client MUST then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST eventually delete the private key belonging to the PreKey after use (this is subject to the business rules).

    +

    If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. This is subject to TODO: recovering from broken sessions.

    +

    + After either the OMEMOKeyExchange or the OMEMOAuthenticatedMessage is decrypted, the content is decrypted as described in the section about Message Decryption. +

    Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

    -

    Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial PreKeySignalMessage later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

    -

    As there are no explicit error messages in this protocol, if a client does receive a PreKeySignalMessage using an invalid PreKey, they SHOULD respond with a normal OMEMO encrypted message with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

    -

    If a PreKeySignalMessage is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

    +

    Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

    +

    As there are no explicit error messages in this protocol, if a client does receive a OMEMOKeyExchange using an invalid PreKey, they SHOULD respond with a normal OMEMO encrypted message with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

    +

    If a OMEMOKeyExchange is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

    As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

    When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

    @@ -541,8 +555,16 @@ message OMEMOMessage { } message OMEMOAuthenticatedMessage { - bytes omemo_message; bytes mac; + bytes omemo_message; +} + +message OMEMOKeyExchange { + uint32 pk_id; + uint32 spk_id; + bytes ik; + bytes ek; + bytes omemo_authenticated_message; } ]]> From 928d6ffd6308a1b43d90019ac35089ed6b2d48a9 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 8 Mar 2020 13:35:34 +0100 Subject: [PATCH 20/49] XEP-0384: define encrypted element --- xep-0384.xml | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 6713bc94..6c1f7226 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -400,14 +400,7 @@
  • SHOULD contain a <from/> affix element.
  • MUST contain a <to/> affix element whenever a message is sent via a group chat (MUC/MIX). This is used to prevent the server from silently converting a group message into a private message and vice versa.
  • - -

    - The &content; element is encrypted as described in the section about Message Encryption. -

    -

    - The ciphertext that is the encrypted &content; element is then encoded using base64 and placed as text content into the &payload; element. -

    - @@ -417,8 +410,27 @@ ... ]]> - - + + +

    + The &content; element is encrypted as described in the section about Message Encryption. + The client MUST use fresh, randomly generated key AES-256 with. + The SCE &content; element is encrypted using this key (TODO) +

    +

    + The 32-byte AES key and the 32-byte HMAC are concatenated and the result of this concatenation is encrypted using the corresponding long-standing OMEMO session for each intended recipient device. + Clients SHOULD only consider the devices on the 'urn:xmpp:omemo:1:devices' node of each recipient (i.e. including his own devices node, but excluding itself). +

    +
    + +

    + An OMEMO encrypted message is specified to include an the <encrypted> element in the 'urn:xmpp:omomo:1' namespace. It always contains two child nodes, the <header> and the &payload; element. + The <header> element has an attribute named 'sid' referencing the device id of the sending device and contains one or multiple <keys> elements, each with an attribute 'jid' of one recipient JID as well as one or multiple <key> elements. + A <key> element has an attribute named 'rid' referencing the device id of the recipient device. The ciphertext that is the key and HMAC encrypted using the long-standing OMEMO session for that recipient device is encoded using base64 and places as text content into the <key> element. + The ciphertext that is the encrypted &content; element is encoded using base64 and placed as text content into the &payload; element. +

    +
    @@ -437,6 +449,7 @@ ]]> +

    When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device ID. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

    @@ -454,6 +467,7 @@

    If a OMEMOKeyExchange is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

    As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

    When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

    +

    When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

    From f60fdbec981e0a0eff7882e3d87990a677513f53 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 14:07:20 +0100 Subject: [PATCH 21/49] Added information about OMEMOKeyExchange and the key exchange flow --- xep-0384.xml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 6c1f7226..430dc758 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -182,6 +182,9 @@
    associated data
    The associated data is created by concatenating the identity keys of Alice and Bob: AD = Encode(IK_A) || Encode(IK_B)
    XEdDSA
    To reduce the amount of bytes that have to be transferred, the key exchange uses XEdDSA on curves X25519/Ed25519 (aka XEd25519) to derive signing keys from encryption keys.
    +

    + The key exchange is done just-in-time when sending the first message to a device. Thus, each key exchange message always also contains encrypted content as produced by the double ratchet algorithm below. +

    NOTE: OMEMOMessage.proto, OMEMOAuthenticatedMessage.proto and OMEMOKeyExchange.proto refer to the protobuf structures as defined here.

    @@ -210,6 +213,16 @@ +

    + If encrypting this message required a key exchange, the X3DH key exchange header data is placed into a new OMEMOKeyExchange.proto structure together with the OMEMOAuthenticatedMessage.proto structure. +

    +

    + To account for lost and out-of-order messages during the key exchange, OMEMOKeyExchange.proto structures are sent until a response by the recipient confirms that the key exchange was successfully completed. To do so, the X3DH key exchange header data is stored and added on each subsequent message until a response is received. This looks roughly as follows: +

    +
      +
    1. The first content is encrypted for a new recipient. This results in an X3DH header and a OMEMOAuthenticatedMessage.proto structure. Both are packed into an OMEMOKeyExchange.proto structure. The X3DH header is stored for following messages.
    2. +
    3. A second message is encrypted for the same recipient. This results in only a OMEMOAuthenticatedMessage.proto structure, as a new key exchange is not required. Together with the X3DH header that was stored in the previous step, an OMEMOKeyExchange.proto structure is constructed and sent to the recipient.
    4. +

    @@ -471,23 +484,12 @@ -

    - The SignalProtocol-library uses a trust model that doesn't work very well with - OMEMO. For this reason it may be desirable to have the library consider all - keys trusted, effectively disabling its trust management. This makes it - necessary to implement trust handling oneself. -

    +

    Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

    -

    When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user.

    +

    When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user. TODO: consistent color foo

    While it is RECOMMENDED that clients postpone private key deletion until after MAM catch-up and this standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

    -

    - In order to be able to handle out-of-order messages, the SignalProtocol stack has to - cache the keys belonging to "skipped" messages that have not been seen yet. - It is up to the implementor to decide how long and how many of such keys to - keep around. -

    This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

    From 94c8f01e53a6981140eab5d24f75eb0fabb0291e Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 14:12:10 +0100 Subject: [PATCH 22/49] Protobuf structures improved --- xep-0384.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 430dc758..661a3ed0 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -564,23 +564,23 @@ From b0efdf064802950cf82390923760e6dfc9a87c3e Mon Sep 17 00:00:00 2001 From: sualko Date: Sun, 8 Mar 2020 15:29:51 +0100 Subject: [PATCH 23/49] XEP-0384: update requirements --- xep-0384.xml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 661a3ed0..80662b06 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -132,12 +132,27 @@
    -
      -
    • Provide forward secrecy
    • -
    • Ensure chat messages can be deciphered by all (capable) clients of both parties
    • -
    • Be usable regardless of the participants' online statuses
    • -
    • Provide a method to exchange auxilliary keying material. This could for example be used to secure encrypted file transfers.
    • -
    +

    It is a result of XMPPs federated nature that a message may pass more than just one server. Therefore it is in the users interest to secure their communication from any intermediate host. End-to-end encryption is an efficient way to protect any data exchanged between sender and receiver against passive and active attackers such as servers and network nodes.

    +

    OMEMO is an end-to-end encryption protocol based on the Double Ratchet specified in section Double Ratchet. It provides the following guarantees under the threat model described in the next section:

    +
      +
    • Confidentiality: Nobody else except sender and receiver is able to read the content of a message.
    • +
    • Perfect forward secrecy: A compromised long-term key does not compromise any previous message exchange.
    • +
    • Authentication: Every peer is able to authenticate the sender or receiver of a message, even if the details of the authentication process is out-of-scope for this specification.
    • +
    • Immutability: Every peer can ensure that a message was not changed by any intermediate node.
    • +
    • Plausible deniability: No participant can proof who created a specific message.
    • +
    • Asynchronicity: The usability of the protocol does not depend on the online status of any participant.
    • +
    +

    Omemo is not intended to protect against the following use cases:

    +
      +
    • An attacker has access to your device.
    • +
    • You lost your device and an attacker can read messages on your notification screen.
    • +
    • Any kind of denial-of-service attack.
    • +
    • tbc
    • +
    + +

    The OMEMO protocol protects against passive and active attackers which are able to read, modify, replay, delay and delete messages.

    +

    tbc

    +
    From 834bf3fd875cbe4ef0b03226210c4766f4e57dab Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 15:56:42 +0100 Subject: [PATCH 24/49] More consistent use of Double Ratchet encryption scheme vs protocol vs algorithm --- xep-0384.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 80662b06..05e0ea11 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -93,10 +93,10 @@ external complexity. The wire format issues were resolved with &xep0373;.

    - This XEP defines a protocol that leverages the Double Ratchet Algorithm to provide + This XEP defines a protocol that leverages the Double Ratchet encryption scheme to provide multi-end to multi-end encryption, allowing messages to be synchronized securely across multiple clients, even if some of them are offline. - The Double Ratched protocol is based on work by Trevor Perrin + The Double Ratchet encryption scheme is based on work by Trevor Perrin and Moxie Marlinspike and was first published as the Axolotl protocol. The specification for the protocol is available in the public domain.

    @@ -119,7 +119,7 @@

    As the encrypted payload is common to all recipients, it only has to be included once, reducing overhead. Furthermore, the transparent handling by the - double ratchet protocol of messages that were lost or received out of order, as well + Double Ratchet encryption scheme of messages that were lost or received out of order, as well as those sent while the recipient was offline, is maintained by this protocol. As a result, in combination with &xep0280; and &xep0313;, the desired property of inter-client history synchronization is achieved. @@ -178,7 +178,7 @@

    - This protocol uses the DoubleRatchet encryption mechanism in conjunction with the X3DH key exchange. The following section provides detailed technical information about the protocol that should be sufficient to build a compatible OMEMO implementation. Readers who do not intend to build an OMEMO-compatible library can safely skip this section, relevant details are repeated where needed. + This protocol uses the Double Ratchet encryption scheme in conjunction with the X3DH key exchange. The following section provides detailed technical information about the protocol that should be sufficient to build an implementation of the OMEMO Double Ratchet. Readers who do not intend to build an OMEMO-compatible library can safely skip this section, relevant details are repeated where needed.

    @@ -198,16 +198,16 @@
    XEdDSA
    To reduce the amount of bytes that have to be transferred, the key exchange uses XEdDSA on curves X25519/Ed25519 (aka XEd25519) to derive signing keys from encryption keys.

    - The key exchange is done just-in-time when sending the first message to a device. Thus, each key exchange message always also contains encrypted content as produced by the double ratchet algorithm below. + The key exchange is done just-in-time when sending the first message to a device. Thus, each key exchange message always also contains encrypted content as produced by the Double Ratchet encryption scheme below.

    NOTE: OMEMOMessage.proto, OMEMOAuthenticatedMessage.proto and OMEMOKeyExchange.proto refer to the protobuf structures as defined here.

    - The DoubleRatchet protocol is specified here and placed under the public domain. OMEMO uses this protocol with the following parameters/settings: + The Double Ratchet encryption scheme is specified here and placed under the public domain. OMEMO uses this protocol with the following parameters/settings:

    -
    ratchet initialization
    The double ratchet is initialized using the shared secret, ad and public keys as yielded by the X3DH key exchange, as explained in the double ratchet specification.
    +
    ratchet initialization
    The Double Ratchet is initialized using the shared secret, ad and public keys as yielded by the X3DH key exchange, as explained in the Double Ratchet specification.
    MAX_SKIP
    It is RECOMMENDED to keep around 1000 skipped message keys.
    deletion policy for skipped message keys
    Skipped message keys MUST be stored until MAX_SKIP message keys are stored. At that point, keys are discarded on a LRU basis to make space for new message keys. Implementations SHOULD not keep skipped message keys around forever, but discard old keys on a different implementation-defined policy. It is RECOMMENDED to base this policy on deterministic events rather than time.
    authentication tag truncation
    Authentication tags are truncated to 16 bytes/128 bits.
    @@ -245,7 +245,7 @@

    1. Generate 16 bytes of cryptographically secure random data, called key in the remainder of this algorithm.
    2. -
    3. Encrypt this key using the double ratchet as specified above, once for each intended recipient. This yields one OMEMOKeyExchange or OMEMOAuthenticatedMessage per recipient device.
    4. +
    5. Encrypt this key using the Double Ratchet as specified above, once for each intended recipient. This yields one OMEMOKeyExchange or OMEMOAuthenticatedMessage per recipient device.
    6. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
    7. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
    8. Encrypt the plaintext using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
    9. @@ -257,7 +257,7 @@ The contents are decrypted by reversing the encryption steps.

        -
      1. Decrypt the 16 bytes key from the OMEMOKeyExchange or OMEMOAuthenticatedMessage, encrypted using the double ratchet belonging to this device.
      2. +
      3. Decrypt the 16 bytes key from the OMEMOKeyExchange or OMEMOAuthenticatedMessage, encrypted using the Double Ratchet belonging to this device.
      4. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
      5. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
      6. Verify the HMAC-SHA-256 using the authentication key derived in the previous step and the ciphertext.
      7. @@ -492,7 +492,7 @@

        Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

        Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

        As there are no explicit error messages in this protocol, if a client does receive a OMEMOKeyExchange using an invalid PreKey, they SHOULD respond with a normal OMEMO encrypted message with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

        -

        If a OMEMOKeyExchange is received as part of a &xep0313; catch-up and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after MAM catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

        +

        If a OMEMOKeyExchange is received as part of a message catch-up mechanism (like &xep0313;) and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after the catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

        As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

        When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

        When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

        @@ -504,7 +504,7 @@

        Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

        When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user. TODO: consistent color foo

        -

        While it is RECOMMENDED that clients postpone private key deletion until after MAM catch-up and this standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

        +

        While it is RECOMMENDED that clients postpone private key deletion until after message catch-up, the standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, so clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

        This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

        From f17f86418c8b3d7af3ddfb9ef331efe586275fbe Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 16:02:09 +0100 Subject: [PATCH 25/49] XEP-0384: define group chats --- xep-0384.xml | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index 05e0ea11..536a2448 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -29,6 +29,32 @@ andy@strb.org andy@strb.org + + Daniel + Gultsch + daniel@gultsch.de + daniel@gultsch.de + + + Tim + Henkes + + + Klaus + Herberth + klaus@jsxc.org + + + Paul + Schaub + vanitasvitae@fsfe.org + + + Marvin + Wißfeld + jabber@larma.de + xmpp@larma.de + 0.3.0 2018-07-31 @@ -465,7 +491,7 @@ BASE64ENCODED... - + BASE64ENCODED... BASE64ENCODED... @@ -487,6 +513,47 @@ After either the OMEMOKeyExchange or the OMEMOAuthenticatedMessage is decrypted, the content is decrypted as described in the section about Message Decryption.

        + +

        Note: OMEMO encrypted group chats are currently specified to work with &xep0045;. This XEP might be updated in the future to also specify the usage in &xep0369;.

        +

        A Multi-User Chat room that supports OMEMO MUST be configured non-anonymous and SHOULD be configured members-only.

        +

        A participant wanting to send a message to a group chat MUST first retrieve the members list and then fetch the device list for each member (via pubsub and to their real JIDs) and then subsequently fetch all active bundles.

        + +

        On join a participant MUST request the member list, the admin list and the owner list as described in XEP-0045 §9.5, XEP-0045 §10.8, and XEP-0045 §10.5 respectively. Those three lists MUST be combined as the recipients of OMEMO encrypted messages. Once joined a participant MUST keep track of affiliation changes that occur in the room. This is both for removals (users getting banned or have their affiliation set to none) and users becoming members, admins or owners.

        +
        + +

        Before sending a message a participant SHOULD explicitly fetch device lists for all other participant if the list isn’t already cached..

        + + + + + + + + + + +]]> + + + + + + + + + + + + + + +]]> +
        + + +

        Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

        From 98c541956aa6bd1f3b8494fdb8c0237df60b655b Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 16:19:16 +0100 Subject: [PATCH 26/49] The HMAC has to be encrypted for each device using the Double Ratchet --- xep-0384.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 536a2448..8948c5fb 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -271,11 +271,11 @@

        1. Generate 16 bytes of cryptographically secure random data, called key in the remainder of this algorithm.
        2. -
        3. Encrypt this key using the Double Ratchet as specified above, once for each intended recipient. This yields one OMEMOKeyExchange or OMEMOAuthenticatedMessage per recipient device.
        4. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
        5. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
        6. Encrypt the plaintext using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
        7. Calculate the HMAC-SHA-256 using the authentication key and the ciphertext from the previous steps.
        8. +
        9. Concatenate the key and the HMAC, encrypt them using the Double Ratchet as specified above, once for each intended recipient. This yields one OMEMOKeyExchange or OMEMOAuthenticatedMessage per recipient device.
        @@ -283,7 +283,7 @@ The contents are decrypted by reversing the encryption steps.

          -
        1. Decrypt the 16 bytes key from the OMEMOKeyExchange or OMEMOAuthenticatedMessage, encrypted using the Double Ratchet belonging to this device.
        2. +
        3. Decrypt the key and HMAC from the OMEMOKeyExchange or OMEMOAuthenticatedMessage, encrypted using the Double Ratchet belonging to this device.
        4. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
        5. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
        6. Verify the HMAC-SHA-256 using the authentication key derived in the previous step and the ciphertext.
        7. From a4e6f0a8a302cec472dd9514d1a2ccfa85bfdd8e Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 16:20:59 +0100 Subject: [PATCH 27/49] Flipped jid and email to satisfy the DTD validation, added own email --- xep-0384.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 8948c5fb..c6012a7d 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -32,12 +32,13 @@ Daniel Gultsch - daniel@gultsch.de daniel@gultsch.de + daniel@gultsch.de Tim Henkes + me@syndace.dev Klaus @@ -52,8 +53,8 @@ Marvin Wißfeld - jabber@larma.de xmpp@larma.de + jabber@larma.de 0.3.0 From 27b2dd2bd43891688d47903c7c4075b472cbca14 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 16:26:25 +0100 Subject: [PATCH 28/49] XEP-0384: group chat message sending --- xep-0384.xml | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index c6012a7d..3cd4c6ba 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -515,7 +515,7 @@

          -

          Note: OMEMO encrypted group chats are currently specified to work with &xep0045;. This XEP might be updated in the future to also specify the usage in &xep0369;.

          +

          Note: OMEMO encrypted group chats are currently specified to work with &xep0045;. This XEP might be updated in the future to specify the usage of OMEMO in conjunction with &xep0369;.

          A Multi-User Chat room that supports OMEMO MUST be configured non-anonymous and SHOULD be configured members-only.

          A participant wanting to send a message to a group chat MUST first retrieve the members list and then fetch the device list for each member (via pubsub and to their real JIDs) and then subsequently fetch all active bundles.

          @@ -533,9 +533,8 @@ - -]]> - ]]> + @@ -549,10 +548,34 @@ - -]]> +]]> +

          Sending a message to a group chat is similiar to sending a message in a 1:1 conversation. Instead of the <header> element having two <keys> elements (one for the recipient and one for other devices of the sender) it will contain multiple <keys> elements. One for each participant of the room; including, again, other devices of the sender.

          + + +
          + + BASE64ENCODED... + + + BASE64ENCODED... + + + BASE64ENCODED... + +
          + + -- MESSAGE-KEY-ENCRYPTED CONTENT ELEMENT -- + +
          + + +]]>
          From dd4f34ee1af760df8154fb8e1d275b5836ab1dd7 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 16:49:40 +0100 Subject: [PATCH 29/49] Business rules about broken session healing --- xep-0384.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index 3cd4c6ba..90095788 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -446,6 +446,7 @@ For this reason OMEMO defines its own SCE profile.

          +

          An OMEMO SCE &content; element

          @@ -582,7 +583,7 @@

          Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

          Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

          -

          As there are no explicit error messages in this protocol, if a client does receive a OMEMOKeyExchange using an invalid PreKey, they SHOULD respond with a normal OMEMO encrypted message with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session.

          +

          There are various reasons why decryption of an OMEMOKeyExchange or an OMEMOAuthenticatedMessage could fail. One reason is if the message was received twice and already decrypted once, in this case the client MUST ignore the decryption failure and not show any warnings/errors. In all other cases of decryption failure, clients SHOULD respond by forcibly doing a new key exchange and sending a new OMEMOKeyExchange with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session. This does NOT apply to the actual SCE content. If decrypting the SCE content fails, e.g. because the HMAC does not verify, this is not a reason to forcibly initiate a new key exchange.

          If a OMEMOKeyExchange is received as part of a message catch-up mechanism (like &xep0313;) and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after the catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

          As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

          When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

          From ccaff4b18282e8e464120244ce0da9ba923916fc Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 16:51:52 +0100 Subject: [PATCH 30/49] consistent casing of device id --- xep-0384.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 90095788..f6e9a939 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -322,7 +322,7 @@

          In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devicelist PEP node.

          It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:devices’ node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

          The access model can be changed efficiently by using publish-options.

          - @@ -347,7 +347,7 @@ ]]>

          NOTE: as per XEP-0060 §12.20, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.

          -

          This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device ID is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

          +

          This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device id is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

          Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

          @@ -508,7 +508,7 @@
          -

          When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device ID. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

          +

          When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device id. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

          If this is the case, a new session is built from this received element. The client MUST then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST eventually delete the private key belonging to the PreKey after use (this is subject to the business rules).

          If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. This is subject to TODO: recovering from broken sessions.

          @@ -581,7 +581,7 @@ -

          Before publishing a freshly generated Device ID for the first time, a device MUST check whether that Device ID already exists, and if so, generate a new one.

          +

          Before publishing a freshly generated device id for the first time, a device MUST check whether that device id already exists, and if so, generate a new one.

          Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

          There are various reasons why decryption of an OMEMOKeyExchange or an OMEMOAuthenticatedMessage could fail. One reason is if the message was received twice and already decrypted once, in this case the client MUST ignore the decryption failure and not show any warnings/errors. In all other cases of decryption failure, clients SHOULD respond by forcibly doing a new key exchange and sending a new OMEMOKeyExchange with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session. This does NOT apply to the actual SCE content. If decrypting the SCE content fails, e.g. because the HMAC does not verify, this is not a reason to forcibly initiate a new key exchange.

          If a OMEMOKeyExchange is received as part of a message catch-up mechanism (like &xep0313;) and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after the catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

          From 030329ecf4a92b44a271f5f4ac9c259e4c50cf7a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 17:15:54 +0100 Subject: [PATCH 31/49] XEP-0384: add version log --- xep-0384.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/xep-0384.xml b/xep-0384.xml index f6e9a939..68e422b9 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -56,6 +56,24 @@ xmpp@larma.de jabber@larma.de
          + + 0.4.0 + 2020-03-08 + dg + +
            +
          • Incorporate the double ratchet protocol specification.
          • +
          • Use one node to store all bundles. One item per bundle.
          • +
          • Recommend 'open' access model for both PEP nodes.
          • +
          • Specify OMEMO encryption for XEP-0045 Multi-User Chats.
          • +
          • Use XEP-0420: Stanza Content Encryption.
          • +
          • Use AES256/CBC to encrypt SCE payload.
          • +
          • Change namespace to 'urn:xmpp:omemo:1'
          • +
          • Use wrapping 'keys' element for key elements in 'header'.
          • +
          • Define threat model
          • +
          +
          +
          0.3.0 2018-07-31 From 2e28c9cc589d27b0b2bdc3fcb6c7984c4c744c5c Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 17:25:11 +0100 Subject: [PATCH 32/49] Handled a lot of TODOs in the XEP --- xep-0384.xml | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 68e422b9..b30096c8 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -194,31 +194,22 @@
        8. Any kind of denial-of-service attack.
        9. tbc
        10. +

          + Trust management is a difficult topic, which is out of scope of this document. +

          The OMEMO protocol protects against passive and active attackers which are able to read, modify, replay, delay and delete messages.

          tbc

          - -
          -
          Device
          A communication end point, i.e. a specific client instance
          -
          OMEMO element
          An <encrypted> element in the urn:xmpp:omemo:1 namespace.
          -
          MessageElement
          An OMEMO element that contains a chat message. Its <payload>, when decrypted, corresponds to a <message>'s <body>.
          -
          Bundle
          A collection of publicly accessible data that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
          -
          rid
          The device id of the intended recipient of the containing <key>
          -
          sid
          The device id of the sender of the containing OMEMO element
          - -
          -
          - -
          -
          IdentityKey
          Per-device public/private key pair used to authenticate communications
          -
          PreKey
          A Diffie-Hellman public key, published in bulk and ahead of time
          -
          OMEMOKeyExchange
          An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.
          -
          OMEMOAuthenticatedMessage
          An encrypted and authenticated message
          -
          -
          +
          +
          Device
          A communication end point, i.e. a specific client instance
          +
          OMEMO element
          An <encrypted> element in the urn:xmpp:omemo:1 namespace
          +
          Bundle
          A collection of publicly accessible data used by the X3DH key exchange that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
          +
          rid
          The device id of the intended recipient of the containing <key>
          +
          sid
          The device id of the sender of the containing OMEMO element
          +
          @@ -234,7 +225,7 @@
          curve
          X25519
          hash function
          SHA-256
          info string
          "OMEMO X3DH"
          -
          byte-encoding of the public keys
          the default as used by most crypto libraries TODO
          +
          byte-encoding of the public keys
          The little-endian encoding of the u-coordinate as specified here (this is the default way most crypto-libraries encode the public key).
          signed pre-key rotation period
          Signed pre-keys SHOULD be rotated periodically once a week to once a month. A faster or slower rotation period should not be required.
          time to keep the private key of the old signed pre-key after rotating it
          The private key of the old signed pre-key SHOULD be kept for another rotation period as defined above, to account for delayed messages using the old signed pre-key.
          number of pre-keys to provide in the bundle
          The bundle SHOULD always contain around 100 pre-keys.
          @@ -448,7 +439,7 @@

          A random pk entry is selected, and used to build an OMEMO session.

          -

          In order to signal (TODO: english?) a contact that you like to terminate a session, your +

          In order to signal a contact that you like to terminate a session, your device MUST send a <terminate> element to all intended recipient devices inside an encrypted stanza. A user or client MAY tag the element with a reason. If a device is receiving a stanza containing a <terminate> element, @@ -489,11 +480,8 @@

          The &content; element is encrypted as described in the section about Message Encryption. - The client MUST use fresh, randomly generated key AES-256 with. - The SCE &content; element is encrypted using this key (TODO)

          - The 32-byte AES key and the 32-byte HMAC are concatenated and the result of this concatenation is encrypted using the corresponding long-standing OMEMO session for each intended recipient device. Clients SHOULD only consider the devices on the 'urn:xmpp:omemo:1:devices' node of each recipient (i.e. including his own devices node, but excluding itself).

          @@ -528,7 +516,7 @@

          When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device id. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

          If this is the case, a new session is built from this received element. The client MUST then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST eventually delete the private key belonging to the PreKey after use (this is subject to the business rules).

          -

          If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. This is subject to TODO: recovering from broken sessions.

          +

          If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. Also refer to the section about revocering from broken sessions in the Business Rules.

          After either the OMEMOKeyExchange or the OMEMOAuthenticatedMessage is decrypted, the content is decrypted as described in the section about Message Decryption.

          @@ -608,12 +596,10 @@

          When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

          - -

          Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

          -

          When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user. TODO: consistent color foo

          +

          When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user. When displaying the fingerprint as a hex string, one way to make it easier to compare the fingerprint is to split the hex string into 8 substrings of 8 chars each, then coloring each 8-char group using &xep0392;. Lowercase letters are recommended when displaying the fingerprint as a hex string.

          While it is RECOMMENDED that clients postpone private key deletion until after message catch-up, the standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, so clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

          From 649e389bf4ee9c0f7f36dc2b5cfcbe0100a327a1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 17:26:22 +0100 Subject: [PATCH 33/49] XEP-0384: move label from bundle to devices --- xep-0384.xml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index b30096c8..f7e67028 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -330,16 +330,17 @@

          In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devicelist PEP node.

          It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:devices’ node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

          -

          The access model can be changed efficiently by using publish-options.

          +

          The access model can be changed efficiently by using publish-options.

          +

          The device element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle. It is RECOMMENDED to keep the length of the label under 53 characters.

          - + - + @@ -361,15 +362,13 @@

          Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

          A bundle is an element called 'bundle' in the 'urn:xmpp:omomo:1' namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

          -

          The bundle element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle.

          When publishing bundles a client MUST make sure that the 'urn:xmpp:omemo:1' node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

          - + BASE64ENCODED BASE64ENCODED BASE64ENCODED From 8ac3c35e98a5419262e160a9182074dbb2b5399e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 17:36:17 +0100 Subject: [PATCH 34/49] XEP-0384: thank chaosdorf and modify device event example --- xep-0384.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index f7e67028..01db3ac4 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -319,7 +319,7 @@ - + @@ -697,5 +697,6 @@ message OMEMOKeyExchange {

          Big thanks to Daniel Gultsch for mentoring me during the development of this protocol. Thanks to Thijs Alkemade and Cornelius Aschermann for talking through some of the finer points of the protocol with me. And lastly I would also like to thank Sam Whited, Holger Weiss, and Florian Schmaus for their input on the standard.

          +

          The authors would like to thank the Chaosdorf for hosting them during the development of version 0.4.0 of this specification.

          From 24d82799d38c64ac4041fed267cf2ff569f2f589 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 17:37:55 +0100 Subject: [PATCH 35/49] depend on xep-0060 --- xep-0384.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/xep-0384.xml b/xep-0384.xml index 01db3ac4..c520b4c1 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -18,6 +18,7 @@ Council XMPP Core + XEP-0060 XEP-0163 From 20e29ee94b2734db515250169b43d3d04ddaf8e6 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 17:45:14 +0100 Subject: [PATCH 36/49] Minor clarification --- xep-0384.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index c520b4c1..e115e33f 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -232,7 +232,7 @@
          number of pre-keys to provide in the bundle
          The bundle SHOULD always contain around 100 pre-keys.
          minimum number of pre-keys to provide in the bundle
          The bundle MUST always contain at least 25 pre-keys.
          associated data
          The associated data is created by concatenating the identity keys of Alice and Bob: AD = Encode(IK_A) || Encode(IK_B)
          -
          XEdDSA
          To reduce the amount of bytes that have to be transferred, the key exchange uses XEdDSA on curves X25519/Ed25519 (aka XEd25519) to derive signing keys from encryption keys.
          +
          XEdDSA
          To reduce the amount of bytes that have to be transferred, the key exchange uses XEdDSA on curves X25519/Ed25519 (aka XEd25519) to build and verify signatures using encryption key pairs.

    The key exchange is done just-in-time when sending the first message to a device. Thus, each key exchange message always also contains encrypted content as produced by the Double Ratchet encryption scheme below. From 779af896e2f4e94670c837ac427b1c5c12cb4293 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 17:59:33 +0100 Subject: [PATCH 37/49] XEP-0384: server side requirments --- xep-0384.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xep-0384.xml b/xep-0384.xml index e115e33f..b709b101 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -596,6 +596,15 @@

    When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

    + +

    While OMEMO uses a Pubsub Service (&xep0060;) on the user’s account it has more requirments than those defined in &xep0163;. The requirements are:

    +
      +
    • The pubsub service MUST persist node items.
    • +
    • The pubsub service MUST support publishing options as defined XEP-0060 §7.1.5
    • +
    • The pubsub service MUST support 'max' as a value for the 'pubsub#persist_items' node configuration
    • +
    • The pubsub service SHOULD support the 'open' access model for node configuration and 'pubsub#access_model' as a publish option.
    • +
    +

    Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

    From 11af6f025272391bf33787cfe180dd69bec5ce5c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 18:03:14 +0100 Subject: [PATCH 38/49] fixed typos --- xep-0384.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index b709b101..66fd881d 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -600,8 +600,8 @@

    While OMEMO uses a Pubsub Service (&xep0060;) on the user’s account it has more requirments than those defined in &xep0163;. The requirements are:

    • The pubsub service MUST persist node items.
    • -
    • The pubsub service MUST support publishing options as defined XEP-0060 §7.1.5
    • -
    • The pubsub service MUST support 'max' as a value for the 'pubsub#persist_items' node configuration
    • +
    • The pubsub service MUST support publishing options as defined in XEP-0060 §7.1.5.
    • +
    • The pubsub service MUST support 'max' as a value for the 'pubsub#persist_items' node configuration.
    • The pubsub service SHOULD support the 'open' access model for node configuration and 'pubsub#access_model' as a publish option.
    From c7a29c7462dea0f9d9c3f3cef29f5e64cbbe5129 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 8 Mar 2020 17:27:47 +0100 Subject: [PATCH 39/49] XEP-0384: update XML schema --- xep-0384.xml | 168 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 109 insertions(+), 59 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 66fd881d..39c473c1 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -370,14 +370,14 @@ - BASE64ENCODED - BASE64ENCODED - BASE64ENCODED + b64/encoded/data + b64/encoded/data + b64/encoded/data - BASE64ENCODED - BASE64ENCODED + b64/encoded/data + b64/encoded/data - BASE64ENCODED + b64/encoded/data @@ -489,7 +489,7 @@

    An OMEMO encrypted message is specified to include an the <encrypted> element in the 'urn:xmpp:omomo:1' namespace. It always contains two child nodes, the <header> and the &payload; element. The <header> element has an attribute named 'sid' referencing the device id of the sending device and contains one or multiple <keys> elements, each with an attribute 'jid' of one recipient JID as well as one or multiple <key> elements. - A <key> element has an attribute named 'rid' referencing the device id of the recipient device. The ciphertext that is the key and HMAC encrypted using the long-standing OMEMO session for that recipient device is encoded using base64 and places as text content into the <key> element. + A <key> element has an attribute named 'rid' referencing the device id of the recipient device, and an attribute named 'kex' which defaults to 'false' and indicates if the enclosed encrypted message includes a key exchange. The ciphertext that is the key and HMAC encrypted using the long-standing OMEMO session for that recipient device is encoded using base64 and places as text content into the <key> element. The ciphertext that is the encrypted &content; element is encoded using base64 and placed as text content into the &payload; element.

    - BASE64ENCODED... + b64/encoded/data - BASE64ENCODED... - BASE64ENCODED... + b64/encoded/data + b64/encoded/data
    - -- MESSAGE-KEY-ENCRYPTED CONTENT ELEMENT -- + base64/encoded/message/key/encrypted/content/element @@ -567,17 +567,17 @@
    - BASE64ENCODED... + b64/encoded/data - BASE64ENCODED... + b64/encoded/data - BASE64ENCODED... + b64/encoded/data
    - -- MESSAGE-KEY-ENCRYPTED CONTENT ELEMENT -- + base64/encoded/message/key/encrypted/content/element
    @@ -627,57 +627,107 @@
    + + targetNamespace="urn:xmpp:omemo:1" + xmlns="urn:xmpp:omemo:1"> - - - - - - - - - - - + + + + + + + - - - - - - - - - - - + - - - - - - - - - - - - - - + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> From 5f1fb4822011e7acd932a7ed129956b41f609a18 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Sun, 8 Mar 2020 18:27:33 +0100 Subject: [PATCH 40/49] Implementation notes about deactivating OMEMO, switched to 32 byte keys --- xep-0384.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 39c473c1..d593aace 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -256,7 +256,7 @@
    1. Use HKDF-SHA-256 to generate 80 bytes of output from the message key by providing mk as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Message Key Material" as HKDF info.
    2. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
    3. -
    4. Encrypt the plaintext (which is a 16 bytes key as specified here) using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
    5. +
    6. Encrypt the plaintext (which is a 32 bytes key as specified here) using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
    7. Split the associated data as returned by CONCAT into the original ad and the OMEMOMessage.proto structure.
    8. Add the ciphertext to the OMEMOMessage.proto structure.
    9. Serialize the ad and the OMEMOMessage.proto structure into a parseable byte array by concatenating ad and the serialized protobuf structure.
    10. @@ -281,7 +281,7 @@ The contents are encrypted and authenticated using a combination of AES-256-CBC and HMAC-SHA-256.

        -
      1. Generate 16 bytes of cryptographically secure random data, called key in the remainder of this algorithm.
      2. +
      3. Generate 32 bytes of cryptographically secure random data, called key in the remainder of this algorithm.
      4. Use HKDF-SHA-256 to generate 80 bytes of output from the key by providing the key as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Payload" as HKDF info.
      5. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
      6. Encrypt the plaintext using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
      7. @@ -594,6 +594,7 @@

        As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

        When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

        When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

        +

        When the user of a client deactivates OMEMO for an account or globally, the client SHOULD delete the corresponding bundles and device ids from the PEP nodes. That way other clients should stop encrypting for that device.

        From d4f1790a7e3b068a3b82f45e3b5324c3d6a14e8e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 23:24:34 +0100 Subject: [PATCH 41/49] s/devicelist node/devices node/ + unicode chars --- xep-0384.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index d593aace..bff0202e 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -309,7 +309,7 @@

        -

        In order to determine whether a given contact has devices that support OMEMO, the devicelist node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:1:devices' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the devicelist.

        +

        In order to determine whether a given contact has devices that support OMEMO, the devices node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:1:devices' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the device list.

        -

        In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devicelist PEP node.

        +

        In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devices PEP node.

        It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:devices’ node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

        The access model can be changed efficiently by using publish-options.

        -

        The device element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle. It is RECOMMENDED to keep the length of the label under 53 characters.

        +

        The device element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle. It is RECOMMENDED to keep the length of the label under 53 Unicode code points.

        From c55d88b45e357fa92e46dea06d61999a7cdcf7f3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 8 Mar 2020 23:27:20 +0100 Subject: [PATCH 42/49] fixed typos --- xep-0384.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index bff0202e..041360f8 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -362,8 +362,8 @@

        Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

        -

        A bundle is an element called 'bundle' in the 'urn:xmpp:omomo:1' namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

        -

        When publishing bundles a client MUST make sure that the 'urn:xmpp:omemo:1' node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

        +

        A bundle is an element called 'bundle' in the 'urn:xmpp:omemo:1' namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

        +

        When publishing bundles a client MUST make sure that the 'urn:xmpp:omemo:1:bundles' node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

        @@ -487,7 +487,7 @@

        - An OMEMO encrypted message is specified to include an the <encrypted> element in the 'urn:xmpp:omomo:1' namespace. It always contains two child nodes, the <header> and the &payload; element. + An OMEMO encrypted message is specified to include an the <encrypted> element in the 'urn:xmpp:omemo:1' namespace. It always contains two child nodes, the <header> and the &payload; element. The <header> element has an attribute named 'sid' referencing the device id of the sending device and contains one or multiple <keys> elements, each with an attribute 'jid' of one recipient JID as well as one or multiple <key> elements. A <key> element has an attribute named 'rid' referencing the device id of the recipient device, and an attribute named 'kex' which defaults to 'false' and indicates if the enclosed encrypted message includes a key exchange. The ciphertext that is the key and HMAC encrypted using the long-standing OMEMO session for that recipient device is encoded using base64 and places as text content into the <key> element. The ciphertext that is the encrypted &content; element is encoded using base64 and placed as text content into the &payload; element. From 45b6821385852b99cc7e803e0620c4007f80e212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Mon, 9 Mar 2020 00:18:10 +0100 Subject: [PATCH 43/49] xep-0384: use entities for NSs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- xep-0384.xml | 57 +++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 041360f8..e6a980b8 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -3,6 +3,9 @@ + + + %ents; ]> @@ -69,7 +72,7 @@

      8. Specify OMEMO encryption for XEP-0045 Multi-User Chats.
      9. Use XEP-0420: Stanza Content Encryption.
      10. Use AES256/CBC to encrypt SCE payload.
      11. -
      12. Change namespace to 'urn:xmpp:omemo:1'
      13. +
      14. Change namespace to &ns;
      15. Use wrapping 'keys' element for key elements in 'header'.
      16. Define threat model
      17. @@ -206,7 +209,7 @@
        Device
        A communication end point, i.e. a specific client instance
        -
        OMEMO element
        An <encrypted> element in the urn:xmpp:omemo:1 namespace
        +
        OMEMO element
        An <encrypted> element in the &ns; namespace
        Bundle
        A collection of publicly accessible data used by the X3DH key exchange that can be used to build a session with a device, namely its public IdentityKey, a signed PreKey with corresponding signature, and a list of (single use) PreKeys.
        rid
        The device id of the intended recipient of the containing <key>
        sid
        The device id of the sender of the containing OMEMO element
        @@ -309,16 +312,16 @@

        -

        In order to determine whether a given contact has devices that support OMEMO, the devices node in PEP is consulted. Devices MUST subscribe to 'urn:xmpp:omemo:1:devices' via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the device list.

        +

        In order to determine whether a given contact has devices that support OMEMO, the devices node in PEP is consulted. Devices MUST subscribe to &nsdevices; via PEP, so that they are informed whenever their contacts add a new device. They MUST cache the most up-to-date version of the device list.

        - + - + @@ -330,15 +333,15 @@

        In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devices PEP node.

        -

        It is RECOMMENDED to set the access model of the ‘urn:xmpp:omemo:1:devices’ node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

        +

        It is RECOMMENDED to set the access model of the &nsdevices; node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

        The access model can be changed efficiently by using publish-options.

        The device element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle. It is RECOMMENDED to keep the length of the label under 53 Unicode code points.

        - + - + @@ -361,15 +364,15 @@

        This step presents the risk of introducing a race condition: Two devices might simultaneously try to announce themselves, unaware of the other's existence. The second device would overwrite the first one. To mitigate this, devices MUST check that their own device id is contained in the list whenever they receive a PEP update from their own account. If they have been removed, they MUST reannounce themselves.

        -

        Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called ‘urn:xmpp:omemo:1:bundles’. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

        -

        A bundle is an element called 'bundle' in the 'urn:xmpp:omemo:1' namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

        -

        When publishing bundles a client MUST make sure that the 'urn:xmpp:omemo:1:bundles' node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

        +

        Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called &nsbundles;. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

        +

        A bundle is an element called 'bundle' in the &ns; namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

        +

        When publishing bundles a client MUST make sure that the &nsbundles; node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

        - + - + b64/encoded/data b64/encoded/data b64/encoded/data @@ -394,14 +397,14 @@ ]]> -

        As with the 'urn:xmpp:omemo:1:devices' node it is RECOMMENDED to set the access model of the 'urn:xmpp:omemo:1:bundles' to open. Clients that do not adhere to the recommended access model (and for example want to stick to the default 'presence') are highly encouraged to configure the same access model for 'urn:xmpp:omemo:1:devices' and 'urn:xmpp:omemo:1:bundles', otherwise remote entities might end up in a situation where they are able to retrieve the device list but not the bundle or vice versa.

        +

        As with the &nsdevices; node it is RECOMMENDED to set the access model of the &nsbundles; to open. Clients that do not adhere to the recommended access model (and for example want to stick to the default 'presence') are highly encouraged to configure the same access model for &nsdevices; and &nsbundles; otherwise remote entities might end up in a situation where they are able to retrieve the device list but not the bundle or vice versa.

        The access model can be changed efficiently by using publish-options.

        - + - + @@ -431,7 +434,7 @@ to='juliet@capulet.lit' id='fetch1'> - + @@ -482,7 +485,7 @@ The &content; element is encrypted as described in the section about Message Encryption.

        - Clients SHOULD only consider the devices on the 'urn:xmpp:omemo:1:devices' node of each recipient (i.e. including his own devices node, but excluding itself). + Clients SHOULD only consider the devices on the &nsdevices; node of each recipient (i.e. including his own devices node, but excluding itself).

        @@ -494,7 +497,7 @@

        - +
        b64/encoded/data @@ -533,25 +536,25 @@ - + - + ]]> - + - + @@ -564,7 +567,7 @@ from='juliet@capulet.lit/balcony' to='secret-room@conference.capulet.lit' type='groupchat'> - +
        b64/encoded/data @@ -619,7 +622,7 @@

        This specification defines the following XMPP namespaces:

          -
        • urn:xmpp:omemo:1
        • +
        • &ns;
        @@ -630,8 +633,8 @@ + targetNamespace="]]>&ns;&ns; From ff176e720c612464313f57aa6561d14614463fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Mon, 9 Mar 2020 00:23:09 +0100 Subject: [PATCH 44/49] xep-0384: fix typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- xep-0384.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index e6a980b8..709112e9 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -181,14 +181,14 @@ -

        It is a result of XMPPs federated nature that a message may pass more than just one server. Therefore it is in the users interest to secure their communication from any intermediate host. End-to-end encryption is an efficient way to protect any data exchanged between sender and receiver against passive and active attackers such as servers and network nodes.

        +

        It is a result of XMPP's federated nature that a message may pass more than just one server. Therefore it is in the users' interest to secure their communication from any intermediate host. End-to-end encryption is an efficient way to protect any data exchanged between sender and receiver against passive and active attackers such as servers and network nodes.

        OMEMO is an end-to-end encryption protocol based on the Double Ratchet specified in section Double Ratchet. It provides the following guarantees under the threat model described in the next section:

        • Confidentiality: Nobody else except sender and receiver is able to read the content of a message.
        • Perfect forward secrecy: A compromised long-term key does not compromise any previous message exchange.
        • Authentication: Every peer is able to authenticate the sender or receiver of a message, even if the details of the authentication process is out-of-scope for this specification.
        • Immutability: Every peer can ensure that a message was not changed by any intermediate node.
        • -
        • Plausible deniability: No participant can proof who created a specific message.
        • +
        • Plausible deniability: No participant can prove who created a specific message.
        • Asynchronicity: The usability of the protocol does not depend on the online status of any participant.

        Omemo is not intended to protect against the following use cases:

        @@ -276,7 +276,7 @@

        1. The first content is encrypted for a new recipient. This results in an X3DH header and a OMEMOAuthenticatedMessage.proto structure. Both are packed into an OMEMOKeyExchange.proto structure. The X3DH header is stored for following messages.
        2. -
        3. A second message is encrypted for the same recipient. This results in only a OMEMOAuthenticatedMessage.proto structure, as a new key exchange is not required. Together with the X3DH header that was stored in the previous step, an OMEMOKeyExchange.proto structure is constructed and sent to the recipient.
        4. +
        5. A second message is encrypted for the same recipient. This results in only an OMEMOAuthenticatedMessage.proto structure, as a new key exchange is not required. Together with the X3DH header that was stored in the previous step, an OMEMOKeyExchange.proto structure is constructed and sent to the recipient.
        @@ -332,7 +332,7 @@ -

        In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devices PEP node.

        +

        In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devices PEP node.

        It is RECOMMENDED to set the access model of the &nsdevices; node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

        The access model can be changed efficiently by using publish-options.

        The device element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle. It is RECOMMENDED to keep the length of the label under 53 Unicode code points.

        @@ -485,7 +485,7 @@ The &content; element is encrypted as described in the section about Message Encryption.

        - Clients SHOULD only consider the devices on the &nsdevices; node of each recipient (i.e. including his own devices node, but excluding itself). + Clients SHOULD only consider the devices on the &nsdevices; node of each recipient (i.e. including their own devices node, but excluding itself).

        @@ -518,8 +518,8 @@

        When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device id. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

        -

        If this is the case, a new session is built from this received element. The client MUST then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST eventually delete the private key belonging to the PreKey after use (this is subject to the business rules).

        -

        If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. Also refer to the section about revocering from broken sessions in the Business Rules.

        +

        If this is the case, a new session is built from this received element. The client MUST then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST eventually delete the private key belonging to the PreKey after use (this is subject to the Business rules).

        +

        If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. Also refer to the section about recovering from broken sessions in the Business Rules.

        After either the OMEMOKeyExchange or the OMEMOAuthenticatedMessage is decrypted, the content is decrypted as described in the section about Message Decryption.

        @@ -591,11 +591,11 @@

        Before publishing a freshly generated device id for the first time, a device MUST check whether that device id already exists, and if so, generate a new one.

        -

        Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

        +

        Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

        There are various reasons why decryption of an OMEMOKeyExchange or an OMEMOAuthenticatedMessage could fail. One reason is if the message was received twice and already decrypted once, in this case the client MUST ignore the decryption failure and not show any warnings/errors. In all other cases of decryption failure, clients SHOULD respond by forcibly doing a new key exchange and sending a new OMEMOKeyExchange with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session. This does NOT apply to the actual SCE content. If decrypting the SCE content fails, e.g. because the HMAC does not verify, this is not a reason to forcibly initiate a new key exchange.

        If a OMEMOKeyExchange is received as part of a message catch-up mechanism (like &xep0313;) and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after the catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

        As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

        -

        When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where they SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

        +

        When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where the SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

        When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

        When the user of a client deactivates OMEMO for an account or globally, the client SHOULD delete the corresponding bundles and device ids from the PEP nodes. That way other clients should stop encrypting for that device.

        @@ -616,7 +616,7 @@

        While it is RECOMMENDED that clients postpone private key deletion until after message catch-up, the standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, so clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

        -

        This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

        +

        This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

        From 22a6085cac312f55109d5ebefb50d8ffba64cb1e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 9 Mar 2020 08:29:15 +0100 Subject: [PATCH 45/49] XEP-0384: add sce as dependency --- xep-0384.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/xep-0384.xml b/xep-0384.xml index 709112e9..5b893b1f 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -23,6 +23,7 @@ XMPP Core XEP-0060 XEP-0163 + XEP-0420 From 9ecaa1ee733d4d3ce222680005462bab828fd45d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 9 Mar 2020 08:31:43 +0100 Subject: [PATCH 46/49] XEP-0384: rephrase 'session termination' to 'opting-out' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sessions are device-to-device relationships. When we talk about 'opting-out' we want to communicate a _preference_ for an entire account not just on specific device-to-device relationship. The actual double ratchet sessions will also remain intact. So it is not reversing what ever we did in 'Starting a session' but just switching back from omemo to plain. (When we currently do that manuelly we also wouldn’t touch the actual underlying sessions) I would like to note at this point that we don’t have a way of 'opting-in' either. Nowhere do we say that a client MUST use OMEMO if they discover that the other side has bundles. Therefor I find it strange that the opt-out was a MUST and i weakend it to SHOULD. (we don’t say that a client SHOULD start omemo when it discovers support either so I even find a SHOULD too strong) --- xep-0384.xml | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 5b893b1f..d6dde962 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -442,15 +442,6 @@ ]]>

        A random pk entry is selected, and used to build an OMEMO session.

        - -

        In order to signal a contact that you like to terminate a session, your - device MUST send a <terminate> element to all intended recipient devices - inside an encrypted stanza. A user or client MAY tag the element with a - reason. If a device is receiving a stanza containing a <terminate> element, - it MUST show an information that the peer has ended the session. To prevent - that the user is accidentally sending plaintext messages, the client MUST - block all outgoing message until the user switched to plaintext.

        -

        In order to send a chat message, extension elements that are deemed sensible first have to be @@ -525,6 +516,31 @@ After either the OMEMOKeyExchange or the OMEMOAuthenticatedMessage is decrypted, the content is decrypted as described in the section about Message Decryption.

        + +

        An account can signal to a peer that it wants to stop communicating using + OMEMO encrypted messages and would like to proceed in plain text instead. To do + that any of that account’s devices sends an <opt-out/> element qualified + by the &ns; namespace to all intended recipient devices + inside an encrypted stanza. The element MAY contain a child element <reason>. + If a device is receiving an encrypted stanza containing an <opt-out/> element, + it SHOULD display the information, that the peer would like to receive plain text messages. + To prevent that the user is accidentally sending plaintext messages, the client MUST + block all outgoing message until the user has confirmed the switch to plaintext. + Any existing double ratchet sessions SHOULD remain intact. At any point any party MAY + revert their decision and go back to sending OMEMO encrypted messages again.

        + + + + + Sorry, but for compliance reasons I need a permanent, + server-side, record of our conversation. + + + + +]]> +

        Note: OMEMO encrypted group chats are currently specified to work with &xep0045;. This XEP might be updated in the future to specify the usage of OMEMO in conjunction with &xep0369;.

        A Multi-User Chat room that supports OMEMO MUST be configured non-anonymous and SHOULD be configured members-only.

        From 74577e9adc08b5f683e96a5e4c353888ac1ba04b Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Mon, 9 Mar 2020 17:34:13 +0100 Subject: [PATCH 47/49] Add vanitasvitae jid --- xep-0384.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index d6dde962..826bc69b 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -50,11 +50,7 @@ Herberth klaus@jsxc.org - - Paul - Schaub - vanitasvitae@fsfe.org - + &paulschaub; Marvin Wißfeld From 0ab5532af11bb6d533f794bc25f897207464c555 Mon Sep 17 00:00:00 2001 From: Tim Henkes Date: Mon, 9 Mar 2020 23:56:19 +0100 Subject: [PATCH 48/49] A lot of smaller improvements --- xep-0384.xml | 57 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/xep-0384.xml b/xep-0384.xml index 826bc69b..afb135f1 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -172,7 +172,7 @@

        While in the future a dedicated key server component could be used to distribute - key material for session creation, the current specification relies on PEP to publish + key material for session creation, the current specification relies on &xep0163; to publish and acquire key bundles.

        @@ -182,15 +182,15 @@

        OMEMO is an end-to-end encryption protocol based on the Double Ratchet specified in section Double Ratchet. It provides the following guarantees under the threat model described in the next section:

        • Confidentiality: Nobody else except sender and receiver is able to read the content of a message.
        • -
        • Perfect forward secrecy: A compromised long-term key does not compromise any previous message exchange.
        • +
        • Perfect forward secrecy: Compromised key material does not compromise previous or future message exchanges.
        • Authentication: Every peer is able to authenticate the sender or receiver of a message, even if the details of the authentication process is out-of-scope for this specification.
        • Immutability: Every peer can ensure that a message was not changed by any intermediate node.
        • Plausible deniability: No participant can prove who created a specific message.
        • Asynchronicity: The usability of the protocol does not depend on the online status of any participant.
        -

        Omemo is not intended to protect against the following use cases:

        +

        OMEMO is not intended to protect against the following use cases:

          -
        • An attacker has access to your device.
        • +
        • An attacker has permanent access to your device. Temporary access is covered by perfect forward secrecy.
        • You lost your device and an attacker can read messages on your notification screen.
        • Any kind of denial-of-service attack.
        • tbc
        • @@ -227,11 +227,11 @@
          hash function
          SHA-256
          info string
          "OMEMO X3DH"
          byte-encoding of the public keys
          The little-endian encoding of the u-coordinate as specified here (this is the default way most crypto-libraries encode the public key).
          -
          signed pre-key rotation period
          Signed pre-keys SHOULD be rotated periodically once a week to once a month. A faster or slower rotation period should not be required.
          -
          time to keep the private key of the old signed pre-key after rotating it
          The private key of the old signed pre-key SHOULD be kept for another rotation period as defined above, to account for delayed messages using the old signed pre-key.
          -
          number of pre-keys to provide in the bundle
          The bundle SHOULD always contain around 100 pre-keys.
          -
          minimum number of pre-keys to provide in the bundle
          The bundle MUST always contain at least 25 pre-keys.
          -
          associated data
          The associated data is created by concatenating the identity keys of Alice and Bob: AD = Encode(IK_A) || Encode(IK_B)
          +
          signed PreKey rotation period
          Signed PreKeys SHOULD be rotated periodically once a week to once a month. A faster or slower rotation period should not be required.
          +
          time to keep the private key of the old signed PreKey after rotating it
          The private key of the old signed PreKey SHOULD be kept for another rotation period as defined above, to account for delayed messages using the old signed PreKey.
          +
          number of PreKeys to provide in the bundle
          The bundle SHOULD always contain around 100 PreKeys.
          +
          minimum number of PreKeys to provide in the bundle
          The bundle MUST always contain at least 25 PreKeys.
          +
          associated data
          The associated data is created by concatenating the IdentityKeys of Alice and Bob: AD = Encode(IK_A) || Encode(IK_B)
          XEdDSA
          To reduce the amount of bytes that have to be transferred, the key exchange uses XEdDSA on curves X25519/Ed25519 (aka XEd25519) to build and verify signatures using encryption key pairs.

        @@ -246,7 +246,7 @@

        ratchet initialization
        The Double Ratchet is initialized using the shared secret, ad and public keys as yielded by the X3DH key exchange, as explained in the Double Ratchet specification.
        MAX_SKIP
        It is RECOMMENDED to keep around 1000 skipped message keys.
        -
        deletion policy for skipped message keys
        Skipped message keys MUST be stored until MAX_SKIP message keys are stored. At that point, keys are discarded on a LRU basis to make space for new message keys. Implementations SHOULD not keep skipped message keys around forever, but discard old keys on a different implementation-defined policy. It is RECOMMENDED to base this policy on deterministic events rather than time.
        +
        deletion policy for skipped message keys
        Skipped message keys MUST be stored until MAX_SKIP message keys are stored. At that point, keys are discarded on a FIFO basis to make space for new message keys. Implementations SHOULD not keep skipped message keys around forever, but discard old keys on a different implementation-defined policy. It is RECOMMENDED to base this policy on deterministic events rather than time.
        authentication tag truncation
        Authentication tags are truncated to 16 bytes/128 bits.
        CONCAT(ad, header)
        CONCAT(ad, header) = ad || OMEMOMessage.proto(header) NOTE: the OMEMOMessage.proto is initialized without the ciphertext, which is optional. NOTE: Implementations are not strictly required to return a parseable byte array here, as the unpacked/parsed data is required later in the protocol.
        KDF_RK(rk, dh_out)
        HKDF-SHA-256 using the rk as HKDF salt, dh_out as HKDF input material and "OMEMO Root Chain" as HKDF info.
        @@ -256,7 +256,7 @@
        1. Use HKDF-SHA-256 to generate 80 bytes of output from the message key by providing mk as HKDF input, 256 zero-bits as HKDF salt and "OMEMO Message Key Material" as HKDF info.
        2. Divide the HKDF output into a 32-byte encryption key, a 32-byte authentication key and a 16 byte IV.
        3. -
        4. Encrypt the plaintext (which is a 32 bytes key as specified here) using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
        5. +
        6. Encrypt the plaintext (which consists of a 32 bytes key and a 32 bytes HMAC as specified here) using AES-256-CBC with PKCS#7 padding, using the encryption key and IV derived in the previous step.
        7. Split the associated data as returned by CONCAT into the original ad and the OMEMOMessage.proto structure.
        8. Add the ciphertext to the OMEMOMessage.proto structure.
        9. Serialize the ad and the OMEMOMessage.proto structure into a parseable byte array by concatenating ad and the serialized protobuf structure.
        10. @@ -330,7 +330,7 @@

          In order for other devices to be able to initiate a session with a given device, it first has to announce itself by adding its device id to the devices PEP node.

          -

          It is RECOMMENDED to set the access model of the &nsdevices; node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

          +

          It is REQUIRED to set the access model of the &nsdevices; node to ‘open’ to give entities without presence subscription read access to the devices and allow them to establish an OMEMO session. Not having presence subscription is a common occurrence on the first few messages between two contacts and can also happen fairly frequently in group chats as not every participant had prior communication with every other participant.

          The access model can be changed efficiently by using publish-options.

          The device element MAY contain an attribute called label, which is a user defined string describing the device that published that bundle. It is RECOMMENDED to keep the length of the label under 53 Unicode code points.

          Furthermore, a device MUST publish its IdentityKey, a signed PreKey, and a list of PreKeys. This tuple is called a bundle and is provided by OMEMO libraries. Bundles are maintained as multiple items in a PEP node called &nsbundles;. Each bundle MUST be stored in a seperate item. The item id MUST be set to the device id.

          -

          A bundle is an element called 'bundle' in the &ns; namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the identity key as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element.

          +

          A bundle is an element called 'bundle' in the &ns; namespace. It has a child element called ‘spk’ that contains the public part of the signed PreKey as base64 encoded data, a child element called ‘spks’ that contains the signed PreKey signature as base64 encoded data and a child element called ‘ik’ that contains the public part of the IdentityKey as base64 encoded data. PreKeys are multiple elements called ‘pk’ that each contain the public part of one PreKey as base64 encoded data. PreKeys are wrapped in an element called ‘prekeys’ which is a child of the bundle element. The ‘spk’ and the ‘pk’s are tagged with an ‘id’-attribute which is a positive integer that uniquely identifies the keys. The ‘spk’ and the ‘pk’s are considered separate, which means that an ‘spk’ can have the same ‘id’ as a ‘pk’. These ids are used to save bandwidth during key exchanges, which refer to the keys using their id instead of their full public parts.

          When publishing bundles a client MUST make sure that the &nsbundles; node is configured to store multiple items. This is not the default with &xep0163;. If the node doesn’t exist yet it can be configured on the fly by using publish-options as described in XEP-0060 §7.1.5. The value for 'pubsub#max_items' in publish_options MUST be set to 'max'. If the node did exist and was configured differently the bundle publication will fail. Clients MUST then reconfigure the node as described in XEP-0060 §8.2.

          @@ -394,7 +394,7 @@ ]]> -

          As with the &nsdevices; node it is RECOMMENDED to set the access model of the &nsbundles; to open. Clients that do not adhere to the recommended access model (and for example want to stick to the default 'presence') are highly encouraged to configure the same access model for &nsdevices; and &nsbundles; otherwise remote entities might end up in a situation where they are able to retrieve the device list but not the bundle or vice versa.

          +

          As with the &nsdevices; node it is REQUIRED to set the access model of the &nsbundles; to open.

          The access model can be changed efficiently by using publish-options.

          @@ -440,7 +440,7 @@

          - In order to send a chat message, extension elements that are deemed sensible first have to be + In order to send a message, extension elements that are deemed sensible first have to be encrypted. For this purpose, extensions that are only intended to be accessible to the recipient are placed inside a &xep0420; &content; element, which is then encrypted using a message key. For this reason OMEMO defines its own SCE profile. @@ -473,14 +473,14 @@ The &content; element is encrypted as described in the section about Message Encryption.

          - Clients SHOULD only consider the devices on the &nsdevices; node of each recipient (i.e. including their own devices node, but excluding itself). + Clients MUST only consider the devices on the &nsdevices; node of each recipient (i.e. including their own devices node, but excluding itself).

          - An OMEMO encrypted message is specified to include an the <encrypted> element in the 'urn:xmpp:omemo:1' namespace. It always contains two child nodes, the <header> and the &payload; element. - The <header> element has an attribute named 'sid' referencing the device id of the sending device and contains one or multiple <keys> elements, each with an attribute 'jid' of one recipient JID as well as one or multiple <key> elements. - A <key> element has an attribute named 'rid' referencing the device id of the recipient device, and an attribute named 'kex' which defaults to 'false' and indicates if the enclosed encrypted message includes a key exchange. The ciphertext that is the key and HMAC encrypted using the long-standing OMEMO session for that recipient device is encoded using base64 and places as text content into the <key> element. + An OMEMO encrypted message is specified to include an <encrypted> element in the 'urn:xmpp:omemo:1' namespace. It always contains two child nodes, the <header> and the &payload; element. + The <header> element has an attribute named 'sid' referencing the device id of the sending device and contains one or multiple <keys> elements, each with an attribute 'jid' of one of the recipients bare JIDs as well as one or multiple <key> elements. + A <key> element has an attribute named 'rid' referencing the device id of the recipient device, and an attribute named 'kex' which defaults to 'false' and indicates if the enclosed encrypted message includes a key exchange. The ciphertext that is the key and HMAC encrypted using the long-standing OMEMO session for that recipient device is encoded using base64 and placed as text content into the <key> element. The ciphertext that is the encrypted &content; element is encoded using base64 and placed as text content into the &payload; element.

          -

          When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with an rid attribute matching its own device id. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

          +

          When an OMEMO element is received, the client MUST check whether there is a <keys> element with a jid attribute matching its own bare jid and an inner <key> element with a rid attribute matching its own device id. If this is not the case the message was not encrypted for this particular device and a warning message SHOULD be displayed instead. If such an element exists, the client checks whether the element's contents are an OMEMOKeyExchange.

          If this is the case, a new session is built from this received element. The client MUST then republish their bundle information, replacing the used PreKey, such that it won't be used again by a different client. If the client already has a session with the sender's device, it MUST replace this session with the newly built session. The client MUST eventually delete the private key belonging to the PreKey after use (this is subject to the Business rules).

          If the element's contents are a OMEMOAuthenticatedMessage, and the client has a session with the sender's device, it tries to decrypt the OMEMOAuthenticatedMessage using this session. If the decryption fails or there is no session with the sending device, a warning message SHOULD be displayed instead. Also refer to the section about recovering from broken sessions in the Business Rules.

          @@ -540,12 +540,12 @@

          Note: OMEMO encrypted group chats are currently specified to work with &xep0045;. This XEP might be updated in the future to specify the usage of OMEMO in conjunction with &xep0369;.

          A Multi-User Chat room that supports OMEMO MUST be configured non-anonymous and SHOULD be configured members-only.

          -

          A participant wanting to send a message to a group chat MUST first retrieve the members list and then fetch the device list for each member (via pubsub and to their real JIDs) and then subsequently fetch all active bundles.

          +

          A participant wanting to send a message to a group chat MUST first retrieve the members list and then fetch the device list for each member (via pubsub and to their real JIDs) and then subsequently fetch all bundles referenced by the device lists.

          On join a participant MUST request the member list, the admin list and the owner list as described in XEP-0045 §9.5, XEP-0045 §10.8, and XEP-0045 §10.5 respectively. Those three lists MUST be combined as the recipients of OMEMO encrypted messages. Once joined a participant MUST keep track of affiliation changes that occur in the room. This is both for removals (users getting banned or have their affiliation set to none) and users becoming members, admins or owners.

          -

          Before sending a message a participant SHOULD explicitly fetch device lists for all other participant if the list isn’t already cached..

          +

          Before sending a message a participant MUST explicitly fetch device lists (if not already cached) for each of the members.

          @@ -606,11 +606,10 @@

          Before publishing a freshly generated device id for the first time, a device MUST check whether that device id already exists, and if so, generate a new one.

          Clients SHOULD NOT immediately fetch the bundle and build a session as soon as a new device is announced. Before the first message is exchanged, the contact does not know which PreKey has been used (or, in fact, that any PreKey was used at all). As they have not had a chance to remove the used PreKey from their bundle announcement, this could lead to collisions where both Alice and Bob pick the same PreKey to build a session with a specific device. As each PreKey SHOULD only be used once, the party that sends their initial OMEMOKeyExchange later loses this race condition. This means that they think they have a valid session with the contact, when in reality their messages MAY be ignored by the other end. By postponing building sessions, the chance of such issues occurring can be drastically reduced. It is RECOMMENDED to construct sessions only immediately before sending a message.

          There are various reasons why decryption of an OMEMOKeyExchange or an OMEMOAuthenticatedMessage could fail. One reason is if the message was received twice and already decrypted once, in this case the client MUST ignore the decryption failure and not show any warnings/errors. In all other cases of decryption failure, clients SHOULD respond by forcibly doing a new key exchange and sending a new OMEMOKeyExchange with a potentially empty SCE payload. By building a new session with the original sender this way, the invalid session of the original sender will get overwritten with this newly created, valid session. This does NOT apply to the actual SCE content. If decrypting the SCE content fails, e.g. because the HMAC does not verify, this is not a reason to forcibly initiate a new key exchange.

          -

          If a OMEMOKeyExchange is received as part of a message catch-up mechanism (like &xep0313;) and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after the catch-up is completed. If this is done, the client MUST then also send a normal OMEMO encrypted message with an empty SCE payload before sending any payloads using this session, to trigger re-keying. (as above) This practice can mitigate the previously mentioned race condition by preventing message loss.

          -

          As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; <store /> hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a <body />

          +

          If an OMEMOKeyExchange is received as part of a message catch-up mechanism (like &xep0313;) and used to establish a new session with the sender, the client SHOULD postpone deletion of the private key corresponding to the used PreKey until after the catch-up is completed. If this is done, the client MUST send an OMEMO encrypted message with empty SCE payload right after the key exchange is completed, to forward the ratchet and to move away from the possibly double-used PreKey. This practice can mitigate the previously mentioned race condition by preventing message loss.

          When a client receives the first message for a given ratchet key with a counter of 53 or higher, it MUST send a heartbeat message. Heartbeat messages are normal OMEMO encrypted messages where the SCE payload does not include any elements. These heartbeat messages cause the ratchet to forward, thus consequent messages will have the counter restarted from 0.

          -

          When a client receives the message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

          -

          When the user of a client deactivates OMEMO for an account or globally, the client SHOULD delete the corresponding bundles and device ids from the PEP nodes. That way other clients should stop encrypting for that device.

          +

          When a client receives a message from a device id that is not on the device list, it SHOULD try to retrieve that user's devices node directly to ensure their local cached version of the devices list is up-to-date.

          +

          When the user of a client deactivates OMEMO for an account or globally, the client SHOULD delete the corresponding bundles and device ids from the PEP nodes. That way other clients should stop encrypting for that account.

          @@ -619,14 +618,14 @@
        11. The pubsub service MUST persist node items.
        12. The pubsub service MUST support publishing options as defined in XEP-0060 §7.1.5.
        13. The pubsub service MUST support 'max' as a value for the 'pubsub#persist_items' node configuration.
        14. -
        15. The pubsub service SHOULD support the 'open' access model for node configuration and 'pubsub#access_model' as a publish option.
        16. +
        17. The pubsub service MUST support the 'open' access model for node configuration and 'pubsub#access_model' as a publish option.
        18. Clients MUST NOT use a newly built session to transmit data without user intervention. If a client were to opportunistically start using sessions for sending without asking the user whether to trust a device first, an attacker could publish a fake device for this user, which would then receive copies of all messages sent by/to this user. A client MAY use such "not (yet) trusted" sessions for decryption of received messages, but in that case it SHOULD indicate the untrusted nature of such messages to the user.

          -

          When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user. When displaying the fingerprint as a hex string, one way to make it easier to compare the fingerprint is to split the hex string into 8 substrings of 8 chars each, then coloring each 8-char group using &xep0392;. Lowercase letters are recommended when displaying the fingerprint as a hex string.

          -

          While it is RECOMMENDED that clients postpone private key deletion until after message catch-up, the standards mandates that clients MUST NOT use duplicate-PreKey sessions for sending, so clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

          +

          When prompting the user for a trust decision regarding a key, the client SHOULD present the user with a fingerprint in the form of a hex string, QR code, or other unique representation, such that it can be compared by the user. The fingerprint is often chosen to be the public part of the device's IdentityKey, but could also be a different combination data that guarantees absence of a man-in-the-middle when verified. When displaying the fingerprint as a hex string, one way to make it easier to compare the fingerprint is to split the hex string into 8 substrings of 8 chars each, then coloring each 8-char group using &xep0392;. Lowercase letters are recommended when displaying the fingerprint as a hex string.

          +

          While it is RECOMMENDED that clients postpone private key deletion until after message catch-up, the X3DH standard mandates that clients should not use duplicate-PreKey sessions for sending, so clients MAY delete such keys immediately for security reasons. For additional information on potential security impacts of this decision, refer to Menezes, Alfred, and Berkant Ustaoglu. "On reusing ephemeral keys in Diffie-Hellman key agreement protocols." International Journal of Applied Cryptography 2, no. 2 (2010): 154-158..

          This document requires no interaction with the Internet Assigned Numbers Authority (IANA).

          From 91cf8060c5b3a238307c54e90209b2861c1140ab Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 10 Mar 2020 09:09:50 +0100 Subject: [PATCH 49/49] XEP-0384: mention that sending to group chat involves offline members --- xep-0384.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xep-0384.xml b/xep-0384.xml index afb135f1..d72e029b 100644 --- a/xep-0384.xml +++ b/xep-0384.xml @@ -542,7 +542,7 @@

          A Multi-User Chat room that supports OMEMO MUST be configured non-anonymous and SHOULD be configured members-only.

          A participant wanting to send a message to a group chat MUST first retrieve the members list and then fetch the device list for each member (via pubsub and to their real JIDs) and then subsequently fetch all bundles referenced by the device lists.

          -

          On join a participant MUST request the member list, the admin list and the owner list as described in XEP-0045 §9.5, XEP-0045 §10.8, and XEP-0045 §10.5 respectively. Those three lists MUST be combined as the recipients of OMEMO encrypted messages. Once joined a participant MUST keep track of affiliation changes that occur in the room. This is both for removals (users getting banned or have their affiliation set to none) and users becoming members, admins or owners.

          +

          On join a participant MUST request the member list, the admin list and the owner list as described in XEP-0045 §9.5, XEP-0045 §10.8, and XEP-0045 §10.5 respectively. The real JIDs from those three lists MUST be combined as the recipients of OMEMO encrypted messages. This includes recipients who are currently offline. Once joined a participant MUST keep track of affiliation changes that occur in the room. This is both for removals (users getting banned or have their affiliation set to none) and users becoming members, admins or owners.

          Before sending a message a participant MUST explicitly fetch device lists (if not already cached) for each of the members.