<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep xmlns="">
<header>
  <title>Entity Capabilities 2.0</title>
  <abstract>This document overhauls the XMPP protocol extension Entity Capabilities (XEP-0115). It defines an XMPP protocol extension for broadcasting and dynamically discovering client, device, or generic entity capabilities. In order to minimize network impact, the transport mechanism is standard XMPP presence broadcast (thus forestalling the need for polling related to service discovery data), the capabilities information can be cached either within a session or across sessions, and the format has been kept as small as possible.</abstract>
  
<legal>
<copyright>This XMPP Extension Protocol is copyright © 1999 – 2024 by the <link url="https://xmpp.org/">XMPP Standards Foundation</link> (XSF).</copyright>
<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.</permissions>
<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. ##</warranty>
<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.</liability>
<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 &lt;<link url="https://xmpp.org/about/xsf/ipr-policy">https://xmpp.org/about/xsf/ipr-policy</link>&gt; or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).</conformance>
</legal>
  <number>0390</number>
  <status>Deferred</status>
  <type>Standards Track</type>
  <sig>Standards</sig>
  <approver>Council</approver>
  <dependencies>
    <spec>XMPP Core</spec>
    <spec>XMPP IM</spec>
    <spec>XEP-0030</spec>
    <spec>XEP-0300</spec>
  </dependencies>
  <supersedes>
    <spec>XEP-0115</spec>
  </supersedes>
  <supersededby/>
  <shortname>ecaps2</shortname>
  
  <author>
    <firstname>Jonas</firstname>
    <surname>Schäfer</surname>
    <email>jonas@wielicki.name</email>
    <jid>jonas@wielicki.name</jid>
  </author>

  <revision>
    <version>0.3.2</version>
    <date>2018-03-05</date>
    <initials>fs</initials>
    <remark>
	  <p>Explain that ASCII Seperators are only invalid in XML 1.0, but not in XML 1.1.</p>
    </remark>
  </revision>
  <revision>
    <version>0.3.1</version>
    <date>2020-04-28</date>
    <initials>fs</initials>
    <remark>Add another xml:lang example</remark>
  </revision>
  <revision>
    <version>0.3.0</version>
    <date>2018-10-01</date>
    <initials>XEP Editor (jsc)</initials>
    <remark>Defer due to lack of activity.</remark>
  </revision>
  <revision>
    <version>0.2</version>
    <date>2017-06-14</date>
    <initials>jwi</initials>
    <remark>
      <ul>
        <li>Clearly specify handling of xml:lang attributes.</li>
        <li>Add Query Interception.</li>
        <li>Add Gratuitous Caps.</li>
      </ul>
    </remark>
  </revision>
  <revision>
    <version>0.1</version>
    <date>2017-03-23</date>
    <initials>jwi</initials>
    <remark><ul><li>Add security consideration for caps spamming.</li><li>Properly reference UTF-8 and Base64 RFCs.</li><li>Remove namespace prefixes from examples.</li><li>Properly reference FULL STOP character (U+002E, ".").</li><li>Clarify the first error condition in the Hash Function Input algorithm.</li></ul></remark>
  </revision>
  <revision>
    <version>0.0.1</version>
    <date>2017-02-28</date>
    <initials>jwi</initials>
    <remark><p>First draft.</p></remark>
  </revision>
</header>

<section1 topic="Introduction" anchor="intro">
  <p>XMPP applications often face choices based on the disco#info (see <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note>) exposed by other entities. For example, for a client, knowledge about whether a roster entry is a <span class="ref"><link url="https://xmpp.org/extensions/xep-0369.html">Mediated Information eXchange (MIX) (XEP-0369)</link></span> <note>XEP-0369: Mediated Information eXchange (MIX) &lt;<link url="https://xmpp.org/extensions/xep-0369.html">https://xmpp.org/extensions/xep-0369.html</link>&gt;.</note> entity or a normal client is important for user experience. It may also be desirable to provide indicators on the type of client a contact is using (mobile or not).</p>
  <p>The canonical way to do so has been issueing <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> requests to the entities emitting presence. This, with the evergrowing featureset of XMPP, induces a lot of traffic for all involed parties, especially during startup. This is a waste of resources, as <cite>XEP-0030</cite> information rarely changes and even more, common client configurations and versions share exactly the same information.</p>
  <p><span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> has provided the XMPP ecosystem with a way to share this information with less bandwith. Entities using that protocol send a hash of their disco#info result along with presence or stream features. As those hashes can be cached, entities receiving these hashes only need to query the information for each hash once, greatly reducing the Service Discovery traffic.</p>
  <p>However, <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> has two main flaws:</p>
  <ul>
    <li>The hash agility mechanism is underspecified. While it is possible to change the hash function, there is no clearly defined way to send multiple hashes at once to allow for a transition period. Even though it is technically not forbidden to send multiple <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> &lt;c/&gt; elements with different hashes at once, it is unclear how implementations behave when this happens. Possible issues lie in the use of caps optimization, as well as clients expecting only one &lt;c/&gt; element.</li>
    <li>The algorithm to generate the input for the hash function has flaws as pointed out by Waqas Hussain <note>org.jabber.security Mailing List Archive: '[Security] Trivial preimage attack against the entity capabilities protocol)' from 2009-07-22, &lt;<link url="https://mail.jabber.org/pipermail/security/2009-July/000812.html">https://mail.jabber.org/pipermail/security/2009-July/000812.html</link>&gt;.</note>. Even though these flaws have partially been fixed and worked around, the fundamental problem that the structural information of the individual strings from the disco response is lost persists.</li>
  </ul>
</section1>

<section1 topic="Requirements" anchor="reqs">
  <p>The <em>Entity Capabilities 2.0</em> protocol aims to satisfy the following requirements:</p>
  <ol>
    <li>Entities must be able to participate even if they support only <span class="ref"><link url="http://tools.ietf.org/html/rfc6120">XMPP Core</link></span> <note>RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core &lt;<link url="http://tools.ietf.org/html/rfc6120">http://tools.ietf.org/html/rfc6120</link>&gt;.</note>, <span class="ref"><link url="http://tools.ietf.org/html/rfc6121">XMPP IM</link></span> <note>RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence &lt;<link url="http://tools.ietf.org/html/rfc6121">http://tools.ietf.org/html/rfc6121</link>&gt;.</note> and <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note><note>While elements of XEP-0300 are re-used here, full support of XEP-0300 is not formally required to implement this specification.</note>.</li>
    <li>Entities must be able to participate without connectivity to services except their own XMPP server and without connectivity to specialized XMPP services, including cached information from those services.</li>
    <li>Entities should be able to learn Service Discovery information without actively querying for it.</li>
    <li>The bandwidth consumption should be as minimal as possible, while reusing existing specifications.</li>
    <li>It must be possible to write <span class="ref"><link url="https://xmpp.org/extensions/xep-0045.html">Multi-User Chat (XEP-0045)</link></span> <note>XEP-0045: Multi-User Chat &lt;<link url="https://xmpp.org/extensions/xep-0045.html">https://xmpp.org/extensions/xep-0045.html</link>&gt;.</note> and <span class="ref"><link url="https://xmpp.org/extensions/xep-0369.html">Mediated Information eXchange (MIX) (XEP-0369)</link></span> <note>XEP-0369: Mediated Information eXchange (MIX) &lt;<link url="https://xmpp.org/extensions/xep-0369.html">https://xmpp.org/extensions/xep-0369.html</link>&gt;.</note> implementations which can forward this protocol with negligible extra work.</li>
    <li>Entities must be able to update their published information arbitrarily often in a single presence session.</li>
    <li>Server infrastructure beyond <cite>XMPP Core</cite> and <cite>XMPP IM</cite> must not be required for this to work (but may be beneficial).</li>
    <li>Entities must be able to be confident that the information obtained from the broadcast is equivalent to the information which would be obtained from querying the generating entity directly at the time the broadcast was generated.</li>
    <li>The protocol must be able to coexist (but not necessarily exchange information) with <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note>.</li>
    <li>No special XML features beyond what is needed to implement <cite>XMPP Core</cite> itself should be required.</li>
    <li>Obsoletion of hash functions should not need a new version of the specification.</li>
    <li>Support for pushing Entity Capabilities to the clients server without sending presence.</li>
  </ol>
</section1>

<section1 topic="Glossary" anchor="glossary">
  <dl>
    <di><dt>Capability Hash</dt><dd>A tuple of hash function and hash value generated as described in the <link url="#algorithm">Hash Function Input</link> section.</dd></di>
    <di><dt>Capability Hash Cache</dt><dd>A mapping which maps <em>Capability Hashes</em> to disco#info &lt;query/&gt; responses with an empty 'node' attribute.</dd></di>
    <di><dt>Cabability Hash Node</dt><dd>The name of a <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> 'node' for a given <em>Capability Hash</em>. See <link url="#algorithm-hashnodes">Construction of Capability Hash Nodes</link>.</dd></di>
    <di><dt>Capability Hash Set</dt><dd>A set of <em>Capability Hashes</em> which cover the same <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> response, possibly in the form of a &lt;c/&gt; element with <span class="ref"><link url="https://xmpp.org/extensions/xep-0300.html">Use of Cryptographic Hash Functions in XMPP (XEP-0300)</link></span> <note>XEP-0300: Use of Cryptographic Hash Functions in XMPP &lt;<link url="https://xmpp.org/extensions/xep-0300.html">https://xmpp.org/extensions/xep-0300.html</link>&gt;.</note> &lt;hash/&gt; children.</dd></di>
    <di><dt>Generating Entity</dt><dd>An entity which emits a <em>Capability Hash Set</em> to other entities.</dd></di>
    <di><dt>Processing Entity</dt><dd>An entity which receives and processes a <em>Capability Hash Set</em> from a <em>Generating Entity</em>.</dd></di>
    <di><dt>Query Interception</dt><dd>Server-side processing of disco#info queries directed to a resource based on the <em>Capability Hash Sets</em> published by that resource.</dd></di>
    <di><dt>Gratuitous Capabilities</dt><dd>The sending of a <em>Capability Hash Set</em> to a server before initial presence has been sent and without being asked by the server.</dd></di>
  </dl>
</section1>

<section1 topic="Algorithms" anchor="algorithm">
  <p>The following algorithms provide data which is sent using this protocol.</p>

  <section2 topic="Hash Function Input" anchor="algorithm-input">
    <p>The input to this algorithm is a <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> disco#info &lt;query/&gt; response. The output is an octet string which can be used as input to a hash function or an error.</p>
    <div class="box"><p>General remarks:</p>
    <ul>
      <li><p>The algorithm strongly distinguishes between character data (sequences of Unicode code points) and octet strings (sequences of 8-bit bytes). Whenever character data is encoded to octet strings in the following algorithm, the UTF-8 as specified in <span class="ref"><link url="http://tools.ietf.org/html/rfc3629">RFC 3629</link></span> <note>RFC 3629: UTF-8, a transformation format of ISO 10646 &lt;<link url="http://tools.ietf.org/html/rfc3629">http://tools.ietf.org/html/rfc3629</link>&gt;.</note> encoding is used. Whenever octet strings are sorted in the following algorithm, the i;octet collation as specified in <span class="ref"><link url="http://tools.ietf.org/html/rfc4790">RFC 4790</link></span> <note>RFC 4790: Internet Application Protocol Collation Registry &lt;<link url="http://tools.ietf.org/html/rfc4790">http://tools.ietf.org/html/rfc4790</link>&gt;.</note> is used.</p></li>
      <li><p>The algorithm uses the <tt>xml:lang</tt> attribute. Implementations must take implicit values for the <tt>xml:lang</tt> attribute into account, for example those inherited from the disco#info, the IQ element, or from the root &lt;stream&gt; tag.</p></li>
    </ul></div>
    <ol>
      <li>If the &lt;query/&gt; element contains any elements except &lt;identity/&gt;, &lt;feature/&gt; (both from the <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> disco#info namespace) or <span class="ref"><link url="https://xmpp.org/extensions/xep-0128.html">Service Discovery Extensions (XEP-0128)</link></span> <note>XEP-0128: Service Discovery Extensions &lt;<link url="https://xmpp.org/extensions/xep-0128.html">https://xmpp.org/extensions/xep-0128.html</link>&gt;.</note> data forms, abort with an error.</li>
      <li>If any <span class="ref"><link url="https://xmpp.org/extensions/xep-0128.html">Service Discovery Extensions (XEP-0128)</link></span> <note>XEP-0128: Service Discovery Extensions &lt;<link url="https://xmpp.org/extensions/xep-0128.html">https://xmpp.org/extensions/xep-0128.html</link>&gt;.</note> &lt;x/&gt; element contains a data form which contains a &lt;reported/&gt; or &lt;item/&gt; element, abort with an error.</li>
      <li>If any <span class="ref"><link url="https://xmpp.org/extensions/xep-0128.html">Service Discovery Extensions (XEP-0128)</link></span> <note>XEP-0128: Service Discovery Extensions &lt;<link url="https://xmpp.org/extensions/xep-0128.html">https://xmpp.org/extensions/xep-0128.html</link>&gt;.</note> &lt;x/&gt; element does not adhere to the "FORM_TYPE" protocol specified by <span class="ref"><link url="https://xmpp.org/extensions/xep-0068.html">Field Standardization for Data Forms (XEP-0068)</link></span> <note>XEP-0068: Field Data Standardization for Data Forms &lt;<link url="https://xmpp.org/extensions/xep-0068.html">https://xmpp.org/extensions/xep-0068.html</link>&gt;.</note>, abort with an error.</li>
      <li><p>Processing of &lt;feature/&gt; elements:</p>
        <ol>
          <li>For each &lt;feature/&gt; element: Encode the character data of the 'var' attribute and append an octet of value 0x1f (ASCII Unit Separator)</li>
          <li>Join the resulting octet strings together, ordered from lesser to greater.</li>
          <li>Append an octet of value 0x1c (ASCII File Separator).</li>
        </ol>
        <p>The result of this step is referenced as <em>Features String</em> later.</p>
      </li>
      <li><p>Processing of &lt;identity/&gt; nodes:</p>
        <ol>
          <li><p>For each &lt;identity/&gt; node:</p>
            <ol>
              <li>Encode the character data of the 'category', 'type', 'xml:lang' and 'name' attributes.</li>
              <li>Append an octet of value 0x1f (ASCII Unit Separator) to each resulting octet string.</li>
              <li>Join the resulting octet strings together, in the order of 'category', 'type', 'xml:lang' and 'name', resulting in a single octet string for the &lt;identity/&gt; node.</li>
              <li>Append an octet of value 0x1e (ASCII Record Separator).</li>
            </ol>
          </li>
          <li>Join the resulting octet strings together, ordered from lesser to greater.</li>
          <li>Append an octet of value 0x1c (ASCII File Separator).</li>
        </ol>
        <p>The result of this step is referenced as <em>Identities String</em> later.</p>
      </li>
      <li><p>Processing of <span class="ref"><link url="https://xmpp.org/extensions/xep-0128.html">Service Discovery Extensions (XEP-0128)</link></span> <note>XEP-0128: Service Discovery Extensions &lt;<link url="https://xmpp.org/extensions/xep-0128.html">https://xmpp.org/extensions/xep-0128.html</link>&gt;.</note> &lt;x/&gt; elements:</p>
        <ol>
          <li><p>For each &lt;x/&gt; element:</p>
            <ol>
              <li><p>For each &lt;field/&gt; element:</p>
                <ol>
                  <li>Encode the character data of each &lt;value/&gt; element and append an octet of value 0x1f (ASCII Unit Separator)</li>
                  <li>Join the resulting octet strings together, ordered from lesser to greater.</li>
                  <li>Encode the character data of the 'var' attribute and append an octet of value 0x1f (ASCII Unit Separator) and the result from the previous step.</li>
                  <li>Append an octet of value 0x1e (ASCII Record Separator).</li>
                </ol>
              </li>
              <li>Join the resulting octet strings together, ordered from lesser to greater.</li>
              <li>Append an octet of value 0x1d (ASCII Group Separator).</li>
            </ol>
          </li>
          <li>Join the resulting octet strings together, ordered from lesser to greater.</li>
          <li>Append an octet of value 0x1c (ASCII File Separator).</li>
        </ol>
        <p>The result of this step is referenced as <em>Extensions String</em> later.</p>
      </li>
      <li>Join the <em>Features String</em>, <em>Identities String</em> and <em>Extensions String</em> together, in this order. Return the resulting string as result of the algorithm.</li>
    </ol>
  </section2>

  <section2 topic="Construction of Capability Hash Sets" anchor="algorithm-hashsets">
    <p>The entity picks a set of hash functions it wishes to use. The set of hash functions MUST include at least one hash function which MUST be implemented according to <span class="ref"><link url="https://xmpp.org/extensions/xep-0300.html">Use of Cryptographic Hash Functions in XMPP (XEP-0300)</link></span> <note>XEP-0300: Use of Cryptographic Hash Functions in XMPP &lt;<link url="https://xmpp.org/extensions/xep-0300.html">https://xmpp.org/extensions/xep-0300.html</link>&gt;.</note> and SHOULD NOT include any hash functions which MUST NOT be supported according to <span class="ref"><link url="https://xmpp.org/extensions/xep-0300.html">Use of Cryptographic Hash Functions in XMPP (XEP-0300)</link></span> <note>XEP-0300: Use of Cryptographic Hash Functions in XMPP &lt;<link url="https://xmpp.org/extensions/xep-0300.html">https://xmpp.org/extensions/xep-0300.html</link>&gt;.</note>.</p>
    <p>Using the algorithm from the previous subsection, the entity calculates the input for the hash functions. It then runs the input through each hash function individually. The resulting tuples of hash algorithm and hash values constitute the <em>Capability Hash Set</em>.</p>
  </section2>

  <section2 topic="Construction of Capability Hash Nodes" anchor="algorithm-hashnodes">
    <p>The <em>Capability Hash Node</em> is obtained from a <em>Capability Hash</em> with the following simple algorithm:</p>
    <ol>
      <li>To the namespace prefix "urn:xmpp:caps#", append the name of the hash function as per <span class="ref"><link url="https://xmpp.org/extensions/xep-0300.html">Use of Cryptographic Hash Functions in XMPP (XEP-0300)</link></span> <note>XEP-0300: Use of Cryptographic Hash Functions in XMPP &lt;<link url="https://xmpp.org/extensions/xep-0300.html">https://xmpp.org/extensions/xep-0300.html</link>&gt;.</note>.</li>
      <li>Append a FULL STOP character (U+002E, ".").</li>
      <li>Append the Base64 encoded (as specified in <span class="ref"><link url="http://tools.ietf.org/html/rfc3548">RFC 3548</link></span> <note>RFC 3548: The Base16, Base32, and Base64 Data Encodings &lt;<link url="http://tools.ietf.org/html/rfc3548">http://tools.ietf.org/html/rfc3548</link>&gt;.</note>) hash value.</li>
    </ol>
    <p>The <em>Capability Hash Node</em> can be decomposed into its original components with the following algorithm:</p>
    <ol>
      <li>Remove the namespace prefix "urn:xmpp:caps#" from the input.</li>
      <li>From the <em>end</em> of the string, start searching for the FULL STOP character (U+002E, ".") separator.</li>
      <li>Split the string into the hash function and the Base64-encoded hash value at the position found in the previous step.</li>
    </ol>
  </section2>

  <section2 topic="Verification of a Capability Hash Set" anchor="algorithm-verify">
    <p>The algorithm takes a <em>Capability Hash Set</em> as input and returns successfully if the hash matches and an error otherwise.</p>
    <ol>
      <li>Pick a <em>Capability Hash</em> from the <em>Capability Hash Set</em>.</li>
      <li>Query the <em>Generating Entity</em> for disco#info on the <em>Capability Hash Node</em> for the chosen hash like described above. If the entity returns an error, abort with an error.</li>
      <li>Locally calculate the <em>Capability Hash</em> using the same hash function as in the input as described in the algorithm. If the algorithm exits with an error, abort with an error.</li>
      <li>If the hashes do not match, abort with an error.</li>
      <li>Exit successfully, the hash is verified.</li>
    </ol>
  </section2>

  <section2 topic="Examples" anchor="algorithm-example">
    <p>The two examples walk through the process of constructing a <em>Capability Hash Set</em> for SHA-256 and SHA3-256. The full algorithm for generating the hash function input is explained.</p>
    <section3 topic="Simple Example" anchor="algorithm-example-simple">
      <example caption="disco#info payload for the simple example; no XEP-0128 forms"><![CDATA[
<query xmlns="http://jabber.org/protocol/disco#info">
  <identity category="client" name="BombusMod" type="mobile"/>
  <feature var="http://jabber.org/protocol/si"/>
  <feature var="http://jabber.org/protocol/bytestreams"/>
  <feature var="http://jabber.org/protocol/chatstates"/>
  <feature var="http://jabber.org/protocol/disco#info"/>
  <feature var="http://jabber.org/protocol/disco#items"/>
  <feature var="urn:xmpp:ping"/>
  <feature var="jabber:iq:time"/>
  <feature var="jabber:iq:privacy"/>
  <feature var="jabber:iq:version"/>
  <feature var="http://jabber.org/protocol/rosterx"/>
  <feature var="urn:xmpp:time"/>
  <feature var="jabber:x:oob"/>
  <feature var="http://jabber.org/protocol/ibb"/>
  <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
  <feature var="urn:xmpp:receipts"/>
  <feature var="jabber:iq:roster"/>
  <feature var="jabber:iq:last"/>
</query>
]]></example>
    <p>The data from the example was the first entry in the <span class="ref"><link url="https://github.com/xnyhps/capsdb/">capsdb</link></span> <note><link url="https://github.com/xnyhps/capsdb/">https://github.com/xnyhps/capsdb/</link></note> hashes subdirectory which had no data forms at the time of writing. The features have been shuffled to show the sorting step in the algorithm.</p>
    <p>The algorithm starts by constructing the <em>Features String</em>. For this, the values of the 'var' attributes of the feature nodes are encoded as UTF-8 and suffixed with 0x1f (ASCII Unit Separator). The first three of those features are shown as a hexdump below:</p>
    <code>
00000000  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000010  67 2f 70 72 6f 74 6f 63  6f 6c 2f 73 69 1f        |g/protocol/si.|
0000001e

00000000  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000010  67 2f 70 72 6f 74 6f 63  6f 6c 2f 62 79 74 65 73  |g/protocol/bytes|
00000020  74 72 65 61 6d 73 1f                              |treams.|
00000027

00000000  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000010  67 2f 70 72 6f 74 6f 63  6f 6c 2f 63 68 61 74 73  |g/protocol/chats|
00000020  74 61 74 65 73 1f                                 |tates.|
00000026</code>
    <p>Note the appended 0x1f octet for each of the three strings. Now the strings are ordered using the i;octet collation and concatenated. The result is suffixed with 0x1c (ASCII File Separator), which gives the following hexdump of the final <em>Features String</em>:</p>
    <code>
00000000  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000010  67 2f 70 72 6f 74 6f 63  6f 6c 2f 62 79 74 65 73  |g/protocol/bytes|
00000020  74 72 65 61 6d 73 1f 68  74 74 70 3a 2f 2f 6a 61  |treams.http://ja|
00000030  62 62 65 72 2e 6f 72 67  2f 70 72 6f 74 6f 63 6f  |bber.org/protoco|
00000040  6c 2f 63 68 61 74 73 74  61 74 65 73 1f 68 74 74  |l/chatstates.htt|
00000050  70 3a 2f 2f 6a 61 62 62  65 72 2e 6f 72 67 2f 70  |p://jabber.org/p|
00000060  72 6f 74 6f 63 6f 6c 2f  64 69 73 63 6f 23 69 6e  |rotocol/disco#in|
00000070  66 6f 1f 68 74 74 70 3a  2f 2f 6a 61 62 62 65 72  |fo.http://jabber|
00000080  2e 6f 72 67 2f 70 72 6f  74 6f 63 6f 6c 2f 64 69  |.org/protocol/di|
00000090  73 63 6f 23 69 74 65 6d  73 1f 68 74 74 70 3a 2f  |sco#items.http:/|
000000a0  2f 6a 61 62 62 65 72 2e  6f 72 67 2f 70 72 6f 74  |/jabber.org/prot|
000000b0  6f 63 6f 6c 2f 69 62 62  1f 68 74 74 70 3a 2f 2f  |ocol/ibb.http://|
000000c0  6a 61 62 62 65 72 2e 6f  72 67 2f 70 72 6f 74 6f  |jabber.org/proto|
000000d0  63 6f 6c 2f 72 6f 73 74  65 72 78 1f 68 74 74 70  |col/rosterx.http|
000000e0  3a 2f 2f 6a 61 62 62 65  72 2e 6f 72 67 2f 70 72  |://jabber.org/pr|
000000f0  6f 74 6f 63 6f 6c 2f 73  69 1f 68 74 74 70 3a 2f  |otocol/si.http:/|
00000100  2f 6a 61 62 62 65 72 2e  6f 72 67 2f 70 72 6f 74  |/jabber.org/prot|
00000110  6f 63 6f 6c 2f 73 69 2f  70 72 6f 66 69 6c 65 2f  |ocol/si/profile/|
00000120  66 69 6c 65 2d 74 72 61  6e 73 66 65 72 1f 6a 61  |file-transfer.ja|
00000130  62 62 65 72 3a 69 71 3a  6c 61 73 74 1f 6a 61 62  |bber:iq:last.jab|
00000140  62 65 72 3a 69 71 3a 70  72 69 76 61 63 79 1f 6a  |ber:iq:privacy.j|
00000150  61 62 62 65 72 3a 69 71  3a 72 6f 73 74 65 72 1f  |abber:iq:roster.|
00000160  6a 61 62 62 65 72 3a 69  71 3a 74 69 6d 65 1f 6a  |jabber:iq:time.j|
00000170  61 62 62 65 72 3a 69 71  3a 76 65 72 73 69 6f 6e  |abber:iq:version|
00000180  1f 6a 61 62 62 65 72 3a  78 3a 6f 6f 62 1f 75 72  |.jabber:x:oob.ur|
00000190  6e 3a 78 6d 70 70 3a 70  69 6e 67 1f 75 72 6e 3a  |n:xmpp:ping.urn:|
000001a0  78 6d 70 70 3a 72 65 63  65 69 70 74 73 1f 75 72  |xmpp:receipts.ur|
000001b0  6e 3a 78 6d 70 70 3a 74  69 6d 65 1f 1c           |n:xmpp:time..|
000001bd</code>
    <p>For the <em>Identities String</em>, first the character data of the 'category', 'type', 'xml:lang' and 'name' attributes is encoded as UTF-8 and suffixed with 0x1f (ASCII Unit Separator). The resulting individual strings have the following hexdumps:</p>
    <code>
00000000  63 6c 69 65 6e 74 1f                              |client.|
00000007

00000000  6d 6f 62 69 6c 65 1f                              |mobile.|
00000007

00000000  1f                                                |.|
00000001

00000000  42 6f 6d 62 75 73 4d 6f  64 1f                    |BombusMod.|
0000000a</code>
    <p>The strings are now joined together and the result is suffixed with 0x1e (ASCII Record Separator):</p>
    <code>
00000000  63 6c 69 65 6e 74 1f 6d  6f 62 69 6c 65 1f 1f 42  |client.mobile..B|
00000010  6f 6d 62 75 73 4d 6f 64  1f 1e                    |ombusMod..|
0000001a</code>
    <p>Normally, a sorting step would occur here. As the example only has a single string, the sorting and joining is a no-op. The string is now suffixed with 0x1c (ASCII File Separator) to get the <em>Identities String</em>:</p>
    <code>
00000000  63 6c 69 65 6e 74 1f 6d  6f 62 69 6c 65 1f 1f 42  |client.mobile..B|
00000010  6f 6d 62 75 73 4d 6f 64  1f 1e 1c                 |ombusMod...|
0000001b</code>
    <p>The <em>Extensions String</em> is simply the 0x1c (ASCII File Separator) used to terminate it as no extensions are contained in the example. Thus, the final input for the hash function is, as hexdump:</p>
    <code>
00000000  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000010  67 2f 70 72 6f 74 6f 63  6f 6c 2f 62 79 74 65 73  |g/protocol/bytes|
00000020  74 72 65 61 6d 73 1f 68  74 74 70 3a 2f 2f 6a 61  |treams.http://ja|
00000030  62 62 65 72 2e 6f 72 67  2f 70 72 6f 74 6f 63 6f  |bber.org/protoco|
00000040  6c 2f 63 68 61 74 73 74  61 74 65 73 1f 68 74 74  |l/chatstates.htt|
00000050  70 3a 2f 2f 6a 61 62 62  65 72 2e 6f 72 67 2f 70  |p://jabber.org/p|
00000060  72 6f 74 6f 63 6f 6c 2f  64 69 73 63 6f 23 69 6e  |rotocol/disco#in|
00000070  66 6f 1f 68 74 74 70 3a  2f 2f 6a 61 62 62 65 72  |fo.http://jabber|
00000080  2e 6f 72 67 2f 70 72 6f  74 6f 63 6f 6c 2f 64 69  |.org/protocol/di|
00000090  73 63 6f 23 69 74 65 6d  73 1f 68 74 74 70 3a 2f  |sco#items.http:/|
000000a0  2f 6a 61 62 62 65 72 2e  6f 72 67 2f 70 72 6f 74  |/jabber.org/prot|
000000b0  6f 63 6f 6c 2f 69 62 62  1f 68 74 74 70 3a 2f 2f  |ocol/ibb.http://|
000000c0  6a 61 62 62 65 72 2e 6f  72 67 2f 70 72 6f 74 6f  |jabber.org/proto|
000000d0  63 6f 6c 2f 72 6f 73 74  65 72 78 1f 68 74 74 70  |col/rosterx.http|
000000e0  3a 2f 2f 6a 61 62 62 65  72 2e 6f 72 67 2f 70 72  |://jabber.org/pr|
000000f0  6f 74 6f 63 6f 6c 2f 73  69 1f 68 74 74 70 3a 2f  |otocol/si.http:/|
00000100  2f 6a 61 62 62 65 72 2e  6f 72 67 2f 70 72 6f 74  |/jabber.org/prot|
00000110  6f 63 6f 6c 2f 73 69 2f  70 72 6f 66 69 6c 65 2f  |ocol/si/profile/|
00000120  66 69 6c 65 2d 74 72 61  6e 73 66 65 72 1f 6a 61  |file-transfer.ja|
00000130  62 62 65 72 3a 69 71 3a  6c 61 73 74 1f 6a 61 62  |bber:iq:last.jab|
00000140  62 65 72 3a 69 71 3a 70  72 69 76 61 63 79 1f 6a  |ber:iq:privacy.j|
00000150  61 62 62 65 72 3a 69 71  3a 72 6f 73 74 65 72 1f  |abber:iq:roster.|
00000160  6a 61 62 62 65 72 3a 69  71 3a 74 69 6d 65 1f 6a  |jabber:iq:time.j|
00000170  61 62 62 65 72 3a 69 71  3a 76 65 72 73 69 6f 6e  |abber:iq:version|
00000180  1f 6a 61 62 62 65 72 3a  78 3a 6f 6f 62 1f 75 72  |.jabber:x:oob.ur|
00000190  6e 3a 78 6d 70 70 3a 70  69 6e 67 1f 75 72 6e 3a  |n:xmpp:ping.urn:|
000001a0  78 6d 70 70 3a 72 65 63  65 69 70 74 73 1f 75 72  |xmpp:receipts.ur|
000001b0  6e 3a 78 6d 70 70 3a 74  69 6d 65 1f 1c 63 6c 69  |n:xmpp:time..cli|
000001c0  65 6e 74 1f 6d 6f 62 69  6c 65 1f 1f 42 6f 6d 62  |ent.mobile..Bomb|
000001d0  75 73 4d 6f 64 1f 1e 1c  1c                       |usMod....|
000001d9</code>
    <p>Running this octet string through the hash functions leads as to the following <em>Capability Hash Set</em>:</p>
    <code><![CDATA[
<c xmlns="urn:xmpp:caps">
  <hash xmlns="urn:xmpp:hashes:2" algo="sha-256">kzBZbkqJ3ADrj7v08reD1qcWUwNGHaidNUgD7nHpiw8=</hash>
  <hash xmlns="urn:xmpp:hashes:2" algo="sha3-256">79mdYAfU9rEdTOcWDO7UEAt6E56SUzk/g6TnqUeuD9Q=</hash>
</c>]]></code>
    </section3>
    <section3 topic="Complex Example" anchor="algorithm-examples-complex">
      <example caption="disco#info payload for the complex example with XEP-0128 forms"><![CDATA[
<query xmlns="http://jabber.org/protocol/disco#info">
  <identity category="client" name="Tkabber" type="pc" xml:lang="en"/>
  <identity category="client" name="Ткаббер" type="pc" xml:lang="ru"/>
  <feature var="games:board"/>
  <feature var="http://jabber.org/protocol/activity"/>
  <feature var="http://jabber.org/protocol/activity+notify"/>
  <feature var="http://jabber.org/protocol/bytestreams"/>
  <feature var="http://jabber.org/protocol/chatstates"/>
  <feature var="http://jabber.org/protocol/commands"/>
  <feature var="http://jabber.org/protocol/disco#info"/>
  <feature var="http://jabber.org/protocol/disco#items"/>
  <feature var="http://jabber.org/protocol/evil"/>
  <feature var="http://jabber.org/protocol/feature-neg"/>
  <feature var="http://jabber.org/protocol/geoloc"/>
  <feature var="http://jabber.org/protocol/geoloc+notify"/>
  <feature var="http://jabber.org/protocol/ibb"/>
  <feature var="http://jabber.org/protocol/iqibb"/>
  <feature var="http://jabber.org/protocol/mood"/>
  <feature var="http://jabber.org/protocol/mood+notify"/>
  <feature var="http://jabber.org/protocol/rosterx"/>
  <feature var="http://jabber.org/protocol/si"/>
  <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
  <feature var="http://jabber.org/protocol/tune"/>
  <feature var="http://www.facebook.com/xmpp/messages"/>
  <feature var="http://www.xmpp.org/extensions/xep-0084.html#ns-metadata+notify"/>
  <feature var="jabber:iq:avatar"/>
  <feature var="jabber:iq:browse"/>
  <feature var="jabber:iq:dtcp"/>
  <feature var="jabber:iq:filexfer"/>
  <feature var="jabber:iq:ibb"/>
  <feature var="jabber:iq:inband"/>
  <feature var="jabber:iq:jidlink"/>
  <feature var="jabber:iq:last"/>
  <feature var="jabber:iq:oob"/>
  <feature var="jabber:iq:privacy"/>
  <feature var="jabber:iq:roster"/>
  <feature var="jabber:iq:time"/>
  <feature var="jabber:iq:version"/>
  <feature var="jabber:x:data"/>
  <feature var="jabber:x:event"/>
  <feature var="jabber:x:oob"/>
  <feature var="urn:xmpp:avatar:metadata+notify"/>
  <feature var="urn:xmpp:ping"/>
  <feature var="urn:xmpp:receipts"/>
  <feature var="urn:xmpp:time"/>
  <x xmlns="jabber:x:data" type="result">
    <field type="hidden" var="FORM_TYPE">
      <value>urn:xmpp:dataforms:softwareinfo</value>
    </field>
    <field var="software">
      <value>Tkabber</value>
    </field>
    <field var="software_version">
      <value>0.11.1-svn-20111216-mod (Tcl/Tk 8.6b2)</value>
    </field>
    <field var="os">
      <value>Windows</value>
    </field>
    <field var="os_version">
      <value>XP</value>
    </field>
  </x>
</query>
]]></example>
    <p>The data from the example is the shortest entry from the <span class="ref"><link url="https://github.com/xnyhps/capsdb/">capsdb</link></span> <note><link url="https://github.com/xnyhps/capsdb/">https://github.com/xnyhps/capsdb/</link></note> hashes subdirectory which had data forms and multiple identities at the time of writing. The features have been shuffled to show the sorting step in the algorithm.</p>
    <p>We skip over the process for the <em>Features String</em> and only present the final result encoded as base64 for reference:</p>
    <code>
Z2FtZXM6Ym9hcmQfaHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvYWN0aXZpdHkfaHR0cDovL2ph
YmJlci5vcmcvcHJvdG9jb2wvYWN0aXZpdHkrbm90aWZ5H2h0dHA6Ly9qYWJiZXIub3JnL3Byb3Rv
Y29sL2J5dGVzdHJlYW1zH2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2NoYXRzdGF0ZXMfaHR0
cDovL2phYmJlci5vcmcvcHJvdG9jb2wvY29tbWFuZHMfaHR0cDovL2phYmJlci5vcmcvcHJvdG9j
b2wvZGlzY28jaW5mbx9odHRwOi8vamFiYmVyLm9yZy9wcm90b2NvbC9kaXNjbyNpdGVtcx9odHRw
Oi8vamFiYmVyLm9yZy9wcm90b2NvbC9ldmlsH2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2Zl
YXR1cmUtbmVnH2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2dlb2xvYx9odHRwOi8vamFiYmVy
Lm9yZy9wcm90b2NvbC9nZW9sb2Mrbm90aWZ5H2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2li
Yh9odHRwOi8vamFiYmVyLm9yZy9wcm90b2NvbC9pcWliYh9odHRwOi8vamFiYmVyLm9yZy9wcm90
b2NvbC9tb29kH2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL21vb2Qrbm90aWZ5H2h0dHA6Ly9q
YWJiZXIub3JnL3Byb3RvY29sL3Jvc3RlcngfaHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvc2kf
aHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvc2kvcHJvZmlsZS9maWxlLXRyYW5zZmVyH2h0dHA6
Ly9qYWJiZXIub3JnL3Byb3RvY29sL3R1bmUfaHR0cDovL3d3dy5mYWNlYm9vay5jb20veG1wcC9t
ZXNzYWdlcx9odHRwOi8vd3d3LnhtcHAub3JnL2V4dGVuc2lvbnMveGVwLTAwODQuaHRtbCNucy1t
ZXRhZGF0YStub3RpZnkfamFiYmVyOmlxOmF2YXRhch9qYWJiZXI6aXE6YnJvd3NlH2phYmJlcjpp
cTpkdGNwH2phYmJlcjppcTpmaWxleGZlch9qYWJiZXI6aXE6aWJiH2phYmJlcjppcTppbmJhbmQf
amFiYmVyOmlxOmppZGxpbmsfamFiYmVyOmlxOmxhc3QfamFiYmVyOmlxOm9vYh9qYWJiZXI6aXE6
cHJpdmFjeR9qYWJiZXI6aXE6cm9zdGVyH2phYmJlcjppcTp0aW1lH2phYmJlcjppcTp2ZXJzaW9u
H2phYmJlcjp4OmRhdGEfamFiYmVyOng6ZXZlbnQfamFiYmVyOng6b29iH3Vybjp4bXBwOmF2YXRh
cjptZXRhZGF0YStub3RpZnkfdXJuOnhtcHA6cGluZx91cm46eG1wcDpyZWNlaXB0cx91cm46eG1w
cDp0aW1lHxw=</code>
    <p>In the previous example, it was already shown how the individual parts of each &lt;identity/&gt; element are combined. We get the following octet strings as hexdumps:</p>
    <code>
00000000  63 6c 69 65 6e 74 1f 70  63 1f 72 75 1f d0 a2 d0  |client.pc.ru....|
00000010  ba d0 b0 d0 b1 d0 b1 d0  b5 d1 80 1f 1e           |.............|
0000001d

00000000  63 6c 69 65 6e 74 1f 70  63 1f 65 6e 1f 54 6b 61  |client.pc.en.Tka|
00000010  62 62 65 72 1f 1e                                 |bber..|
00000016</code>
    <p>The second string is ordered before the first string in the i;octet collation and afterwards the strings are joined and the result is suffixed with 0x1c (ASCII File Separator) to close the identities part of the input. The final <em>Identities String</em> is thus, as hexdump:</p>
    <code>
00000000  63 6c 69 65 6e 74 1f 70  63 1f 65 6e 1f 54 6b 61  |client.pc.en.Tka|
00000010  62 62 65 72 1f 1e 63 6c  69 65 6e 74 1f 70 63 1f  |bber..client.pc.|
00000020  72 75 1f d0 a2 d0 ba d0  b0 d0 b1 d0 b1 d0 b5 d1  |ru..............|
00000030  80 1f 1e 1c                                       |....|
00000034</code>
    <p>The example has a <span class="ref"><link url="https://xmpp.org/extensions/xep-0128.html">Service Discovery Extensions (XEP-0128)</link></span> <note>XEP-0128: Service Discovery Extensions &lt;<link url="https://xmpp.org/extensions/xep-0128.html">https://xmpp.org/extensions/xep-0128.html</link>&gt;.</note> form. For each field, a string consisting of the 'var' attributes character data and the values is created as per the algorithm:</p>
    <code>
00000000  46 4f 52 4d 5f 54 59 50  45 1f 75 72 6e 3a 78 6d  |FORM_TYPE.urn:xm|
00000010  70 70 3a 64 61 74 61 66  6f 72 6d 73 3a 73 6f 66  |pp:dataforms:sof|
00000020  74 77 61 72 65 69 6e 66  6f 1f 1e                 |twareinfo..|
0000002b

00000000  73 6f 66 74 77 61 72 65  1f 54 6b 61 62 62 65 72  |software.Tkabber|
00000010  1f 1e                                             |..|
00000012

00000000  73 6f 66 74 77 61 72 65  5f 76 65 72 73 69 6f 6e  |software_version|
00000010  1f 30 2e 31 31 2e 31 2d  73 76 6e 2d 32 30 31 31  |.0.11.1-svn-2011|
00000020  31 32 31 36 2d 6d 6f 64  20 28 54 63 6c 2f 54 6b  |1216-mod (Tcl/Tk|
00000030  20 38 2e 36 62 32 29 1f  1e                       | 8.6b2)..|
00000039

00000000  6f 73 1f 57 69 6e 64 6f  77 73 1f 1e              |os.Windows..|
0000000c
</code>
    <p>The strings need to be sorted using i;octet and joined together. The result is suffixed with 0x1d (ASCII Group Separator), which closes the form. As this is the only form, the resulting <em>Extensions String</em> is obtained by adding a 0x1c (ASCII File Separator) to close the extensions section of the hash input:</p>
    <code>
00000000  46 4f 52 4d 5f 54 59 50  45 1f 75 72 6e 3a 78 6d  |FORM_TYPE.urn:xm|
00000010  70 70 3a 64 61 74 61 66  6f 72 6d 73 3a 73 6f 66  |pp:dataforms:sof|
00000020  74 77 61 72 65 69 6e 66  6f 1f 1e 6f 73 1f 57 69  |twareinfo..os.Wi|
00000030  6e 64 6f 77 73 1f 1e 6f  73 5f 76 65 72 73 69 6f  |ndows..os_versio|
00000040  6e 1f 58 50 1f 1e 73 6f  66 74 77 61 72 65 1f 54  |n.XP..software.T|
00000050  6b 61 62 62 65 72 1f 1e  73 6f 66 74 77 61 72 65  |kabber..software|
00000060  5f 76 65 72 73 69 6f 6e  1f 30 2e 31 31 2e 31 2d  |_version.0.11.1-|
00000070  73 76 6e 2d 32 30 31 31  31 32 31 36 2d 6d 6f 64  |svn-20111216-mod|
00000080  20 28 54 63 6c 2f 54 6b  20 38 2e 36 62 32 29 1f  | (Tcl/Tk 8.6b2).|
00000090  1e 1d 1c                                          |...|
00000093</code>
    <p>Note the "os" field is now before the other fields but after "FORM_TYPE", due to the sorting.</p>
    <p>The final hash function input is obtained by concatenating the <em>Features String</em>, <em>Identities String</em> and <em>Extensions String</em>:</p>
    <code>
00000000  67 61 6d 65 73 3a 62 6f  61 72 64 1f 68 74 74 70  |games:board.http|
00000010  3a 2f 2f 6a 61 62 62 65  72 2e 6f 72 67 2f 70 72  |://jabber.org/pr|
00000020  6f 74 6f 63 6f 6c 2f 61  63 74 69 76 69 74 79 1f  |otocol/activity.|
00000030  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000040  67 2f 70 72 6f 74 6f 63  6f 6c 2f 61 63 74 69 76  |g/protocol/activ|
00000050  69 74 79 2b 6e 6f 74 69  66 79 1f 68 74 74 70 3a  |ity+notify.http:|
00000060  2f 2f 6a 61 62 62 65 72  2e 6f 72 67 2f 70 72 6f  |//jabber.org/pro|
00000070  74 6f 63 6f 6c 2f 62 79  74 65 73 74 72 65 61 6d  |tocol/bytestream|
00000080  73 1f 68 74 74 70 3a 2f  2f 6a 61 62 62 65 72 2e  |s.http://jabber.|
00000090  6f 72 67 2f 70 72 6f 74  6f 63 6f 6c 2f 63 68 61  |org/protocol/cha|
000000a0  74 73 74 61 74 65 73 1f  68 74 74 70 3a 2f 2f 6a  |tstates.http://j|
000000b0  61 62 62 65 72 2e 6f 72  67 2f 70 72 6f 74 6f 63  |abber.org/protoc|
000000c0  6f 6c 2f 63 6f 6d 6d 61  6e 64 73 1f 68 74 74 70  |ol/commands.http|
000000d0  3a 2f 2f 6a 61 62 62 65  72 2e 6f 72 67 2f 70 72  |://jabber.org/pr|
000000e0  6f 74 6f 63 6f 6c 2f 64  69 73 63 6f 23 69 6e 66  |otocol/disco#inf|
000000f0  6f 1f 68 74 74 70 3a 2f  2f 6a 61 62 62 65 72 2e  |o.http://jabber.|
00000100  6f 72 67 2f 70 72 6f 74  6f 63 6f 6c 2f 64 69 73  |org/protocol/dis|
00000110  63 6f 23 69 74 65 6d 73  1f 68 74 74 70 3a 2f 2f  |co#items.http://|
00000120  6a 61 62 62 65 72 2e 6f  72 67 2f 70 72 6f 74 6f  |jabber.org/proto|
00000130  63 6f 6c 2f 65 76 69 6c  1f 68 74 74 70 3a 2f 2f  |col/evil.http://|
00000140  6a 61 62 62 65 72 2e 6f  72 67 2f 70 72 6f 74 6f  |jabber.org/proto|
00000150  63 6f 6c 2f 66 65 61 74  75 72 65 2d 6e 65 67 1f  |col/feature-neg.|
00000160  68 74 74 70 3a 2f 2f 6a  61 62 62 65 72 2e 6f 72  |http://jabber.or|
00000170  67 2f 70 72 6f 74 6f 63  6f 6c 2f 67 65 6f 6c 6f  |g/protocol/geolo|
00000180  63 1f 68 74 74 70 3a 2f  2f 6a 61 62 62 65 72 2e  |c.http://jabber.|
00000190  6f 72 67 2f 70 72 6f 74  6f 63 6f 6c 2f 67 65 6f  |org/protocol/geo|
000001a0  6c 6f 63 2b 6e 6f 74 69  66 79 1f 68 74 74 70 3a  |loc+notify.http:|
000001b0  2f 2f 6a 61 62 62 65 72  2e 6f 72 67 2f 70 72 6f  |//jabber.org/pro|
000001c0  74 6f 63 6f 6c 2f 69 62  62 1f 68 74 74 70 3a 2f  |tocol/ibb.http:/|
000001d0  2f 6a 61 62 62 65 72 2e  6f 72 67 2f 70 72 6f 74  |/jabber.org/prot|
000001e0  6f 63 6f 6c 2f 69 71 69  62 62 1f 68 74 74 70 3a  |ocol/iqibb.http:|
000001f0  2f 2f 6a 61 62 62 65 72  2e 6f 72 67 2f 70 72 6f  |//jabber.org/pro|
00000200  74 6f 63 6f 6c 2f 6d 6f  6f 64 1f 68 74 74 70 3a  |tocol/mood.http:|
00000210  2f 2f 6a 61 62 62 65 72  2e 6f 72 67 2f 70 72 6f  |//jabber.org/pro|
00000220  74 6f 63 6f 6c 2f 6d 6f  6f 64 2b 6e 6f 74 69 66  |tocol/mood+notif|
00000230  79 1f 68 74 74 70 3a 2f  2f 6a 61 62 62 65 72 2e  |y.http://jabber.|
00000240  6f 72 67 2f 70 72 6f 74  6f 63 6f 6c 2f 72 6f 73  |org/protocol/ros|
00000250  74 65 72 78 1f 68 74 74  70 3a 2f 2f 6a 61 62 62  |terx.http://jabb|
00000260  65 72 2e 6f 72 67 2f 70  72 6f 74 6f 63 6f 6c 2f  |er.org/protocol/|
00000270  73 69 1f 68 74 74 70 3a  2f 2f 6a 61 62 62 65 72  |si.http://jabber|
00000280  2e 6f 72 67 2f 70 72 6f  74 6f 63 6f 6c 2f 73 69  |.org/protocol/si|
00000290  2f 70 72 6f 66 69 6c 65  2f 66 69 6c 65 2d 74 72  |/profile/file-tr|
000002a0  61 6e 73 66 65 72 1f 68  74 74 70 3a 2f 2f 6a 61  |ansfer.http://ja|
000002b0  62 62 65 72 2e 6f 72 67  2f 70 72 6f 74 6f 63 6f  |bber.org/protoco|
000002c0  6c 2f 74 75 6e 65 1f 68  74 74 70 3a 2f 2f 77 77  |l/tune.http://ww|
000002d0  77 2e 66 61 63 65 62 6f  6f 6b 2e 63 6f 6d 2f 78  |w.facebook.com/x|
000002e0  6d 70 70 2f 6d 65 73 73  61 67 65 73 1f 68 74 74  |mpp/messages.htt|
000002f0  70 3a 2f 2f 77 77 77 2e  78 6d 70 70 2e 6f 72 67  |p://www.xmpp.org|
00000300  2f 65 78 74 65 6e 73 69  6f 6e 73 2f 78 65 70 2d  |/extensions/xep-|
00000310  30 30 38 34 2e 68 74 6d  6c 23 6e 73 2d 6d 65 74  |0084.html#ns-met|
00000320  61 64 61 74 61 2b 6e 6f  74 69 66 79 1f 6a 61 62  |adata+notify.jab|
00000330  62 65 72 3a 69 71 3a 61  76 61 74 61 72 1f 6a 61  |ber:iq:avatar.ja|
00000340  62 62 65 72 3a 69 71 3a  62 72 6f 77 73 65 1f 6a  |bber:iq:browse.j|
00000350  61 62 62 65 72 3a 69 71  3a 64 74 63 70 1f 6a 61  |abber:iq:dtcp.ja|
00000360  62 62 65 72 3a 69 71 3a  66 69 6c 65 78 66 65 72  |bber:iq:filexfer|
00000370  1f 6a 61 62 62 65 72 3a  69 71 3a 69 62 62 1f 6a  |.jabber:iq:ibb.j|
00000380  61 62 62 65 72 3a 69 71  3a 69 6e 62 61 6e 64 1f  |abber:iq:inband.|
00000390  6a 61 62 62 65 72 3a 69  71 3a 6a 69 64 6c 69 6e  |jabber:iq:jidlin|
000003a0  6b 1f 6a 61 62 62 65 72  3a 69 71 3a 6c 61 73 74  |k.jabber:iq:last|
000003b0  1f 6a 61 62 62 65 72 3a  69 71 3a 6f 6f 62 1f 6a  |.jabber:iq:oob.j|
000003c0  61 62 62 65 72 3a 69 71  3a 70 72 69 76 61 63 79  |abber:iq:privacy|
000003d0  1f 6a 61 62 62 65 72 3a  69 71 3a 72 6f 73 74 65  |.jabber:iq:roste|
000003e0  72 1f 6a 61 62 62 65 72  3a 69 71 3a 74 69 6d 65  |r.jabber:iq:time|
000003f0  1f 6a 61 62 62 65 72 3a  69 71 3a 76 65 72 73 69  |.jabber:iq:versi|
00000400  6f 6e 1f 6a 61 62 62 65  72 3a 78 3a 64 61 74 61  |on.jabber:x:data|
00000410  1f 6a 61 62 62 65 72 3a  78 3a 65 76 65 6e 74 1f  |.jabber:x:event.|
00000420  6a 61 62 62 65 72 3a 78  3a 6f 6f 62 1f 75 72 6e  |jabber:x:oob.urn|
00000430  3a 78 6d 70 70 3a 61 76  61 74 61 72 3a 6d 65 74  |:xmpp:avatar:met|
00000440  61 64 61 74 61 2b 6e 6f  74 69 66 79 1f 75 72 6e  |adata+notify.urn|
00000450  3a 78 6d 70 70 3a 70 69  6e 67 1f 75 72 6e 3a 78  |:xmpp:ping.urn:x|
00000460  6d 70 70 3a 72 65 63 65  69 70 74 73 1f 75 72 6e  |mpp:receipts.urn|
00000470  3a 78 6d 70 70 3a 74 69  6d 65 1f 1c 63 6c 69 65  |:xmpp:time..clie|
00000480  6e 74 1f 70 63 1f 65 6e  1f 54 6b 61 62 62 65 72  |nt.pc.en.Tkabber|
00000490  1f 1e 63 6c 69 65 6e 74  1f 70 63 1f 72 75 1f d0  |..client.pc.ru..|
000004a0  a2 d0 ba d0 b0 d0 b1 d0  b1 d0 b5 d1 80 1f 1e 1c  |................|
000004b0  46 4f 52 4d 5f 54 59 50  45 1f 75 72 6e 3a 78 6d  |FORM_TYPE.urn:xm|
000004c0  70 70 3a 64 61 74 61 66  6f 72 6d 73 3a 73 6f 66  |pp:dataforms:sof|
000004d0  74 77 61 72 65 69 6e 66  6f 1f 1e 6f 73 1f 57 69  |twareinfo..os.Wi|
000004e0  6e 64 6f 77 73 1f 1e 6f  73 5f 76 65 72 73 69 6f  |ndows..os_versio|
000004f0  6e 1f 58 50 1f 1e 73 6f  66 74 77 61 72 65 1f 54  |n.XP..software.T|
00000500  6b 61 62 62 65 72 1f 1e  73 6f 66 74 77 61 72 65  |kabber..software|
00000510  5f 76 65 72 73 69 6f 6e  1f 30 2e 31 31 2e 31 2d  |_version.0.11.1-|
00000520  73 76 6e 2d 32 30 31 31  31 32 31 36 2d 6d 6f 64  |svn-20111216-mod|
00000530  20 28 54 63 6c 2f 54 6b  20 38 2e 36 62 32 29 1f  | (Tcl/Tk 8.6b2).|
00000540  1e 1d 1c                                          |...|
00000543</code>
    <p>Feeding the concatenated octet string as input to the hash functions yields the following <em>Capability Hash Set</em>:</p>
    <code><![CDATA[
<c xmlns="urn:xmpp:caps">
  <hash xmlns="urn:xmpp:hashes:2" algo="sha-256">u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=</hash>
  <hash xmlns="urn:xmpp:hashes:2" algo="sha3-256">XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=</hash>
</c>]]></code>
    </section3>
  </section2>
</section1>

<section1 topic="Use Cases" anchor="usecases">
  <section2 topic="Advertising Support" anchor="usecases-support">
    <p>If an entity supports <em>Entity Capabilities 2.0</em>, it MUST advertise the fact by returning a feature of "urn:xmpp:caps".</p>
    <example caption="Response to a disco#info request"><![CDATA[
<iq from='romeo@montague.lit/orchard'
    id='disco1'
    to='juliet@capulet.lit/chamber'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    ...
    <feature var='urn:xmpp:caps'/>
    ...
  </query>
</iq>
]]></example>
  </section2>
  <section2 topic="Advertisement of Support and Capabilities by Servers" anchor="usecases-stream-feature">
    <p>A server MAY advertise its support for this protocol as well as the current hashes in the stream features.</p>
    <example caption="Stream Features of a server"><![CDATA[
<stream:features>
  ...
  <c xmlns="urn:xmpp:caps">
    <hash xmlns="urn:xmpp:hashes:2" algo="sha-256">K1Njy3HZBThlo4moOD5gBGhn0U0oK7/CbfLlIUDi6o4=</hash>
    <hash xmlns="urn:xmpp:hashes:2" algo="sha3-256">+sDTQqBmX6iG/X3zjt06fjZMBBqL/723knFIyRf0sg8=</hash>
  </c>
  ...
</stream:features>
]]></example>
    <p>When a connected client or peer server sends a service discovery information request to determine the entity capabilities of a server that advertises capabilities via the stream feature, the requesting entity MUST send the disco#info request to the server's JID as provided in the 'from' attribute of the response stream header. To enable this functionality, a server that advertises support for entity capabilities MUST provide a 'from' address in its response stream headers, in accordance with <span class="ref"><link url="http://tools.ietf.org/html/rfc6120">RFC 6120</link></span> <note>RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core &lt;<link url="http://tools.ietf.org/html/rfc6120">http://tools.ietf.org/html/rfc6120</link>&gt;.</note>.</p>
  </section2>
  <section2 topic="Advertising Support of Caps Optimizations" anchor="usecases-support">
    <p>If a server supports Caps Optimizations, it MUST advertise the fact by returning a feature of "urn:xmpp:caps:optimize".</p>
    <example caption="Response to a disco#info request"><![CDATA[
<iq from='montague.lit'
    id='disco2'
    to='romeo@montague.lit/chamber'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    ...
    <feature var='urn:xmpp:caps'/>
    <feature var='urn:xmpp:caps:optimize'/>
    ...
  </query>
</iq>
]]></example>
  </section2>
  <section2 topic="Broadcasting Entity Capabilities" anchor="usecases-broadcast">
    <p>An entity publishes the current <em>Capability Hash Set</em> in presence stanzas it sends:</p>
    <example caption="Presence broadcast with hashes"><![CDATA[
<presence from='juliet@capulet.lit'>
  <c xmlns="urn:xmpp:caps">
    <hash xmlns="urn:xmpp:hashes:2" algo="sha-256">u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=</hash>
    <hash xmlns="urn:xmpp:hashes:2" algo="sha3-256">XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=</hash>
  </c>
</presence>
]]></example>
    <p>The &lt;hash/&gt; element is specified by <span class="ref"><link url="https://xmpp.org/extensions/xep-0300.html">Use of Cryptographic Hash Functions in XMPP (XEP-0300)</link></span> <note>XEP-0300: Use of Cryptographic Hash Functions in XMPP &lt;<link url="https://xmpp.org/extensions/xep-0300.html">https://xmpp.org/extensions/xep-0300.html</link>&gt;.</note> and is used to transport the <em>Capability Hashes</em>.</p>
  </section2>
  <section2 topic="Service Discovery Query for a Specific Hash Value" anchor="usecases-hash-query">
    <p>To query the <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> information for a specific <em>Capability Hash</em> value, an entity MUST query a Service Discovery node equal to the <em>Capability Hash Node</em><note>As outlined in the Business Rules, this statement does not oblige an entity to actually perform this query.</note>.</p>
    <p>An entity is free to choose for which <em>Capability Hash</em> of a <em>Capability Hash Set</em> the request is sent.</p>
    <example caption="Service Discovery request in response to a broadcast Capability Hash Set"><![CDATA[
<presence from='juliet@capulet.lit/chamber' to='romeo@montague.lit/orchard'>
  <c xmlns="urn:xmpp:caps">
    <hash xmlns="urn:xmpp:hashes:2" algo="sha-256">u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=</hash>
    <hash xmlns="urn:xmpp:hashes:2" algo="sha3-256">XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=</hash>
  </c>
</presence>

<iq from='romeo@montague.lit/orchard'
    id='disco3'
    to='juliet@capulet.lit/chamber'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='urn:xmpp:caps#sha-256.u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY='/>
</iq>

<iq from='juliet@capulet.lit/chamber'
    id='disco3'
    to='romeo@montague.lit/orchard'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='urn:xmpp:caps#sha-256.u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY='>
    <identity category="client" name="Tkabber" type="pc" xml:lang="en"/>
    <identity category="client" name="Ткаббер" type="pc" xml:lang="ru"/>
    <feature var="games:board"/>
    <feature var="http://jabber.org/protocol/activity"/>
    <feature var="http://jabber.org/protocol/activity+notify"/>
    <feature var="http://jabber.org/protocol/bytestreams"/>
    <feature var="http://jabber.org/protocol/chatstates"/>
    <feature var="http://jabber.org/protocol/commands"/>
    <feature var="http://jabber.org/protocol/disco#info"/>
    <feature var="http://jabber.org/protocol/disco#items"/>
    <feature var="http://jabber.org/protocol/evil"/>
    <feature var="http://jabber.org/protocol/feature-neg"/>
    <feature var="http://jabber.org/protocol/geoloc"/>
    <feature var="http://jabber.org/protocol/geoloc+notify"/>
    <feature var="http://jabber.org/protocol/ibb"/>
    <feature var="http://jabber.org/protocol/iqibb"/>
    <feature var="http://jabber.org/protocol/mood"/>
    <feature var="http://jabber.org/protocol/mood+notify"/>
    <feature var="http://jabber.org/protocol/rosterx"/>
    <feature var="http://jabber.org/protocol/si"/>
    <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
    <feature var="http://jabber.org/protocol/tune"/>
    <feature var="http://www.facebook.com/xmpp/messages"/>
    <feature var="http://www.xmpp.org/extensions/xep-0084.html#ns-metadata+notify"/>
    <feature var="jabber:iq:avatar"/>
    <feature var="jabber:iq:browse"/>
    <feature var="jabber:iq:dtcp"/>
    <feature var="jabber:iq:filexfer"/>
    <feature var="jabber:iq:ibb"/>
    <feature var="jabber:iq:inband"/>
    <feature var="jabber:iq:jidlink"/>
    <feature var="jabber:iq:last"/>
    <feature var="jabber:iq:oob"/>
    <feature var="jabber:iq:privacy"/>
    <feature var="jabber:iq:roster"/>
    <feature var="jabber:iq:time"/>
    <feature var="jabber:iq:version"/>
    <feature var="jabber:x:data"/>
    <feature var="jabber:x:event"/>
    <feature var="jabber:x:oob"/>
    <feature var="urn:xmpp:avatar:metadata+notify"/>
    <feature var="urn:xmpp:ping"/>
    <feature var="urn:xmpp:receipts"/>
    <feature var="urn:xmpp:time"/>
    <x xmlns="jabber:x:data" type="result">
      <field type="hidden" var="FORM_TYPE">
        <value>urn:xmpp:dataforms:softwareinfo</value>
      </field>
      <field var="software">
        <value>Tkabber</value>
      </field>
      <field var="software_version">
        <value>0.11.1-svn-20111216-mod (Tcl/Tk 8.6b2)</value>
      </field>
      <field var="os">
        <value>Windows</value>
      </field>
      <field var="os_version">
        <value>XP</value>
      </field>
    </x>
  </query>
</iq>
]]></example>
  </section2>
  <section2 topic="Gratuitous Capabilities" anchor="usecases-gratuitous">
    <p>A server MAY support pushing of <em>Capability Hashes</em> from clients before sending initial presence. This allows servers to discover capabilities of clients before those have sent initial presence, which may be useful or important for some protocols (such as <span class="ref"><link url="https://xmpp.org/extensions/xep-0369.html">Mediated Information eXchange (MIX) (XEP-0369)</link></span> <note>XEP-0369: Mediated Information eXchange (MIX) &lt;<link url="https://xmpp.org/extensions/xep-0369.html">https://xmpp.org/extensions/xep-0369.html</link>&gt;.</note>). This feature is called <em>Gratuitous Capabilities</em>.</p>
    <p>To advertise support, the server publishes the <tt>urn:xmpp:caps:gratuitous</tt> feature:</p>
    <example caption="Response to a disco#info request if the server supports Gratuitous Capabilities"><![CDATA[
<iq from='montague.lit'
    id='disco3'
    to='romeo@montague.lit/chamber'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    ...
    <feature var='urn:xmpp:caps'/>
    <feature var='urn:xmpp:caps:gratuitous'/>
    ...
  </query>
</iq>
]]></example>
    <p>After determining server support, a client can send <em>Capability Hashes</em> via <em>Gratuitous Capabilities</em> before sending initial presence:</p>
    <example caption="Sending Gratuitous Capabilities"><![CDATA[
<iq from='romeo@montague.lit/chamber'
    to='montague.lit'
    id='grat1'
    type='set'>
  <c xmlns="urn:xmpp:caps">
    <hash xmlns="urn:xmpp:hashes:2" algo="sha-256">u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=</hash>
    <hash xmlns="urn:xmpp:hashes:2" algo="sha3-256">XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=</hash>
  </c>
</iq>

<iq from='montague.lit'
    to='romeo@montague.lit/chamber'
    id='grat1'
    type='result'>
</iq>
]]></example>
    <p>The server replies with an empty result on success.</p>
    <p>The server MUST NOT broadcast the <em>Capability Hashes</em> submitted via <em>Gratuitous Capabilities</em> using presence.</p>
    <p>Clients SHOULD NOT send <em>Gratuitous Capabilities</em> after they have sent initial presence; instead, they SHOULD re-send presence to update the <em>Capability Hashes</em>. Otherwise, entities subscribed to the presence will not receive the updated <em>Capability Hashes</em>.</p>
  </section2>
</section1>

<section1 topic="Business Rules" anchor="rules">
  <section2 topic="Rules for Generating Entities" anchor="rules-generating">
    <ul>
      <li>Entities MUST respond to disco#info queries for all <em>Capability Hash Nodes</em> of at least the most recent 3 <em>Capability Hash Sets</em> emitted.</li>
      <li>Entities MUST broadcast the <em>Capability Hash Set</em> of the current disco#info it publishes in every non-directed "available" &lt;presence/&gt; they send and SHOULD do so for directed "available" &lt;presence/&gt;.</li>
      <li>After initial presence has been sent, entities MUST re-broadcast the <em>Capability Hash Set</em> after their disco#info response changes, but MAY limit the rate at which presences are emitted solely for the purpose of sending new <em>Capability Hash Sets</em>.</li>
      <li>Before initial presence has been sent and if the server supports <em>Gratuitous Capabilities</em>, entities SHOULD send <em>Gratuitous Capabilities</em> after their disco#info response changes, but MAY limit the rate at which <em>Gratuitous Capabilities</em> are sent. (For example, a client may load and enable additional functionality (thus changing its features) based on server support and only send <em>Gratuitous Capabilities</em> once all functionality has been set up, not after each individual feature.)</li>
      <li>Entities MAY assume that another entity supports <em>Entity Capabilities 2.0</em> after receiving a <em>Capability Hash Set</em> from that entity.</li>
      <li>Entities MAY also send <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> capabilities to support legacy entities.</li>
    </ul>
  </section2>

  <section2 topic="Rules for Processing Entities" anchor="rules-processing">
    <ul>
      <li>Entities MAY limit the rate at which they process incoming <em>Capability Hash Sets</em>.</li>
      <li>Entities MUST be able to process <em>Capability Hash Nodes</em> which use a hash function whose name includes the FULL STOP character (U+002E, ".").</li>
      <li>Entities MAY verify incoming <em>Capability Hash Sets</em>.</li>
      <li>Entities MUST NOT expect to receive <em>Capability Hash Sets</em> on every presence sent by an entity supporting <em>Entity Capabilities 2.0</em>.</li>
    </ul>
    <section3 topic="Caching" anchor="rules-processing-caching">
      <p>A <em>Capability Hash</em> MAY be stored alongside with its disco#info in a <em>Capability Hash Cache</em>. A received <em>Capability Hash</em> which has not been verified MUST NOT be stored.</p>
      <p>Instead of issuing a <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> disco#info &lt;query/&gt; with absent 'node' attribute to a target entity, an entity MAY use a <em>Capability Hash Cache</em> to obtain the response. To look up the disco#info response in the <em>Capability Hash Cache</em>, an entity MUST use a hash from the <em>Capability Hash Set</em> which was most recently received from the entity to which the &lt;query/&gt; would have been sent otherwise. If none of the most recently received <em>Capability Hashes</em> are found in the <em>Capability Hash Cache</em>, the entity MUST fall back to sending the request.</p>
      <p>An entity MUST NOT use <em>Capability Hashes</em> which were not included in the most recent <em>Capability Hash Set</em> received from the target entity.</p>
      <p>An entity MAY use external data sources to fill the <em>Capability Hash Cache</em>.</p>
      <p>An entity MUST ensure that implicit values for <tt>xml:lang</tt> attributes is preserved when disco#info data is cached. This can for example happen by making the implicit values explicit in the storage.</p>
    </section3>
  </section2>

  <section2 topic="Additional Rules for Clients and Servers implementing Caps Optimizations" anchor="rules-optimize">
    <ul>
      <li>Servers MAY strip off the &lt;c/&gt; element if it has not changed since the previous presence broadcast.</li>
      <li>Servers MUST ensure that the first presence notification sent to each subscriber contains the most recent &lt;c/&gt; element, if any were sent in the current presence session.</li>
      <li>Servers MUST ensure that every change in the &lt;c/&gt; element is sent to all subscribers.</li>
      <li>Clients MAY omit the &lt;c/&gt; element if it has not changed since the last presence <em>iff</em> they determined that their server supports Caps Optimization.</li>
      <li>Servers MAY answer disco#info requests for <em>Capability Hash Nodes</em> on behalf of their and others clients if the disco#info response belonging to that <em>Capability Hash</em> is known to them.</li>
    </ul>
  </section2>

  <section2 topic="Query Interception" anchor="rules-servers">
    <p>Servers MAY implement <em>Query Interception</em> to further optimise bandwidth consumption. The idea is that servers intercept <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> disco#info queries sent to clients if they already know the answer from <em>Capability Hashes</em> published by the client. The rules for <em>Query Interception</em> are the following (to be applied in this order):</p>
    <ul>
      <li>Servers MUST NOT intercept disco#info queries except those with empty <tt>node</tt> or a <tt>node</tt> which refers to a <em>Capability Hash Node</em> known to the server.</li>
      <li>Servers MUST NOT intercept disco#info queries on behalf of the resource unless the query would be forwarded to the resource otherwise.</li>
      <li>Servers MUST NOT intercept disco#info queries to resources which do not support <em>Entity Capabilities 2.0</em> (clients not implementing <em>Entity Capabilities 2.0</em> may legitimately use disco#info nodes matching the format of <em>Capability Hash Nodes</em> for different purposes).</li>
      <li>Servers SHOULD intercept disco#info queries with empty <tt>node</tt> and answer them with the disco#info of the most recent <em>Capability Hash Set</em> published by the client.</li>
      <li>Servers SHOULD intercept disco#info queries a valid <em>Capability Hash Node</em> <tt>node</tt>, if the server knows the disco#info for the <em>Capability Hash Node</em>. Otherwise, the query MUST be forwarded to the addressed resource. Note that it is valid for a sevrer to reply for <em>Capability Hash Nodes</em> which have not been published by the resource.</li>
    </ul>
  </section2>
</section1>

<section1 topic="Implementation Notes" anchor="impl">
  <section2 topic="Caching" anchor="impl-caching">
    <p>It is RECOMMENDED that entities use the caching mechanisms outlined in <link url="#rules-processing-caches">the Caching Business Rules</link>. Entities MAY share caches among connections and accounts.</p>
  </section2>
  <section2 topic="Upgrading from XEP-0115" anchor="impl-upgrade">
    <p><em>Generating Entities</em> are encouraged to also emit <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> &lt;c/&gt; elements in their presence updates (as specified in <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note>) for a reasonable transition period.</p>
    <p>When receiving a <em>Capability Hash Set</em> along with <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> capabilities, a <em>Processing Entity</em> MAY obtain the disco#info &lt;query/&gt; for verification from a <cite>XEP-0115</cite> based cache instead of querying the <em>Generating Entity</em> directly. A <em>Processing Entity</em> MUST NOT use disco#info data from a <cite>XEP-0115</cite> cache without verification if a <em>Entity Capabilities 2.0</em> &lt;c/&gt; element is available.</p>
  </section2>
</section1>

<section1 topic="Security Considerations" anchor="security">
  <section2 topic="Hash Function Input Data Separators" anchor="security-separators">
    <p>The codepoints used for separating the different parts in the <link url="#algorithm-input">Hash Function Input Algortihm</link> (0x1c (ASCII File Separator) through 0x1f (ASCII Unit Separator)) are not allowed in well-formed <link url="https://www.w3.org/TR/2008/REC-xml-20081126/#charsets">XML 1.0 character data</link><note>Note that the "ASCII Seperators" codepoints would be valid, although discouraged, <link url="https://www.w3.org/TR/2006/REC-xml11-20060816/#charsets">characters of XML 1.1</link>, but XMPP mandates XML 1.0.</note>. As entities are, per <span class="ref"><link url="http://tools.ietf.org/html/rfc6120">XMPP Core</link></span> <note>RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core &lt;<link url="http://tools.ietf.org/html/rfc6120">http://tools.ietf.org/html/rfc6120</link>&gt;.</note>, required to close a stream if non-well-formed XML 1.0 data is received, these codepoints cannot occur in the input to the algorithm and their use as separators is safe.</p>
  </section2>

  <section2 topic="Caching" anchor="security-caching">
    <p>If the algorithm for constructing the input to the hash function or the used hash function itself allow for cheap collisions, caching the hashes will become dangerous as it allows for cache poisoning. This in turn allows entities to effectively fake disco#info responses of other entities.</p>
    <p>This was an issue with <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> and has been addressed with a new algorithm for generating the hash function input which keeps the structural information of the disco#info input.</p>
    <p>An entity MUST NOT ever use disco#info which has not been verified to belong to a <em>Capability Hash</em> obtained from a cache using that <em>Capability Hash</em>. Using cache contents from a trusted source (at the discretion of the entity) counts as verifying.</p>
    <p>A malicious entity could send a large amount of <em>Capability Hash Sets</em> in short intervals, while making sure that it provides matching disco#info responses. If a <em>Processing Entity</em> uses caching, this can overflow or thrash the caches. <em>Processing Entities</em> should be aware of this risk and apply proper rate-limiting for processing <em>Capability Hash Sets</em>. To reduce the attack surface, an entity MAY choose to not cache <em>Capability Hashes</em> obtained from entities not in its roster.</p>
    <p>As mentioned earlier, when storing disco#info data in a cache for later retrieval, implementations MUST ensure that implicit values for <tt>xml:lang</tt> attributes are reconstructed correctly when the disco#info is restored.</p>
  </section2>

  <section2 topic="Directed Presence" anchor="security-directed-presence">
    <p>Entities MAY choose to not send <em>Capability Hash Sets</em> with directed presence (for example to increase privacy). In that case, entities SHOULD also refuse direct <span class="ref"><link url="https://xmpp.org/extensions/xep-0030.html">Service Discovery (XEP-0030)</link></span> <note>XEP-0030: Service Discovery &lt;<link url="https://xmpp.org/extensions/xep-0030.html">https://xmpp.org/extensions/xep-0030.html</link>&gt;.</note> queries.</p>
  </section2>

  <section2 topic="Query Interception" anchor="security-query-interception">
    <p>The server replies to certain disco#info queries on behalf of the client. This means that the client has no choice on to whom they reply. Otherwise, a client could choose to reply with <tt>&lt;service-unavailable/&gt;</tt> to mask its existence. We consider two effects of this:</p>
    <ul>
      <li>
        <p>A remote entity could attempt to detect that an entity exists behind a resource. For this, they send a disco#info query to the resource since nearly everyone implements disco#info. As the client responds with <tt>&lt;service-unavailable/&gt;</tt>, it looks as if no client was present at this resource.</p>
        <p>With <em>Query Interception</em>, the server would reply on behalf of the client. However, the consensus in the community is that by measuring the difference between the reply from the server of the resource and the reply from the actual resource, it would generally be possible to detect the existence of a resource.</p>
      </li>
      <li>
        <p>A remote entity can obtain the disco#info information of any resource which supports <em>Entity Capabilities 2.0</em> and of which the entity knows the resource.</p>
        <p>This cannot be mitigated with <em>Query Interception</em>. The risk is deemed acceptable considering that resources should generally be chosen randomly.</p>
      </li>
    </ul>
  </section2>
</section1>

<section1 topic="Design Considerations" anchor="design">
  <p>The following alternatives to the custom algorithm were considered and eventually rejected:</p>
  <section2 topic="Canonical XML" anchor="design-c14n">
    <p>A common way to canonicalize XML which could be used is <span class="ref"><link url="http://www.w3.org/TR/xml-c14n">Canonical XML</link></span> <note>Canonical XML 1.0 &lt;<link url="http://www.w3.org/TR/xml-c14n">http://www.w3.org/TR/xml-c14n</link>&gt;.</note>. It was decided not to use <cite>Canonical XML</cite> for the following reasons:</p>
    <ul>
      <li>Implementing it is quite some effort and not all XML libraries come with an implementation.</li>
      <li>It is sensitive to the relative ordering of the elements. The relative ordering of children in disco#info &lt;query/&gt; elements, however, does not matter.</li>
      <li>Several children of <span class="ref"><link url="https://xmpp.org/extensions/xep-0128.html">Service Discovery Extensions (XEP-0128)</link></span> <note>XEP-0128: Service Discovery Extensions &lt;<link url="https://xmpp.org/extensions/xep-0128.html">https://xmpp.org/extensions/xep-0128.html</link>&gt;.</note> data forms are deliberately ignored, like instructions and other descriptive text. The descriptive text is not relevant for the information is being conveyed.</li>
    </ul>
    <p>Thus, using <cite>Canonical XML</cite> would require additional, non-trivial software support and still require non-trivial additional canonicalization rules.</p>
  </section2>
</section1>

<section1 topic="IANA Considerations" anchor="iana">
    <p>This document requires no interaction with the <span class="ref"><link url="http://www.iana.org/">Internet Assigned Numbers Authority (IANA)</link></span> <note>The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see &lt;<link url="http://www.iana.org/">http://www.iana.org/</link>&gt;.</note>. </p>
</section1>

<section1 topic="XMPP Registrar Considerations" anchor="registrar">
    <section2 topic="Protocol Namespaces" anchor="ns">
      <p>The <span class="ref"><link url="https://xmpp.org/registrar/">XMPP Registrar</link></span> <note>The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see &lt;<link url="https://xmpp.org/registrar/">https://xmpp.org/registrar/</link>&gt;.</note> includes "urn:xmpp:caps" in its registry of protocol namespaces  (see &lt;<link url="https://xmpp.org/registrar/namespaces.html">https://xmpp.org/registrar/namespaces.html</link>&gt;).</p>
      <code><![CDATA[
<ns>
  <name>urn:xmpp:caps</name>
  <doc>&xep0390;</doc>
</ns>
]]></code>
    </section2>
    <section2 topic="Service Discovery Features" anchor="registrar-features">
      <p>The XMPP Registrar includes "urn:xmpp:caps" and "urn:xmpp:caps:optimize" in its registry of service discovery features (see &lt;<link url="https://xmpp.org/registrar/disco-features.html">https://xmpp.org/registrar/disco-features.html</link>&gt;).</p>
      <code><![CDATA[
<var>
  <name>urn:xmpp:caps</name>
  <desc>Indicate support for Entity Capabilities 2.0</desc>
  <doc>&xep0390;</doc>
</var>
<var>
  <name>urn:xmpp:caps:optimize</name>
  <desc>Indicate support for optimisation of Entity Capabilities 2.0 broadcast.</desc>
  <doc>&xep0390;</doc>
</var>]]></code>
    </section2>
    <section2 topic="Stream Features" anchor="registrar-stream-features">
      <p>The XMPP Registrar includes "urn:xmpp:caps" in its registry of stream features (see &lt;<link url="https://xmpp.org/registrar/stream-features.html">https://xmpp.org/registrar/stream-features.html</link>&gt;).</p>
      <code><![CDATA[
<feature>
  <ns>urn:xmpp:caps</ns>
  <name>ecaps2</name>
  <element>c</element>
  <desc>Indicate support for Entity Capabilities 2.0 and publish capabilities to peer.</desc>
  <doc>&xep0390;</doc>
</feature>
]]></code>
    </section2>
</section1>

<section1 topic="XML Schema" anchor="schema">
  <code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
  xmlns:xs='http://www.w3.org/2001/XMLSchema'
  targetNamespace='urn:xmpp:caps'
  xmlns='urn:xmpp:caps'
  elementFormDefault='qualified'
  xmlns:hashes='urn:xmpp:hashes:2'>

  <!-- FIXME: import of XEP-0300 schema, which isn't at https://xmpp.org/schemas/ at the time of writing -->

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in XEP-0390:
      http://www.xmpp.org/extensions/xep-0390.html
    </xs:documentation>
  </xs:annotation>

  <xs:element name='c'>
    <xs:complexType>
      <xs:sequence minOccurs='1'>
        <xs:element ref='hashes:hash' minOccurs='1' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>
]]></code>
</section1>

<section1 topic="Acknowledgements" anchor="acknowledgements">
  <p>Thanks to the authors of <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> for coming up with the original idea of using presence broadcast to convey service discovery information, as well as the optimization strategies.</p>
  <p>The note below the example in <link url="#usecases-stream-feature">Advertisement of Support and Capabilities by Servers</link> has been copied verbatimly from <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note>.</p>
  <p>Thanks to Waqas Hussain for originally (to my knowledge) pointing out the security flaws in <span class="ref"><link url="https://xmpp.org/extensions/xep-0115.html">Entity Capabilities (XEP-0115)</link></span> <note>XEP-0115: Entity Capabilities &lt;<link url="https://xmpp.org/extensions/xep-0115.html">https://xmpp.org/extensions/xep-0115.html</link>&gt;.</note> (see <note>org.jabber.security Mailing List Archive: '[Security] Trivial preimage attack against the entity capabilities protocol)' from 2009-07-22, &lt;<link url="https://mail.jabber.org/pipermail/security/2009-July/000812.html">https://mail.jabber.org/pipermail/security/2009-July/000812.html</link>&gt;.</note>).</p>
  <p>Thanks to Dave Cridland, Georg Lukas, Link Mauve, Sebastian Riese, Florian Schmaus and Sam Whited for their input, editorial and otherwise.</p>
</section1>

</xep>
