1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-12-22 15:48:52 -05:00

Merge branches 'feature/xep-0065', 'feature/xep-0278', 'feature/xep-0319' and 'feature/xep-0384'

This commit is contained in:
Jonas Wielicki 2017-09-15 18:20:20 +02:00
commit fff5868bc4
3 changed files with 154 additions and 42 deletions

View File

@ -3,6 +3,8 @@
<!ENTITY % ents SYSTEM 'xep.ent'> <!ENTITY % ents SYSTEM 'xep.ent'>
<!ENTITY CHANNEL "&lt;channel/&gt;"> <!ENTITY CHANNEL "&lt;channel/&gt;">
<!ENTITY RELAY "&lt;relay/&gt;"> <!ENTITY RELAY "&lt;relay/&gt;">
<!ENTITY STUN "&lt;stun/&gt;">
<!ENTITY TURN "&lt;turn/&gt;">
<!ENTITY SERVICES "&lt;services/&gt;"> <!ENTITY SERVICES "&lt;services/&gt;">
<!ENTITY TRACKER "&lt;tracker/&gt;"> <!ENTITY TRACKER "&lt;tracker/&gt;">
%ents; %ents;
@ -14,7 +16,7 @@
<abstract>This documents specifies how Jingle Clients can interact with Jingle Relay Nodes Services and how XMPP entities can provide, search and list available Jingle Relay Nodes.</abstract> <abstract>This documents specifies how Jingle Clients can interact with Jingle Relay Nodes Services and how XMPP entities can provide, search and list available Jingle Relay Nodes.</abstract>
&LEGALNOTICE; &LEGALNOTICE;
<number>0278</number> <number>0278</number>
<status>Deferred</status> <status>Experimental</status>
<type>Standards Track</type> <type>Standards Track</type>
<sig>Standards</sig> <sig>Standards</sig>
<approver>Council</approver> <approver>Council</approver>
@ -32,6 +34,12 @@
<email>thiago@xmppjingle.com</email> <email>thiago@xmppjingle.com</email>
<jid>barata7@gmail.com</jid> <jid>barata7@gmail.com</jid>
</author> </author>
<revision>
<version>0.2</version>
<date>2017-09-14</date>
<initials>tc</initials>
<remark><p>Added TURN Credentials Service Support.</p></remark>
</revision>
<revision> <revision>
<version>0.2</version> <version>0.2</version>
<date>2011-06-21</date> <date>2011-06-21</date>
@ -115,6 +123,7 @@ All signalling, request, response and publishing is done via XMPP, not requiring
<services xmlns='http://jabber.org/protocol/jinglenodes'> <services xmlns='http://jabber.org/protocol/jinglenodes'>
<relay policy='public' address='montague.lit' protocol='udp'/> <relay policy='public' address='montague.lit' protocol='udp'/>
<tracker policy='public' address='capulet.lit' protocol='udp'/> <tracker policy='public' address='capulet.lit' protocol='udp'/>
<turn policy='public' address='stun.capulet.lit' protocol='udp'/>
<stun policy='public' address='200.111.111.111' port='3857' protocol='udp'/> <stun policy='public' address='200.111.111.111' port='3857' protocol='udp'/>
</services> </services>
</iq> </iq>
@ -194,6 +203,34 @@ All signalling, request, response and publishing is done via XMPP, not requiring
]]></example> ]]></example>
<p><em>After receiving the &CHANNEL; the requester MUST send his stream to 'host' and 'localport' pair and send a &CANDIDATE; containing the 'host' and 'remoteport' values.</em></p> <p><em>After receiving the &CHANNEL; the requester MUST send his stream to 'host' and 'localport' pair and send a &CANDIDATE; containing the 'host' and 'remoteport' values.</em></p>
</section2> </section2>
<section2 topic="Jingle Client Consuming TURN Credentials Service" anchor="clientconsumingturncredentials">
<p>A Jingle Client can request volative TURN credentials, to be used in cases where connectivity check is a requirement. Like, for example, WebRTC. The concept and mechanism is quite similar to the RFC draft <link url='https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00'>REST API For Access To TURN Services'.</link></p>
<p>TURN provides an access control mechanism described in &rfc5389;, where long-term credentials are provided as part of the TURN protocol. Therefore the credentials provided in this Jingle Nodes mechanism are time-limited, but SHOULD be used as long-term credentials, when authentication against a TURN Server.
</p>
<p>
<em>Note: There is no need to run TURN server or support within a Jingle Relay. This mechanism allows decoupled deployment of distributed TURN Servers, without the requirement of database based authentication. </em>
</p>
<example caption="TURN Credentials request"><![CDATA[
<iq from='romeo@montague.lit/orchard'
id='uw72g176'
to='juliet@capulet.lit/balcony'
type='get'>
<turn xmlns='http://jabber.org/protocol/jinglenodes#turncredentials' protocol='udp'/>
</iq>
]]></example>
<example caption="TUNR Credentials Returned by the service"><![CDATA[
<iq from='juliet@capulet.lit/balcony'
id='uw72g176'
to='romeo@montague.lit/orchard'
type='result'>
<turn ttl='60000'
uri='turn:200.20.2.10:1984?transport=udp'
username='1433895918506:romeocapulet'
password='1Dj9XZ5fwvKS6YoQZOoORcFnXaI='
/>
</iq>
]]></example>
</section2>
</section1> </section1>
<section1 topic="Services Definitions" anchor="servicesdefinition"> <section1 topic="Services Definitions" anchor="servicesdefinition">
<section2 topic="Relay Channel Service" anchor="relaychannelservice"> <section2 topic="Relay Channel Service" anchor="relaychannelservice">
@ -293,7 +330,7 @@ All signalling, request, response and publishing is done via XMPP, not requiring
</section3> </section3>
</section2> </section2>
<section2 topic="Services Element" anchor="def-services"> <section2 topic="Services Element" anchor="def-services">
<p>The &SERVICES; element MAY be empty or contain &RELAY; and/or &TRACKER; elements.</p> <p>The &SERVICES; element MAY be empty or contain &RELAY;, &STUN; and/or &TRACKER; elements.</p>
<p>The attributes of the &RELAY; and &TRACKER; element are as follows.</p> <p>The attributes of the &RELAY; and &TRACKER; element are as follows.</p>
<table caption="Attributes of Relay and Tracker Elements"> <table caption="Attributes of Relay and Tracker Elements">
<tr> <tr>
@ -323,6 +360,48 @@ All signalling, request, response and publishing is done via XMPP, not requiring
</tr> </tr>
</table> </table>
</section2> </section2>
<section2 topic="TURN Credentials Service Element" anchor="def-turn-credentials">
<p>The attributes of the &TURN; element are as follows.</p>
<table caption="Attributes of TURN Elements">
<tr>
<th>Attribute</th>
<th>Definition</th>
<th>Inclusion</th>
</tr>
<tr>
<td>ttl</td>
<td>The duration in seconds for which the provided credentials are valid.</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>uri</td>
<td>The TURN Server URI.</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>username</td>
<td>The username to be used on TURN authentication. THe recommended format is a colon-delimited concatenation of expiration timestamp and the requester bare JID.</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>password</td>
<td>The ppassword to be used on TURN authentication. Is the result of 'base64(hmac(secret_key, username))'. Where 'secret_key' is shared between the TURN server and entity providing the credentials.</td>
<td>REQUIRED</td>
</tr>
</table>
<section3 topic="Ttl Attribute" anchor="def-ttlattribute">
<p>The duration in seconds for which the provided credentials are valid. The usual and recommended value is 86400 seconds (one day).</p>
</section3>
<section3 topic="URI Attribute" anchor="def-uriattribute">
<p>The TURN Server URI as described in <link url="https://tools.ietf.org/html/draft-petithuguenin-behave-turn-uris-03">I-D.petithuguenin-behave-turn-uris</link></p>
</section3>
<section3 topic="Username Attribute" anchor="def-ttlattribute">
<p>WebRTC's TURN request uses the 'username' value for its USERNAME and PASSWORD attributes, for the input to the MESSAGE-INTEGRITY hash.</p>
</section3>
<section3 topic="Password Attribute" anchor="def-ttlattribute">
<p>Along with 'username', WebRTC's TURN request uses the 'password' value for its USERNAME and PASSWORD attributes, for the input to the MESSAGE-INTEGRITY hash.</p>
</section3>
</section2>
</section1> </section1>
<section1 topic="Determining Support" anchor="support"> <section1 topic="Determining Support" anchor="support">
<p>To advertise its support for the Jingle Nodes support, when replying to &xep0030; information requests an entity MUST return URNs for any version of this protocol that the entity supports -- e.g., "http://jabber.org/protocol/jinglenodes" for this version&VNOTE;.</p> <p>To advertise its support for the Jingle Nodes support, when replying to &xep0030; information requests an entity MUST return URNs for any version of this protocol that the entity supports -- e.g., "http://jabber.org/protocol/jinglenodes" for this version&VNOTE;.</p>
@ -344,6 +423,7 @@ All signalling, request, response and publishing is done via XMPP, not requiring
<query xmlns='http://jabber.org/protocol/disco#info'> <query xmlns='http://jabber.org/protocol/disco#info'>
<feature var='http://jabber.org/protocol/jinglenodes'/> <feature var='http://jabber.org/protocol/jinglenodes'/>
<feature var='http://jabber.org/protocol/jinglenodes#channel'/> <feature var='http://jabber.org/protocol/jinglenodes#channel'/>
<feature var='http://jabber.org/protocol/jinglenodes#turncredentials'/>
</query> </query>
</iq> </iq>
]]></example> ]]></example>
@ -356,6 +436,10 @@ All signalling, request, response and publishing is done via XMPP, not requiring
<em>Note: This use case is also similar to a Jingle to SIP Interoperability Service.</em> <em>Note: This use case is also similar to a Jingle to SIP Interoperability Service.</em>
</p> </p>
</section2> </section2>
<section2 topic="Jingle Client that uses WebRTC with TURN required" anchor="webrtcturn">
<p>A Jingle Client that uses WebRTC, therefore requiring a TURN Server and its credentials to successfully alocate channels. This specification describes a simple way of discovering TURN Services and retrieving credentials to successfully allocate channels.
This also simplifies deployment and distribution of TURN servers, since its stateless authentication does not require connectivity to database authoriztion services.</p>
</section2>
<section2 topic="Jingle Client with ICE-UDP Transport with STUN support but no TURN support" anchor="iceudpnoturn"> <section2 topic="Jingle Client with ICE-UDP Transport with STUN support but no TURN support" anchor="iceudpnoturn">
<p>A Jingle Client with STUN support but no TURN support can use Relay Node Services as the fallback candidate instead of a TURN candidate. For instance, after a connectivity check proccess, none of the direct candidates worked. The Client can use the Relay Node Candidate as the fallback candidate(the lowest priority candidate).</p> <p>A Jingle Client with STUN support but no TURN support can use Relay Node Services as the fallback candidate instead of a TURN candidate. For instance, after a connectivity check proccess, none of the direct candidates worked. The Client can use the Relay Node Candidate as the fallback candidate(the lowest priority candidate).</p>
</section2> </section2>
@ -420,6 +504,13 @@ All signalling, request, response and publishing is done via XMPP, not requiring
<xs:attribute name='expire' type='xs:string' use='required'/> <xs:attribute name='expire' type='xs:string' use='required'/>
</xs:element> </xs:element>
<xs:element name='turn'>
<xs:attribute name='ttl' type='xs:string' use='required'/>
<xs:attribute name='uri' type='xs:string' use='required'/>
<xs:attribute name='username' type='xs:string' use='required'/>
<xs:attribute name='password' type='xs:string' use='required'/>
</xs:element>
<xs:element name='services'> <xs:element name='services'>
<xs:complexType> <xs:complexType>
<xs:sequence> <xs:sequence>
@ -435,6 +526,10 @@ All signalling, request, response and publishing is done via XMPP, not requiring
type='serviceElementType' type='serviceElementType'
minOccurs='0' minOccurs='0'
maxOccurs='unbounded'/> maxOccurs='unbounded'/>
<xs:element name='turn'
type='serviceElementType'
minOccurs='0'
maxOccurs='unbounded'/>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>

View File

@ -24,6 +24,12 @@
<supersededby/> <supersededby/>
<shortname>idle</shortname> <shortname>idle</shortname>
&tobias; &tobias;
<revision>
<version>1.0.2</version>
<date>2017-07-17</date>
<initials>egp</initials>
<remark><p>Make the schema more precise about a date being a xs:dateTime.</p></remark>
</revision>
<revision> <revision>
<version>1.0.1</version> <version>1.0.1</version>
<date>2017-05-30</date> <date>2017-05-30</date>
@ -104,7 +110,7 @@
<xs:element name="idle"> <xs:element name="idle">
<xs:complexType> <xs:complexType>
<xs:attribute name="since" use="required" type="xs:string"/> <xs:attribute name="since" use="required" type="xs:dateTime"/>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>

View File

@ -27,6 +27,15 @@
<email>andy@strb.org</email> <email>andy@strb.org</email>
<jid>andy@strb.org</jid> <jid>andy@strb.org</jid>
</author> </author>
<revision>
<version>0.2</version>
<date>2017-06-02</date>
<initials>dg</initials>
<remark>
<p>Depend on SignalProtocol instead of Olm.</p>
<p>Changed to eu.siacs.conversations.axolotl Namespace which is currently used in the wild</p>
</remark>
</revision>
<revision> <revision>
<version>0.1</version> <version>0.1</version>
<date>2016-12-07</date> <date>2016-12-07</date>
@ -63,17 +72,21 @@
external complexity. external complexity.
</p> </p>
<p> <p>
This XEP defines a protocol that leverages &olm; encryption to provide This XEP defines a protocol that leverages the SignalProtocol encryption to provide
multi-end to multi-end encryption, allowing messages to be synchronized multi-end to multi-end encryption, allowing messages to be synchronized
securely across multiple clients, even if some of them are offline. Olm 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 is a cryptographic double ratched protocol based on work by Trevor Perrin
and Moxie Marlinspike first published as the Axolotl protocol. 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.
</p> </p>
</section2> </section2>
<section2 topic='Overview' anchor='intro-overview'> <section2 topic='Overview' anchor='intro-overview'>
<p> <p>
The general idea behind this protocol is to maintain separate, The general idea behind this protocol is to maintain separate,
long-standing Olm-encrypted sessions with each device of each contact 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 (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 transport channels. In this scheme, each message is encrypted with a
fresh, randomly generated encryption key. An encrypted header is added to fresh, randomly generated encryption key. An encrypted header is added to
@ -87,14 +100,14 @@
</p> </p>
<p> <p>
As the encrypted payload is common to all recipients, it only has to be As the encrypted payload is common to all recipients, it only has to be
included once, reducing overhead. Furthermore, Olm's transparent handling included once, reducing overhead. Furthermore, SignalProtocolss transparent handling
of messages that were lost or received out of order, as well as those sent 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 while the recipient was offline, is maintained by this protocol. As a
result, in combination with &xep0280; and &xep0313;, the desired property result, in combination with &xep0280; and &xep0313;, the desired property
of inter-client history synchronization is achieved. of inter-client history synchronization is achieved.
</p> </p>
<p> <p>
OMEMO currently uses version 1 Olm protocol. Instead of an Axolotl key OMEMO currently uses version 3 SignalProtocol. Instead of a Signal key
server, &xep0163; (PEP) is used to publish key data. server, &xep0163; (PEP) is used to publish key data.
</p> </p>
</section2> </section2>
@ -111,7 +124,7 @@
<section2 topic='General Terms' anchor='glossary-general'> <section2 topic='General Terms' anchor='glossary-general'>
<dl> <dl>
<di><dt>Device</dt><dd>A communication end point, i.e. a specific client instance</dd></di> <di><dt>Device</dt><dd>A communication end point, i.e. a specific client instance</dd></di>
<di><dt>OMEMO element</dt><dd>An &lt;encrypted&gt; element in the urn:xmpp:omemo:0 namespace. Can be either MessageElement or a KeyTransportElement</dd></di> <di><dt>OMEMO element</dt><dd>An &lt;encrypted&gt; element in the eu.siacs.conversations.axolotl namespace. Can be either MessageElement or a KeyTransportElement</dd></di>
<di><dt>MessageElement</dt><dd>An OMEMO element that contains a chat message. Its &lt;payload&gt;, when decrypted, corresponds to a &lt;message&gt;'s &lt;body&gt;.</dd></di> <di><dt>MessageElement</dt><dd>An OMEMO element that contains a chat message. Its &lt;payload&gt;, when decrypted, corresponds to a &lt;message&gt;'s &lt;body&gt;.</dd></di>
<di><dt>KeyTransportElement</dt><dd>An OMEMO element that does not have a &lt;payload&gt;. It contains a fresh encryption key, which can be used for purposes external to this XEP.</dd></di> <di><dt>KeyTransportElement</dt><dd>An OMEMO element that does not have a &lt;payload&gt;. It contains a fresh encryption key, which can be used for purposes external to this XEP.</dd></di>
<di><dt>Bundle</dt><dd>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.</dd></di> <di><dt>Bundle</dt><dd>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.</dd></di>
@ -120,12 +133,12 @@
</dl> </dl>
</section2> </section2>
<section2 topic='Olm-specific' anchor='glossary-olm'> <section2 topic='SignalProtocol-specific' anchor='glossary-signalprotocol'>
<dl> <dl>
<di><dt>IdentityKey</dt><dd>Per-device public/private key pair used to authenticate communications</dd></di> <di><dt>IdentityKey</dt><dd>Per-device public/private key pair used to authenticate communications</dd></di>
<di><dt>PreKey</dt><dd>A Diffie-Hellman public key, published in bulk and ahead of time</dd></di> <di><dt>PreKey</dt><dd>A Diffie-Hellman public key, published in bulk and ahead of time</dd></di>
<di><dt>PreKeyOlmMessage</dt><dd>An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.</dd></di> <di><dt>PreKeySignalMessage</dt><dd>An encrypted message that includes the initial key exchange. This is used to transparently build sessions with the first exchanged message.</dd></di>
<di><dt>OlmMessage</dt><dd>An encrypted message</dd></di> <di><dt>SignalMessage</dt><dd>An encrypted message</dd></di>
</dl> </dl>
</section2> </section2>
</section1> </section1>
@ -139,16 +152,16 @@
</p> </p>
</section2> </section2>
<section2 topic='Discovering peer support' anchor='usecases-discovering'> <section2 topic='Discovering peer support' anchor='usecases-discovering'>
<p>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:0: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.</p> <p>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.</p>
<example caption='Devicelist update received by subscribed clients'><![CDATA[ <example caption='Devicelist update received by subscribed clients'><![CDATA[
<message from='juliet@capulet.lit' <message from='juliet@capulet.lit'
to='romeo@montague.lit' to='romeo@montague.lit'
type='headline' type='headline'
id='update_01'> id='update_01'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='urn:xmpp:omemo:0:devicelist'> <items node='eu.siacs.conversations.axolotl.devicelist'>
<item> <item>
<list xmlns='urn:xmpp:omemo:0'> <list xmlns='eu.siacs.conversations.axolotl'>
<device id='12345' /> <device id='12345' />
<device id='4223' /> <device id='4223' />
</list> </list>
@ -162,9 +175,9 @@
<example caption='Adding the own device ID to the list'><![CDATA[ <example caption='Adding the own device ID to the list'><![CDATA[
<iq from='juliet@capulet.lit' type='set' id='announce1'> <iq from='juliet@capulet.lit' type='set' id='announce1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='urn:xmpp:omemo:0:devicelist'> <publish node='eu.siacs.conversations.axolotl.devicelist'>
<item> <item>
<list xmlns='urn:xmpp:omemo:0'> <list xmlns='eu.siacs.conversations.axolotl'>
<device id='12345' /> <device id='12345' />
<device id='4223' /> <device id='4223' />
<device id='31415' /> <device id='31415' />
@ -178,9 +191,9 @@
<example caption='Announcing bundle information'><![CDATA[ <example caption='Announcing bundle information'><![CDATA[
<iq from='juliet@capulet.lit' type='set' id='announce2'> <iq from='juliet@capulet.lit' type='set' id='announce2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='urn:xmpp:omemo:0:bundles:31415'> <publish node='eu.siacs.conversations.axolotl.bundles:31415'>
<item> <item>
<bundle xmlns='urn:xmpp:omemo:0'> <bundle xmlns='eu.siacs.conversations.axolotl'>
<signedPreKeyPublic signedPreKeyId='1'> <signedPreKeyPublic signedPreKeyId='1'>
BASE64ENCODED... BASE64ENCODED...
</signedPreKeyPublic> </signedPreKeyPublic>
@ -216,10 +229,10 @@
to='juliet@capulet.lit' to='juliet@capulet.lit'
id='fetch1'> id='fetch1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='urn:xmpp:omemo:0:bundles:31415'/> <items node='eu.siacs.conversations.axolotl.bundles:31415'/>
</pubsub> </pubsub>
</iq>]]></example> </iq>]]></example>
<p>A random preKeyPublic entry is selected, and used to build an Olm session.</p> <p>A random preKeyPublic entry is selected, and used to build a SignalProtocol session.</p>
</section2> </section2>
<section2 topic='Sending a message' anchor='usecases-messagesend'> <section2 topic='Sending a message' anchor='usecases-messagesend'>
<p> <p>
@ -230,15 +243,15 @@
128 bit) are concatenated and for each intended recipient device, 128 bit) are concatenated and for each intended recipient device,
i.e. both own devices as well as devices associated with the contact, the i.e. both own devices as well as devices associated with the contact, the
result of this concatenation is encrypted using the corresponding result of this concatenation is encrypted using the corresponding
long-standing Olm session. Each encrypted payload key/authentication tag long-standing SignalProtocol session. Each encrypted payload key/authentication tag
tuple is tagged with the recipient device's ID. The key element MUST be tuple is tagged with the recipient device's ID. The key element MUST be
tagged with a prekey attribute set to true if a PreKeyOlmMessage is being tagged with a prekey attribute set to true if a PreKeySignalMessage is being
used. This is all serialized into a MessageElement, which is transmitted used. This is all serialized into a MessageElement, which is transmitted
in a &lt;message&gt; as follows: in a &lt;message&gt; as follows:
</p> </p>
<example caption="Sending a message"><![CDATA[ <example caption="Sending a message"><![CDATA[
<message to='juliet@capulet.lit' from='romeo@montague.lit' id='send1'> <message to='juliet@capulet.lit' from='romeo@montague.lit' id='send1'>
<encrypted xmlns='urn:xmpp:omemo:0'> <encrypted xmlns='eu.siacs.conversations.axolotl'>
<header sid='27183'> <header sid='27183'>
<key rid='31415'>BASE64ENCODED...</key> <key rid='31415'>BASE64ENCODED...</key>
<key prekey="true" rid='12321'>BASE64ENCODED...</key> <key prekey="true" rid='12321'>BASE64ENCODED...</key>
@ -258,14 +271,14 @@
SHOULD have at least 128 bit) are concatenated and for each intended SHOULD have at least 128 bit) are concatenated and for each intended
recipient device, i.e. both own devices as well as devices associated recipient device, i.e. both own devices as well as devices associated
with the contact, this key is encrypted using the corresponding with the contact, this key is encrypted using the corresponding
long-standing Olm session. Each encrypted payload key/authentication tag long-standing SignalProtocol session. Each encrypted payload key/authentication tag
tuple is tagged with the recipient device's ID. The key element MUST be tuple is tagged with the recipient device's ID. The key element MUST be
tagged with a prekey attribute set to true if a PreKeyOlmMessage is being tagged with a prekey attribute set to true if a PreKeySignalMessage is being
used This is all serialized into a KeyTransportElement, omitting the used This is all serialized into a KeyTransportElement, omitting the
&lt;payload&gt; as follows: &lt;payload&gt; as follows:
</p> </p>
<example caption="Sending a key"><![CDATA[ <example caption="Sending a key"><![CDATA[
<encrypted xmlns='urn:xmpp:omemo:0'> <encrypted xmlns='eu.siacs.conversations.axolotl'>
<header sid='27183'> <header sid='27183'>
<key rid='31415'>BASE64ENCODED...</key> <key rid='31415'>BASE64ENCODED...</key>
<key prekey="true" rid='12321'>BASE64ENCODED...</key> <key prekey="true" rid='12321'>BASE64ENCODED...</key>
@ -276,25 +289,24 @@
<p>This KeyTransportElement can then be sent over any applicable transport mechanism.</p> <p>This KeyTransportElement can then be sent over any applicable transport mechanism.</p>
</section2> </section2>
<section2 topic='Receiving a message' anchor='usecases-receiving'> <section2 topic='Receiving a message' anchor='usecases-receiving'>
<p>When an OMEMO element is received, the client MUST check whether there is a &lt;key&gt; 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 PreKeyOlmMessage.</p> <p>When an OMEMO element is received, the client MUST check whether there is a &lt;key&gt; 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.</p>
<p>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.</p> <p>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.</p>
<p>If the element's contents are a OlmMessage, and the client has a session with the sender's device, it tries to decrypt the OlmMessage using this session. If the decryption fails or if the element's contents are not a OlmMessage either, the OMEMO element MUST be silently discarded.</p> <p>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.</p>
<p>If the OMEMO element contains a &lt;payload&gt;, 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 &lt;key&gt; element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the &lt;body&gt; of the received message.</p> <p>If the OMEMO element contains a &lt;payload&gt;, 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 &lt;key&gt; element. If the decryption fails, the client MUST silently discard the OMEMO message. If it succeeds, the decrypted contents are treated as the &lt;body&gt; of the received message.</p>
<p>If the OMEMO element does not contain a &lt;payload&gt;, the client has received a KeyTransportElement. The key extracted from the &lt;key&gt; element can then be used for other purposes (e.g. encrypted file transfer).</p> <p>If the OMEMO element does not contain a &lt;payload&gt;, the client has received a KeyTransportElement. The key extracted from the &lt;key&gt; element can then be used for other purposes (e.g. encrypted file transfer).</p>
</section2> </section2>
</section1> </section1>
<section1 topic='Business Rules' anchor='rules'> <section1 topic='Business Rules' anchor='rules'>
<p>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.</p> <p>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.</p>
<p>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 PreKeyOlmMessage 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. </p> <p>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. </p>
<p>As there are no explicit error messages in this protocol, if a client does receive a PreKeyOlmMessage using an invalid PreKey, they SHOULD respond with a KeyTransportElement, sent in a &lt;message&gt; using a PreKeyOlmMessage. 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.</p> <p>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 &lt;message&gt; 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.</p>
<p>If a PreKeyOlmMessage 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 PreKeyOlmMessage 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.</p> <p>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.</p>
<p>As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; &lt;store /&gt; hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a &lt;body /&gt;</p> <p>As the asynchronous nature of OMEMO allows decryption at a later time to currently offline devices client SHOULD include a &xep0334; &lt;store /&gt; hint in their OMEMO messages. Otherwise, server implementations of &xep0313; will generally not retain OMEMO messages, since they do not contain a &lt;body /&gt;</p>
</section1> </section1>
<section1 topic='Implementation Notes' anchor='impl'> <section1 topic='Implementation Notes' anchor='impl'>
<!-- TODO: I think this is still true? --> <!-- TODO: I think this is still true? -->
<p> <p>
The Olm library's reference implementation (and presumably its ports to The SignalProtocol-library uses a trust model that doesn't work very well with
various other platforms) 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 OMEMO. For this reason it may be desirable to have the library consider all
keys trusted, effectively disabling its trust management. This makes it keys trusted, effectively disabling its trust management. This makes it
necessary to implement trust handling oneself. necessary to implement trust handling oneself.
@ -305,7 +317,7 @@
<p>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.</p> <p>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.</p>
<p>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 <note>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.</note>.</p> <p>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 <note>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.</note>.</p>
<p> <p>
In order to be able to handle out-of-order messages, the Olm stack has to 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. 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 It is up to the implementor to decide how long and how many of such keys to
keep around. keep around.
@ -318,9 +330,8 @@
<section2 topic='Protocol Namespaces' anchor='namespaces'> <section2 topic='Protocol Namespaces' anchor='namespaces'>
<p>This specification defines the following XMPP namespaces:</p> <p>This specification defines the following XMPP namespaces:</p>
<ul> <ul>
<li>urn:xmpp:omemo:0</li> <li>eu.siacs.conversations.axolotl</li>
</ul> </ul>
<p>The &REGISTRAR; shall include the foregoing namespace in its registry at &NAMESPACES;, as goverened by &xep0053;.</p>
</section2> </section2>
<section2 topic='Protocol Versioning' anchor='versioning'> <section2 topic='Protocol Versioning' anchor='versioning'>
&NSVER; &NSVER;
@ -330,8 +341,8 @@
<code><![CDATA[ <code><![CDATA[
<xml version="1.0" encoding="utf8"> <xml version="1.0" encoding="utf8">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:xmpp:omemo:0" targetNamespace="eu.siacs.conversations.axolotl"
xmlns="urn:xmpp:omemo:0"> xmlns="eu.siacs.conversations.axolotl">
<xs:element name="encrypted"> <xs:element name="encrypted">
<xs:element name="header"> <xs:element name="header">